2D in OpenGL

| Comments

After some experimentation, I have finally come to a point where I have written some code that does scaling, rotation and alpha on images that I want to display on the screen. Although the concept of drawing 2D in OpenGL is fairly easy to grasp, in that everything is the same except you don’t deal with the z-dimension, most of the time when you deal with 2D, you want to deal in actual pixel coordinates on the screen, and you want to do some things differently. Despite the numerous tutorial in OpenGL you can find online, few actually provide much information about using OpenGL for 2D graphics.

Why OpenGL for 2D graphics?

Not too long ago I was working on a project to greatly simplify drawing an image on to screen and rotating and scaling it just as you could do in photoshop, but programatically, after a few months of working on it I started realizing how slow and heavy the process of actually doing that kind of transformation was. On a framebuffer, performing transforms like those and blitting it to the screen was something that was painfully slow, used 75% of the CPU time usually, and not suitable for any application that would be rich in graphic content.

This led me to attempting to try OpenGL. The main selling point OpenGL had was it enabled direct access to any graphics accelerator hardware available on the computer. Graphics cards have been purpose built to perform sampling on images, and were designed to reduce the amount of data transferred from the main memory for the purposes of drawing stuff on the screen. This enabled acceleration to the point where hundreds of images could be transformed on the fly without any drop in frame rate, and without burdening the CPU with having to process images at every frame.

OpenGL is now found almost everywhere a graphics card is installed, and most, if not all PCs and Macs now come with graphics card that supports OpenGL in one way or another. This means that an application written using OpenGL, will effectively, theoretically be usable on any computer at all. Also, its OS-neutral nature meant that any programs I write with it will be usable on any modern OS that supports a half-decent graphics subsystem.

Portability, ubiquity and performance. These were the key reasons I thought that it was time to give OpenGL a go, so I did.

So how do you do it?

OpenGL in 2D is nothing more than just OpenGL without using the Z-axis. There are tons of OpenGL tutorials out there coughNeHecough that will teach you how to create a window and a rendering context for OpenGL. I recommend SDL for that purpose, because it has a set of libraries that work with it that simply does so much that you don’t have to find a library that does basic stuff like playing sounds and concentrate more on making your game. The only things you really need in addition to the standard 3D setup are to to map each pixel on the screen to OpenGL coordinates with gluOrtho2D and enabling alpha testing.

Some sample code stolen from somewhere below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void glEnable2D()
{
  glEnable (GL_ALPHA_TEST);

  int vPort[4];

  glGetIntegerv(GL_VIEWPORT, vPort);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  gluOrtho2D(0.0, vPort[2], vPort[3], 0.0);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  
}

So setting up OpenGL for 2D drawing is extremely simple. To draw something on the screen, simply go:

1
2
3
4
5
6
7
8
9
10
11
12
13
void drawFilledRectangle()
{
  glColor4f(255.0 , 0.0, 0.0, 255.0);

  glBindTexture( GL_TEXTURE_2D, 0 );

  glBegin( GL_QUADS );
  glVertex3i( 0, 0, 0 );
  glVertex3i( 100, 0, 0 );
  glVertex3i( 100, 100, 0 );
  glVertex3i( 0, 100, 0 );
  glEnd();
}

There we go, we have successfully drawn a rectangle on the screen. This may just become the start of a series of tutorials that I will write up as I learn more about using OpenGL for 2D drawings.

Comments