5.3.Моделирование анизотропного материала В данном разделе под анизотропным материалом будем понимать материал, свойства которого не постоянны и зависят от положения вершины. В Direct3D это может быть реализовано через возможность брать свойства материала не из структуры D3DMATERIAL9, а из вершины, которая может содержать два цвета: DIFFUSE (COLOR1) и SPECULAR (COLOR2). За эту возможность отвечают настройки:
D3DRS_DIFFUSEMATERIALSOURCE,
D3DRS_SPECULARMATERIALSOURCE,
D3DRS_AMBIENTMATERIALSOURCE,
D3DRS_EMISSIVEMATERIALSOURCE,
которые позволяют задать источник для соответствующего свойства материала. Эти настройки могут принимать значения:
D3DMCS_MATERIAL (цвет берется из материала),
D3DMCS_COLOR1 (цвет берется из DIFFUSE вершины),
D3DMCS_COLOR2 (цвет берется из SPECULAR вершины).
Чтобы включить такое использование цвета из вершины следует установить настройку D3DRS_COLORVERTEX в TRUE.
Приведем пример. Допустим, ambient и diffuse компоненты материала совпадают, но меняются по поверхности. Specular компонента также меняется, но по другому закону. Самосветимость материала является неизменной. Для задания компонент ambient и diffuse выберем первый цвет вершины (diffuse), для specular – второй. В таком случае в структуре появятся поля:
struct Vertex
{
...
DWORD diffuse; // Сюда запишем ambient == diffuse
DWORD specular; // Сюда запишем specular
...
};
В FVF флагах, описывающих вершину, появятся D3DFVF_DIFFUSE | D3DFVF_SPECULAR. Задание настроек будет выглядеть следующим образом:
pDev->SetRenderState(D3DRS_COLORVERTEX, TRUE);
pDev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
pDev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
pDev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
pDev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
6.Текстурирование 6.1.Понятие текстуры Под текстурой будем понимать некоторое изображение, определенным образом загруженное в Direct3D и используемое для “наложения” на треугольники (см. рис. 6).
Рис 6. “Наложение” текстуры. В Direct3D для представления текстуры существует следующая иерархия классов:
IDirect3DBaseTexture9
IDirect3DTexture9 – обычная 2D текстура
IDirect3DCubeTexture9 – “кубическая” текстура (6 2D квадратных сторон)
IDirect3DVolumeTexture9 – 3D текстура
Последние два типа применяются для создания сложных эффектов, не рассматриваемых в данном руководстве. Поэтому мы остановимся на изучении IDirect3DTexture9.
Создать IDirect3DTexture9 можно следующими способами.
Используя метод CreateTexture(), позволяющий задать ширину, высоту, количество уменьшенных копий текстуры (mipmap) (см. раздел 6.6), метод использования (usage), местонахождение (pool) и формат.
Таким же образом, но используя D3DXCreateTexture(), которая изменит входные параметры, если они не поддерживаются устройством.
D3DXCreateTextureFromFile(), которая прочтет графический файл с диска, сделает для него мипмапы (см. раздел 6.6), выставит правильный формат и пр. Функция может прочитать следующие форматы: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, .tga. Может считаться самой простым способом сделать текстуру, так как принимает только 3 параметра: IDirect3DDevice9, путь до файла и указатель на IDirect3DTexture9*.
D3DXCreateTextureFromFileEx(). Функция, аналогичная предыдущей, но позволяющая задать ширину, высоту, количество мипмапов, метод использования (usage), местонахождение (pool) и формат, методы фильтрации при изменении размера, методы фильтрации при построении уменьшенных копий.
Остановимся более подробно на параметрах, задаваемых этим функциям.
Размеры текстуры ограничены следующими факторами:
Максимальным размером текстуры, поддерживаемый устройством (см. D3DCAPS910.MaxTextureWidth и MaxTextureHeight).
Устройство может поддерживать или не поддерживать текстуры, сторона которых не является степенью 2 (это также можно определить с помощью D3DCAPS9, однако, для простоты, мы будем считать, что текстуры со стороной не степенью двойки не поддерживаются).
Формат текстуры (перечисляемый тип D3DFORMAT) определяет размер и метод хранения информации в пикселе. Общепринятым методом описания формата является такой:
<буква названия канала><кол-во бит><буква><кол-во бит> ... <буква><кол-во бит>.
Например, запись R8G8B8 обозначает 24-битный пиксель с 8-битами на канал, причем красный канал кодируется старшим байтом, а голубой – младшим. Буква Х обозначает неиспользуемый канал (биты, применяемые для выравнивания). Именно такой способ записи и используется в перечисляемом типе D3DFORMAT для записи текстурных форматов. Например, D3DFMT_R8G8B8.
На настоящий момент наиболее широко распространены следующие форматы:
16-битные: R5G6B5, A1R5G5B5, A4R4G4B4;
32-битные: X8R8G8B8, A8R8G8B8.
Они поддерживаются на всех современных видеокартах.
Параметр usage, как и в случае вершинных буферов, определяет использование текстуры. Рекомендуется использовать флаг D3DUSAGE_WRITEONLY. В качестве параметра pool, следует выбирать D3DPOOL_DEFAULT. Именно эта комбинация флагов гарантирует оптимальную скорость и использование памяти. Однако за все приходится платить: использование функции LockRect (аналог Lock для вершинных буферов) для таких текстур не возможно. Чтобы заполнить содержимым такую текстуру следует создавать аналогичную текстуру в D3DPOOL_SYSTEMMEM и копировать ее в целевую текстуру, используя UpdateTexture(). Понятно, что это касается только 1 и 2 способов создания текстуры (через CreateTexture() и D3DXCreateTexture()). Остальные способы запишут в текстуру прочитанное содержимое самостоятельно, но вы не сможете загрузить собственные уменьшенные копии (кроме как используя формат DDS).
Далее созданная текстура может быть удалена своим методом Release() и установлена, как текущая текстура для рендеринга методом SetTexture(int stageIndex, IDirect3DBaseTexture9 *pTex). Первый параметр задает номер этапа (stage), на который устанавливается текстура. Что такое текстурные этапы будет рассмотрено подробно в параграфе 6.5. В случае использования одной текстуры stageIndex задается в 0.
|