So I'm creating a game engine with many features, last time I focused on textures.
When I finished implementing some new code (Made by myself) I created new Entity with texture, and it was working really nice.
But If I create 2 or more textured objects game starts lagging..
- 1 Cube without texture = > 60 FPS
- 1 Cube with texture = > 60 FPS
- 2 Cubes without texture = > 60 FPS
- 2 Cubes with texture = 40-50 FPS
- 10 Cubes without texture = > 60 FPS
- 10 Cubes with texture = 20 FPS
- 100 Cubes without Texture = > 60 FPS
- 100 Cubes with Texture = < 1 FPS
- 10000 Cubes without Texture = > 60 FPS
I'm using GLSL sampler2D, texture UV from VBO, here is my renderer code:
bool textured = false;
if(entity->hasComponent("MaterialComponent"))
{
MaterialComponent *materialComponent = (MaterialComponent*) entity->getComponent("MaterialComponent");
if(materialComponent->material != NULL && materialComponent->material->texture != NULL) textured = true;
}
if(component->cullFaces)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
if(textured) glEnable(GL_TEXTURE_2D);
glBindVertexArray(component->model->vaoID);
glEnableVertexAttribArray(0);
if(textured) glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
//glDrawElements(GL_TRIANGLES, component->model->getVertexCount(), GL_UNSIGNED_INT, 0);
if(textured)
{
MaterialComponent *materialComponent = (MaterialComponent*) entity->getComponent("MaterialComponent");
if(materialComponent->material->texture->textureID == 0) glGenTextures(1, &materialComponent->material->texture->textureID);
glBindTexture(GL_TEXTURE_2D, materialComponent->material->texture->textureID);
SDL_Surface *surface = IMG_Load(materialComponent->material->texture->textureFile->getPath().c_str());
if(!surface) Error::throwError("Cannot load texture file!");
S32 colorMode = GL_RGB;
if(surface->format->BytesPerPixel == 4) colorMode = GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0, colorMode, surface->w, surface->h, 0, colorMode, GL_UNSIGNED_BYTE, surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glUniform1i(baseShader->loc_sampler, 0);
SDL_FreeSurface(surface);
}
glDrawElements(GL_TRIANGLES, component->model->getVertexCount(), GL_UNSIGNED_INT, 0);
if(textured)
{
//glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
glDisableVertexAttribArray(0);
if(textured) glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindVertexArray(0);
if(textured) glDisable(GL_TEXTURE_2D);
if(component->cullFaces)
{
glDisable(GL_CULL_FACE);
}
So I can create new TextureAsset for each cube or I can use one TextureAsset for each cube, it makes no difference about FPS.
I'm creating new TextureAsset like this:
TextureAsset *textureAsset = new TextureAsset(new FilePath("PATH_TO_TEXTURE"));
Then putting it inside Entity' MaterialComponent:
MaterialComponent *materialC = (MaterialComponent*) cube1->getComponent("MaterialComponent");
materialC->materialAsset->texture = textureAsset;
I think there is something bad inside my renderer method, it happens only if there is more than 1 textured object. Maybe I have to clean-up texture in different way?
I'm using SDL2, SDL2_image and GLEW.
If you need more code - just tell me.