Hi
I'm trying to render a Quake 3 BSP file using core OpenGL. I have the file loaded ok ( using the same code from a old OpenGL program ) - but I can't work out how to translate the old way of glDrawElements into the new core way of drawing indexed arrays.
this is what I end up with - a scrambled mess
So, once the BSP is loaded - I upload all the data to the GPU like this:
//-----------------------------------------------------------------------------
//
// Upload vertex arrays to GPU
bool bsp_uploadBspToGPU()
//-----------------------------------------------------------------------------
{
//
// Store model and all meshes in one VAO
glGenVertexArrays(1, &bspVAO_ID);
glBindVertexArray(bspVAO_ID);
// GL_CHECK(glGenBuffers(1, &elementArrayID));
// GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayID));
// GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_numOfMeshIndexes * sizeof(int)), &m_pMeshIndex, GL_STATIC_DRAW));
//
// Load vertices into GPU
GL_CHECK(glGenBuffers(1, &bspVBO_VERT));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_VERT));
// GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(tBSPVertex), &(m_pVerts[0].vPosition), GL_STATIC_DRAW));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(glm::vec3), &(m_pVerts[0].vPosition), GL_STATIC_DRAW));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
//
// Load texture coordinates into GPU
GL_CHECK(glGenBuffers(1, &bspVBO_TEXCOORD));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_TEXCOORD));
// GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(tBSPVertex), &(m_pVerts[0].vTextureCoord), GL_STATIC_DRAW));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(glm::vec2), &(m_pVerts[0].vTextureCoord), GL_STATIC_DRAW));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
//
// Load lightmap coordinates into GPU
GL_CHECK(glGenBuffers(1, &bspVBO_LIGHTMAP));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_LIGHTMAP));
// GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(tBSPVertex), &(m_pVerts[0].vLightmapCoord), GL_STATIC_DRAW));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(glm::vec2), &(m_pVerts[0].vLightmapCoord), GL_STATIC_DRAW));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
//
// Load normals into GPU
GL_CHECK(glGenBuffers(1, &bspVBO_NORMALS));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_NORMALS));
// GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(tBSPVertex), &(m_pVerts[0].vNormal), GL_STATIC_DRAW));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, m_numOfVerts * sizeof(glm::vec3), &(m_pVerts[0].vNormal), GL_STATIC_DRAW));
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
and after walking the BSP and finding all the viewable faces which I store in an array for later sorting, I then render each face like this:
//-----------------------------------------------------------------------------
//
// Actually draw the BSP face
void bsp_drawFace(tBSPFace *ptrFace)
//-----------------------------------------------------------------------------
{
GL_ASSERT(glBindVertexArray(bspVAO_ID));
GL_ASSERT(glUseProgram(shaderProgram[SHADER_GEOMETRY_PASS].programID));
wrapglBindTexture(GL_TEXTURE0, texturesLoaded[TEX_WALL].texID);
GL_ASSERT(glUniform1i(shaderProgram[SHADER_GEOMETRY_PASS].inTextureUnit, 0));
GL_ASSERT(glUniformMatrix4fv(glGetUniformLocation(shaderProgram[SHADER_GEOMETRY_PASS].programID, "u_modelMat"), 1, false, glm::value_ptr(modelMatrix) ));
// GL_ASSERT(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayID));
// GL_ASSERT(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * m_numOfMeshIndexes, &m_pMeshIndex[0], GL_STATIC_DRAW));
GL_ASSERT(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_VERT));
GL_ASSERT(glEnableVertexAttribArray(shaderProgram[SHADER_GEOMETRY_PASS].inVertsID));
GL_ASSERT(glVertexAttribPointer(shaderProgram[SHADER_GEOMETRY_PASS].inVertsID, 3, GL_FLOAT, GL_FALSE, 0, NULL));
GL_ASSERT(glBindBuffer(GL_ARRAY_BUFFER, bspVBO_TEXCOORD));
GL_ASSERT(glEnableVertexAttribArray(shaderProgram[SHADER_GEOMETRY_PASS].inTextureCoordsID));
GL_ASSERT(glVertexAttribPointer(shaderProgram[SHADER_GEOMETRY_PASS].inTextureCoordsID, 2, GL_FLOAT, GL_FALSE, 0, NULL));
GL_ASSERT(glDrawElements(GL_TRIANGLES, ptrFace->numOfVerts, GL_UNSIGNED_INT, &m_pMeshIndex[ptrFace->startVertIndex]));
// GL_ASSERT(glDrawElements(GL_TRIANGLES, ptrFace->numMeshVerts, GL_UNSIGNED_INT, &m_pMeshIndex[ptrFace->meshVertIndex]));
printf("Num verts in this face [ %i ] \n", ptrFace->numOfVerts);
for (int i = 0; i != ptrFace->numOfVerts; i++)
{
printf("Index [ %i ] - [ %i ]\n", i, m_pMeshIndex[ptrFace->startVertIndex + i]);
}
}
The data appears to be correct, ptrFace->numOfVerts seems to be the right number, and the indexes printed out seem correct as well.
<snip>
Num verts in this face [ 8 ]
Index [ 0 ] - [ 0 ]
Index [ 1 ] - [ 2 ]
Index [ 2 ] - [ 4 ]
Index [ 3 ] - [ 0 ]
Index [ 4 ] - [ 1 ]
Index [ 5 ] - [ 2 ]
Index [ 6 ] - [ 2 ]
Index [ 7 ] - [ 6 ]
Num verts in this face [ 4 ]
Index [ 0 ] - [ 4 ]
Index [ 1 ] - [ 0 ]
Index [ 2 ] - [ 4 ]
Index [ 3 ] - [ 5 ]
</snip>
I have also read that when using glDrawElements that you can use an indexed buffer as well, but I couldn't get that working either.
Any pointers on getting glDrawElements working correctly?
Thanks