В этом разделе, называемом "3D структуры", вы узнаете, как закодировать информацию о вершинах, гранях, объектах в 3D. Например, вершины в 3D можно представить в виде:
float VertexX[1000]
float VertexY[1000]
float VertexZ[1000]
UV координаты текстуры можно хранить вот так:
float VertexU[1000]
float VertexV[1000]
Можно подумать, что это здорово. Но на самом деле можно сделать лучше! Потому что, если Вы ограничились1000 вершин, то это означает, что Вы не можете загружать объекты, у которых больше чем 1000 вершин. И второе, вершины при этом не объединены друг с другом. Это означает, что нет логического построения объекта. Теперь, рассмотрим другой метод:
typedef struct VertexTYPE
{
float x,y,z; - координаты в мире
float u,v; - координаты на текстуре
} vertextype;
Или же:
typedef struct VertexTYPE
{
float x,y,z;
} vertextype;
typedef struct MappingTYPE
{
float u,v;
} mappingtype;
Но давайте вернемся к первому примеру. Пусть мы имеем структуру (vertextype), но что, если мы хотим иметь n-вершин? Отлично, мы выделяем их динамически:
vertextype *vertices;
vertices = malloc(sizeof(vertextype)*n);
где n - определяет число вершин. Так, мы можем иметь n-вершин, но как быть с гранями? Как мы их сохраним? Отлично, для определения грани мы нуждаемся в указателях на три вершины, и мы могли бы нуждаться в значении затенении или в среднем значении для сортировки. Вот так, например:
typedef struct FaceTYPE
{
vertextype *p1,*p2,*p3;
long vertex[3]; - номера вершин, в списке вершин
char shading;
long midz;
} facetype;
Теперь, если мы допустим, что p1, p2 и p3 указатели на вершины, через которые мы можем модифицировать вершину непосредственно. Массив Vertex [3], который мы используем, если мы желаем обратиться к структурам вершины, т.е.
x = vertices[face[currentface].vertex[0]].x;
y = vertices[face[currentface].vertex[0]].y;
z = vertices[face[currentface].vertex[0]].z;
Или с использованием указателей:
x = face[currentface]->p1.x;
y = face[currentface]->p2.y;
z = face[currentface]->p3.z;
Также необходимо задать структуру объекта, чтобы сохранить все эти вершины. Структура могла бы содержать данные относительно того, как объект должен вращаться, где он позиционирован и возможно указатель на текстуру.
typedef struct ObjectTYPE
{
float rotatex,rotatey,rotatez;
long numvertices;
long numfaces;
vertextype *vertices;
facetype *face;
char *textptr;
} objecttype;
Допустим по указателю object.vertices мы можем найти все вершины, которые находится в этом объекте, вершина из object.vertices [0] первая, а вершина оbject.vertex[numvertices-1] последняя. То же самое и для структур граней. Это также дает нам возможность использовать один и тот же массив вершин для описания нескольких объектов. Следовательно, мы можем найти все вершины в нашем мире внутри переменной называемой "vertices" и каждую грань в переменной называемой "face". Следовательно, все вершины могут вращаться в новом массиве, который мы вызываем "vertices_rot", и мы имеем возможность обратиться к каждому объекту, чтобы вращать их отдельную вершину. Тот же самое относиться и к сортировке плоскостей, мы можем сортировать все плоскости на сцене, начинающейся с face[0], затем двигаемся далее. Мы нуждаемся в другой переменной, называемой "facesort", это массив плоскостей, но отсортированный по значению face.midz. Все это должно помочь в том, как представить объекты в 3D.