Остается
в строке кода
if
ChangeWindowModeKey in m_DXInput.States then {выполнить
нужное действие};
комментарий
{выполнить
нужное действие}
заменить
на вызов метода, который бы вызывал фактическое переключение режима приложения
из оконного в полноэкранный и обратно.
Таким
методом является следующий -
procedure
TOptionsMenu.AcceptOptions;
var
ScreenSizeMetric: TScreenSizeMetric;
begin
if g_d3dApp = nil then Exit;
ScreenSizeMetric := GetScreenSize;
if (not g_d3dApp.m_bFullScreen = Windowed) and
(g_d3dApp.m_dwScreenWidth = ScreenSizeMetric.Width) then Exit;
g_d3dApp.SwitchDisplayModes(not Windowed, ScreenSizeMetric.Width,
ScreenSizeMetric.Height);
end;
В
данном случае такой метод реализован как метод объекта меню TOptionsMenu
и вызывается при подтверждении смены заданных настроек приложения. В данном
случае настройки достаточно просты. Проверяется заданное в настройках
разрешение экрана и если произошла смена режима оконный/полноэкранный
или изменилось заданное разрешение будет вызван метод SwitchDisplayModes
объекта g_d3dApp, который является экземпляром класса TD3DGameApp.
В
простейшем случае можно рассмотреть реализацию переключений между оконным
режимом приложения и полноэкранным режимом с разрешением например 800x600
пикселей и максимальной частотой покадровой развертки поддерживаемой монитором
(100 Hz или выше).
Предварительно
добавьте данный метод в описание класса TD3DGameApp
function
SwitchDisplayModes(bFullScreen: Boolean;
dwWidth, dwHeight: Cardinal): HRESULT;
Затем
реализуйте его в коде следующим образом -
function
TD3DGameApp.SwitchDisplayModes(bFullScreen: Boolean;
dwWidth, dwHeight: Cardinal): HRESULT;
var
hr: HResult;
begin
if not m_bIsActive or not m_bDisplayReady then begin
result := S_OK;
Exit;
end;
// Check to see if a change was actually requested
if bFullScreen then
begin
if ((m_dwScreenWidth = dwWidth) and (m_dwScreenHeight = dwHeight)) and
(m_bFullScreen = bFullScreen ) then
begin
result := S_OK;
Exit;
end;
end
else
begin
if not m_bFullScreen then begin
result := S_OK;
Exit;
end;
end;
// Invalidate the old display objects
m_bDisplayReady := FALSE;
InvalidateDisplayObjects;
// Set up the new presentation paramters
if bFullScreen then
begin
m_d3dpp.Windowed := FALSE;
m_d3dpp.hDeviceWindow := m_hWndMain;
m_dwScreenWidth := dwWidth;
m_d3dpp.BackBufferWidth := dwWidth;
m_dwScreenHeight := dwHeight;
m_d3dpp.BackBufferHeight := dwHeight;
m_d3dpp.BackBufferFormat := m_d3dfmtFullscreen;
end
else
begin
m_d3dpp.Windowed := TRUE;
m_d3dpp.hDeviceWindow := 0;
m_d3dpp.BackBufferWidth := 0;
m_d3dpp.BackBufferHeight := 0;
m_dwScreenWidth := dwWidth;
m_dwScreenHeight := dwHeight;
m_d3dpp.BackBufferFormat := m_DesktopMode.Format;
end;
// Reset the device
hr := m_pd3dDevice.Reset( m_d3dpp );
if SUCCEEDED(hr) then
begin
m_bFullScreen := bFullScreen;
hr := RestoreDisplayObjects;
if SUCCEEDED(hr) then
begin
m_bDisplayReady := TRUE;
result := S_OK;
Exit;
end;
end;
// If we get here, a fatal error occurred
PostMessage( m_hWndMain, WM_CLOSE, 0, 0 );
result := E_FAIL;
end;
Все
недостающие поля, описанные в реализации данного метода необходимо добавить
в класс TD3DGameApp и инициализировать их в методе конструктора TD3DGameApp.Create
и других необходимых методах, где это понадобится.
Заметьте,
что внутри данного метода каждый раз при переключении между полноэкранным/оконным
режимами или при смене разрешения полноэкранного режима происходит инвалидация
InvalidateDisplayObjects
всех
зависимых от Direct3DDevice ресурсов, вызывается метод сброса устройства
Direct3DDevice, а затем происходит восстановление ресурсов RestoreDisplayObjects
Этот
момент очень важно учитывать при создании многоуровневых игр, в которых
ресурсы для каждого уровня различны и загружаются при разных состояниях
приложения. Тогда при переключении режимов инвалидация и восстановление
необходимых ресурсов должна происходить в зависимости от заданного состояния
приложения, в противном случае Вы получите логические ошибки, ошибки времени
выполнения и множество других ошибок!!!
В
случае с игрой "Ну, Погоди!" этот момент упущен, т.к. все необходимые
ресурсы загружаются, инвалидируются, восстанавливаются и уничтожаются
централизованно при старте приложения и его закрытии, а переключение в
полноэкранный режим не используется. |