# OpenGL 2D performance problem

This topic is 2815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello. I'm making a 2D game in C++ and OpenGL, and although it runs quite fine on my PC, it performs terribly on my Asus EEE netbook. I know it isn't very powerful, but it has no problems running some older 3D games and my project only consists of a hundred or so textured quads, most of which have the same 64x64 texture, and as i said, it is 2D. I know it's the graphics that's slow because the FPS changes according to window size.

I'm also using SDL for multiplatform compatibility, but with an OpenGL context that i draw into. Could this have an impact on performance?

Also, on my PC, although it mostly runs smoothly, sometimes, when i maximize the window to a full HD resolution, it starts using 100% of one CPU core for some reason, during which some frames are delayed, but this usually randomly stops after around a minute. Does anyone know why this could be happening?

I admit i don't have much experience with OpenGL, but eventually, i'd like to make this into something serious, so i really want to do everything correctly. Could you please look at this code and point out anything that can cause the performance issues or anything else i've done wrong, even if only slightly? Any other tips are welcome as well. Thanks.

Initialization - This is only called once at the beginning:
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) return -1; SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, colorDepth); // 24 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, multisample > 0); // true SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multisample); // 4 if (!(window = SDL_CreateWindow(windowCaption.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, windowFlags))) return -1; if (!(glContext = SDL_GL_CreateContext(window))) return -1; if (glewInit() != GLEW_OK) return -1; glClearColor(0, 0, 0, 1); glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // This part is also called when the window is resized. glViewport(0, 0, windowWidth, windowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, windowWidth, windowHeight, 0, 1, 0); // This also flips the Y axis. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); SDL_GL_SetSwapInterval(vsync);

Drawing - This is called in a loop:
SDL_GL_SwapWindow(window); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); // Transform the view so that x, y is in the center and s is the scale. glScaled(s, s, 1); double width = viewWidth/s/2; double height = viewHeight/s/2; glTranslated(width-x, height-y, 0); // DRAWING OBJECTS glPopMatrix();

GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); gluBuild2DMipmaps(GL_TEXTURE_2D, 3+alpha, width, height, alpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, data);

Drawing an object with a texture:
// textureAnchors = { 0, 1, 1, 0, 0 } glPushAttrib(GL_ENABLE_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); glTexCoord2sv(textureAnchors+3); glVertex2d(x+xOffset, y+yOffset); glTexCoord2sv(textureAnchors+2); glVertex2d(x+xOffset+width, y+yOffset); glTexCoord2sv(textureAnchors+1); glVertex2d(x+xOffset+width, y+yOffset+height); glTexCoord2sv(textureAnchors); glVertex2d(x+xOffset, y+yOffset+height); glEnd(); glPopAttrib();

Thanks for any help.

##### Share on other sites

Hello. I'm making a 2D game in C++ and OpenGL, and although it runs quite fine on my PC, it performs terribly on my Asus EEE netbook. I know it isn't very powerful, but it has no problems running some older 3D games and my project only consists of a hundred or so textured quads, most of which have the same 64x64 texture, and as i said, it is 2D. I know it's the graphics that's slow because the FPS changes according to window size.

I'm also using SDL for multiplatform compatibility, but with an OpenGL context that i draw into. Could this have an impact on performance?

Also, on my PC, although it mostly runs smoothly, sometimes, when i maximize the window to a full HD resolution, it starts using 100% of one CPU core for some reason, during which some frames are delayed, but this usually randomly stops after around a minute. Does anyone know why this could be happening?

I admit i don't have much experience with OpenGL, but eventually, i'd like to make this into something serious, so i really want to do everything correctly. Could you please look at this code and point out anything that can cause the performance issues or anything else i've done wrong, even if only slightly? Any other tips are welcome as well. Thanks.

Initialization - This is only called once at the beginning:
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) return -1; SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, colorDepth); // 24 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, multisample > 0); // true SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, multisample); // 4 if (!(window = SDL_CreateWindow(windowCaption.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, windowFlags))) return -1; if (!(glContext = SDL_GL_CreateContext(window))) return -1; if (glewInit() != GLEW_OK) return -1; glClearColor(0, 0, 0, 1); glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // This part is also called when the window is resized. glViewport(0, 0, windowWidth, windowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, windowWidth, windowHeight, 0, 1, 0); // This also flips the Y axis. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); SDL_GL_SetSwapInterval(vsync);

Drawing - This is called in a loop:
SDL_GL_SwapWindow(window); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); // Transform the view so that x, y is in the center and s is the scale. glScaled(s, s, 1); double width = viewWidth/s/2; double height = viewHeight/s/2; glTranslated(width-x, height-y, 0); // DRAWING OBJECTS glPopMatrix();

GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); gluBuild2DMipmaps(GL_TEXTURE_2D, 3+alpha, width, height, alpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, data);

Drawing an object with a texture:
// textureAnchors = { 0, 1, 1, 0, 0 } glPushAttrib(GL_ENABLE_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glBegin(GL_QUADS); glTexCoord2sv(textureAnchors+3); glVertex2d(x+xOffset, y+yOffset); glTexCoord2sv(textureAnchors+2); glVertex2d(x+xOffset+width, y+yOffset); glTexCoord2sv(textureAnchors+1); glVertex2d(x+xOffset+width, y+yOffset+height); glTexCoord2sv(textureAnchors); glVertex2d(x+xOffset, y+yOffset+height); glEnd(); glPopAttrib();

Thanks for any help.

a few things you can try:

1) don't use immediate mode, use vertexarrays or VBOs instead (1 VBO or VA is all you really need for quads, use glScalef and glTranslatef to position and scale that quad if you're using a VBO, (if you're using a VA it might be faster to do it on the CPU for such a low number of vertices though but in general its faster to let the GPU do the transformations), if you are drawing tiles you should consider using incremental transformations (so rather than pushing and popping the matrix or loading the identitymatrix before each tile you just keep translating by the same amount for each tile until you reach the end of the line)
2) use a texture atlas and only rebind the texture when you change atlas, draw your objects in an order that minimizes these changes.
3) Write your render function so that it renders more than one object at the time and remove unnecessary pushing and popping of attributes.
4) use floats instead of doubles (For really new hardware this is less of an issue but cheap or old hardware can perform significantly worse when you use double precision)

##### Share on other sites
Issuing draw calls per quad can quickly become a CPU bottleneck, especially on older machines. Follow the advice of SimonForsman, focus on batching multiple quads that use the same texture in a single VBO. This should greatly improve your performance on older computers.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 23
• 39
• 75