For the past few days I've been trying to get a a square to render using VBOs but, unfortunately, have not been able to. So, any help I could get would be much appreciated. Sorry in advance for this post being so long: I wanted to give enough information on the problem.
Here's the problem:
The square isn't rendering. I'm trying to render it using the primitive type GL_TRIANGLES. Of course, it has four vertices for the corners and 2 indicies to specify the top left triangle and bottom right triangle.
Here's what I've done so far to try to solve the problem myself:
I've compared the code I'm writing now to the code I've written before where I actually used VBOs and was successful. I've checked out several threads on VBOs on this forum and others. I've checked out several sites that had tutorials on VBO's and read the vertex array, display lists and VBOs chapter in the "OpenGL SuperBible" book. I've also been comparing my code to the VBO code samples in that book and on the sites with the tutorials. I've also run my program through the program gDEBugger and used the OpenGL function glGetError(). You guys are my last resort and I figure there must be something small that I'm missing that some fresh eyes would see.
First, here's the output of gDEBugger's OpenGL calls history HTML log file. I've split it up into the setup and rendering to make it easier to read. I've also removed some of the calls that I thought were not related or useless; the comments are mine:
// SETUP
...
...
glGenBuffers(1, 0xE7648C) // generate buffer for vertices
glGenBuffers(1, 0xE764EC) // generate buffer for indices
glGenBuffers(1, 0xE7655C) // generate buffer for tex. coords: not used right now
glBindBuffer(GL_ARRAY_BUFFER, 1)
glBufferData(GL_ARRAY_BUFFER, 48, 0xE765B8, GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, 0xE76728, GL_STATIC_DRAW)
...
...
// RENDERING
glClear(0x4100)
glPushMatrix()
glMultMatrixf((1.00, 0.00, -0.00, 0.00) (-0.00, 1.00, -0.00, 0.00) (0.00, 0.00, 1.00, 0.00) (0.00, 0.00, 0.00, 1.00))
glTranslatef(-0.00, -0.00, -0.00)
glTranslatef(0.00, 0.00, -2.00)
// here's the VBO specific rendering:
glEnableClientState(GL_VERTEX_ARRAY)
glBindBuffer(GL_ARRAY_BUFFER, 1)
glVertexPointer(3, GL_FLOAT, 0, 0x0)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0x0)
glDisableClientState(GL_VERTEX_ARRAY)
glBegin(GL_LINES) // drawing a line for testing purposes
glVertex3f(0.50, 0.00, 0.00)
glVertex3f(-0.50, 0.00, 0.00)
glEnd()
glBegin(GL_TRIANGLES) // used this to check winding order: it was fine
glEnd()
glPopMatrix()
glGetError()
wglSwapBuffers(0x1601202D)
Here's my init code where I create the vertex and index buffers and add in the data:
void InitContextGL(void)
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
// the buffers are being generated in the constructor of CModel (see below).
testModel = new CModel;
// adding vertices to the vertex list
const float fHalfWidth = 1.0f;
const float fHalfHeight = 1.0f;
const float fDepth = 2.0f;
testModel->GetVertexData()->GetVertexList().reserve(4);
testModel->GetVertexData()->GetVertexList().push_back(new tVertex3f(-fHalfWidth, fHalfHeight, -fDepth)); // top left
testModel->GetVertexData()->GetVertexList().push_back(new tVertex3f(-fHalfWidth, -fHalfHeight, -fDepth)); // bottom left
testModel->GetVertexData()->GetVertexList().push_back(new tVertex3f(fHalfWidth, -fHalfHeight, -fDepth)); // bottom right
testModel->GetVertexData()->GetVertexList().push_back(new tVertex3f(fHalfWidth, fHalfHeight, -fDepth)); // top right
testModel->GetVertexData()->SetData(GL_STATIC_DRAW);
// creating a square using indicies
testModel->GetIndexData()->GetIndexList().reserve(2);
testModel->GetIndexData()->GetIndexList().push_back(new tIndex3n(3,0,1)); // top left triangle
testModel->GetIndexData()->GetIndexList().push_back(new tIndex3n(3,1,2)); // bottom right triangle
testModel->GetIndexData()->SetData(GL_STATIC_DRAW);
}
Here's the rendering specific code:
void RenderFrame(void)
{
Input(); // getting input
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
{
camera.ApplyCameraTransform();
glTranslatef(0.0f, 0.0f, -2.0f);
testModel->Render(); // this is where the VBO data is supposed
// to be rendering (see below for
// definition).
// drawing a line for test purposes (removed)
...
// rendering a white square to test winding order: it worked
// fine. (removed)
...
}
glPopMatrix();
// this function checks if there was an OpenGL error using glGetError and displays
// that error as a windows message box
CheckForOpenGLError(__FILE__, __LINE__);
}
void CModel::Render()
{
glEnableClientState(GL_VERTEX_ARRAY);
m_VertexData->PrepareForRender();
m_IndexData->Render();
glDisableClientState(GL_VERTEX_ARRAY);
}
You may be wondering where I'm calling glGenBuffers and what testModel->SetData(), m_VertexData->PrepareForRender(), and m_IndexData->Render() do. Here they are:
CModelData::CModelData()
{
// CVertexData and CIndexData (below) are derived off of CModelData, so
// they automatically get a buffer.
...
glGenBuffers(1, &m_uVertexBufferHandle);
}
void CModelData::BindBuffer()
{
glBindBuffer(GetTarget(), GetVertexBufferHandle());
}
...
void CVertexData::SetData(GLenum usage)
{
BindBuffer();
// tVertex3f is a struct that contains an array of 3 floats
glBufferData(GetTarget(), sizeof(tVertex3f) * m_VertexList.size(), &m_VertexList.front(), usage);
}
void CVertexData::SetVertexPointer()
{
glVertexPointer(3, GL_FLOAT, 0, 0);
}
void CVertexData::PrepareForRender()
{
BindBuffer();
SetVertexPointer();
}
...
void CIndexData::Render()
{
BindBuffer();
glDrawElements(GetPrimitiveType(), GetNumElementsToRender(), GetTypeOfValue(), GetBufferDrawOffset());
}
void CIndexData::SetData(GLenum usage)
{
BindBuffer();
// tIndex3n is a struct that contains an array of 3 integers
glBufferData(GetTarget(), sizeof(tIndex3n) * m_IndexList.size(), &m_IndexList.front(), usage);
SetNumElementsToRender(static_cast<GLsizei>(m_IndexList.size()) * GetNumIndexComponents());
}
Sorry if the code isn't very helpful with all of the function calls and it being split up so much (I'm going to be fixing it up). I'm hoping the gDEBugger log file will help if you want to know what values are getting passed to the OpenGL functions.
Edit: removed glEnableClientState(GL_INDEX_ARRAY) and glDisableClientState(GL_INDEX_ARRAY) to reflect a change that V-man suggested
[Edited by - Switch0025 on November 24, 2007 7:46:02 PM]