netlib.narod.ru | < Назад | Оглавление | Далее > |
В следующих подразделах будет показано как инициализировать Direct3D. Процесс инициализации Direct3D может быть разбит на следующие этапы:
Запрос указателя на интерфейс IDirect3D9. Этот интерфейс применяется для получения информации об установленных в компьютере устройствах и создания интерфейса IDirect3DDevice9, являющимся нашим объектом C++, представляющим аппаратные устройства, используемые для вывода трехмерной графики.
Проверка возможностей устройства (D3DCAPS9), чтобы узнать поддерживает ли первичный видеоадаптер (основная видеокарта) аппаратную обработку вершин или нет. Мы должны знать это, чтобы создать интерфейс IDirect3DDevice9.
Инициализация экземпляра структуры D3DPRESENT_PARAMETERS. Эта структура содержит ряд параметров, позволяющих нам задать характеристики интерфейса IDirect3DDevice9, который мы намереваемся создать.
Создание объекта IDirect3DDevice9, основываясь на инициализированной структуре D3DPRESENT_PARAMETERS. Как говорилось ранее, объект IDirect3DDevice9 — это наш объект C++, представляющий аппаратные устройства, используемые для отображения трехмерной графики.
Помните, что в этой книге для отображения трехмерной графики мы используем первичный адаптер. Если в вашей системе только одна видеокарта, она и будет первичным адаптером. Если у вас несколько видеокарт, то первичной будет та, которую вы используете в данный момент (т.е. та, которая отображает рабочий стол Windows и т.д.).
Инициализация Direct3D начинается с запроса указателя на интерфейс IDirect3D9. Это выполняется с помощью простого вызова специальной функции Direct3D, как показано в приведенном ниже фрагменте кода:
IDirect3D9* _d3d9; _d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
Единственным параметром функции Direct3DCreate9 всегда должна быть константа D3D_SDK_VERSION, гарантирующая, что при построении приложения будут использованы правильные заголовочные файлы. Если при работе функции возникли ошибки, она возвращает нулевой указатель.
Объект IDirect3D9 используется для двух вещей: перечисления устройств и создания объекта IDirect3DDevice9. Перечисление устройств подразумевает определение возможностей, видеорежимов, форматов и другой информации о каждой установлденной в системе видеокарте. Например, чтобы создать представляющий физическое устройство объект IDirect3DDevice9, необходимо указать поддерживаемую устройством конфигурацию видеорежима и формата. Чтобы найти такую работающую конфигурацию, используются методы перечисления IDirect3D9.
Однако, поскольку перечисление устройств может быть достаточно сложной задачей, а мы хотим как можно быстрее перейти к работе с Direct3D, мы решили не выполнять перечисление устройств, за исключением единственной проверки, о которой будет рассказано в следующем разделе. Чтобы отсутствие перечисления не привело к проблемам, мы выбрали «безопасную» конфигурацию, которую должны поддерживать почти все аппаратные устройства.
Создавая объект IDirect3DDevice9, представляющий первичный видеоадаптер, мы должны указать используемый им способ обработки вершин. Мы хотим по-возможности использовать аппаратную обработку вершин, но не все видеокарты поддерживают ее и мы сперва должны проверить наличие поддержки аппаратной обработки вершин.
Чтобы сделать это мы сперва должны инициализировать экземпляр D3DCAPS9 на основании возможностей первичного видеоадаптера. Воспользуемся следующим методом:
HRESULT IDirect3D9::GetDeviceCaps( UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps );
Adapter — указывает физический видеоадаптер, возможности которого мы хотим определить.
DeviceType — задает тип устройства (т.е. аппаратное устройство (D3DDEVTYPE_HAL) или программное устройство (D3DDEVTYPE_REF)).
pCaps — возвращает инициализированную структуру с описанием возможностей устройства.
Теперь мы можем проверить возможности устройства, как описывалось в разделе 1.3.8. Это иллюстрирует следующий фрагмент кода:
// Заполняем структуру D3DCAPS9 информацией о // возможностях первичного видеоадаптера. D3DCAPS9 caps; d3d9->GetDeviceCaps( D3DADAPTER_DEFAULT, // Означает первичный видеоадаптер. deviceType, // Задает тип устройства, обычно D3DDEVTYPE_HAL. &caps); // Возвращает заполненную структуру D3DCAPS9, которая содержит // информацию о возможностях первичного видеоадаптера. // Поддерживается аппаратная обработка вершин? int vp = 0; if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { // да, сохраняем в vp флаг поддержки аппаратной // обработки вершин. vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else { // Нет, сохраняем в vp флаг использования программной // обработки вершин. vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
Обратите внимание, что мы сохраняем способ обработки вершин, который будем использовать, в переменной vp. Это вызвано тем, что нам надо будет указать используемый тип обработки вершин, когда позднее мы будем создавать объект IDirect3DDevice9.
Следующий этап процесса инициализации — заполнение экземпляра структуры D3DPRESENT_PARAMETERS. Эта структура используется для задания ряда характеристик объекта IDirect3DDevice9, который мы будем создавать, и объявлена следующим образом:
typedef struct _D3DPRESENT_PARAMETERS_ { UINT BackBufferWidth; UINT BackBufferHeight; D3DFORMAT BackBufferFormat; UINT BackBufferCount; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BOOL Windowed; BOOL EnableAutoDepthStencil; D3DFORMAT AutoDepthStencilFormat; DWORD Flags; UINT FullScreen_RefreshRateInHz; UINT PresentationInterval; } D3DPRESENT_PARAMETERS;
BackBufferWidth — Ширина поверхности вторичного буфера в пикселах.
BackBufferHeight — Высота поверхности вторичного буфера в пикселах.
BackBufferFormat — Формат пикселей во вторичном буфере (т.е. для 32-разрядного формата укажите D3DFMT_A8R8G8B8).
BackBufferCount — Количество используемых вторичных буферов. Обычно мы задаем значение 1, чтобы указать, что нам нужен только один вторичный буфер.
MultiSampleType — Используемый для вторичного буфера тип множественной выборки. Подробная информация об этом параметре содержится в документации SDK.
MultiSampleQuality — Уровень качества множественной выборки. Подробная информация об этом параметре содержится в документации SDK.
SwapEffect — Член перечисления D3DSWAPEFFECT, указывающий, как будет осуществляться переключение буферов в цепочке переключений. Для большинства случаев можно указать значение D3DSWAPEFFECT_DISCARD.
hDeviceWindow — Дескриптор связанного с устройством окна. Укажите дескриптор того окна приложения, в котором вы хотите выводить изображение.
Windowed — Укажите true для запуска приложения в оконном режиме или false — для работы в полноэкранном режиме.
EnableAutoDepthStencil — укажите значение true, чтобы Direct3D автоматически создал и поддерживал буферы глубины и трафарета.
AutoDepthStencilFormat — формат буферов глубины и трафарета (например, для 24-разрядного буфера глубины с 8 разрядами, зарезервированными для буфера трафарета, укажите D3DFMT_D24S8).
Flags&nbnsp;— Дополнительные параметры. Укажите ноль (если флаги отсутствуют) или член набора D3DPRESENTFLAG. Полный список допустимых флагов приведен в документации. Здесь мы рассмотрим два наиболее часто используемых:
FullScreen_RefreshRateInHz — Частота кадров; используйте частоту кадров по умолчанию, указав значение D3DPRESENT_RATE_DEFAULT.
PresentationInterval — член набора D3DPRESENT. Полный список допустимых значений приведен в документации. Наиболее часто используются следующие два:
Вот пример заполнения структуры:
D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = 800; d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //формат пикселей d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = false; // полноэкранный режим d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // формат буфера глубины d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
Заполнив структуру D3DPRESENT_PARAMETERS мы можем создать объект IDirect3DDevice9 с помощью следующего метода:
HRESULT IDirect3D9::CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface );
Adapter — указывает физический видеоадаптер, который будет представлять создаваемый объект IDirect3DDevice9.
DeviceType — задает тип используемого устройства (т.е. аппаратное устройство (D3DDEVTYPE_HAL) или программное устройство (D3DDEVTYPE_REF)).
hFocusWindow — дескриптор окна с которым будет связано устройство. Обычно это то окно, в которое будет выводиться изображение и для наших целей мы здесь задаем тот же дескриптор, который указан в члене d3dpp.hDeviceWindow структуры D3DPRESENT_PARAMETERS.
BehaviorFlags — в этом параметре указывается значение D3DCREATE_HARDWARE_VERTEXPROCESSING либо D3DCREATE_SOFTWARE_VERTEXPROCESSING.
pPresentationParameters — указывается инициализированный экземпляр структуры D3DPRESENT_PARAMETERS, задающий параметры устройства.
ppReturnedDeviceInterface — возвращает указатель на созданное устройство.
Вот пример использования функции:
IDirect3DDevice9* device = 0; hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, // первичный видеоадаптер D3DDEVTYPE_HAL, // тип устройства hwnd, // окно, связанное с устройством D3DCREATE_HARDWARE_VERTEXPROCESSING, // тип обработки вершин &d3dpp, // параметры показа &device); // возвращает созданное устройство if(FAILED(hr)) { ::MessageBox(0, "CreateDevice() - FAILED", 0, 0); return 0; }
netlib.narod.ru | < Назад | Оглавление | Далее > |