使用glutBitmapString调整字体大小

时间:2013-07-19 04:06:53

标签: opengl

我目前正在使用Glut的函数glutBitmapString来叠加我的窗口上的文本。我知道我可以使用不同的Bitmapped字体指定字体/大小。但是,可能的最大文本是GLUT_BITMAP_TIMES_ROMAN_24,是否可以使用更大的字体打印2D文本?或者有没有办法调整glutBitmapString显示的字体大小?

1 个答案:

答案 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;
}