我目前正在使用Glut的函数glutBitmapString来叠加我的窗口上的文本。我知道我可以使用不同的Bitmapped字体指定字体/大小。但是,可能的最大文本是GLUT_BITMAP_TIMES_ROMAN_24,是否可以使用更大的字体打印2D文本?或者有没有办法调整glutBitmapString显示的字体大小?
答案 0 :(得分:2)
将文本渲染为纹理,然后使用所需的缩放系数渲染具有该纹理的四边形。
这样的事情:
#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;
}