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

Ошибка переключения режимов DirectDraw


В DirectDraw есть одна ошибка, связанная с переключением режимов, которую никак не может исправить Microsoft (или тот, кто для них пишет видеодрайверы). Впервые я столкнулся с ней во время работы над предыдущей книгой. Я надеялся, что к моменту написания этой книги ошибку уже исправят, но она так и осталась.

Проблемы возникают при активизации видеорежимов, которые отличаются по глубине пикселей от текущего активного режима Windows. Например, если Windows работает в 8-битном видеорежиме, а ваше приложение DirectDraw попытается активизировать 16-битный видеорежим, ничего не получится, даже когда новый режим вполне допустим. Если попытаться установить 8-битный видеорежим при 16-битном режиме Windows, результат будет тем же. В таких случаях DirectX выдает отладочное сообщение следующего вида:


DDHEL: ChangeDisplaySettings LIED!!!

DDHEL: Wanted 640x480x16 got 1024x768x8

DDHEL: ChangeDisplaySettings FAILED: returned -1


К счастью, это происходит только при первой попытке изменения видеорежима. Если эта попытка удалась, после этого можно установить любой видеорежим. Следовательно, у нас появляется обходной путь: если текущий видеорежим отличается по глубине пикселей от желаемого, переключение следует производить в два этапа; сначала перейдите к видеорежиму, который совпадает по глубине пикселей с текущим, а затем— к видеорежиму, нужному вам.

Такой обходной маневр нетрудно реализовать с помощью класса DirectDrawWin, представленного в этой книге. В функции SelectInitialDisplayMode()

(которая вызывается до переключения видеорежима) следует проверить глубину пикселей текущего режима. Если она отличается от требуемой, выполните «фиктивное» переключение. Программа может выглядеть так:


int SampleWin::SelectInitialDisplayMode() { DWORD curdepth=GetDisplayDepth(); int i, nummodes=GetNumDisplayModes(); DWORD w,h,d;

if (curdepth!=16) ddraw2->SetDisplayMode(640, 480, curdepth, 0, 0 ); // Искать режим 640x480x16 после смены видеорежима for (i=0;i>nummodes;i++) { GetDisplayModeDimensions( i, w, h, d ); if (w==640 && h==480 && d==16) return i; }

return -1; }

<

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