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

       

Функция Render()


Функция Render() — это последняя (и простейшая) функция класса RMWin, которую мы рассмотрим. Функция Render() объявлена, но не определена:

virtual void Render() = 0;

Render() — это чисто виртуальная функция. Это означает, что функция Render() должна быть переопределена в классах, производных от RMWin. Функция Render() объявлена таким способом чтобы гарантировать, что производные от RMWin классы будут осуществлять обновление экрана приложения. Помимо прочего, функция Render() должна выполнять переключение страниц.


Обратите внимание, как восстанавливается поверхность меню видеорежимов:

if (menusurf->IsLost() == DDERR_SURFACELOST) { TRACE("Restoring menusurf...\n"); menusurf->Restore(); UpdateMenuSurface(); }

Если произошла потеря поверхности, вызывается функция Restore(). Она выполняет восстановление памяти поверхности, а вызов функции UpdateMenuSurface() необходим для восстановления содержимого поверхности.

Затем стирается содержимое поверхности backsurf:

DDBLTFX bltfx; memset(&bltfx, 0, sizeof(bltfx)); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = 0; backsurf->Blt(0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx);

Аналогичный код используется в функции RMWin::ClearSurface(). Функция Blt() применяется для заливки поверхности указанным цветом. Поверхность заполняется нулевыми байтами, но для данной поверхности не был назначен цветовой ключ, так что все пиксели поверхности остаются нулевыми.

Теперь можно нарисовать часть сцены, относящуюся к Direct3D:

scene->Move(D3DVALUE(1.0)); viewport->Clear(); viewport->Render(scene); device->Update();

Функция Move() интерфейса Direct3DRMFrame обновляет внутренние значения иерархии фреймов и выполняет вызов любых функций обратного вызова, выполняющих перемещение входящих в иерархию фреймов. Вызов функций интерфейса Direct3DRMViewport (Clear() и Render()) очищает содержимое порта просмотра (это не оказывает никакого действия на наши поверхности) и вычисляет новое выводимое изображение. Функция Update() интерфейса Direct3DRMDevice копирует сформированное изображение на поверхность backsurf. Это может ускользнуть от вашего взора, поскольку поверхность backsurf не упоминается в данном фрагменте кода. Однако, следует вспомнить, что поверхность backsurf была использована при создании устройства Direct3D. Эта связь объясняет, почему сформированное изображение передается функцией Update() непосредственно на поверхность backsurf.

Затем поверх сформированного Direct3D изображения выводится поверхность для вывода FPS:



UpdateFPSSurface(); if (displayfps) { DWORD w, h, d; GetCurDisplayModeDims(w, h, d); backsurf->BltFast(w - fpsrect.right, h - fpsrect.bottom, fpssurf, &fpsrect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT); }

Вызов функции UpdateFPSSurface() обновляет содержимое поверхности fpssurf. Затем, если значение логической переменной displayfps равно TRUE, содержимое поверхности копируется на поверхность backsurf функцией BltFast() (BltFast() — это оптимизированная версия функции Blt()).

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

Потом на поверхность backsurf копируется поверхность меню видеорежимов:

backsurf->BltFast(0, 0, menusurf, &menurect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);

Этот код очень простой, поскольку поверхность меню видеорежимов всегда видна и располагается в левом верхнем углу экрана.

В конце функции содержимое поверхности backsurf перемещается на первичную поверхность операцией переключения страниц:

primsurf->Flip(0, DDFLIP_WAIT);

Этот вызов функции делает видимым содержимое поверхности backsurf.


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