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

         

Функция UpdateMenuSurface()


Задача функции UpdateMenuSurface() (код которой приведен в листинге10.11) — инициализировать содержимое поверхности меню видеорежимов.

Листинг 10.11. Функция UpdateMenuSurface()

BOOL FullScreenWin::UpdateMenuSurface() { char buf[80]; int len; RECT rect; ClearSurface(menusurf, 0); HDC hdc; menusurf->GetDC(&hdc); SelectObject(hdc, largefont); SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, textshadow); ExtTextOut(hdc, 1, 1, 0, 0, headertext, strlen(headertext), 0); SetTextColor(hdc, textcolor); ExtTextOut(hdc, 0, 0, 0, 0, headertext, strlen(headertext), 0); SelectObject(hdc, smallfont); int nmodes = GetNumDisplayModes(); if (nmodes > maxmodes) nmodes = maxmodes; int rows = nmodes / menucols; if (nmodes % menucols) rows++; for (int i = 0; i < nmodes; i++) { rect.left = (i / rows) * colwidth; rect.top = (i % rows) * rowheight + reservedspace; rect.right = rect.left + colwidth; rect.bottom = rect.top + rowheight; DWORD w,h,d; GetDisplayModeDims(i, w, h, d); len = sprintf(buf, "%dx%dx%d", w, h, d); SetTextColor(hdc, textshadow); ExtTextOut(hdc, rect.left + 1, rect.top + 1, 0, &rect, buf, len, 0); if (i == selectmode) SetTextColor(hdc, highlightcolor); else SetTextColor(hdc, textcolor); ExtTextOut(hdc, rect.left, rect.top, 0, &rect, buf, len, 0); } rect.left = 0; rect.right = 319; rect.top = 179; rect.bottom = 199; len=sprintf(buf, "[Arrows] [Enter] [W] [F] [G] [Escape]"); SetTextColor(hdc, textshadow); ExtTextOut(hdc, 1, 180, 0, &rect, buf, len, 0); SetTextColor(hdc, textcolor); ExtTextOut(hdc, 0, 179, 0, &rect, buf, len, 0); menusurf->ReleaseDC(hdc); return TRUE; }

Сперва функция UpdateMenuSurface() очищает всю поверхность, заполняя отведенную для нее память нулями. Это делается с помощью функции RMWin::ClearSurface(). Ноль, передаваемый во втором аргументе ClearSurface(), задает желаемое значение пикселей поверхности. Поскольку ноль задан в качестве цветового ключа данной поверхности, вся поверхность станет прозрачной.

Затем вызывается функция GetDC() интерфейса DirectDrawSurface, чтобы получить контекст устройства Windows для поверхности. Полученный в результате HDC (дескриптор контекста устройства) позволяет нам пользоваться функциями контекста устройства Windows. В нашем случае мы воспользуемся дескриптором контекста устройства для вывода текста на поверхность.

Большая часть кода функции UpdateMenuSurface() осуществляет вывод текста на поверхность menusurf. Сначала используется функция Win32 ExtTextOut() для отображения заголовка приложения. Затем создаются и выводятся строки для каждого обнаруженного видеорежима. И, наконец, в нижней части поверхности выводится список клавиш, на которые реагирует программа.

Обратите внимание, что текст выводится дважды, разным цветом и с небольшим сдвигом. Благодаря этому создается эффект тени.

Перед возвратом из функции UpdateMenuSurface() вызывается функция ReleaseDC() интерфейса DirectDrawSurface. Это очень важно, поскольку часть механизмов управления Windows отключается между вызовами функций GetDC() и ReleaseDC(). Если вы забудете освободить контекст устройства для поверхности DirectDraw, то это приведет к впечатляющему краху системы (поверьте мне — я знаю!).



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