OpenGL 2D Independent Resolution Rendering

Around two years ago I made a tutorial for XNA in which you could render 2D games scaled to the current window resolution with proper letter-boxes or pillar-boxes.

As many know since then I moved to C++ and OpenGL, and ocasionally people ask me “Can you still do that independent resolution thing?”, and yes it’s perfectly possible. I’ve used this on all latest Windows, Mac and iOS, in case you are wondering.

The code is quite straight forward actually. In case you are not familiar with what we are trying to achieve here I recommend my other tutorial first, where I explain this is more detail.

So first we need to set our viewport with proper letterbox or pillar box, if required.

// Let's start by clearing the whole screen with black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);	
// Both these values must be your real window size, so of course these values can't be static
int screen_width = 1024;  
int screen_height = 728; 
// This is your target virtual resolution for the game, the size you built your game to
int virtual_width=1280;
int virtual_height=720;
float targetAspectRatio = virtual_width/virtual_height;
// figure out the largest area that fits in this resolution at the desired aspect ratio
int width = screen_width ;
int height = (int)(width / targetAspectRatio + 0.5f);
if (height > screen_height )
   //It doesn't fit our height, we must switch to pillarbox then
    height = screen_height ;
    width = (int)(height * targetAspectRatio + 0.5f);
// set up the new viewport centered in the backbuffer
int vp_x = (screen_width  / 2) - (width / 2);
int vp_y = (screen_height / 2) - (height/ 2);

Now that our viewport is set we should set our 2d perspective

// Now we use glOrtho
// This function is for Mac and Windows only, if you are using
// iOS you should use glOrthof instead
glOrtho(0, screen_width, screen_height, 0, -1, 1);
/*if on iOS*/ //glOrthof(0, screen_width, screen_height, 0, -1, 1);

So now we should push the transformations before actually drawing anything

// Push in scale transformations
//Now to calculate the scale considering the screen size and virtual size
float scale_x = (float)((float)(screen_width)) / (float)virtual_width);
float scale_y = (float)((float)(screen_height) / (float)virtual_height);
glScalef(scale_x, scale_y, 1.0f);

We can now proceed to drawing everything we want, that’s is really up to you now.

// Place your sprites drawing code here
// Example
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0,  0, 0);
glVertex3f(50, 0, 0);
glVertex3f(0, 50, 0);

I really don’t recommend using glBegin() and glEnd(), this was just for simplicity, you should use glDrawElements or glDrawArrays

After you finish you drawing code we can proceed to the rest

// This pops those matrices for the scale transformations.

//Now to finish we should end our 2D perspective


And that’s pretty much it. I have this code on my games and it works fine, at least for what I usually need. Feel free to tweak it around for your needs. Hope this helps to get a picture on how to achieve this effect. Let me know if you find any bug.

Here’s an example of what you might achieve with this


More Reading

Post navigation

  • Are you sure it is:
    glOrtho(0, screen_width, screen_height, 0, -1, 1);

    glOrtho(0, screen_width, 0, screen_height, -1, 1);


  • Hey!

    Just writing to say thanks for this post. I have been able to make it work for me but with a little tweak.
    I have looked at games like StarCraft, and some other strategy games and it seems that they always keep the same hight for the virtual viewport and only allow you to see more map on the sides like here:

    So I have implemented it the same way.

    I wanted to ask, how do you deal with sprite corruption after you scale matrix with glScalef()?
    Here is my image Not Scaled:
    Here is my image scaled:

    Sprite quality suffers after any scaling with glScaleF();

    Any tips?

    Regards. Juris.

Leave a Reply

Your email address will not be published. Required fields are marked *