2011-12-27 2 views
1

У меня проблема с VBO, что я действительно не понимаю. Моя проблема решена путем случайного изменения последнего параметра в вызове метода glVertexAttribPointer. Итак, я ищу ответ, как ПОЧЕМУ это неожиданно работает или почему мой предыдущий код больше не работает. (Только, чтобы получить лучшее представление о OpenGL)glDrawElements EXC_BAD_ACCESS с помощью VBO

STRUCT:

typedef struct 
{ 
    float position[3]; 
    float color[4]; 
} Vertex; 

Без РВО:

// Get pointers to the data 
GLsizei stride = sizeof(Vertex); 
const GLvoid *pCoords = &squareVertices[0].position[0]; 
const GLvoid *pColors = &squareVertices[0].color[0]; 

// Setup pointers to positions and colors 
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, pCoords); 
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors); 

// Draw 
glDrawArrays(GL_TRIANGLES, 0, sizeof(squareVertices)/sizeof(Vertex)); 

С РВО (это дает мне EXC_BAD_ACCESS)

// Stide 
GLsizei stride = sizeof(Vertex); 

// Setup pointers to positions and colors 
glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0); 
glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, (GLvoid*) (sizeof(float) * 3)); 

// Draw 
glDrawElements(GL_TRIANGLES, sizeof(squareIndices)/sizeof(squareIndices[0]), GL_UNSIGNED_BYTE, 0); 

Итак, единственное, что на самом деле отличается, - это вызов glVertexAttribPointer, который имел указатель на данные и теперь имеет фиксированные номера. Может ли кто-нибудь уточнить это? Заранее спасибо.

ответ

4

Когда активен VBO, последний параметр glVertexAttribPointer на самом деле не является указателем, но смещение внутри объекта-объекта буфера вершины-литье к указателю. Вот как работают VBOs: данные были скопированы в некоторую память, управляемую графическим драйвером, вы не знаете его адрес. Фактически, он может даже не иметь нормального адреса, когда он где-то хранится на вашей видеокарте.

Остальное обманывает систему типа C/C++. Система типов нигде не достаточно умна, чтобы понять, что последний аргумент glVertexAttribPointer должен быть смещением целочисленного размера указателя при активном VBO и указателем в противном случае. Поэтому для компилятора C++ это должно выглядеть как указатель все время, потому что именно так glVertexAttribPointer (или, скорее, его предшественники glVertexPointer и друзья), где определено первоначально. Когда это действительно просто число, мы просто используем тип cast, чтобы обмануть компилятор.

+0

Ничего себе! Это был быстрый андер. Действительно оценен. Cristal clear;) – polyclick

Смежные вопросы