Reputation: 415
I'm currently using Glut's function glutBitmapString to overlay text on my windows. I know that I can specify the font/size using different Bitmapped fonts. However, the largest text possible is GLUT_BITMAP_TIMES_ROMAN_24, is it possible to print 2D text with even bigger fonts? Or is there any way to resize the font displayed by glutBitmapString?
Upvotes: 1
Views: 4552
Reputation: 52084
Render your text to a texture and then render a quad with that texture with whatever scaling factor you want.
Something like this:
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cmath>
GLuint tex = 0, fbo = 0, rbo = 0;
GLuint fbo_w = 0, fbo_h = 0;
bool SetFboSize(int width, int height)
{
int max_size;
glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size );
if( width > max_size || height > max_size ) return false;
fbo_w = width;
fbo_h = height;
// create FBO
if(fbo) glDeleteFramebuffersEXT( 1, &fbo );
glGenFramebuffersEXT( 1, &fbo );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );
// create and attach a new texture as the FBO's color buffer
if(tex) glDeleteTextures( 1, &tex );
glGenTextures( 1, &tex );
glBindTexture( GL_TEXTURE_2D, tex );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0 );
// create and attach a new depth buffer to currently bound FBO
if(rbo) glDeleteRenderbuffersEXT( 1, &rbo );
glGenRenderbuffersEXT( 1, &rbo );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo );
if( GL_FRAMEBUFFER_COMPLETE_EXT != glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ) )
{
return false;
}
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // unbind fbo
return true;
}
void display()
{
// render to texture
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );
glBindTexture( GL_TEXTURE_2D, 0 );
{
glViewport( 0, 0, fbo_w, fbo_h );
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 0, 0 );
glWindowPos2i( 0, 0 );
glutBitmapString( GLUT_BITMAP_TIMES_ROMAN_24, (unsigned char*)"Hello, world!" );
}
// render to screen
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
{
int w = glutGet( GLUT_WINDOW_WIDTH );
int h = glutGet( GLUT_WINDOW_HEIGHT );
glViewport( 0, 0, w, h );
glClearColor( 0, 0, 0, 0 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double ar = w / (double)h;
glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub( 255, 255, 255 );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, tex );
float scale = sin( (double)glutGet( GLUT_ELAPSED_TIME ) / 1000.0f );
glScalef( scale, scale, 1 );
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 );
glVertex2i( -1, -1 );
glTexCoord2i( 1, 0 );
glVertex2i( 1, -1 );
glTexCoord2i( 1, 1 );
glVertex2i( 1, 1 );
glTexCoord2i( 0, 1 );
glVertex2i( -1, 1 );
glEnd();
}
glutSwapBuffers();
}
void timer( int extra )
{
glutPostRedisplay();
glutTimerFunc( 16, timer, 0 );
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glewInit();
if( !GLEW_VERSION_1_4 )
return -1;
if( !GLEW_EXT_framebuffer_object )
return -1;
if( !SetFboSize( 200, 50 ) )
return -1;
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
Upvotes: 2