How do I draw text with GLUT / OpenGL in C++?
There are two ways to draw strings with GLUT
glutStrokeString will draw text in 3D
(source: uwa.edu.au)
and glutBitmapString will draw text facing the user
(source: sourceforge.net)
using glutBitmapCharacter() to draw text closing opengl program
If you want to use any function of the GLUT library, then GLUT has to be initialized by glutInit
. e.g.:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
// [...]
}
Using GLUT to simply print text
You don't say what's specifically wrong, but I'm suspecting that your text is not showing up. The reason is likely that the raster position is being clipped, and this is causing your text to not be rendered.
The raster position is the "anchor point" of where a bitmap will be drawn. Usually, this is the lower-left corner of the bitmap (the glBitmap
can change that with by setting the x and y parameters to something other than zero, but assume you're not doing that). The raster position is transformed by the model-view matrix, just like a vertex in a geometric primitive. And just like a vertex, if the transformed raster position lies outside of the viewport, it's clipped, and nothing is rendered. What's important to know here is that any rendering of a bitmap - regardless of its size - is predicated on the raster position being inside of the viewport.
In your example, you don't show the viewport you're using, nor the projection transformation (the matrix on the GL_PROJECTION
stack), but you set the raster position to (1280, 720), which may well be outside of the viewport.
Let's say you want to render your text in the lower-left corner of your window (and for the sake of argument, let's say your window is 1280 x 1024). When it's time to render your text, drop the following into your rendering routine:
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0, 1280, 0, 1024 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glRasterPos2i( 10, 1014 ); // move in 10 pixels from the left and bottom edges
for ( int i = 0; i < len; ++i ) {
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, menu[i]);
}
glPopMatrix();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
Depending on which version of OpenGL you're using, you may be able to use a simpler routine glWindowPos2i()
(the 2i
can be replaced with other dimension-type pairs like other OpenGL functions), which bypasses transforming the raster position by the model-view and projection matrices, and works directly in window coordinates. In that case, you'd write the above code as:
glWindowPos2i( 10, 1014 ); // move in 10 pixels from the left and bottom edges
for ( int i = 0; i < len; ++i ) {
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, menu[i]);
}
How to display text over rectangle in OpenGL in C++?
Okay after a day I got it, I'm so dumb :')
#ifdef __APPLE_CC__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
void init2D(float r, float g, float b)
{
glClearColor(r, g, b, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 600.0, 0.0, 600.0);
}
void rectangle()
{
glBegin(GL_POLYGON);
glColor3f(0.4,0,0.8);
glVertex3f(150.0f, 200.0f, 0.0f);
glColor3f(0.4,0,0.8);
glVertex3f(450.0f, 200.0f, 0.0f);
glColor3f(0.6,0,0.6);
glVertex3f(450.0f, 400.0f, 0.0f);
glColor3f(0.6,0,0.6);
glVertex3f(150.0f, 400.0f, 0.0f);
glEnd();
}
void text()
{
char menu[80];
strcpy(menu,"Have courage and be kind");
int len;
len = strlen(menu);
glColor3f(1,1,1);
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0, 600, 0, 600 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glRasterPos2i(190, 300);
for ( int i = 0; i < len; ++i )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, menu[i]);
}
glPopMatrix();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
rectangle();
text();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(0, 0);
glutInitWindowSize(600, 600);
glutCreateWindow("Assignment 1 Question 2");
init2D(0.0f, 0.0f, 0.0f);
glutDisplayFunc(display);
glutMainLoop();
}
opengl display shape and draw text
Try this:
#include <GL/glut.h>
GLfloat g_xeye;
GLfloat g_yeye;
bool rollOn;
GLfloat g_light_position[] = {0.0, 10.0, 10.0, 0.0};
void timer( int extra )
{
if (rollOn){
g_xeye = g_xeye + 00000.1;
g_yeye = g_yeye + 00000.1;
}
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
void drawBitmapText(char *string, float x, float y, float z)
{
char *c;
glRasterPos3f(x, y, z);
for (c=string; *c != '\0'; c++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, *c);
}
}
void display(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
// draw cube in 3D
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(60, w / h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(g_xeye, 1, 0, 0);
glRotatef(g_yeye, 0, 1, 0);
GLfloat redDiffuseMaterial[] = {0.50, 0.0, 0.50, 0.0};
glMaterialfv(GL_FRONT, GL_DIFFUSE, redDiffuseMaterial);
glutSolidCube(2.0);
glPopMatrix();
// switch to 2D for text overlay
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, w, 0, h, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable( GL_LIGHTING );
glColor3ub(255,255,255);
drawBitmapText("Hello world",200,200,0);
glEnable( GL_LIGHTING );
glutSwapBuffers ();
}
void keyboard(unsigned char key, int x, int y)
{
if (key==27)
exit(0);
if (key == ',')
{
g_light_position[0] = g_light_position[0] - 1;
}
if (key == '.')
{
g_light_position[0] = g_light_position[0] + 1;
glLightfv(GL_LIGHT0, GL_POSITION, g_light_position);
}
if (key==32)
{
rollOn = !rollOn;
}
}
void special(int key, int x, int y)
{
if (key==27)
exit(0);
if (key == GLUT_KEY_UP)
{
g_xeye = g_xeye + 2;
}
if (key == GLUT_KEY_DOWN)
{
g_xeye = g_xeye - 2;
}
if (key == GLUT_KEY_RIGHT)
{
g_yeye = g_yeye + 2;
}
if (key == GLUT_KEY_LEFT)
{
g_yeye = g_yeye - 2;
}
}
void init(void)
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, g_light_position);
rollOn = false;
g_xeye = 0;
g_yeye = 0;
}
int main(int argc, char** argv)
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100, 100);
glutCreateWindow ("Project");
init();
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutDisplayFunc(display);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
You can avoid the 2D switch if you're willing to use glWindowPos()
from OpenGL 1.4 instead of glRasterPos()
.
Text on screen with GLUT
Is it possible without Freeglut.h?
Yup. glutBitmapCharacter()
and glutStrokeCharacter()
are both in the regular glut.h
.
freeglut.h
just adds glutBitmapHeight()/glutBitmapString()
and their stroked equivalents.
EDIT: How do I implement it into a loop?
The straightforward way:
void MyBitmapString( void* font, const std::string& str )
{
for( size_t i = 0; i < str.size(); ++i )
{
glutBitmapCharacter( font, (int)str[i] );
}
}
Use glRasterPos()
or glWindowPos()
for positioning.
Related Topics
Why Doesn't Emplace_Back() Use Uniform Initialization
How to Get a "Codesigned" Gdb on Osx
Thread Safe Lazy Construction of a Singleton in C++
What Is the C++ Function to Raise a Number to a Power
Is There Any Alternative to Using % (Modulus) in C/C++
Converting an Int to Std::String
What Is the Default Hash Function Used in C++ Std::Unordered_Map
App Does Not Run with VS 2008 Sp1 Dlls, Previous Version Works with Rtm Versions
In C++, What Does & Mean After a Function's Return Type
Practical Uses for the "Curiously Recurring Template Pattern"
Why am I Getting String Does Not Name a Type Error
How to Create a Dll with Swig from Visual Studio 2010
Compiling Qt 4.8.X for Visual Studio 2012
Xcode with Boost:Linker(Id) Warning About Visibility Settings