Sunday, 4 December 2011

OpenGL / Allegro 5.1 2D bitmap overlay panel

And here's another small tidbit of using OpenGL with Allegro 5.1. Sooner or later, rendering 3D objects is not going to be enough to interact with an application. We are going to need a 2D "control panel", which will have indicators and switches, etcetera, like this very lame one I threw together...

It is a straight forward PNG bitmap, 800 x 197 pixels. The object is to put this "panel" at the bottom of my OpenGL display, after I have rendered my "3D" object.

First some familiar stuff, except this time I'll make a flat triangle as my object just to vary a little...

Note: Once again, all the following blocks of code can be put together to create the working sample program.

#include "allegro5/allegro.h"
#include "allegro5/allegro_opengl.h"
#include "allegro5/allegro_image.h"
#include "GL/glu.h"

int main()
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_BITMAP *bmp_panel = NULL;

al_init();
al_init_image_addon();

al_set_new_display_flags(ALLEGRO_OPENGL);
display = al_create_display(800, 600);

bmp_panel = al_load_bitmap("panel.png");

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(35.0, GLdouble(800.0 / 600.0), 1.0, 200.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.75, -10.0);

glBegin(GL_TRIANGLES);

glColor3f(0.7, 0.0, 0.1);
glVertex3f(-1.5, -1.5, 0.0);
glColor3f(0.3, 0.0, 0.3);
glVertex3f(1.5, -1.5, 0.0);
glColor3f(0.2, 0.0, 0.7);
glVertex3f(0.0, 1.5, 0.0);

glEnd();

Nothing really new here, but if I tried to put my panel onto the screen right now with al_draw_bitmap(), I would not get any results at all, as I would be trying to draw a 2D panel "into" a 3D world. OpenGL does not know how to fit it. However, there is a way. The display projection needs to be reset to 2D. This is where glOrtho() comes in handy. The following bit of code will make the OpenGL display 2D "compatible".
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0.0, 800.0, 600.0, 0.0, 0.0, 1.0);

More about 2D drawing with OpenGL here...

Now I am able to draw my bitmap onto the screen with al_draw_bitmap(). Note, I use al_get_bitmap_height() to obtain how many pixels high the panel is, then subtract that value from the display Y value to place it properly on the display...
int bmp_height = al_get_bitmap_height(bmp_panel);
al_draw_bitmap(bmp_panel, 0.0, 600.0 - float(bmp_height), 0);

al_flip_display();
al_rest(5.0);

al_destroy_bitmap(bmp_panel);
al_destroy_display(display);

return 0;
}

And that would be it. Here's the result...

No comments:

Post a Comment