NeHe OpenGL Lesson17 – 2D Texture Font
This sample show us how to display 2D texture font on the screen with OpenGL. This 2d texture font is just an image painted with characters instead of windows fonts.
The mainly workflow for 2D texture font as following:
1) Create a group of display list: render with texture coordinates and 2d screen size position, then translate a bit to prepare the next characters screen position. This translation will make those characters are not overlap with each other. Here is the source code;
GLvoid BuildFont(GLvoid) { float cx; float cy; base=glGenLists(256); glBindTexture(GL_TEXTURE_2D, texture[0]); for (loop=0; loop<256; loop++) { cx=float(loop%16)/16.0f; cy=float(loop/16)/16.0f; glNewList(base+loop,GL_COMPILE); glBegin(GL_QUADS); glTexCoord2f(cx,1-cy-0.0625f); glVertex2i(0,0); glTexCoord2f(cx+0.0625f,1-cy-0.0625f); glVertex2i(16,0); glTexCoord2f(cx+0.0625f,1-cy); glVertex2i(16,16); glTexCoord2f(cx,1-cy); glVertex2i(0,16); glEnd(); glTranslated(10,0,0); glEndList(); } }
The left image is the 2d texture font.
2) call glCallDisplayLists when you want to display some thing on the screen, do as what you did for the previous tutorials.
3) How about other language support with 2D texture font instead of English? Of course, we could do with this way. But we need to know the maximum number of characters, and texture storage for such fonts will become huge soon. At some situation, if we know the maximum number of characters, and the storage usage will not too much, we could use this solution. Actually, this solution is very easy to implement.
The other point that I could figure out is that, OpenGL provides some stack function, that means we could push/pop some attribute like matrix, color attributes. This could be very useful, we could push the current projection matrix, and set it to screen text mode matrix, then we will pop it up after we finish the screen text rendering. This is just glBeginTextMode() and glEndTextMode() do, the source code are following:
GLvoid glBeginTextMode() { glDisable(GL_DEPTH_TEST); // Disables Depth Testing glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glPushMatrix(); // Store The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix glOrtho(0,640,0,480,-1,1); // Set Up An Ortho Screen glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glPushMatrix(); } GLvoid glEndTextMode() { glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glPopMatrix(); // Restore The Old Projection Matrix glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glPopMatrix(); // Restore The Old Projection Matrix glEnable(GL_DEPTH_TEST); }
Here are the sample source code about how text mode should be used:
glBeginTextMode(); // Pulsing Colors Based On Text Position glColor3f(1.0f*float(cos(cnt1)),1.0f*float(sin(cnt2)),
1.0f-0.5f*float(cos(cnt1+cnt2))); glPrint(int((280+250*cos(cnt1))),int(235+200*sin(cnt2)),
"NeHe",0); // Print GL Text To The Screen // ... glEndTextMode();
The full source code could be downloaded from here.