7

I have an OpenGL project which uses GLUT (not freeglut) wherein I would like to display 2D text on the viewport at a fixed location. The rest of my objects are in 3D world co-ordinates.

This answer to a related old question says that,

the bitmap fonts which ship with GLUT are simple 2D fonts and are not suitable for display inside your 3D environment. However, they're perfect for text that needs to be overlayed on the display window.

I've tried the approach outlined in the accepted answer, but it does not give me the desired output. Following is a code snippet of the display function:

void display()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glLoadIdentity();  
  glTranslatef(0.0, 0.0, -(dis+ddis));   //Translate the camera
  glRotated(elev+delev, 1.0, 0.0, 0.0);  //Rotate the camera
  glRotated(azim+dazim, 0.0, 1.0, 0.0);  //Rotate the camera

       .
       .
       .
  draw 3D scene
       .
       .
       .

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  gluOrtho2D(0.0, win_width, 0.0, win_height);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
  glRasterPos2i(10, 10);
  string s = "Some text";
  void * font = GLUT_BITMAP_9_BY_15;
  for (string::iterator i = s.begin(); i != s.end(); ++i)
  {
    char c = *i;
    glColor3d(1.0, 0.0, 0.0);
    glutBitmapCharacter(font, c);
  }
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glFlush();
  glSwapBuffers();
}

A similar question to what I want seems to have been asked, but has no accepted answers by the author.

Answers in general seem to suggest using other libraries (mostly OS specific) to achieve the overlay. However, there is no clear indication to whether this can be achieved with GLUT alone. Can it be done?

Community
  • 1
  • 1
Papouh
  • 504
  • 1
  • 3
  • 12
  • Well if it rotates that you have some calls to `glRotatef` or `glMultMatrix` between `glLoadIdentity()` and `glutBitmapCharacter`. You should just render your 3D scene and then do everything that the first answer you posted proposes. – PeterT Sep 17 '13 at 10:40
  • I tried that already, but that overwrites the rendered 3D scene and simply displays the text in a blank screen. – Papouh Sep 17 '13 at 10:52
  • You aren't supposed to call `glClear` or `swapBuffers` inbetween. We can keep guessing what the problem is or you can post a minimal code example of what doesn't work. – PeterT Sep 17 '13 at 10:55
  • The code you posted works for me, your issue seems to be somewhere else. – PeterT Sep 17 '13 at 12:09
  • When you say it works, are you drawing a 3D scene and rotating the camera around too and still getting the overlay? – Papouh Sep 17 '13 at 12:15
  • [here's](http://www.youtube.com/watch?v=6JGOqUcjNZk) what I'm looking at, I only inserted a triangle in the "draw 3d scene" elision. Apparently some people had problems with it not working without `glDisable(GL_TEXTURE_2D);` but for me it seems to work either way. – PeterT Sep 17 '13 at 12:29
  • Hmm, `glDisable(GL_TEXTURE_2D)` does not make a difference in my case. I must be doing something wrong. Would it be too much to ask you to post a link to the code in your video example as an answer perhaps? Thanks for the video anyway. – Papouh Sep 17 '13 at 13:27
  • it's a bit silly since it's a copy & paste from your code which is largely a copypasta from the answer that you linked in your question but alright. – PeterT Sep 17 '13 at 13:40

3 Answers3

8

I ran into this same problem using glut to create a model of the solar system. Here's how I solved it: (using your code from above)

glDisable(GL_TEXTURE_2D); //added this
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, win_width, 0.0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, 10);
string s = "Some text";
void * font = GLUT_BITMAP_9_BY_15;
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
  char c = *i;
  glColor3d(1.0, 0.0, 0.0);
  glutBitmapCharacter(font, c);
}
glMatrixMode(GL_PROJECTION); //swapped this with...
glPopMatrix();
glMatrixMode(GL_MODELVIEW); //...this
glPopMatrix();
//added this
glEnable(GL_TEXTURE_2D);


You'll note i switched glMatrixMode(GL_PROJECTION); and glMatrixMode(GL_MODELVIEW); near the end. I decided to do this because of this website. I also has to surround the code section with glDisable(GL_TEXTURE_2D) and glEnable(GL_TEXTURE_2D).

Hope that helps- I worked for me. My solar system uses classes to perform all of this, I'd be happy to share more details upon request.

SyntaxRules
  • 2,056
  • 23
  • 32
6

As I said, the code you posted works perfectly fine. Here's the code I used to test it:

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include "GL/glu.h"
//glm not required
//#include <glm.hpp>
//#include <gtc/matrix_transform.hpp>
#include <string>

int win_width = 500, win_height = 500;

void renderScene(void) {

    static float dis=0, ddis=0, elev=0, delev=0, azim=0, dazim=0;

    azim += 0.5f;
    if (azim >= 360.0f){
        azim -= 360.0f;
    }

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -(dis + ddis));
    glRotated(elev + delev, 1.0, 0.0, 0.0);
    glRotated(azim + dazim, 0.0, 1.0, 0.0);
    glScalef(2.0f,2.0f,2.0f);

    glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 1.0f, 0.0f);
        glVertex3f(-0.5f, -0.5f, 0.0f);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(0.5f, 0.0f, 0.0f);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(0.0f, 0.5f, 0.0f);
    glEnd();


    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    //I like to use glm because glu is deprecated
    //glm::mat4 orth= glm::ortho(0.0f, (float)win_width, 0.0f, (float)win_height);
    //glMultMatrixf(&(orth[0][0]));
    gluOrtho2D(0.0, win_width, 0.0, win_height);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glColor3f(1.0f, 0.0f, 0.0f);//needs to be called before RasterPos
    glRasterPos2i(10, 10);
    std::string s = "Some text";
    void * font = GLUT_BITMAP_9_BY_15;

    for (std::string::iterator i = s.begin(); i != s.end(); ++i)
    {
        char c = *i;
        //this does nothing, color is fixed for Bitmaps when calling glRasterPos
        //glColor3f(1.0, 0.0, 1.0); 
        glutBitmapCharacter(font, c);
    }
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glEnable(GL_TEXTURE_2D);

    glutSwapBuffers();
    glutPostRedisplay();
}

int main(int argc, char **argv) {

    // init GLUT and create Window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(win_width, win_height);
    glutCreateWindow("GLUT Test");

    // register callbacks
    glutDisplayFunc(renderScene);

    // enter GLUT event processing cycle
    glutMainLoop();

    return 1;
}

The usual disclaimers about deprecated fixed function pipeline and others apply.

PeterT
  • 7,981
  • 1
  • 26
  • 34
  • 1
    Thanks for the code. It helped me debug my program. I haven't located the problem exactly, but there seems to be some problem with my drawing of the 3D scene. Accepting this, since it answers the question. – Papouh Sep 17 '13 at 15:49
0

There is a tricky way to solve your problem.

Please write a code before you call a function or what ever it is as written below:

glutBitmaCharacter(font, ' ');// 

Does it....! And it should work...

Shadow
  • 33,525
  • 10
  • 51
  • 64