Настало время нам оградиться стеной :)
Снова изменим нашу структуру вершин добавив в нее пару дополнительных параметров содержащие координаты текстуры:
#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1) struct CUSTOMVERTEX { float x, y, z, nx, ny, nz, tu, tv; };
Установим новые вершины:
CUSTOMVERTEX g_Vertices[] = { { -100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { -100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { 100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { -100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { 100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, };
Перейдем в функцию Transform3D и изменим параметры камеры или глаза наблюдателя, кому как удобней, повыше и заодно поставим сцену в исходное положение.
D3DXMatrixRotationY (&matWorld, 0.0f); D3DXMatrixLookAtLH (&matView, &D3DXVECTOR3 (0.0f, 500.0f, -500.0f), &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));
Теперь в структуру класса рамки добавим текстуру:
class CMainWnd : public CFrameWnd { private: LPDIRECT3D8 p_d3d; // наш главный интерфейс LPDIRECT3DDEVICE8 p_d3d_Device; // наше устройство d3d8 D3DDISPLAYMODE d3ddm; // способ отображения D3DPRESENT_PARAMETERS d3dpp; // параметры монитора LPDIRECT3DVERTEXBUFFER8 p_VertexBuffer; // наш буфер вершин LPDIRECT3DTEXTURE8 textura001; // наша текстура . . .
Более подробно об этой структуре см. раздел Справка по DirectX: "Шаг 67 - Описание интерфейса IDirect3DTexture8". Так как мы создали указатель, то не забудем его удалить:
CMainWnd::~CMainWnd(void) { _RELEASE_ (textura001); _DELETE_ (textura001); _RELEASE_ (p_VertexBuffer); _DELETE_ (p_VertexBuffer); _RELEASE_ (p_d3d_Device); _DELETE_ (p_d3d_Device); _RELEASE_ (p_d3d); _DELETE_ (p_d3d); }
В конструкторе главного окна загрузим нашу текстуру и присвоим указатель на нее, добавьте перед закрывающей скобкой:
D3DXCreateTextureFromFile (p_d3d_Device, "01.jpg", &textura001);
Более подробно об этой функции см. раздел Справка по DirectX: "Шаг 68 - Текстурная функция D3DXCreateTextureFromFile". И, конечно, нам нужно не только загрузить в память, но и отобразить в нашей сцене:
p_d3d_Device->BeginScene (); p_d3d_Device->SetVertexShader (D3DFVF_CUSTOMVERTEX); p_d3d_Device->SetStreamSource (0, p_VertexBuffer, sizeof(CUSTOMVERTEX)); p_d3d_Device->SetTexture (0, textura001); p_d3d_Device->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE); p_d3d_Device->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 2); p_d3d_Device->EndScene ();
Более подробно об этих функциях см. раздел Справка по DirectX:
Компилируем, запускаем. И видим, что стенка есть, текстуры нет... Все правильно, мы не указали как текстуре накладываться на наш объект:
Из рисунка видно, как спроецировать текстуру на наш объект. 0,0 - это начало координат, 1 - это максимум пикселей в текстуре по оси tu и tv. Точку 0,0 на текстуре у нас занимает вторая вершина первого треугольника, поэтому в структуре вершин здесь оставляем 0,0. 0,1 - занимает первая вершина первого треугольника, а также первая вершина второго треугольника. 1,0 - соответствует третьей вершине первого треугольника и вторая вершина второго треугольника. А 1,1 - это третья вершина второго треугольника, поэтому структура у нас выглядит следующим образом:
CUSTOMVERTEX g_Vertices[] = { { -100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, { -100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, { 100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, { -100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, { 100.0f, 180.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, { 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, };
Компилируем и запускаем :) Yes, у нас это получилось :) но доски слишком широкие... Размножим текстуру по оси tu. Вместо выделенных единиц поставьте 6.0f. Скомпилируйте и запустите свое приложение. Симпатично :)
Самый важный атрибут у текстуры - это размер изображения. Так как именно из за него зависит скорость игрушки. Размер изображения должен быть 32х32, 128х256 или 4х4, т.е. кратный двум. Размер 320х240 не подходит и лучше не использовать... Я в данном шаге принебрег этим правилом, т.к. здесь скорость не столь важна...
Вывод: мы можем много что сделать с текстурой, комбинируя разными значениями: например, повернуть или заставить ее вращаться в реальном времени, сделать зеркальное отражение, размножить на поверхности и т.д. и т.п. Заставьте снова вращаться нашу сцену, замените флажок D3DCULL_NONE, скажем, на D3DCULL_CCW и посмотрите, что будет.