Hi,
I am facing an issue where my FPS drops drastically (1200 fps to 80 fps) when I introduce the sponza mesh into my scene. moreover, my CPU and GPU usage are both low around 20% (CPU) and 10%(GPU). The sponza mesh that I am using is the Crytek version and has 145, 193 vertices and 262, 217 triangles. I think I am properly using VBOs and VAO to load the data into the GPU when the mesh is loaded during initialization. Here is a piece of code from my mesh class that runs once when the mesh is loaded
void Mesh::setupMesh() {
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()* sizeof(Vertex), &vertices[0], GL_STATIC_DRAW) ;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()* sizeof(unsigned int),
&indices[0],GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
if (hasNormals) {
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normals));
}
if (hasTexCoords) {
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texCoords));
}
glBindVertexArray(0);
}
And here is the part of my rendering code that is run every frame.
for (; it != entities.end(); it++) {
Entity* ent = (*it);
if (ent->mesh == nullptr) {
return;
}
Mesh* currentMesh = ent->mesh;
glBindVertexArray(currentMesh->VAO);
Shader* currentShader = nullptr;
if(overrideMaterial) {
currentShader = overrideMaterial->getShader();
}
for (int i = 0; i < currentMesh->subMeshes.size(); i++) {
SubMesh currentSubMesh = currentMesh->subMeshes[i];
Shader* submeshShader = currentSubMesh.material->getShader();
if (!currentShader && !overrideMaterial) {
currentShader = submeshShader;
currentShader->use();
}
if (!overrideMaterial && submeshShader->shaderName.compare(currentShader->shaderName)) {
currentShader = submeshShader;
currentShader->use();
}
currentShader->setMat4("modelMatrix", ent->getTransform()->getTransformationMatrix());
unsigned int diffuseNr = 0;
unsigned int specularNr = 0;
for (int j = 0; j < currentSubMesh.material->textures.size(); j++) {
Texture* currentTexture = currentSubMesh.material->textures[j];
string name, number;
if (currentTexture->type == TextureType::DIFFUSE) {
name = "texture_diffuse";
number = std::to_string(diffuseNr++);
}
else if (currentTexture->type == TextureType::SPECULAR) {
name = "texture_specular";
number = std::to_string(specularNr++);
}
currentTexture->bind(GL_TEXTURE0 + j);
currentShader->setInt("material." + name + "[" + number + "]", j);
}
currentShader->setInt("material.specularCount", specularNr);
currentShader->setInt("material.diffuseCount", diffuseNr);
currentShader->setInt("shadowMap", 10);
glDrawElementsBaseVertex(GL_TRIANGLES, currentSubMesh.indexCount, GL_UNSIGNED_INT, (void*)(sizeof(unsigned int) * currentSubMesh.baseIndex), currentSubMesh.baseVertex);
}
}
glBindVertexArray(0);
}
I am storing the entire Sponza mesh into a single VBO and using the glDrawElementsBaseVertex to draw the different parts of the mesh that use different textures. my total draw call count according to NVIDIA NSight is 400.
I know I can add more optimizations to this scene by adding CPU level culling but I still feel 80fps is quite low for such a small scene given that I am only doing a single pass with no shadows/reflections. My question is, is this performance expected or is there some part of my code that is unoptimized and is causing this issue?
I have a GTX 1060 and i7 7700k