На маломощных видеокартах даже в самых простых программах, использующих DirectSD, будет порождаться исключение. Вы можете предусмотреть обработку этого исключения, чтобы попытаться повторно инициализировать систему с параметром DSDDEVTYPE_REF. Тогда скорость работы будет настолько низкой, что вряд ли пользователи останутся удовлетворенными.
Третьим аргументом метода createDevice задается идентификатор окна, в котором осуществляется вывод, свойство Handle формы хранит значение этого идентификатора. Следующий параметр задает порядок работы с вершинами: обрабатываются математические операции центральным процессором либо ускорителем. Здесь мы будем использовать константу DSDCREATE SOFTWAREJ/ERTEXPROCESSING, чтобы наши профаммы работали на всех графических картах. Пятый, предпоследний, аргумент метода createDevice - переменная типа TDSDPRESENT^PARAMETERS, с помощью которой мы передаем заполненную нами ранее структуру. В ней же будут содержаться скорректированные системой значения устанавливаемого режима. Например, количество задних буферов в примере задается первоначально равным нулю, система скорректирует это значение при создании объекта устройства. Добавьте в код следующую строку:
ShowMessage (IntToStr(d3dpp.BackBufferCount));
И убедитесь, что наше приложение не осталось без вспомогательного экрана. Последний аргумент рассматриваемого метода - собственно формируемый объект. Процедура инициализации вызывается при создании окна, обработка возможных ошибок является, по-прежнему, необходимым элементом наших программ:
procedure TfrmDBD.FormCreate(Sender: TObject);
var
hRet : HRESULT;
begin
hRet := InitD3D;
if Failed (hRet} then ErrorOut ('InitD3D', hRet);
end;
Основная нагрузка в примере ложится на функцию Render, в которой выполняется единственное действие - экран окрашивается синим цветом:
function TfrmDSD.Render : HRESULT;
var
hRet : HRESULT;
begin
// Инициализация не выполнена, либо произошла серьезная авария
if FDSDDevice = nil then begin
Result := E__FAIL;
Exit;
end;
hRet := FD3DDevice.Clear(0, nil, D3DCLEARJTARGET,
D3DCOLOR_XRGB(0, 0, 255), 0.0, 0); // Очистка заднего буфера
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
// Переключение буферов устройства
Result := FD3DDevice.Present(nil, nil, 0, nil);
end;
Начинается код функции с проверки присутствия объекта устройства. Этот объект может отсутствовать, если инициализация не выполнилась успешно, либо объект потерян. Последняя ситуация может возникнуть, когда, например, по ходу работы приложения меняются установки рабочего стола. Обратите внимание, что при отсутствии объекта устройства наша функция Render возвращает значение E_FAIL, но функция обработки ошибки DXGErrorString в ответ на такую ошибку возвращает строку 'Unrecognized Error' (Неопознанная ошибка). Вы можете избавиться от неопределенности сообщения, введя собственную константу на случай потери объекта устройства.
Далее в функции Render вызывается метод clear объекта устройства. Первый и второй аргументы метода позволяют задавать очищаемую область: первый аргумент задает количество используемых прямоугольников, вторым аргументом передается указатель на массив, содержащий набор величин типа TRect.
Третьим аргументом метода clear уточняются параметры очистки. Здесь указывается флаг или комбинация флагов. Константа DSDCLEARJTARGET используется в ситуации, когда очищается цветовая поверхность устройства. Сам цвет, в который "перекрашивается" устройство, передается следующим параметром. В примере цвет, которым будет окрашено окно, идентифицируем, используя готовую функцию D3DCOLOR_XRGB. Ее аргументом является тройка весов чистых цветов, образующих нужный нам оттенок. Последние два аргумента метода пока оставим без рассмотрения, связаны они со специальными буферами.
Окрасив задний буфер чистым синим цветом, нам остается только переставить буферы - вызываем метод Present объекта устройства. Если третий аргумент метода нулевой, то идентификатором окна, в котором происходит работа, берется значение, установленное ранее, во время инициализации работы системы. Все остальные параметры метода или не используются, или при указанных нулевых значениях задают работу со всей клиентской областью окна, что, как правило, и необходимо.
В состоянии ожидания сообщений беспрерывно вызывается функция Render, если окно приложения не минимизировано:
procedure TfrmDBD.ApplicationEventslMinimize(Sender: TObject);
begin
FActive := False; // При минимизации окна приложения флаг опускаем
end;
procedure TfrmDSD.ApplicationEventslRestore(Sender: TObject);
begin
FActive := True; // Окно восстановлено, флаг поднимаем
end;
Помимо непрерывной перерисовки окна периодически подсчитывается и выводится в его заголовке значение FPS:
Читать дальше
Конец ознакомительного отрывка
Купить книгу