Использование VBO для рендеринга квадрата
У меня возникли проблемы с пониманием того, как используются VBO. Я пытался получить изображение, эквивалентное:
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (70, 4.0f / 3, 1, 1000);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (0, 0, -5,
0, 0, 0,
0, 1, 0);
glBegin (GL_TRIANGLES);
glVertex3f (-1, -1, -1);
glVertex3f (1, -1, -1);
glVertex3f (1, 1, -1);
glVertex3f (-1, -1, -1);
glVertex3f (1, 1, -1);
glVertex3f (-1, 1, -1);
glEnd ();
что приводит к белому квадрату. Использование VBO, из того, что я мог бы извлечь из учебников, должно изменить код на:
float vertexes[][3] = {
{ 1, 1, -1},
{ 1, -1, -1},
{-1, 1, -1},
{-1, -1, -1},
};
unsigned int indexes[] = {
3, 1, 0,
3, 0, 2,
};
GLuint vbo, ibo;
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, 0);
glGenBuffers (1, &ibo);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, ibo);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (70, 4.0f / 3, 1, 1000);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (0, 0, -5,
0, 0, 0,
0, 1, 0);
glBufferData (GL_ARRAY_BUFFER, sizeof vertexes, vertexes, GL_STATIC_DRAW);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof indexes, indexes, GL_STATIC_DRAW);
glDrawElements (GL_TRIANGLES, 2, GL_UNSIGNED_INT, 0);
Однако это ничего не делает.
2 ответа
Выяснил в чем моя ошибка. Этот звонок:
glDrawElements (GL_TRIANGLES, 2, GL_UNSIGNED_INT, 0);
просит OpenGL нарисовать треугольник с двумя вершинами, а не два треугольника с тремя вершинами, как я думал. Правильный вызов:
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
VBO используется для подачи данных в систему рендеринга OpenGL, но вам нужно взять его за руку и провести по нему....
Скажите ему, какие вершины ему нужно построить и декартовы координаты одинаковы. Вы сделали это правильно.
Затем вы должны сказать ему, как это сделать. Это делается массивом индексов массива. Это также сделано правильно вами.
Но у меня есть ощущение, что это происходит потому, что между последовательными вызовами glBindBuffer() вы не очищаете буферы, поэтому возникают проблемы с тем, в какой буфер их помещать.
Пожалуйста, посмотрите на этот образец (написанный мной)
void InitVBO()
{
glGenBuffers(noOfVBO, vboHandle); // create an interleaved VBO object
for(int i =0;i<noOfVBO;i++)
{
glBindBuffer(GL_ARRAY_BUFFER, vboHandle[i]); // bind the first handle
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*masterNumberVertices[i], masterSolidVertex[i], GL_STATIC_DRAW); // allocate space and copy the position data over
glBindBuffer(GL_ARRAY_BUFFER, 0); // clean up
glGenBuffers(1, &indexVBO[i]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*masterNumberIndices[i], masterSolidIndices[i], GL_STATIC_DRAW); // load the index data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); // clean up
}
// by now, we moved the position and color data over to the graphics card. There will be no redundant data copy at drawing time
}
И это рутина квадратного рисунка.
//Draw Cube
glBindBuffer(GL_ARRAY_BUFFER, vboHandle[3]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO[3]);
glVertexPointer(4,GL_FLOAT, sizeof(Vertex),(char*) NULL+0);
glNormalPointer(GL_FLOAT, sizeof(Vertex),(char*) NULL+16);
glColorPointer(4,GL_FLOAT, sizeof(Vertex),(char*) NULL+32);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, .1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5,0,0,0,0,0,0,0,1);
glRotatef(x_angle, 0, 0,1);
glRotatef(y_angle, 0,1,0);
glScalef(scale_size, scale_size, scale_size);
glTranslatef(0,-1.5,-1.5);
//glScalef(1,5,5);
glDrawElements(GL_QUADS, masterNumberIndices[3], GL_UNSIGNED_INT, (char*) NULL+0);
Надеюсь это поможет...