DirectX 8. Начинаем работу с DirectX Graphics - [6]
>#define D3DFVF_MYVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
D3DFVF_XYZ — вершина задается тремя координатами в пространстве (а может задаваться и четырьмя — при D3DFVF_XYZRHW)
D3DFVF_DIFFUSE — вершина содержит цвет, который влияет на рассеяние света
D3DFVF_TEX1 -—вершина содержит две текстурные координаты
Т.к. запись
>D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1
интерпретируется компилятором в точности, как и
>D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE
значит порядок расположения данных в памяти в этом месте программы не задается. На программиста накладываются обязательства следовать схеме расположения данных, приведенной в руководстве D3D8 (раздел "About Vertex Formats").
Ну, надеюсь с этим все ясно. Теперь нужно занести вершины всех полигонов пирамиды в память. Для этого создаем массив из вершин и заполняем его данными:
>MYVERTEX Vertices[] = {
> vertS, vertA, vertD,
> vertS, vertB, vertA,
> vertS, vertC, vertB,
> vertS, vertD, vertC,
>};
Следующий шаг — нужно создать буфер вершин (VB) требуемого размера и формата. Пирамида будет отображена на экране так, что ее нижнего основания не будет видно, значит можно обойтись лишь 4-мя полигонами вместо 6-ти. Здесь я следовал правилу, которое прочитал в руководстве DX: "Remember, the fastest polygons are the ones you don't draw" (что в переводе означает: "Помни, наиболее быстрые полигоны — это те, которые ты не рисуешь"). Создание VB производится функцией CreateVertexBuffer:
>HRESULT CreateVertexBuffer(UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer8** ppVertexBuffer);
Length — длина VB в байтах
Usage — дополнительная информация о VB, которую D3D использует для создания оптимального VB
FVF — формат вершин, которые будут храниться в VB
Pool — в какой памяти создавать VB (можно создать его как в видеопамяти, так и в RAM)
ppVertexBuffer — адрес переменной, которая будет содержать указатель на созданный VB
Всего для хранения полигонов пирамиды используется 4*3*sizeof(MYVERTEX) байт (4 полигона, по 3 вершины в каждом).
>if (FAILED(g_pD3DDevice->CreateVertexBuffer(4*3*sizeof(MYVERTEX), 0, D3DFVF_MYVERTEX, D3DPOOL_DEFAULT, &g_pVB))) {
> return FALSE;
>}
Остается заполнить буфер вершинами. Для операций заполнения в DX (не только в D3D) используется пара команд Lock() и Unlock(). Команда Lock() возвращает адрес памяти, по которому расположен первый байт буфера. При этом вся память, отведенная под буфер как бы "запирается", и становится недоступной для других приложений. Операция "отпирания" памяти производится командой Unlock(). После запирания памяти, скопируем данные с помощью Си'шной функции memcpy().
>VOID* pVertices;
>if (FAILED(g_pVB->Lock(0, sizeof(Vertices), (BYTE**)&pVertices, 0))) return FALSE;
>memcpy(pVertices, Vertices, sizeof(Vertices));
>g_pVB->Unlock();
Я считаю, что это — самая сложная для понимания функция. Разговор о матрицах выходит за формат данной статьи, т.к. это очень обширная тема. Советую почитать статьи JM'а по этому поводу (скажу по секрету — он фанат матриц ;o)). Но вкратце, я все равно расскажу о матрицах :-)
У нас есть трехмерное пространство сцены, которое содержит вершины всех объектов, есть камера - глаз, с помощью которого мы видим это пространство, а также плоскость экрана монитора, на которую осуществляется проектирование. Все это ("мир", камера, операция проектирования) может быть выражено тремя матрицами: World Matrix (мировая матрица), View Matrix (видовая матрица) и Projection Matrix (проекционная матрица).
Вычислять эти матрицы "вручную" довольно сложно, поэтому воспользуемся функциями D3DX. Для матриц создан специальный тип данных D3DMATRIX. В библиотеке D3DX он расширен до типа данных D3DXMATRIX, в который добавлены арифметические операции с матрицами, и некоторые другие удобные свойства.
• Функция 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;
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.