Лучшие практики с вершинами в Open GL

8

Какова наилучшая практика в отношении хранения данных вершин в Open GL? То есть:

struct VertexColored {
    public:
        GLfloat position[];
        GLfloat normal[];

        byte colours[];
}

class Terrian  {
    private:
        GLuint vbo_vertices;
        GLuint vbo_normals;
        GLuint vbo_colors;
        GLuint ibo_elements;

        VertexColored vertices[];
} 

или хранить их отдельно в требуемом классе, например:

class Terrian  {
    private:
        GLfloat vertices[];
        GLfloat normals[];
        GLfloat colors[];

        GLuint vbo_vertices;
        GLuint vbo_normals;
        GLuint vbo_colors;
        GLuint ibo_elements;
}
Darestium
источник
Я продолжаю слышать, что переплетение значений для каждой вершины важно для производительности, было бы замечательно, если бы кто-то мог объяснить, почему именно
dreta
1
Второй пример имеет неправильный код: GLfloat [] ... -> GLfloat ... []
Кравемир
Да, извините, я просто привел пример, я пришел из C # фона, где вы объявляете массивы примерно так: GLfloat [] array;
Darestium

Ответы:

11

Нет лучшей практики. Все зависит от приложения, которое разрабатывается.

Для игры визуализатора нет никакой необходимости хранить вершины как в RAM и VRAM , это означает , что вам нужно держать только ВБО идентификатор. Исключением является местность, где вам нужно иметь доступ к позициям из-за высоты размещения / столкновения игроков.

Вам нужно объединить все данные вершин? Если вы хотите иметь несколько цветов для одних и тех же вершин, например, разные цвета для одних и тех же моделей игроков, то объединение всего может создать небольшое препятствие для развития.

Вы получаете доступ к данным вне класса? Если нет, вы получите только больше кода, чем vertices->position[i]вместо positions[i]. В конструкторе игр / моделей вам нужен доступ к ним извне, но вы не получаете доступ ко всем данным одновременно, когда вы моделируете, затем вы получаете доступ к позициям, а когда вы красите, вы получаете доступ к цветам.

Единственное, что я бы собрал - это xyz( rgb) значения в одну структуру для более приятного кода:

Vector3 {
   GLfloat x,y,z;
};

Color3 {
   GLbyte r,g,b;
};

Изменить: Я хотел бы добавить, что некоторые люди используют unionsдля упрощения glVertex * 3v, glVertex * 4v, glUniform * v ... вызова, где массив передается вместо отдельных переменных:

union Vector3f {
   GLfloat v[3];
   struct {
      GLfloat x,y,z;
   };
};

union Color3b {
   GLbyte c[3];
   struct {
      GLbyte r,g,b;
   };
};
kravemir
источник
Если вам нужны разные цвета для одной и той же модели, вы просто меняете текстуры или получаете все в оттенках серого и умножаетесь на цвет (или карту цветовой текстуры) в пиксельном шейдере. Но не храните данные процессора, если вам это не нужно. Но иногда вы хотите сохранить их, например для радиопередачи, это зависит, но оставить только вершины.
Notabene