|
|
|
В этой статье мы научимся отображать простейший трехмерный объект - кубик. За основу мы возьмём проект из "первой статьи". Далее я приведу текст который нужно будет вставить в него, а незатронутые здесь функции будут опущены. Для начала определим несколько новых переменных в начале переменных: первым делов объявляем два буфера: один буфер вершинный, другой - индексный. Можно воспользоваться и одним, но так уйдет меньше памяти. |
LPDIRECT3DVERTEXBUFFER9 MyVertexBuffer; // Вертекс буфер для отрисовки кубика LPDIRECT3DINDEXBUFFER9 MyIndexBuffer; // Индекс буфер для отрисовки кубика |
|
Далее определяем структуру наших вершин. У нас они содержат свою позицию и цвет: |
struct MyVertex
{
D3DXVECTOR3 position;
D3DCOLOR color;
};
|
|
Потом оговариваем формат вершин. |
const DWORD MyVertex_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; |
|
Теперь переходим к функции инициализации AllInit. Вот как она должна выглядеть: |
bool AllInit()
{
if(!InitD3D())
return false;
|
|
После этого создадим буфер вершин: |
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 8*sizeof(MyVertex), // Размер буфера (в нашем случае 8 вершин // каждая размером в структуру MyVertex) D3DUSAGE_WRITEONLY, // Используем буфер только для чтения MyVertex_FVF, // Формат наших вершин D3DPOOL_MANAGED, // DirectX сам управляет пересозданием буфера &MyVertexBuffer, // Наш указатель на буфер NULL // Оставим NULL ) ) ) return false; // Если произошла ошибка сообщить об этом |
|
И буфер индексов: |
if( FAILED( g_pd3dDevice->CreateIndexBuffer( 36*sizeof(short), // Размер буфера индексов (в нашем случае // 36 индексов каждый размером в short) D3DUSAGE_WRITEONLY, // Используем буфер только для чтения D3DFMT_INDEX16, // Формат индексов (для short - D3DFMT_INDEX16 // для DWORD - D3DFMT_INDEX32) D3DPOOL_MANAGED, // DirectX сам управляет пересозданием буфера &MyIndexBuffer, // Наш указатель на буфер NULL // Оставим NULL ) ) ); return false; |
|
А теперь надо их заполнить :)) Сначала вершины: |
// Вершины для кубика
MyVertex v[] =
{
{ -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 0, 0), },
{ -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), },
{ 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 0, 0, 255), },
{ 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 0), },
{ 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 255), },
{ 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 0, 255, 255), },
{ -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 0), },
{ -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 255), }
};
void * pBuf;
// заполненяем вершинный буфер
MyVertexBuffer->Lock( 0, 8 * sizeof(MyVertex), &pBuf, 0 );
memcpy( pBuf, v, 8 * sizeof(MyVertex));
MyVertexBuffer->Unlock();
|
|
Теперь индексы: |
// Индексы для кубика
short inds[36] =
{
0, 1, 2,
2, 1, 3,
2, 3, 4,
4, 3, 5,
4, 5, 6,
6, 5, 7,
6, 7, 0,
0, 7, 1,
1, 7, 3,
3, 7, 5,
0, 2, 6,
2, 4, 6};
// заполненяем индексный буфер
MyIndexBuffer->Lock( 0, 36 * sizeof(short), &pBuf, 0 );
memcpy( pBuf, inds, 36 * sizeof(short));
MyIndexBuffer->Unlock();
|
|
По умолчанию Direct3D не рисует задние стороны полигонов, поэтому на всякий пожарный мы отключим эту функцию (cull). У нас не ни одной лампочки на сцене (пока...), и поэтому отключим освещение, иначе все будет темно (???). И напоследок включаем буфер глубины (Z-буфер), чтобы наш кубик правильно отображался. Потом просчитываем проекционную матрицу. Все это происходит в функции ReInit. Добавляем ее сюда: |
ReInit(); return true; } |
|
Переходим к процедуре рисования. Чтобы отрисовать наш кубик мы должны: 1. Устанавливить вершинный буфер. Делается это функцией SetStreamSource( 0, MyVertexBuffer, 0, sizeof(MyVertex) ); 2. Устанавливить индексный буфер: SetIndices(MyIndexBuffer); 3. Установить формат вершин: SetFVF( MyVertex_FVF ); 4. Произвести отрисовку примитива: DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12); Теперь функция отрисовки у нас будет выглядеть так: |
VOID Render()
{
HRESULT hr;
// Проверяем Direct3dDevice на потерянность
hr = g_pd3dDevice->TestCooperativeLevel();
// если окно не в фокусе выходим из цикла рендеринга
if(hr==D3DERR_DEVICELOST)
return;
// если окно опять в фокусе пытаемся восстановить устройство рендеринга
if(hr==D3DERR_DEVICENOTRESET)
{
Cleanup();
g_pd3dDevice->Reset(&d3dpp); // если окно опять в фокусе пытаемся
// восстановить наш g_pd3dDevice
if( g_pd3dDevice )
ReInit();
}
if( NULL == g_pd3dDevice )
return;
// Начинаем отрисовку нашей сцены
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Очищаем задний буфер и буфер глубины
g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(rand()%255, rand()%255, rand()%255), 1.0f, 0L);
//--------------------------//
// Здесь мы будем рисовать! //
//--------------------------//
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
//D3DXMatrixRotationZ(&matWorld, GetTickCount()/1024.0f);
D3DXMatrixRotationYawPitchRoll( &matWorld,
GetTickCount()/1024.0f,
GetTickCount()/2048.0f,
GetTickCount()/2048.0f );
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3(4.0f, 4.0f, 4.0f), // Точка из которой мы смотрим
// Место положения камеры
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), // Точка в которую смотрим
&D3DXVECTOR3(0.0f, 1.0f, 0.0f)); // Где верх?
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
// Устанавливаем вершинный и индексный буфера
g_pd3dDevice->SetStreamSource( 0, MyVertexBuffer, 0, sizeof(MyVertex) );
g_pd3dDevice->SetIndices(MyIndexBuffer);
// устанавливаем формат вершин
g_pd3dDevice->SetFVF( MyVertex_FVF );
// Производим отрисовку
g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
g_pd3dDevice->EndScene(); // Закончили рисовать
g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); // Отображаем задний буфер
}
}
|
|
Перед завершением программы нам остается только освободить память из под буферов: переходим в функцию AllShutdown() и добавляем: |
SAFE_RELEASE(MyVertexBuffer); SAFE_RELEASE(MyIndexBuffer); |
|
Теперь она выглядит у нас так: |
void AllShutdown()
{
Cleanup();
SAFE_RELEASE(MyVertexBuffer);
SAFE_RELEASE(MyIndexBuffer);
SAFE_RELEASE(g_pd3dDevice);
SAFE_RELEASE(g_pD3D);
}
|
|
На этом статья заканчивается, и теперь у вас есть возможность пофантазировать... Исходник к статье можете взять ЗДЕСЬ! (~100Kb) Всем пока. Автор: L1f 
|
|
|