Войти
ПрограммированиеСтатьиГрафика

Direct3D: Текстурирование.

Автор:

Текстуры — это самый простой в реализации способ сделать наш виртуальный мир похожим на реальный. Текстуры представляют собой обычное графическое изображение, которое «натягивается» поверх модели. Наиболее простым примером текстуры могут служить ОБОИ.

И так, рассмотрим подробнее, как работать с текстурами.

Для того, чтобы мы могли использовать текстуры, нам необходимо определить формат вершин, который будет включать в себя текстурные координаты. Для этого мы воспользуемся следующим кодом:

#define MY_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

struct SMyVertex
{
  D3DXVECTOR3 pos;    
  D3DXVECTOR3 norm;    
  FLOAT tu, tv;      
};

В описании вершины добавились переменные tu и tv. Это текстурные координаты. Определяются они следующим образом: левый верхний угол графического изображения имеет координаты (0.0, 0.0), а правый нижний координаты (1.0, 1.0). Т.е. значения текстурных координат могут лежать в интервале от 0.0 до 1.0. Также возможны значения и больше 1.0, но тогда текстура будет повторяться (по-английски это звучит как tiling).

И так, после того, как мы определили формат вершин, нам необходимо загрузить текстуры и установить вершинные координаты, причем каждая из них должна включать также и текстурные.

И так, приступим к загрузке текстуры.

В Direct3D текстуры представлены интерфейсом IDirect3DTexture8, с помощью которого и производится большинство манипуляций с ними. Объявим переменную, через которую мы будем "общаться" с этим интерфейсом:

LPDIRECT3DTEXTURE8 g_pTexture;
Тип LPDIRECT3DTEXTURE8 объявлен как указатель на IDirect3DTexture8

Теперь мы можем загружать нашу текстуру. Воспользуемся функцией вспомогательной библиотеки D3DX: D3DXCreateTextureFromFile:

if (FAILED(D3DXCreateTextureFormFile(g_pd3dDevice, "Tex1.bmp", &g_pTexture)))
  return E_FAIL;

В качестве текстур мы можем использовать любые графические форматы, такие как: jpg, bmp, tga, tiff и др. В целях оптимизации рекомендуется использовать текстуры, размеры сторон которых кратны степеням двойки (т.е. 2, 4, 8, 16, 32, 64, и т.д.).

И так, мы загрузили текстуру. Далее мы должны задать наши вершины, по которым мы будем строить объект:

vertices[0].pos = D3DXVECTOR3(-1.0, 1.0, 0.0);
vertices[0].norm = D3DXVECTOR3(0.0, 0.0, -1.0);
vertices[0].tu = 0.0f;
vertices[0].tv = 0.0f;

vertices[1].pos = D3DXVECTOR3(1.0, 1.0, 0.0);
vertices[1].norm = D3DXVECTOR3(0.0, 0.0, -1.0);  
vertices[1].tu = 1.0f;
vertices[1].tv = 0.0f;

vertices[2].pos = D3DXVECTOR3(-1.0, -1.0, 0.0);
vertices[2].norm = D3DXVECTOR3(0.0, 0.0, -1.0);  
vertices[2].tu = 0.0f;
vertices[2].tv = 1.0f;

vertices[3].pos = D3DXVECTOR3(-1.0, -1.0, 0.0);
vertices[3].norm = D3DXVECTOR3(0.0, 0.0, -1.0);  
vertices[3].tu = 0.0f;
vertices[3].tv = 1.0f;  

vertices[4].pos = D3DXVECTOR3(1.0, 1.0, 0.0);
vertices[4].norm = D3DXVECTOR3(0.0, 0.0, -1.0);  
vertices[4].tu = 1.0f;
vertices[4].tv = 0.0f;

vertices[5].pos = D3DXVECTOR3(1, -1.0, 0.0);
vertices[5].norm = D3DXVECTOR3(0.0, 0.0, -1.0);  
vertices[5].tu = 1.0f;
vertices[5].tv = 1.0f;

Элементами структуры tu и tv мы как раз и устанавливаем текстурные координаты, в данном примере, мы просто растянули текстуру на весь квадрат.

После того, как мы загрузили текстуру и установили вершинные координаты, необходимо сказать Direct3D что он может использовать данную текстуру. Делается это с помощью следующего кода:

g_pd3dDevice->SetTexture(0, g_pTexture);

g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,  D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1,D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2,D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,  D3DTOP_DISABLE);

В первой строке мы устанавливаем в первый текстурный уровень (stage) нашу текстуру. В Direct3D мы можем использовать до 8 текстурных уровней, т.е. первый параметр функции SetTexture может принимать значение от 0 до 7. С помощью данной возможности в Direct3D реализуется мультитекстурирование, но об этом как-нибудь потом.

В следующих строках мы устанавливаем текстурные состояния, при помощи которых Direct3D будет знать, как он должен визуализировать текстуру.

Вот собственно и все, теперь надо отобразить наш примитив, делается это следующим образом:

g_pd3dDevice->SetStreamSource(0, g_pVB, sizeof(SMyVertex));
g_pd3dDevice->SetVertexShader(MY_VERTEX_FORMAT);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

Да, и надо не забывать, что вышеописанные операции, естественно кроме инициализации необходимо совершать в скобках g_pd3dDevice->Begin() : g_pd3dDevice->End().

Вот собственно и все, после выполнения примера, на экране должно появится нечто похожее на это:

Изображение

Пример:exe + исходник (155 кБ)

#Direct3D, #текстурирование

14 февраля 2002

Комментарии [0]