| Россия |
Расчет освещенности. Файлы эффектов
Полноэкранный режим воспроизведения
До сих пор вывод всех сцен построения производился в окно (на форму). Библиотека Direct3D позволяет осуществить рендеринг в полноэкранном режиме ( Full Screen ). Для перехода в полноэкранный режим вывода примитивов необходимо лишь при заполнении структуры D3DPRESENT_PARAMETERS явно указать размеры заднего буфера ( BackBuffer ), установить флаг Windowed в значение FALSE. Также нужно указать режим переключения первичного и вторичного (заднего) буферов рендеринга и определить интервал смены буферов.
| C++ |
D3DPRESENT_PARAMETERS params; … ZeroMemory( ¶ms, sizeof(params) ); params.Windowed = FALSE; params.SwapEffect = D3DSWAPEFFECT_FLIP; params.BackBufferWidth = 1280; params.BackBufferHeight = 1024; params.BackBufferFormat = display.Format; params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; … |
| Pascal |
var params: TD3DPresentParameters; … ZeroMemory( @params, SizeOf(params) ); params.Windowed := False; params.SwapEffect := D3DSWAPEFFECT_FLIP; params.BackBufferWidth := 1280; params.BackBufferHeight := 1024; params.BackBufferFormat := display.Format; params.PresentationInterval := D3DPRESENT_INTERVAL_IMMEDIATE; … |
Единственно, что необходимо еще проделать – это организовать возможность выхода (закрытия) программы. Для этого можно, например, обработать событие системы WM_KEYDOWN. Полноэкранный режим довольно часто используют в играх, так как именно при таком режиме достигается максимальная производительность видеокарты. Можно воспользоваться функцией Win32 API GetSystemMetrics() для того, чтобы узнать текущее разрешение экрана.
| C++ |
D3DPRESENT_PARAMETERS params; … params.BackBufferWidth = GetSystemMetrics(SM_CXSCREEN); params.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN); |
| Pascal |
var params: TD3DPresentParameters; … params.BackBufferWidth := GetSystemMetrics(SM_CXSCREEN); params.BackBufferHeight := GetSystemMetrics(SM_CYSCREEN); |
Обработка ошибок
При использовании графической библиотеки Direct3D программисту следует уделять особе внимание обработке ошибок. Для этих целей предусмотрены два специальных макроса, которые проверяют код на наличие или отсутствие ошибок:
FAILED() SUCCEEDED()
Принцип работы этих макросов очень прост и представлен ниже.
if ( FAILED()) // ошибка при выполнении команды ... else // команда завершилась успешно
Для второго макроса принцип действия будет противоположным.
if (SUCCEEDED ()) // команда завершилась успешно ... else // ошибка при выполнении команды
Ниже приведены некоторые примеры обработки ошибок.
| C++ |
LPDIRECT3D9 direct3d = NULL;
...
if( FAILED( direct3d -> CreateDevice( … ) ) )
{
// обработка ошибки
} |
| Pascal |
var direct3d: IDirect3D9; ... if Failed ( direct3d.CreateDevice( … ) ) then begin // обработка ошибки end; |
Можно осуществлять анализ ошибок через дополнительную переменную.
| C++ |
HRESULT hr;
hr = direct3d -> CreateDevice( … );
if( FAILED(hr) )
{
} |
| Pascal |
var hr: HRESULT; … hr := direct3d.CreateDevice( … ); if Failed(hr) then begin end |
И еще один способ обработки ошибок заключается в сравнении результата вызова функции с константой D3D_OK.
| C++ |
if ( direct3d -> CreateDevice( … ) != D3D_OK )
{
} |
| Pascal |
if direct3d.CreateDevice( … ) <> D3D_OK then begin end; |
Следует также остановиться на обработке ошибок при компиляции шейдеров. Как мы помним, в одном из параметров функции D3DXCompileShaderFromFile(…) возвращается указатель на буфер ошибок. Ниже приводится программный код, позволяющий вывести на экран сообщение об ошибке, полученное от компилятора HLSL.
| C++ |
if ( D3DXCompileShaderFromFile( "shader.psh", NULL, NULL, "main",
"ps_2_0", 0, &Code, &BufferErrors,
NULL) != D3D_OK )
{
MessageBox(NULL, (const char*)BufferErrors->GetBufferPointer(),
"Ошибка в шейдере!!!", MB_OK | MB_ICONEXCLAMATION);
} |
| Pascal |
if D3DXCompileShaderFromFile('shader.psh', nil, nil, 'Main',
'ps_2_0', 0, @Code, @BufferErrors, nil) D3D_OK
then begin
MessageBox(0, BufferErrors.GetBufferPointer,
'Ошибка в шейдере!!!',
MB_OK or MB_ICONEXCLAMATION);
end; |
Такой информативный способ позволяет легко "увидеть" в какой именно строке шейдера допущена ошибка.
Подсчет количества кадров в секунду
Как правило, показателем производительности в приложениях, связанных с трехмерной графикой, является количество кадров, выводимых приложением в единицу времени (в секунду). Поэтому очень часто возникает необходимость вычислить и отобразить эту информацию в окне приложения. Ниже приведен пример, показывающий как подсчитывать количество кадров в секунду.
| C++ |
count = 0;
last_tick = GetTickCount();
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(Msg);
DispatchMessage(Msg);
}
else
{
this_tick = GetTickCount();
if(this_tick-last_tick>=1000)
{
last_tick=this_tick;
fps=count;
count=0;
// вывод значения fps
}
else count++
Render();
}
} |
| Pascal |
count:=0;
last_tick:=GetTickCount();
while Msg.message <> WM_QUIT do begin
if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end else begin
this_tick:=GetTickCount();
if(this_tick-last_tick>=500) then begin
last_tick:=this_tick;
fps:=count;
count:=0;
// вывод значения fps
end
else count:=count+1;
Render;
end;
end; |