OpenGL Write Bitmap Text with Color


03 Jan 2015 opengl

OpenGL does not provide support for fonts, and hence does not provide support for “text”. But GLUT supports bitmap text with a limited number of fonts. The function glutBitmapCharacter is used to print a bitmap character at a 3D position inside the model. A series of characters can be printer using glutBitmapCharacter which makes a string like functionality.

This small snippet will print a text.

// The character array to hole the string
char text[] = "The text I want to print";
// The color, red for me
glColor3f(1, 0, 0);
// Position of the text to be printer
glRasterPos3f(x, y, z);
for(int i = 0; text[i] != '\0'; i++)
    glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, text[i]);

Let’s test this with an example. I wrote a code that rotates a blue cube by keystrokes. I will print the rotation value of X and Y axis on the screen. So, I used sprintf() to print the rotation value into the character array. Basically the arrangement looks like this.

void text()
{
    char text[32];
    sprintf(text, "X:%.0f Y:%.0f", xrot, yrot);
    glColor3f(1, 1, 0);
    glRasterPos3f( -25 , 20 , zoom);
    for(int i = 0; text[i] != '\0'; i++)
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, text[i]);
}

Now I am going to call the function text from my render function of OpenGL. My code to draw the whole scene is,

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cstdio>

float xrot = 0.00, yrot = 0.00, zoom = -30;

void text()
{
    char text[32];
    sprintf(text, "X:%.0f Y:%.0f", xrot, yrot);
    glColor3f(0, 0, 0);
    glRasterPos3f( -25 , 20 , zoom);
    for(int i = 0; text[i] != '\0'; i++)
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, text[i]);
}

void render(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0, 0, zoom);

    // Write the text before any transformation or rotation
    // Or the text will change its position with the models
    text();

    glRotatef(xrot, 1, 0, 0);
    glRotatef(yrot, 0, 1, 0);

    // Blue Cube
    glColor3f(0.0, 0.5, 0.9);
    glutSolidCube(10);

    glFlush();
    glutSwapBuffers();
}

void init(void)
{
    glClearColor( 1, 1, 1, 1);
    glClearDepth( 1.0 );
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_LIGHT0);
}

void reshape(int w, int h)
{
    float aspectRatio = (float)w/(float)h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, aspectRatio, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 's':
        xrot -= 1.0;
        break;
    case 'a':
        yrot -= 1.0;
        break;
    case 'w':
        xrot += 1.0;
        break;
    case 'd':
        yrot += 1.0;
        break;
    case 27:
        exit(0);
    }
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowSize(400, 300);
    glutCreateWindow("Bitmap Text Example");
    init();
    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glutDisplayFunc(render);
    glutMainLoop();
    return 0;
}

Now save and run the code with appropriate linkers. Mine looks like this.

GLUT Bitmap Text You see the black text at top-left corner of the screen? Why I rotate the cube with W/A/S/D, the values of X and Y changes and that is printed. I used raster point (-25,20) which makes it top-left aligned. You can use custom color, position etc.

If this post does not work for you, let me know.