netlib.narod.ru | < Назад | Оглавление | Далее > |
До сих пор для описания компонентов нашей структуры данных вершины мы использовали настраиваемый формат вершин (FVF). Однако, в программируемом конвейере наши вершины могут содержать больше данных, чем можно описать с помощью FVF. Следовательно, нам нужен более наглядный и мощный способ объявления вершин.
Мы описываем объявление вершин в виде массива структур D3DVERTEXELEMENT9. Каждый элемент массива D3DVERTEXELEMENT9 описывает один компонент данных вершины. Таким образом, если структура данных вершины содержит три компонента (например, местоположение, нормаль и цвет), соответствующее ей объявление вершины будет описано массивом из трех структур D3DVERTEXELEMENT9. Определение структуры D3DVERTEXELEMENT9 выглядит следующим образом:
typedef struct _D3DVERTEXELEMENT9 { BYTE Stream; BYTE Offset; BYTE Type; BYTE Method; BYTE Usage; BYTE UsageIndex; } D3DVERTEXELEMENT9;
Stream — Указывает поток с которым связан данный компонент данных вершины.
Offset — Смещение в байтах от начала структуры данных вершины до начала данных компонента. Например, если структура данных вершины объявлена следующим образом:
struct Vertex { D3DXVECTOR3 pos; D3DXVECTOR3 normal; };
Смещение компонента pos равно 0, поскольку этот компонент первый в структуре. Смещение компонента normal равно 12 потому что sizeof(pos) == 12. Другими словами, компонент normal начинается с 12 байта, считая от начала структуры Vertex.
Type — Указывает тип данных. Здесь можно использовать любой член из перечисления D3DDECLTYPE; чтобы посмотреть полный список типов, обратитесь к документации. Вот наиболее часто используемые типы:
D3DDECLTYPE_FLOAT1 — Скаляр с плавающей точкой.
D3DDECLTYPE_FLOAT2 — Двухмерный вектор с плавающей точкой.
D3DDECLTYPE_FLOAT3 — Трехмерный вектор с плавающей точкой.
D3DDECLTYPE_FLOAT4 — Четырехмерный вектор с плавающей точкой.
D3DDECLTYPE_D3DCOLOR — Значение типа D3DCOLOR, которое расширяется до цветового вектора RGBA с плавающей точкой (r, g, b, a), в котором каждая компонента нормализована в интервале [0, 1].
Method — Задает мозаичный метод триангуляции. Мы считаем, что это достаточно сложная тема и поэтому будем всегда использоватть метод по умолчанию, задаваемый идентификатором D3DDECLMETHOD_DEFAULT.
Usage — Указывает предполагаемый способ использования данного компонента. То есть позволяет определить, чем является данный компонент — вектором местоположения, вектором нормали, координатами текстуры и т.д. В качестве значений используются члены перечисления D3DDECLUSAGE:
typedef enum _D3DDECLUSAGE { D3DDECLUSAGE_POSITION = 0, // Местоположение D3DDECLUSAGE_BLENDWEIGHTS = 1, // Веса смешивания D3DDECLUSAGE_BLENDINDICES = 2, // Индексы смешивания D3DDECLUSAGE_NORMAL = 3, // Вектор нормали D3DDECLUSAGE_PSIZE = 4, // Размер точки D3DDECLUSAGE_TEXCOORD = 5, // Координаты текстуры D3DDECLUSAGE_TANGENT = 6, // Тангенциальный вектор D3DDECLUSAGE_BINORMAL = 7, // Бинормальный вектор D3DDECLUSAGE_TESSFACTOR = 8, // Мозаичный коэффициент D3DDECLUSAGE_POSITIONT = 9, // Преобразованная позиция D3DDECLUSAGE_COLOR = 10, // Цвет D3DDECLUSAGE_FOG = 11, // Значение смешивания тумана D3DDECLUSAGE_DEPTH = 12, // Значение глубины D3DDECLUSAGE_SAMPLE = 13 // Данные выборки } D3DDECLUSAGE;
Тип D3DDECLUSAGE_PSIZE используется для задания размеров точек. Обычно он применяется для точечных спрайтов, чтобы можно было управлять их размером для каждой вершины. Объявление вершины с флагом D3DDECLUSAGE_POSITIONT явно указывает, что эта вершина уже преобразована и, следовательно, процессор видеокарты не должен отправлять ее на этапы обработки вершин (преобразование и освещение).
UsageIndex — Используется для идентификации нескольких компонентов вершины с одинаковым типом использования. Индекс использования представляет собой целое число в диапазоне [0, 15]. Предположим, у нас есть три компонента вершины с флагом типа использования D3DDECLUSAGE_NORMAL. Тогда для первого из них мы должны указать индекс использования 0, для второго — индекс использования 1, и для третьего — индекс использования 2. Благодаря этому мы сможем идентифицировать отдельную нормаль по ее индексу использования.
Рассмотрим пример описания объявления вершины. Предположим, что описываемый формат содержит вектор местоположения и три вектора нормалей. В этом случае описание объявления вершины будет выглядеть так:
D3DVERTEXELEMENT9 decl[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1}, {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 2}, D3DDECL_END() };
Макрос D3DDECL_END применяется для инициализации последнего элемента в массиве D3DVERTEXELEMENT9. Кроме того, обратите внимание на применение индекса использования для отметки векторов нормалей.
Как только вы описали объявление вершины в массиве структур D3DVERTEXELEMENT9, можно получить указатель на интерфейс IDirect3DVertexDeclaration9 с помощью следующего метода:
HRESULT IDirect3DDevice9::CreateVertexDeclaration( CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl );
pVertexElements — Массив структур D3DVERTEXELEMENT9, описывающий объявление вершины, которое мы создаем.
ppDecl — Используется для возврата указателя на созданный интерфейс IDirect3DVertexDeclaration9.
Вот пример вызова, где decl — это массив структур D3DVERTEXELEMENT9:
IDirect3DVertexDeclaration9* _decl = 0; hr = _device->CreateVertexDeclaration(decl, &_decl);
Вспомните, что настраиваемый формат вершин создан лишь для удобства и автоматически преобразуется в объявление вершин. Значит, когда мы используем объявление вершин непосредственно, нам больше не нужен вызов:
Device->SetFVF(fvf);
Вместо него мы используем вызов:
Device->SetVertexDeclaration(_decl);
где _decl — это указатель на интерфейс IDirect3DVertexDeclaration9.
netlib.narod.ru | < Назад | Оглавление | Далее > |