По современным стандартам предпочтительный способ рендеринга полигональных сеток, по-видимому, предусматривает использование объектов вершинных буферов в сочетании с индексными буферами (в конечном итоге, полученными при вызовах glDrawElements()
), и именно поэтому я Я пытаюсь обернуть голову вокруг этих понятий. Кроме того, я настаиваю на использовании glVertexAttribPointer()
вместо устаревших glVertexPointer()
, glNormalPointer()
и т. Д.
Я использую пользовательский двоичный 3d формат файла (производная Wavefront .OBJ), содержимое которого может быть более или менее непосредственно memcpy()
'd для массива вершин. Вот как я объявил мою vertex
структуру:
typedef struct vertex_ {
float vx,vy,vz;
float nx,ny,nz;
float padding[2]; // align to 32 bytes
} vertex;
Функция loadBObj()
возвращает индексный буфер (реализованный в виде простого массива unsigned short int
с) и заполняет массив вершин соответствующими данными вершин / нормалей (все используемые модели имеют было экспортировано, чтобы иметь на каждую вершину-нормали для более плавного результата затенения).
indices = loadBObj("pharaoh.bobj", false, &VBOid);
Сам код загрузки проверен для правильной работы.
Теперь, что также делается в loadBObj()
, это создание нового VBO следующим образом:
glGenBuffers(1, VBOid);
glBindBuffer(GL_ARRAY_BUFFER, *VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*vcount, &vertarray[0].vx, GL_STATIC_DRAW);
После вызова loadBObj()
объект буферного индекса (вероятно, не следует называть его таковым) создается следующим образом:
glGenBuffers(1, &IBOid);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*qfcount*4, indices, GL_STATIC_DRAW);
OK. Когда дело доходит до фактического рендеринга меша, я использовал следующий код:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
...
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(3*sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glDrawElements(GL_QUADS, qfcount*4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
, что приводит к абсолютно правильной геометрии, но затенение не совсем верно:
- Вот изображение модели, отображенное в немедленном режиме:
img http://i44.tinypic.com/i36zcg.png
- Вот один из созданных программой, описанной выше:
img2 http://i43.tinypic.com/sgmhhi.png
Что-то смешное происходит с моей обработкой VBO?