Программирование графики с использованием Direct3D

         

Функция TextureDriftWin::CreateScene()


Функция TextureDriftWin::CreateScene() создает одну сетку и одну текстуру. Текстура связывается с сеткой, но наложения текстуры не выполняется. При каждом обновлении экрана функция обратного вызова генерирует новое наложение текстуры. Текст функции CreateScene() представлен в листинге5.5.



Листинг 5.5. Функция TextureDriftWin::CreateScene()

BOOL TextureDriftWin::CreateScene() { //------ КОНСТРУКТОР СЕТОК ------ D3DRMLOADRESOURCE resinfo; resinfo.hModule = NULL; resinfo.lpName = MAKEINTRESOURCE(IDR_D3DMESH); resinfo.lpType = "MESH"; LPDIRECT3DRMMESHBUILDER meshbuilder; d3drm->CreateMeshBuilder(&meshbuilder); meshbuilder->Load(&resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL); meshbuilder->Scale(D3DVALUE(1), D3DVALUE(1), D3DVALUE(.5)); ScaleMesh(meshbuilder, D3DVALUE(35)); meshbuilder->SetPerspective(TRUE); //------- ТЕКСТУРА ------ HRSRC texture_id = FindResource(NULL, MAKEINTRESOURCE( IDR_TEXTURE), "TEXTURE"); LPDIRECT3DRMTEXTURE texture; d3drm->LoadTextureFromResource(texture_id, &texture); meshbuilder->SetTexture(texture); texture->Release(); texture = 0; //-------- СЕТКА -------- LPDIRECT3DRMMESH mesh; meshbuilder->CreateMesh(&mesh); meshbuilder->Release(); meshbuilder = 0; //-------- ФРЕЙМ СЕТКИ -------- LPDIRECT3DRMFRAME meshframe; d3drm->CreateFrame(scene, &meshframe); meshframe->SetOrientation(scene, D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1), D3DVALUE(0), D3DVALUE(1), D3DVALUE(0)); meshframe->AddVisual(mesh); meshframe->AddMoveCallback(MoveTexture, NULL); meshframe->Release(); meshframe = 0; mesh->Release(); mesh = 0; //-------- СВЕТ ---------- LPDIRECT3DRMLIGHT light; d3drm->CreateLightRGB(D3DRMLIGHT_AMBIENT, D3DVALUE(1),D3DVALUE(1), D3DVALUE(1), &light); scene->AddLight(light); light->Release(); light = 0; //-------- ПОРТ ПРОСМОТРА ---------- d3drm->CreateFrame(scene, &camera); camera->SetPosition(scene, D3DVALUE(0.0), D3DVALUE(0.0), D3DVALUE(-50.0)); d3drm->CreateViewport(device, camera, 0, 0, device->GetWidth(), device->GetHeight(), &viewport); return TRUE; }

Функция CreateScene() выполняет следующие действия:

  1. Создание сетки с использованием интерфейса Direct3DRMMeshBuilder.
  2. Создание текстуры для сетки.
  3. Создание интерфейса Direct3DRMMesh.
  4. Создание фрейма для сетки.
  5. Создание источника света.
  6. Создание порта просмотра.

Сначала для загрузки сетки из ресурсов приложения используется интерфейс Direct3DRMMeshBuilder:

D3DRMLOADRESOURCE resinfo; resinfo.hModule = NULL; resinfo.lpName = MAKEINTRESOURCE(IDR_D3DMESH); resinfo.lpType = "MESH"; LPDIRECT3DRMMESHBUILDER meshbuilder; d3drm->CreateMeshBuilder(&meshbuilder); meshbuilder->Load(&resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL); meshbuilder->Scale(D3DVALUE(1), D3DVALUE(1), D3DVALUE(.5)); ScaleMesh(meshbuilder, D3DVALUE(35)); meshbuilder->SetPerspective(TRUE);

Обратите внимание, что после загрузки сетки мы используем функцию Scale() интерфейса Direct3DRMMeshBuilder для уменьшения размера сетки по оси Z. Мы передаем функции Scale() в качестве аргумента Z значение 0.5, чтобы вдвое уменьшить размер сетки по оси Z. После вызова функции Scale() используется функция ScaleMesh() для масштабирования сетки таким образом, чтобы ее максимальный размер равнялся 35 единицам. Функция SetPerspective() вызывается чтобы разрешить перспективную коррекцию.

Затем создается текстура:

HRSRC texture_id = FindResource(NULL, MAKEINTRESOURCE(IDR_TEXTURE), "TEXTURE"); LPDIRECT3DRMTEXTURE texture; d3drm->LoadTextureFromResource(texture_id, &texture); meshbuilder->SetTexture(texture); texture->Release(); texture = 0;

Новая текстура привязывается к ранее созданному конструктору сеток с помощью функции SetTexture(), но наложение текстуры не создается. Потом существующий конструктор сеток применяется для создания экземпляра интерфейса Direct3DRMMesh:

LPDIRECT3DRMMESH mesh; meshbuilder->CreateMesh(&mesh); meshbuilder->Release(); meshbuilder = 0;

После вызова функции CreateMesh() конструктор сеток нам больше не нужен, поэтому указатель на него освобождается.

Теперь настала пора создать фрейм и присоединить к нему сетку:

LPDIRECT3DRMFRAME meshframe; d3drm->CreateFrame(scene, &meshframe); meshframe->SetOrientation(scene, D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1), D3DVALUE(0), D3DVALUE(1), D3DVALUE(0)); meshframe->AddVisual(mesh); meshframe->AddMoveCallback(MoveTexture, NULL); meshframe->Release(); meshframe = 0; mesh->Release(); mesh = 0;

Новый фрейм ориентируется таким образом, чтобы сетка была расположена под углом 45 градусов к порту просмотра, после чего для присоединения сетки к фрейму вызывается функция AddVisual(). Функция обратного вызова MoveTexture(), которая будет анимировать текстуру, устанавливается с помощью функции AddMoveCallback().

Обратите внимание, что указатель mesh освобождается. Ранее в функции мы уже освободили указатели meshbuilder и texture, а значит у нас больше не осталось никаких указателей на графические объекты. Это затруднило бы установку новых параметров наложения текстуры, если бы не существовало способа получить визуальные объекты фрейма. Мы увидим как это делается при обсуждении функции обратного вызова MoveTexture().

На пятом и шестом этапах для сцены создаются источник света и порт просмотра.



Содержание раздела