Чтение онлайн

ЖАНРЫ

Графика для Windows средствами DirectDraw

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

Шрифт:

 DirectDrawEnumerate(DriverAvailable, this);

 if (totaldrivers==0) {

AfxMessageBox("No DirectDraw drivers detected");

return -1;

 }

 int driverindex=SelectDriver;

 if (driverindex<0) {

TRACE("No DirectDraw driver selected\n");

return -1;

 } else if (driverindex>totaldrivers-1) {

AfxMessageBox("Invalid DirectDraw driver selected\n");

return -1;

 }

 LPDIRECTDRAW ddraw1;

 DirectDrawCreate(driver[driverindex].guid, &ddraw1, 0);

 HRESULT r;

 r=ddraw1->QueryInterface(IID_IDirectDraw2, (void**)&ddraw2);

 if (r!=S_OK) {

AfxMessageBox("DirectDraw2 interface not supported");

return -1;

 }

 ddraw1->Release, ddraw1=0;

 ddraw2->SetCooperativeLevel(GetSafeHwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);

 ddraw2->EnumDisplayModes(0, 0, this, DisplayModeAvailable);

 qsort(displaymode, totaldisplaymodes, sizeof(DisplayModeInfo), CompareModes);

 int initmode=SelectInitialDisplayMode;

 if (ActivateDisplayMode(initmode)==FALSE) return -1;

 return 0;

}

Вся

инициализация DirectDraw выполняется в функции OnCreate (при поддержке нескольких вспомогательных функций). Процесс инициализации состоит из семи этапов:

• Получение списка всех драйверов DirectDraw.

• Выбор драйвера DirectDraw.

• Инициализация DirectDraw с использованием выбранного драйвера.

• Получение списка поддерживаемых видеорежимов.

• Выбор исходного видеорежима.

• Активизация выбранного видеорежима.

• Создание поверхностей приложения.

Все эти этапы рассматриваются в последующих разделах.

Получение списка драйверов DirectDraw

Функция DirectDrawEnumerate предназначена для составления списка доступных драйверов DirectDraw. Чаще всего обнаруживается всего один драйвер DirectDraw — тот, который управляет установленной видеокартой. Тем не менее в некоторых конфигурациях может присутствовать несколько видеоустройств. В таких случаях DirectDrawEnumerate покажет отдельный драйвер для каждого видеоустройства, поддерживаемого DirectDraw.

Функция DirectDrawEnumerate получает два аргумента: указатель на косвенно вызываемую (callback) функцию и указатель на данные, определяемые приложением, которые передаются этой функции при вызове. В нашем случае аргументами являются косвенно вызываемая функция DriverAvailable и указатель на класс DirectDrawWin (this). Функция DriverAvailable определяется так:

BOOL WINAPI DirectDrawWin::DriverAvailable(LPGUID guid, LPSTR desc, LPSTR name, LPVOID p) {

 DirectDrawWin* win=(DirectDrawWin*)p;

 if (win->totaldrivers >= MAXDRIVERS) return DDENUMRET_CANCEL;

 DriverInfo& info=win->driver[win->totaldrivers];

 if (guid) {

info.guid=(GUID*)new BYTE[sizeof(GUID)];

memcpy(info.guid, guid, sizeof(GUID));

 } else info.guid=0;

 info.desc=strdup(desc);

 info.name=strdup(name);

 win->totaldrivers++;

 return DDENUMRET_OK;

}

Сначала

указатель на данные, определяемые приложением (p), преобразуется в указатель на класс DirectDrawWin (win). Поскольку функция DriverAvailable объявлена как статическая (косвенно вызываемые функции обязаны быть статическими), на нее в отличие от обычных функций класса не распространяются правила автоматического доступа; соответственно доступ к переменным и функциям класса приходится осуществлять через указатель win.

DirectDraw вызывает функцию DriverAvailable один раз для каждого обнаруженного драйвера. При каждом вызове передаются три информационных объекта: GUID, описание и имя. GUID (глобально-уникальный идентификатор) однозначно идентифицирует драйвер. Описание и имя представляют собой строки для неформальной идентификации драйвера. Функция DriverAvailable сохраняет сведения о каждом драйвере в массиве с именем driver и отслеживает количество драйверов в переменной totaldrivers. Наконец, функция DriverAvailable возвращает DDNUMRET_OK, показывая, что перечисление драйверов должно продолжаться. При получении кода возврата DDENUMRET_CANCEL DirectDraw прекращает перечисление драйверов.

Если была установлена библиотека DirectX и в системе присутствует видеоустройство, поддерживаемое DirectDraw, то будет обнаружен по крайней мере один драйвер DirectDraw. Этот драйвер соответствует первичному видеоустройству (тому, что используется Windows). Его GUID равен нулю, строка описания содержит текст «Primary Display Driver», а строка имени — «display». При перечислении дополнительных драйверов используются нормальные значения GUID. Строки описаний и имен зависят от типов видеоустройств и версий драйверов.

Выбор драйвера

После того как все драйверы DirectDraw будут перечислены, функция OnCreate выбирает один из них. Выбор драйвера по умолчанию может быть переопределен в производных классах с помощью виртуальной функции SelectDriver. Возвращаясь к листингу 3.1, мы видим, что величина, возвращаемая функцией SelectDriver, используется в качестве индекса массива driver (причем значения индекса начинаются с нуля). Индекс показывает, какой GUID (и, следовательно, драйвер) должен использоваться для инициализации DirectDraw. Версия SelectDriver из класса DirectDrawWin выглядит так:

virtual int SelectDriver {

 return 0;

}

По умолчанию SelectDriver возвращает 0, тем самым показывая, что должно использоваться первичное видеоустройство. Чтобы изменить ее поведение, следует переопределить SelectDriver в классе, производном от DirectDrawWin. В нашем примере класс BounceWin переопределяет SelectDriver так, чтобы в случае обнаружения нескольких драйверов выводилось меню:

Поделиться с друзьями: