Search code examples
performanceopenglglfw

OpenGL combine Textures


I'm programming a 2D-Game in OpenGL and I have to output a level which consists of 20x15 fields.

So I'm currently outputting a texture for each field which is quite slow (300 textures/frame).

But due to the reason that the level never changes, I wondered if it's possible to combine the textures to a big, single texture before the game-loop starts.

Then I would have to output only one texture with 4 Texture Coordinates (0/0)(0/1)(1/1)(1/0) and 4 glVertex2f() which specifies the position in the Window.

This is my current Code for each of the 300 fields:

glColor3f(1,1,1);
glBindTexture(GL_TEXTURE_2D,textur);
glBegin(GL_QUADS);
    glTexCoord2f(textArea.a.x,textArea.b.y);glVertex2f(display.a.x,display.a.y);
    glTexCoord2f(textArea.a.x,textArea.a.y);glVertex2f(display.a.x,display.b.y);
    glTexCoord2f(textArea.b.x,textArea.a.y);glVertex2f(display.b.x,display.b.y);
    glTexCoord2f(textArea.b.x,textArea.b.y);glVertex2f(display.b.x,display.a.y);
glEnd();

Note that I have the images for all possible field-types in one .tga-File. So I'm choosing the right one with glTexCoord2f().

The image-File with all Tiles is loaded into

GLuint textur;

So I bind the same texture for every field.

My target is to decrease CPU-time. Display-Lists didn't work because there is so many data to load in the Graphics Card, that, in the end, display-Lists were even slower.

I also wasn't able to use VBOs because I don't use extensions like GLUT.

So my idea was to generate a single texture which should be quite easy and effective.

I hope you can give me feedback how I can combine textures and if this method would be the easiest one to increase performance

EDIT: that are the OpenGl-Functions I use in my program:

When I start the program, I initialize the window:

glfwInit();                     
if( !glfwOpenWindow(windowSize.x,windowSize.y, 0, 0, 0, 0, 0, 0, GLFW_WINDOW ) ) 
{   glfwTerminate();           
    return;
}

And that's all what the game-loop does with OpenG:

int main()
{
    //INIT HERE (see code above)

    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);                                
    glAlphaFunc(GL_GREATER,0.1f);
    glEnable(GL_ALPHA_TEST);

    long loopStart;//measure loopcycle-time
    do{
        height = height > 0 ? height : 1;
        glViewport( 0, 0, width, height );              //set Origin
        glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );      //background-color
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();                      
        glOrtho(0,windowSize.x,0,windowSize.y,0,128);   //2D-Mode
        glMatrixMode(GL_MODELVIEW);
        loopStart=clock();

        //(...) OUTPUT HERE (code see above)

        glfwSwapBuffers();                              //erzeugte Grafikdaten ausgeben

        printf("%4dms -> ",clock()-loopStart);
    }while(...);

    glDisable(GL_ALPHA_TEST);
    glDisable(GL_TEXTURE_2D);
    glfwTerminate();
}

Solution

  • I identified a huge time-killer now. The textures I was using were too large, and the resolution was very unefficient.

    The main-texture which included the level sprites had a resolution of 2200x2200 Pixels. So the GPU increased the size to 4096x4096 and calculated it with a huge amount of data.

    The image contains 10x10 different Level-Tiles which are outputed on the screen with a resolution of 50x50 pixels each.
    So I saved the Tiles-File with a lower resolution (1020 x 1020 Pixels -> each tile=102x102px) and now I have a loop-cycle time of <=15ms.
    This isn't perfect, but in comparison with my previous 30-60ms it was a huge progress.