Вход/Регистрация
Графика для Windows средствами DirectDraw
вернуться

Трухильо Стэн

Шрифт:

Рис. 3.9. Диалоговое окно для выбора драйвера

После того как интерфейс DirectDraw будет инициализирован, им можно воспользоваться для получения указателя на интерфейс DirectDraw2. Для этого следует вызвать функцию QueryInterface и передать ей GUID интерфейса DirectDraw2, определенный под именем IID_IDirectDraw2. Если вызов QueryInterface заканчивается неудачно, программа выводит диалоговое окно и завершает работу. Фактически мы требуем присутствия библиотеки DirectX версии 2 и выше (потому что интерфейс DirectDraw2 впервые появился в DirectX 2). Если вызов QueryInterface окажется успешным, указатель ddraw1 освобождается. Попеременный вызов функций интерфейсов DirectDraw и DirectDraw2 не рекомендуется, поэтому освобождение указателя на интерфейс DirectDraw гарантирует, что в оставшейся части кода будет использоваться только интерфейс DirectDraw2.

Затем мы вызываем функцию SetCooperativeLevel и в качестве аргументов передаем ей логический номер нашего окна и три флага. По логическому номеру организуется взаимодействие окна с DirectDraw. При вызове SetCooperativeLevel использованы три флага: DDSCL_EXCLUSIVE, DDSCL_FULLSCREEN и DDSCL_ALLOWMODEX. Флаги монопольного и полноэкранного режима обычно используются вместе для получения максимальных полномочий по управлению видеоустройством. Последний флаг означает, что все поддерживаемые видеорежимы Mode X должны быть доступны для выбора в программе. В Windows NT этот флаг игнорируется.

Обнаружение видеорежимов

На следующем этапе необходимо определить все видеорежимы, поддерживаемые инициализированным драйвером DirectDraw. Для перечисления видеорежимов используется функция EnumDisplayModes, аналогичная рассмотренной выше функции DirectDrawEnumerate. В обоих случаях для перечисления используются косвенно вызываемые функции, а также предоставляются средства для передачи им данных, определяемых приложением. В нашем случае DisplayModeAvailable является функцией косвенного вызова (callback function), а указатель this ссылается на произвольные данные. Функция DisplayModeAvailable выглядит так:

HRESULT WINAPI DirectDrawWin::DisplayModeAvailable(LPDDSURFACEDESC desc, LPVOID p) {

 DirectDrawWin* win=(DirectDrawWin*)p;

 int& count=win->totaldisplaymodes;

 if (count==MAXDISPLAYMODES) return DDENUMRET_CANCEL;

 win->displaymode[count].width = desc->dwWidth;

 win->displaymode[count].height = desc->dwHeight;

 win->displaymode[count].depth = desc->ddpfPixelFormat.dwRGBBitCount;

 count++;

 return DDENUMRET_OK;

}

DirectDraw вызывает функцию DisplayModeAvailable для каждого поддерживаемого видеорежима. Структура DDSURFACEDESC, передаваемая косвенно вызываемой функции, содержит описание обнаруженного видеорежима. Функция DisplayModeAvailable сохраняет разрешение экрана и глубину пикселей в специальном массиве, называемом displaymode. В переменной total displaymodes хранится количество обнаруженных видеорежимов; если значение totaldisplaymodes достигает MAXDISPLAYMODES, перечисление завершается возвратом кода DDENUMRET_CANCEL.

Затем функция OnCreate сортирует элементы displaymode так, чтобы режимы с низким разрешением находились в начале массива. Это делается с помощью функции Win32 qsort, которой передается функция косвенного вызова для «сравнения» видеорежимов. В нашем случае используется функция CompareModes, которая сравнивает видеорежимы сначала по разрешению, а затем по глубине пикселей. Я пропускаю дальнейшее обсуждение CompareModes, потому что оно не имеет никакого отношения к DirectDraw.

Выбор видеорежима

На предыдущем этапе был подготовлен отсортированный список видеорежимов. Теперь мы выбираем один из этих режимов в качестве исходного. Класс DirectDrawWin заставляет производные классы принять это решение, объявляя чисто виртуальную функцию. Функция SelectInitialDisplayMode из класса DirectDrawWin выглядит так:

virtual int SelectInitialDisplayMode = 0;

В C++ чисто виртуальные функции обязательно должны переопределяться, в противном случае класс не будет компилироваться. Однако со стороны DirectDrawWin было бы нечестно требовать от производного класса выбора исходного видеорежима, не предоставляя ему средств для просмотра возможных вариантов (переменные класса, в которых хранятся сведения о видеорежимах, являются закрытыми (private)). Для этой цели в классе DirectDrawWin предусмотрены функции GetNumDisplayModes и GetDisplayModeDimensions. В версии SelectInitialDisplayMode класса BounceWin эти функции используются для выбора исходного режима:

int BounceWin::SelectInitialDisplayMode {

 int i, nummodes=GetNumDisplayModes;

 DWORD w,h,d;

 for (i=0;i<nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

if (w==desiredwidth && h==desiredheight && d==desireddepth) return i;

 }

 for (i=0;i>nummodes;i++) {

GetDisplayModeDimensions(i, w, h, d);

  • Читать дальше
  • 1
  • ...
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: