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

на главную - закладки

Жанры

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

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

Шрифт:

• Функция D3DXMatrixIdentity строит единичную матрицу.

• Функция D3DXMatrixRotationZ строит матрицу вращения относительно оси Z на заданный угол.

• Функция D3DXMatrixLookAtLH строит видовую матрицу. Параметры этой функции задают точку, в которую будет смотреть камера. Постфикс -(LH) говорит о том, что матрица будет действительна для левосторонней системы координат (аналогично -(RH) для правосторонней)

• Функция D3DXMatrixPerspectiveFovLH строит проекционную матрицу.

Для того, чтобы "заставить" устройство рендеринга использовать только что созданные нами матрицы, существует функция SetTransform:

HRESULT SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix);

State —

тип матрицы, которую нужно изменить (мировая, видовая, проекционная и т.д.)

pMatrix — указатель на "матрицу-заменитель" :)

Вот что нам требуется от каждой из матриц:

a. Мировая

Сделаем так, чтобы пирамида с течением времени равномерно вращалась вокруг оси Z:

D3DXMATRIX matWorld;

D3DXMatrixIdentity(&matWorld);

D3DXMatrixRotationZ(&matWorld, GetTickCount/1024.0f);

g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

b. Видовая

Камера должна смотреть на пирамиду сбоку, причем не должно быть видно нижнего основания пирамиды (помнишь, мы выбросили два полигона основания?):

D3DXMATRIX matView;

D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(5.0f, 5.0f, 6.5f), &D3DXVECTOR3(0.0f, 0.0f, 1.0f), &D3DXVECTOR3(0.0f, 0.0f, 1.0f));

g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);

c. Проекционная

D3DXMATRIX matProj;

D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/3, 1.0f, 1.0f, 100.0f);

g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);

Здесь D3DX_PI/3 - это поле зрения (field of view) камеры. Попробуй поэкспериментировать с этим параметром.

Функция RenderScene

Собственно, здесь и происходит рендеринг сцены. Как всегда, он начинается с очистки окна и Z-Buffer'а:

g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100, 100, 100), 1.0f, 0);

Затем, подготавливаем D3D к началу сцены.

g_pD3DDevice->BeginScene;

Пересчитываем матрицы:

DoMatrices;

Теперь настроим текстуру. И вообще, здесь подходящее место для того, чтобы вкратце рассказать о том, что такое текстура и текстурные координаты! Итак… Текстура — это графическая картинка, которая используется для натягивания на трехмерный (и не только) объект, что придает ему реалистичный вид (правда, это зависит от текстуры и от того, кто и на что ее натягивает :)) ). При текстурировании объекта, каждая его вершина должна иметь текстурные координаты, т.е. числа от 0 до 1, задающие привязку к конкретному месту текстуры. Рассмотрим пример, т.е. нашу четырехугольную пирамиду. Она была выбрана не случайно именно четырехугольной! Представь себе квадратный (для простоты), очень эластичный лист резины, на котором изображена каменная стена (текстура). Теперь "схвати" его за центр и тяни вверх (при этом края квадрата должны оставаться на месте). Т.к. лист эластичный, он легко поддастся и начнет растягиваться. Вместе с ним будет растягиваться и изображение стены. Тяни до тех пор, пока лист не превратится в правильную четырехугольную пирамиду без нижнего основания. Заморозь полученный объект, чтобы он не вернулся в первоначальное положение. Все! Еще раз вернемся к месту, где задаются вершины пирамиды:

float a=6.0;

#define vertA {-a/2, a/2, 0.0f, 0xffffffff, 0.0f, 1.0f,}

#define vertB {-a/2, -a/2, 0.0f, 0xffffffff, 0.0f, 0.0f,}

#define vertC {a/2, -a/2, 0.0f, 0xffffffff, 1.0f, 0.0f,}

#define vertD {a/2, a/2, 0.0f, 0xffffffff, 1.0f, 1.0f,}

#define vertS {0.0f, 0.0f, (float)(a/sqrt(2)), 0xffffffff, 0.5f, 0.5f,}

0xffffffff (белый

цвет) — цветовой "вес" вершины. Белый цвет означает, что текстура в данной вершине будет того же цвета и яркости, что и в оригинале. Если заменить цвет на 0x00000000, то вершина будет черной и при рендеринге вокруг нее образуется черное пятно. Попробуй! =)

Последние два числа являются текстурными координатами. Вернемся к мысленному эксперименту с квадратным листом… (до того, как мы его деформировали) Возьмем его левый верхний угол за начало координат. Ось X направим вправо, ось Y — вниз. Тогда правый нижний угол будет иметь координаты (1, 1). Как ты уже догадался, центр квадрата (проекция вершины S пирамиды на плоскость основания) имеет координаты (0.5, 0.5). Вот так задаются текстурные координаты.

Вернемся к программе. У нас будет одноуровневая текстура, первым и единственным уровнем которой будет загруженная ранее g_pTexture:

g_pD3DDevice->SetTexture(0, g_pTexture);

При рендеринге на текстуры могут накладываться фильтры, что сглаживает многие недостатки. Изюминкой программы является то, что тип фильтра можно менять прямо во время исполнения (клавишами F1, F2, F3, F4). Кроме того, как я обещал в начале статьи, используем MipMapping! Но для начала расскажу, что он собой представляет…

MipMap - это цепочка текстур, каждая последующая из которых является менее детализированным вариантом предыдущей. Уменьшение детализации на один уровень достигается путем сокращения длины и ширины текстуры в два раза. Цепочка генерируется до тех пор, пока размер одной из сторон текстуры не становится равным 1. Допустим, что текстурированный объект удаляется от наблюдателя. Сначала на него накладывается текстура с максимальным разрешением, затем, по мере удаления, текстура переключается на свой менее детализированный вариант. Согласись, на далекий объект, который занимает на экране всего один пиксель, глупо натягивать текстуру размером 100 Kb. Таким образом, благодаря некоторым дополнительным затратам памяти на MipMap-текстуры, заметно увеличивается быстродействие рендеринга и, вообще говоря, его качество. Во время переключения между детализациями, визуально может быть заметен скачок. Его можно сгладить, используя фильтрацию, что мы и сделаем (напомню, что текущий тип фильтра хранится в переменной CurrentFilter):

g_pD3DDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, CurrentFilter);

g_pD3DDevice->SetTextureStageState(0, D3DTSS_MINFILTER, CurrentFilter);

g_pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, CurrentFilter);

Перед рендерингом из VB, необходимо задать сам буфер и формат вершин, что делается следующими двумя строками:

g_pD3DDevice->SetStreamSource(0, g_pVB, sizeof(MYVERTEX));

g_pD3DDevice->SetVertexShader(D3DFVF_MYVERTEX);

И, наконец! Все готово для рендеринга! Делается это всего одной функцией DrawPrimitive. Первый параметр говорит о том, в каком виде хранятся в VB вершины. В нашем случае, объект задается последовательностью треугольников (D3DPT_TRIANGLELIST). Второй параметр говорит о том, с какой по номеру вершины из VB начинать отрисовку. Третий параметр — количество примитивов (в нашем случае треугольников), которые требуется отрендерить.

g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);

Поделиться:
Популярные книги

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя

Печать мастера

Лисина Александра
6. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
фэнтези
6.00
рейтинг книги
Печать мастера

Идеальный мир для Лекаря

Сапфир Олег
1. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря

Кротовский, не начинайте

Парсиев Дмитрий
2. РОС: Изнанка Империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, не начинайте

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

Прорвемся, опера! Книга 3

Киров Никита
3. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 3

Демон

Парсиев Дмитрий
2. История одного эволюционера
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Демон

Прорвемся, опера! Книга 2

Киров Никита
2. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 2

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

Призыватель нулевого ранга. Том 3

Дубов Дмитрий
3. Эпоха Гардара
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга. Том 3

Сделай это со мной снова

Рам Янка
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сделай это со мной снова

Злыднев Мир. Дилогия

Чекрыгин Егор
Злыднев мир
Фантастика:
фэнтези
7.67
рейтинг книги
Злыднев Мир. Дилогия