【问题标题】:OpenGL, SDL_ttfOpenGL,SDL_ttf
【发布时间】:2013-06-10 02:19:53
【问题描述】:

我无法通过 SDL_ttf 在 OpenGL 中显示文本。我已经编写了 LoadFont() 函数来加载字体并制作 OpenGL 纹理。

int LoadFont( char *name, GLubyte r, GLubyte g, GLubyte b, char *text, int ptsize)
{
SDL_Color color = {r, g, b, 0};
TTF_Font *font = TTF_OpenFont(name, ptsize);

Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

SDL_Surface *msg = TTF_RenderText_Blended(font, text, color);

SDL_SetAlpha(msg, 0, 0);

if(!msg) {
    printf("Unable to Render text\n");
    return -1;
}

SDL_Surface *tmp = SDL_CreateRGBSurface(0, msg->w, msg->h, 32, rmask, gmask, bmask, amask);

SDL_BlitSurface(msg, NULL, tmp, NULL);


glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA,
             GL_UNSIGNED_BYTE, msg->pixels);


return 1;
}

我在 initGL() 中使用了这个函数:

int initGL( GLvoid )
{
glViewport(0, 0, SCREEN_WIDHT, SCREEN_HEIGHT);
LoadFont("THWACK.TTF", 255, 255, 255, "Hello!", 14);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45.0f, (GLfloat)SCREEN_WIDHT/(GLfloat)SCREEN_HEIGHT, 0.1f, 100.0f);

glMatrixMode(GL_MODELVIEW);

return TRUE;
}

我进一步尝试在多边形上显示此文本:

int drawGLScene( GLvoid )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(0.0f, 0.0f, -5.0f);

glBindTexture(GL_TEXTURE_2D, texture[0]);

glEnable(GL_TEXTURE_2D);
glBegin(GL_POLYGON);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glEnd();
glDisable(GL_TEXTURE_2D);

SDL_GL_SwapBuffers();

return TRUE;
}

但文本不显示,只有白色多边形。

【问题讨论】:

    标签: opengl sdl sdl-ttf


    【解决方案1】:

    GL_TEXTURE_MIN_FILTER 默认为 GL_NEAREST_MIPMAP_LINEAR

    如果您请求 mipmap 并且不上传完整的 mipmap,您将获得白色纹理。

    你有这个:

    // disable mipmapping on default texture
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    // create new texture, with default filtering state (==mipmapping on)
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, msg->pixels);
    

    试试这个顺序:

    // create new texture, with default filtering state (==mipmapping on)
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    
    // disable mipmapping on the new texture
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, msg->pixels);
    

    纹理过滤状态属于纹理对象而不是纹理单元,因此glTexParameterf() 之后 glBindTexture():

    OpenGL 2.1 spec,第 3.8.11 节(第 180 页)和第 3.8.12 节(第 182 页):

    3.8.11: ...接下来,有两组纹理属性;每个都包含选定的缩小和放大过滤器...

    3.8.12: ...生成的纹理对象是一个新的状态向量,包含第 3.8.11 节中列出的所有状态值,设置为相同的初始值... p>


    编辑:如果您想使用TTF_Render*_Blended(),您还必须在渲染之前启用混合:

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    
    glColor3ub( 255, 255, 255 );
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, stringTex );
    glBegin(GL_QUADS);
    ...
    

    例子:

    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL_opengl.h>
    
    GLuint TextToTexture( TTF_Font* font, GLubyte r, GLubyte g, GLubyte b, const char* text, int ptsize )
    {
        SDL_Color color = { r, g, b };
        SDL_Surface* msg = TTF_RenderText_Blended( font, text, color );
    
        // create new texture, with default filtering state (==mipmapping on)
        GLuint tex;
        glGenTextures( 1, &tex );
        glBindTexture( GL_TEXTURE_2D, tex );
    
        // disable mipmapping on the new texture
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, msg->w, msg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, msg->pixels );
    
        SDL_FreeSurface( msg );
        return tex;
    }
    
    GLuint stringTex = 0;
    void drawGLScene( int winWidth, int winHeight )
    {
        glViewport(0, 0, winWidth, winHeight );
    
        glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
        glClearDepth(1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45.0f, winWidth / (float)winHeight, 0.1f, 100.0f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.0f, 0.0f, -5.0f);
    
        // this is where the magic happens
        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    
        glColor3ub( 255, 255, 255 );
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, stringTex );
        glBegin(GL_QUADS);
            glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -1.0f, -1.0f );
            glTexCoord2f( 1.0f, 0.0f ); glVertex2f(  1.0f, -1.0f );
            glTexCoord2f( 1.0f, 1.0f ); glVertex2f(  1.0f,  1.0f );
            glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -1.0f,  1.0f );
        glEnd();
        glDisable(GL_TEXTURE_2D);
    }
    
    int main( int argc, char *argv[] )
    { 
        SDL_Init( SDL_INIT_EVERYTHING );
        SDL_Surface* display = SDL_SetVideoMode( 640, 480, 32, SDL_OPENGL );
    
        if( -1 == TTF_Init() )
            return -1;
    
        // http://unifoundry.com/unifont.html
        TTF_Font *font = TTF_OpenFont( "unifont.ttf", 14 );
        stringTex = TextToTexture( font, 255, 255, 255, "Hello!", 14 );
    
        glDepthFunc(GL_LESS);
        glEnable(GL_DEPTH_TEST);
        glShadeModel(GL_SMOOTH);
    
        bool running = true;
        while( running )
        {
            SDL_Event event;
            while( SDL_PollEvent( &event ) )
            {
                if( event.type == SDL_QUIT )
                {
                    running = false;
                    break;
                }
            }
    
            drawGLScene( display->w, display->h );
            SDL_GL_SwapBuffers();
            SDL_Delay( 16 );
        }
    
        TTF_CloseFont(font);
    
        TTF_Quit();
        SDL_Quit();
        return 0;
    }
    

    【讨论】:

    • 非常感谢您的回答和帮助。我已经按照你写的修改了我的代码,但它仍然没有运行。
    猜你喜欢
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 2011-02-19
    • 2014-04-12
    相关资源
    最近更新 更多