Mobile Zone is brought to you in partnership with:

I've been a game developer since 2005. After working 3 years in the game industry I've decided to go indie and make games. The first game was on June 2010 David is a DZone MVB and is not an employee of DZone and has posted 19 posts at DZone. You can read more from them at their website. View Full User Profile

OpenGL 2D Independent Resolution Rendering

04.24.2013
| 2578 views |
  • submit to reddit

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);	
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
// 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);
 
// Since OpenGL considers X=0,Y=0 the Lower left Corner of the Screen
glViewport(vp_x,screen_height-(vp_y+height),width,height);

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

// Now we use glOrtho
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// 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);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

So now we should push the transformations before actually drawing anything

// Push in scale transformations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
 
//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
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0,  0, 0);
glVertex3f(50, 0, 0);
glVertex3f(0, 50, 0);
glEnd();

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.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPopMatrix();

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

glMatrixMode(GL_PROJECTION);
glPopMatrix();   
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

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


Published at DZone with permission of David Amador, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)