I am currently working on a 3D Game Engine that loads a level from an OBJ file and renders it with OpenGL. My problem is related to understanding how to render each object individually when i have multiple ones in one file.
I believe have come up with a solution to this problem. Since my obj loading way loads all of the vertecies,texture coordinates,and normals into one global vector, I needed a way to only send that data to the GPU once. So I do exactly that.
void OBJLevelLoader::InitializeGlobalGLBuffers()
{
glGenVertexArrays(1,&m_vertexBufferObjectId);
glBindVertexArray(m_vertexBufferObjectId);
//Vertex Positions
{
glGenBuffers(1,&m_positionBufferId);
glBindBuffer(GL_ARRAY_BUFFER,m_positionBufferId);
glBufferData(GL_ARRAY_BUFFER,sizeof(float) * m_vertecies.size(),&m_vertecies,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
}
//Texture Coordinates
{
glGenBuffers(1,&m_textureCoordinateBufferId);
glBindBuffer(GL_ARRAY_BUFFER,m_textureCoordinateBufferId);
glBufferData(GL_ARRAY_BUFFER,sizeof(float) * m_texelCoords.size(),&m_texelCoords,GL_STATIC_DRAW);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(1);
}
//Normals
{
glGenBuffers(1,&m_normalBufferId);
glBindBuffer(GL_ARRAY_BUFFER,m_normalBufferId);
glBufferData(GL_ARRAY_BUFFER,sizeof(float) * m_normals.size(),&m_normals,GL_STATIC_DRAW);
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(2);
}
glBindVertexArray(0);
}
Here I bind and do all of the necessary stuff in OpenGL to be able to send my data to the GPU. Now the only part that I am not sending to the GPU are the indicies. Since I want to have individual objects, I decided to store the indicies in a sepearte class for each individual object. The code for sending that to the GPU goes like this:
void GameObject::InitalizeGLBuffers()
{
glGenBuffers(1,&m_facesBufferId);
BindBuffer();
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(int) * m_faces.size(),&m_faces,GL_STATIC_DRAW);
UnbindBuffer();
}
void GameObject::BindBuffer() const
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_facesBufferId);
}
void GameObject::UnbindBuffer() const
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
}
I call InitializeGlobalGLBuffers() once and call InitalizeGLBuffers() per Game Object. The final part of the pipeline, is to draw the objects. Here i simply loop through the vector that contains the objects and draw them.
void OBJLevelLoader::DrawLevel(Textures& textures)
{
glBindVertexArray(m_vertexBufferObjectId);
for(unsigned int i = 0;i < m_objectVector.size();i++)
{
std::string textureName = m_objectVector.at(i)->GetTextureName();
m_objectVector.at(i)->BindBuffer();
(textures.GetTextureByName(textureName))->BindTexture();
glDrawElementsBaseVertex(GL_TRIANGLES,m_objectVector.at(i)->GetFaceVector().size(),GL_UNSIGNED_INT,0,0);
(textures.GetTextureByName(textureName))->UnbindTexture();
m_objectVector.at(i)->UnbindBuffer();
}
glBindVertexArray(0);
}
With this code however, my objects are never rastarized. All I get is a rectangle filled with the color I specified in glClearColor(). How come this design is not working? Am I lacking some sort of fundamental understanding of the way OpenGL works? I am a beginner and this is my first project with OpenGL but I feel as if this code should work as expected. In case my code snippets were not clear enough of the problem I am facing, here is the GitHub link to the project: https://github.com/toshko3331/Inaniloquent-Lamprophony/