Использование 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, но вам нужно взять его за руку и провести по нему....

  1. Скажите ему, какие вершины ему нужно построить и декартовы координаты одинаковы. Вы сделали это правильно.

  2. Затем вы должны сказать ему, как это сделать. Это делается массивом индексов массива. Это также сделано правильно вами.

Но у меня есть ощущение, что это происходит потому, что между последовательными вызовами 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);

Надеюсь это поможет...

Другие вопросы по тегам