13 марта 2010 в 16:32
Direct3D Урок 03: Использование текстур
Мы уже научились инициализировать Direct3D и выводить простые полиональные объекты. Но они как-то странно выглядят. Для придания простым малополигональным объектам 3D сцен в Direct3D можно наложить на них текстуры - простые двухмерные картинки с каким либо рисунком, заменяющим натуральный рельеф.
Итак для отображения текстур нам всего лишь необходимо в каждой вершине модели указать текстурные координаты. В соответствии с ними 2D картинка будет накладываться на поигон. Так как мы отображаем кубик - восемью вершинами нам необойтись, поэтому в этом уроке мы откажемся от индексного буфера, и будем пользоваться только вершинным... Начнем.
Каркас возьмем из первого урока. Теперь будем просто добавлять в него недостающий текст.
В начале объявим вершинный буфер и указатель на нашу будущую текстуру:
LPDIRECT3DVERTEXBUFFER9 MyVertexBuffer; // Вертекс буфер для отрисовки кубика LPDIRECT3DTEXTURE9 MyTexture; // Текстура для нашего кубика
Структура наших вершин обновилась. Теперь вершины содержат еще и две текстурные координаты:
struct MyVertex { float x,y,z; DWORD color; float tx,ty; // Координаты текстуры };
Формат вершин тоже не остался без изменений:
DWORD MyVertex_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
Функции инициализации AllInit обновилась: сначала инициализируем Direct3D, потом создаем буфер вершин, заполняем массив вершин, заполненяем вершинный буфер, и наконец самое главное загружаем нашу текстуру из файла! Выглядит она теперь вот так:
bool AllInit() { if(!InitD3D(Width, Height, fullscreen)) return false; if( FAILED( g_pd3dDevice->CreateVertexBuffer( 36*sizeof(MyVertex), // Размер буфера (в нашем случае 36 вершин // каждая размером в структуру MyVertex) D3DUSAGE_WRITEONLY, // Используем буфер только для чтения (быстрее) MyVertex_FVF, // Формат наших вершин D3DPOOL_MANAGED, // DirectX сам управляет пересозданием буфера &MyVertexBuffer, // Наш указатель на буфер NULL // Оставим NULL ) ) ) return false; // Если произошла ошибка сообщить об этом // Вершины для кубика MyVertex v[] = { { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 0.0f, 0.0f,}, { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 1.0f, 0.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 1.0f, 1.0f,}, { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 0.0f, 0.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 1.0f, 1.0f,}, { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 0), 0.0f, 1.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 1.0f, 0.0f,}, { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 1.0f, 1.0f,}, { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 0.0f, 1.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 1.0f, 0.0f,}, { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 0.0f, 1.0f,}, { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 0, 255, 0), 0.0f, 0.0f,}, { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 0, 255), 0.0f, 1.0f,}, { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255), 0.0f, 0.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255), 1.0f, 0.0f,}, { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 0, 255), 0.0f, 1.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 0, 0, 255), 1.0f, 0.0f,}, { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 0, 0, 255), 1.0f, 1.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 0), 1.0f, 1.0f,}, { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 0), 0.0f, 1.0f,}, { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 0), 0.0f, 0.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 0), 1.0f, 1.0f,}, { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 0), 0.0f, 0.0f,}, { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 0), 1.0f, 0.0f,}, { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 0, 255), 1.0f, 0.0f,}, { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 255, 0, 255), 1.0f, 1.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 255), 0.0f, 1.0f,}, { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 0, 255), 1.0f, 0.0f,}, { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 255), 0.0f, 1.0f,}, { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 0, 255), 0.0f, 0.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 255), 0.0f, 0.0f,}, { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 255), 1.0f, 0.0f,}, { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 255), 1.0f, 1.0f,}, { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 255), 0.0f, 0.0f,}, { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB( 255, 255, 255), 1.0f, 1.0f,}, { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB( 255, 255, 255), 0.0f, 1.0f,} }; void * pBuf; // заполненяем вершинный буфер MyVertexBuffer->Lock( 0, 36 * sizeof(MyVertex), &pBuf, 0 ); memcpy( pBuf, v, 36 * sizeof(MyVertex)); MyVertexBuffer->Unlock(); // Загружаем текстуру из файла D3DXCreateTextureFromFile(g_pd3dDevice, "Texture.bmp", &MyTexture); ReInit(); return true; }
Теперь переходим к самому сладкому - отрисовке сцены. И вставим в секцию
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { }
следующих код:
// переменная для плавного переливания фона (для красоты)... float time=GetTickCount()/2048.0f; // Очищаем задний буфер и буфер глубины g_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( int((cos(time*2.0f)+1.0f)/2.0f*255), int((cos(time )+1.0f)/2.0f*255), int((sin(time*2.0f)+1.0f)/2.0f*255)), 1.0f, 0L); //--------------------------// // Здесь мы будем рисовать! // //--------------------------// D3DXMATRIX matWorld; 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->SetFVF( MyVertex_FVF ); // Если текстура нормально загрузилась if( MyTexture != NULL ) g_pd3dDevice->SetTexture(0, MyTexture); // Ставим текстуру // Устанавливаем фильтрацию текстур // Поэкспериментируйте - увидите разницу: // // D3DTEXF_NONE - фильтрация не испоьзуется // D3DTEXF_POINT - точечная фильтрация // D3DTEXF_LINEAR - линейная фильтрация // D3DTEXF_ANISOTROPIC - анизотропная фильтрация g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); // Производим отрисовку g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 12); g_pd3dDevice->EndScene(); // Закончили рисовать g_pd3dDevice->Present( NULL, NULL, NULL, NULL );// Отображаем задний буфер
Осталось только в AllShutdown() освободить память из-под всех созданных объектов:
void AllShutdown() { Cleanup(); SAFE_RELEASE(MyTexture); // Освобождаем память из-под текстуры SAFE_RELEASE(MyVertexBuffer); SAFE_RELEASE(g_pd3dDevice); SAFE_RELEASE(g_pD3D); }
Теперь вы умеете загружать текстуры в Direct3D, и ваши программы будут выглядеть намного эффектнее.
14 июля 2023 в 20:36
ВЯлА
авторизуйтесь
или войдите через