Положение полей (позиция, нормаль и т.д.) в вершине D3D9

Я пытаюсь прочитать 3D-модели, созданные для приложений DirectX, которые определяются следующим образом:

  • В заголовке файла указан гибкий формат вершин (FVF) меша (на самом деле у меня есть любые комбинации D3DFVF_{XYZ,DIFFUSE,NORMAL,TEX1,TEX2} в протестированных мной мешах)
  • Затем n вершины задаются в виде линейного шаблона с полями, представленными в соответствии с FVF.

Однако я не знаю порядка этих полей. Логика была бы в том, что это определено где-то в документации DirectX, но мне не удалось найти. Например, какая из этих двух структур верна для FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL (синтаксис C, но эта проблема применима ко всем языкам)?

// This one ?
struct vertex1
{
    D3DVERTEX pos;
    DWORD color;
    D3DVERTEX normal;
};

// Or this one ?
struct vertex2
{
    D3DVERTEX pos;
    D3DVERTEX normal;
    DWORD color;
};

Хотелось бы общий ответ на этот вопрос со всеми возможными полями (например, XYZ before DIFFUSE before NORMAL before TEX1 before TEX2). Указатель на нужную страницу документации тоже не помешал бы, потому что я не смог его найти :) .


person Pierre Bourdon    schedule 03.10.2009    source источник


Ответы (3)


а, вот и ты

FVF (OP говорит, что информация на этой странице неверна. Я не знаю, не проверял правильность позиционирования FVF)

Генератор

person Andrew Keith    schedule 03.10.2009
comment
Первая ссылка толком не определяет порядок полей в структуре (уже прочитал перед тем, как задать вопрос). Тем не менее, вторая ссылка кажется довольно полной, большое спасибо! - person Pierre Bourdon; 04.10.2009

Я сам столкнулся с тем же самым.

Я думаю, что порядок битов является требуемым порядком. Из d3d9types.h:

#define D3DFVF_RESERVED0        0x001
#define D3DFVF_POSITION_MASK    0x400E
#define D3DFVF_XYZ              0x002
#define D3DFVF_XYZRHW           0x004
#define D3DFVF_XYZB1            0x006
#define D3DFVF_XYZB2            0x008
#define D3DFVF_XYZB3            0x00a
#define D3DFVF_XYZB4            0x00c
#define D3DFVF_XYZB5            0x00e
#define D3DFVF_XYZW             0x4002

#define D3DFVF_NORMAL           0x010
#define D3DFVF_PSIZE            0x020
#define D3DFVF_DIFFUSE          0x040
#define D3DFVF_SPECULAR         0x080

#define D3DFVF_TEXCOUNT_MASK    0xf00
#define D3DFVF_TEXCOUNT_SHIFT   8
#define D3DFVF_TEX0             0x000
#define D3DFVF_TEX1             0x100
#define D3DFVF_TEX2             0x200
#define D3DFVF_TEX3             0x300
#define D3DFVF_TEX4             0x400
#define D3DFVF_TEX5             0x500
#define D3DFVF_TEX6             0x600
#define D3DFVF_TEX7             0x700
#define D3DFVF_TEX8             0x800

Я почти уверен, что порядок, который вы ищете, таков:

ПОЛОЖЕНИЕ,НОРМАЛЬНОЕ,PSIZE,ДИФФУЗНОЕ,ЗЕРКАЛЬНОЕ,TEX0[,TEXn...]

Я не смог найти окончательного ответа в документации.

person doug65536    schedule 02.05.2012

Ну, вы должны определить это следующим образом.

struct EitherVertex
{
    float x, y, z;
    DWORD col;
    float nx, ny, nz
};

or

struct EitherVertex
{
    D3DXVECTOR3 pos;
    DWORD col;
    D3DXVECTOR3 nrm;
};

(D3DVERTEX относится ко всей структуре вершин, а не только к трехэлементному вектору)

Из ваших двух вариантов многое зависит от того, как вы получаете доступ к этим элементам vert. Если вы используете устаревший FVF, то второй из двух вариантов является более правильным.

Однако, если вы используете объявления вершин, тогда ВЫ определяете, где в структуре находятся соответствующие данные, и порядок не имеет значения.

person Goz    schedule 03.10.2009
comment
Проблема в общем порядке, должен ли DIFFUSE всегда стоять перед NORMAL? Как насчет TEX1, TEX2 и т. д.? Я не использую объявления вершин, потому что исходный формат файла их не использует. На самом деле я использую данные в файле для рисования сетки с помощью OpenGL :). - person Pierre Bourdon; 04.10.2009
comment
Проблема, с которой сталкивается OP, заключается в том, что в C/C++ порядок структуры важен при использовании FVF. FVF должен быть правильно настроен для работы. - person Andrew Keith; 04.10.2009