Как использовать свой собственный класс в glVertexPointer / glColorPointer / glNormalPointer - PullRequest
2 голосов
/ 19 августа 2011

У меня есть класс, представляющий вершину следующим образом:

class Vertex
{
public:
Vertex(void);
~Vertex(void);

GLfloat x;
GLfloat y;
GLfloat z;

GLfloat r;
GLfloat g;
GLfloat b;

GLfloat nx;
GLfloat ny;
GLfloat nz;

Vertex getCoords();

Vertex crossProd(Vertex& b);
void normalize();

Vertex operator-(Vertex& b);
Vertex& operator+=(const Vertex& b);
bool operator==(const Vertex& b) const;
};

Я инициализирую свои VBO следующим образом:

glGenBuffers(2, buffers);

glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, fVertices.size()*sizeof(Vertex), &(fVertices[0].x), GL_STATIC_DRAW);
glVertexPointer(3, GL_UNSIGNED_BYTE, sizeof(Vertex), BUFFER_OFFSET(0));
glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(6*sizeof(GL_FLOAT)));
glNormalPointer( GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(3*sizeof(GL_FLOAT)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, fIndices.size()*sizeof(GLushort), &fIndices[0], GL_STATIC_DRAW);
glIndexPointer(GL_UNSIGNED_SHORT, 0, BUFFER_OFFSET(0));

Но при рисовании все это путается.Возможно, это потому, что я пропускаю неверный шаг и / или смещение буфера.

Странно то, что я экспериментировал с указателем, чтобы увидеть, совпадают ли адреса, пытаясь выяснить это сам, я столкнулся с чем-то странным:

Если я сделаю:

GLfloat *test = &(fVertices[0]).x;
GLfloat *test2 = &(fVertices[0]).y;

, тогда

test + sizeof(GLfloat) != test2;

fVertices - это std :: vector btw.

Надеюсь, что любой может просветитьо том, что передать вызовам указателя gl *.

1 Ответ

4 голосов
/ 19 августа 2011

Байтное расположение данных в структурах / классах (C ++ считает их одинаковыми) гарантируется только в том случае, если этот класс относится к типу простых старых данных (POD).До C ++ 0x правила для типов POD были очень строгими.Класс не может иметь конструкторов или деструкторов любого рода.Он также не может содержать не POD-типы.У него не может быть виртуальных функций.И так далее.

Итак, вам нужно удалить конструктор и деструктор.

Во-вторых, ваши смещения неверны.Ваши цвета находятся в 3 поплавках спереди, а не 6. Вы, кажется, изменили свои цвета и нормали.


Это:

test + sizeof(GLfloat) != test2;

арифметика указателя.Если у вас есть указатель на некоторый тип T, добавление 1 к этому указателю не добавляет 1 к адресу.По сути, это работает как доступ к массиву.Так что это так:

T *p = ...;
&p[1] == p + 1;

Поэтому, если вы хотите получить число с плавающей точкой после test, вы добавляете к нему one , а не размер с плавающей точкой.1019 *

Лично я никогда не понимал, почему так много программистов OpenGL любят собирать эти маленькие структуры формата вершин.Где вершина содержит определенное расположение данных.В то время они всегда кажутся хорошей идеей, но в тот момент, когда вам нужно изменить их, все ломается.

В долгосрочной перспективе гораздо проще не беспокоиться о наличии явной "вершины"объекты вообще.Просто есть сетки, которые имеют любые данные вершин, которые они имеют.Все должно быть сделано в линейном массиве памяти с байтовыми смещениями для атрибутов.Таким образом, если вам нужно вставить другую текстурную координату или вам нужна нормаль или что-то еще, вам не нужно радикально изменять код.Просто измените смещение байтов, и все работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...