Урок 7. Текстуры в Direct3D10
В этом уроке вы узнаете: какие бывают типы текстур в Direct3D; каким образом осуществляется загрузка текстур в Direct3D; каким образом устанавливаются текстуры для использования их в шейдере.
Типы данных текстур Direct3D
В основном, программистам игр и мультимедийных приложений необходимо загрузить текстуру к текущей модели, то есть как правило, если модель вообще использует текстуру, то для одного вершинного и индексного буфера используется одна текстура. Но в Direct3D существуют и другие типы данных текстур, краткий обзор которых мы проведем, прежде чем приступим к изучению того, как устанавливается текстура.
Типы текстур, используемы в Direct3D10:
- Обычная 2Dтекстура формата R8G8B8
- Текстура 2Dс картой прозрачности R8G8B8A8
- Кубическая 2Dтекстура, которая может использоваться для поверхности неба типа скайбокс, состоящая из 6 фрагментов 2Dтекстуры формата R8G8B8
- Трехмерная 3Dтекстура формата R8G8B8
- Пустая текстура, используемая в качестве рендер-таргета
- Пустая текстура, используемая для программной генерации рисунка текстуры
Загрузка и установка текстур в Direct3D является несложным действием. В этом вы можете убедится, в разделе, расположенном чуть ниже. Для того, чтобы более детально понять почему загрузка текстур в DirectX10 осуществляется именно таким образом, вы можете ознакомится в разделе о расширенном методе загрузки текстур в конце данного урока.
Загрузка текстур в Direct3D
Итак, вы подготовили вершинный и индексный буфер, загрузив меш из файла или заполнив процедурно-сгенерированными данными. Для того, чтобы одновременно загрузить текстуру, создав при этом объект для хранения этой текстуры типа ID3D10ShaderResourceView необходимо воспользоваться следующим кодом загрузки текстуры:
ID3D10ShaderResourceView *g_pTextureRv = NULL; D3DX10CreateShaderResourceViewFromFile( g_pd3dDevice, L"seafloor.dds", NULL, NULL, &g_pTextureRV, NULL ); |
Обратите внимание, что в данном примере используется формат текстур типа .dds. Direct3D поддерживает большое разнообразие форматов, включая bmp, jpg иpng. Для текстур, использующих альфа канал подойдут форматы pngиtga.
Установка текстуры в качестве константы шейдера
Вы помните, как устанавливались матрицы в качестве констант шейдера. Также обстоит дело и с текстурами. Мы можем указать константу шейдера, и затем назначать ей новые значения (различные текстуры). В программе текстуры хранятся в виде экземпляров объекта типа ID3D10ShaderResourceView. Итак, после загрузки шейдера вы должны прежде всего создать переменную для хранения константы шейдера в вашей программе.
ID3D10EffectShaderResourceVariable & g_pDiffuseTextureVariable = NULL; g_pDiffuseTextureVariable = g_pEffect->GetVariableByName("txDiffuse")->AsShaderResource(); |
Непосредственно в функции Render мы можем назначить этой константе шейдера новые значения точно также, как мы устанавливали константы шейдера для матриц:
g_pDiffuseVariable->SetResource( g_pTextureRV ); |
Обратите внимание, что у нас может быть несколько переменных g_pTextureRV, например, массив из загруженных текстур вида g_pTextureRV[]. Таким образом, мы можем выбирать текстуру, которую устанавливаем из нескольких загруженных текстур:
g_pDiffuseVariable->SetResource( g_pTextureRV[index] ); |
Использование текстуры в шейдере
Сначала необходимо отметить, что для того, чтобы текстуры в шейдере функционировали, необходимо, чтобы во входящий формат вершинного шейдера была добавлена переменная формата , описывающая координаты текстуры. Но сначала определим константы шейдера для текстуры и mipmap формат:
Texture2D txDiffuse; SamplerState samLinear { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; } |
Входящие данные пиксельногошейдера должны включать такую переменную Tex, хранящую информацию о координатах текстуры.
structVS_OUTPUT { float4 Pos: SV_POSITION; float4 Color: COLOR0; float2 Tex : TEXCOORD0; } |
После того, как такая переменная установлена, вершинныйшейдер может передать эту переменную через себя в пиксельный шейдер:
VS_OUTPUT VS(float4 Pos:POSITION,float4 color: COLOR, float2 Tex: TEXCOORD) { ... output.Tex=Tex; ... } |
Таким образом, пиксельный шейдер во входящей структуре PS_INPUT будет иметь переменную input.Tex типа float2.
float4 PS( PS_INPUT input) : SV_Target { return txDiffuse.Sample( samLinear, input.Tex ) * vMeshColor; } |
После того, как пиксельный шейдер получит данные о текстурных координатах, он может осуществить выборку цвета из текстуры, в соответствии с координатами. Для того используется функция шейдера
txDiffuse.Sample( samLinear, input.Tex ) |
Входящими данными является указание объекта из которого выполняется выборка txDiffuse, тип семплера samLinear а также координаты текстуры input.Tex. Метод txDiffuse.Sample возращает значение типа float4, то есть цвет в формате R8G8B8A8.
Установка формата вершинного буфера, подходящего для использвания текстур
Для того, чтобы текстура могла использоваться в шейдере, каждая из вершин вершинного буфера должна содержать координаты текстуры. Обычно координаты текстуры обозначаются символами u и v, обозначающими координаты текстуры. Значения этих чисел лежат в диапазоне от 0 до 1. Таки образом, координаты текстуры образуют двухкомпонентный вектор.
Вы знаете, что трехмерные вектора в DirectX обозначаются как D3DXVECTOR3. Соответственно для двухмерных мы должны указать D3DXVECTOR2. Соответственно, если в нашем вершинном буфере содержатся только координаты о положении вершины, то мы должны добавить также и текстурные координаты.
structSimpleVertex { D3DXVECTOR3 Pos; // Координата D3DXVECTOR2 Tex; // Координата текстуры }; |
Также мы должны дополнить формат входящих данных вершинного буфера описанием типа вершинного буфера с учетом координат.
// Определение формата вершинного буфера D3D10_INPUT_ELEMENT_DESC layout[] = { { L"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, { L"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, }; |
В данном коде каждая вершина вершинного буфера содержит лишь две переменные. Однако зачастую их больше. Более полный набор данных для вершины будет включать в себя также цвет вершины и информацию о нормали.
Обзор приложения
Теперь посмотрим, какой результат мы достигли при загрузке текстуры.
В нашем приложении, исходный код которого можно скачать тут, выполняется загрузка текстуры, установка её константой шейдера и далее выборка цветой из этой текстуры в пиксельном шейдере.
Заключение
В данном уроке вы ознакомились с тем, какие бывают типы текстур, какие типы данных используются в Direct3Dдля их хранение, как загружать текстуры и устанавливать их в качестве констант шейдера. В следующем уроке мы поговорим о том, как загружать меши в приложение Direct3D10.
Заполнен: DirectX10
