Чтение онлайн

ЖАНРЫ

DirectX 8. Начинаем работу с DirectX Graphics

Поздняков Константин

Шрифт:

Теперь попробуем написать простейшую программу, инициализирующую DirectX. Для этого познакомимся с некоторыми интерфейсами Direct3D и их методами.

Для создания объекта d3d используется функция Direct3DCreate8:

pD3D = Direct3DCreate8(D3D_SDK_VERSION);

здесь pD3D — указатель на интерфейс IDirect3D8,

D3D_SDK_VERSION
объявлено в d3d8.h.

Файл d3d8.h содержит объявления функций, работающих с Direct3D. Поэтому его необходимо включить в свой код директивой препроцессора:

#include <d3d8.h>

Функция Direct3DCreate8 возвращает указатель на созданный объект d3d. Если она вернула значение NULL, то это означает, что

ваша программа не может инициализировать DirectX8. В этом случае ваша программа должна закончить своё выполнение.

Компонент, который занимается просчётом объектов на экран в Direct3D, называется Direct3D device. Он также включает в себя и сохраняет установки, касающиеся просчёта, занимается операциями трансформации, освещения и растеризацией. Метод CreateDevice интерфейса объекта d3d создаёт такой device. Одним из параметров этого метода является объект структурного типа D3DPRESENT_PARAMETERS. Для ознакомления с Direct3D, мы не будем углубляться в значения всех полей этой структуры. Скажем только про те, которые нам сейчас понадобятся. Поле Windowed отвечает за то, будет ли графика отображаться на весь экран или в окне; значение может быть соответственно FALSE или TRUE.

Чтобы не было видно, как перерисовывается графика, все отображаемые объекты выводят сперва в невидимой области видеопамяти, так называемой back buffer (задний буфер). После того, как кадр полностью прорисован, его копируют в видимую область памяти — front buffer или render target. Если приложение отображает графику на весь экран, то в копировании нет необходимости, достаточно просто говорить Direct3D какая часть видеопамяти является видимой, то есть просто переключать (flip) видимость с одного буфера на другой. Ясно, что если мы выводим графику в окно, то мы можем пользоваться только копированием back buffer'а в front buffer. Поле SwapEffect мы выставим в значение d3dswapeffect_discard чтобы наиболее эффективно представить back buffer для отображения.

BackBufferFormat — ещё одно поле структуры D3DPRESENT_PARAMETERS, которое нам необходимо задать, чтобы сказать Direct3D, какого формата будет back buffer. Пусть наше приложение, для простоты, будет выводить графику в окно. Формат back buffer'а должен совпадать с форматом front buffer'а, который в свою очередь в нашем случае совпадает с текущим форматом desktop'а. Его же мы можем получить методом интерфейса объекта d3d GetAdapterDisplayMode, указав в качестве первого параметра D3DADAPTER_DEFAULT.

Итак, мы можем уже написать функцию инициализации Direct3D для последующего просчёта объектов:

// функция Init создаёт объекты d3d и d3d device

bool Init(HWND hWnd) {

 if (pD3d = Direct3DCreate8(D3D_SDK_VERSION)) {

D3DDISPLAYMODE d3ddm; // отсюда нам нужно поле Format

if (FAILED(pD3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))

return false;

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, sizeof(d3dpp)); // выставляем в 0 все поля d3dpp

d3dpp.Windowed = TRUE;

d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

d3dpp.BackBufferFormat = d3ddm.Format;

if (FAILED(pD3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice))) {

return false;

}

return true;

 }

 returnfalse;

}

Здесь pD3d — объект d3d, объявленный как

IDirect3D8 * pD3d;

а pDevice —

указатель на интерфейс device'а

IDirect3DDevice8 * pDevice;

В методе CreateDevice вторым параметром мы задали D3DDEVTYPE_HAL. Это означает, что мы пытаемся создать устройство просчёта, поддерживаемое hardware.

Таким образом, если наша функция Init вернула значение true, означает, что инициализация прошла успешно. После этого мы можем выводить графику средствами DirectX. Об этом мы поговорим во второй части урока. Единственное, что осталось добавить к выше сказанному, раз уж мы научились создавать объекты, нужно не забывать их удалять. Объекты DirectX являются обычными COM объектами. После того, как мы закончили ими пользоваться, необходимо вызвать методы Release, для каждого из этих объектов:

// функция ReleaseAll освобождает объекты d3d device и d3d

void ReleaseAll {

 // Освобождаются в обратном порядке создания

 if (pDevice) pDevice->Release;

 if (pD3d) pD3d->Release;

}

Поведал: Ваткин.

Первые шаги под DirectX 8. (Часть 2)

Автор: Сергей Ваткин.

Попробуем вывести простейший объект в нашем приложении. Любой трехмерный объект, который может вывести DirectX, является полигональной моделью. То есть любой объект состоит из некоторого количества треугольников. Треугольники задаются своими вершинами. Вершины, в свою очередь, могут иметь какие-то координаты, цвет, текстурные координаты и т.д. Вершины могут быть разных типов, например, если мы не используем текстурирование, зачем нам задавать текстурные координаты. Зададим самый простой формат вершины. У вершины такого формата будут координаты положения в трёхмерном пространстве и цвет:

#define D3DFVF_MYVERT (D3DFVF_XYZ | D3DFVF_DIFFUSE)

Структура данных для такой вершины будет выглядеть следующим образом:

struct MyVert{

 float x, y, z; // координаты

 DWORD Color; // диффузный цвет

};

Цвет вершины задаётся 32-х битовым целым числом. Для установки нужного цвета можно использовать макроподстановку D3DCOLOR_XRGB(r,g,b), где r,g и b — составляющие компоненты цвета, соответственно красная, зелёная и синяя, могут принимать целые значения от 0 до 255-ти.

При помощи device вы управляете просчётом, то есть выводом графики. Чтобы заполнить каким-либо цветом, например, синим, всю область просчёта, можно воспользоваться методом Clear:

DWORD dwBlue = D3DCOLOR_XRGB(0, 0, 128);

pDevice->Clear(0, NULL, D3DCLEAR_TARGET, dwBlue, 1.0f, 0);

Перед тем, как вывести объекты, нужно предупредить DirectX об этом специальным вызовом:

pDevice->BeginScene;

После того, как вы закончили посылать объекты на просчет, вызывайте ещё один специальный метод:

pDevice->EndScene;

То есть прорисовка всех объектов происходит между вызовами этих методов. Об этом нужно помнить, если вы попытаетесь вывести объект вне этого блока, то DirectX просто проигнорирует вас.

Попробуем изобразить простой треугольник. Сначала укажем, каким типом вершин мы будем пользоваться.

pDevice->SetVertexShader(D3DFVF_MYVERT);

Это необходимо для того, чтобы DirectX знал, как расположена информация о вершине в структуре MyVert и каким способом он будет выводить объекты.

Поделиться с друзьями: