【问题标题】:Using SDL_ttf and OpenGL, TTF_RenderUTF8_Blended print Red rectangle使用 SDL_ttf 和 OpenGL,TTF_RenderUTF8_Blended 打印红色矩形
【发布时间】:2012-10-02 23:53:10
【问题描述】:

当我使用TTF_RenderUTF8_Blended 渲染我的文本时,我在屏幕上获得了一个实心矩形。颜色取决于我选择的颜色,在我的例子中矩形是红色的。

我的问题

我错过了什么?似乎我没有从使用SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended( ... )) 生成的表面获得正确的 Alpha 值,还是我?有人认识或知道这个问题吗?

其他信息

如果我使用TTF_RenderUTF8_SolidTTF_RenderUTF8_Shaded,文本会正确绘制,但当然不会混合。

我还在屏幕上绘制其他纹理,所以我最后绘制文本以确保混合将考虑当前表面。

编辑:SDL_Color g_textColor = {255, 0, 0, 0};

我试图在不删除太多细节的情况下总结代码。以“g_”为前缀的变量是全局变量。

初始化()函数

// This function creates the required texture.
bool Init()
{
    // ...

    g_pFont = TTF_OpenFont("../arial.ttf", 12);
    if(g_pFont == NULL)
        return false;

    // Write text to surface
    g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended(g_pFont, "My first Text!", g_textColor)); //< Doesn't work

    // Note that Solid and Shaded Does work properly if I uncomment them.
    //g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Solid(g_pFont, "My first Text!", g_textColor));
    //g_pText = SDL_DisplayFormatAlpha(TTF_RenderUTF8_Shaded(g_pFont, "My first Text!", g_textColor, g_bgColor));

    if(g_pText == NULL)
        return false;

    // Prepare the texture for the font
    GLenum textFormat;
    if(g_pText->format->BytesPerPixel == 4)
    {
        // alpha
        if(g_pText->format->Rmask == 0x000000ff)
            textFormat = GL_RGBA;
        else
            textFormat = GL_BGRA_EXT;
    }

    // Create the font's texture
    glGenTextures(1, &g_FontTextureId);
    glBindTexture(GL_TEXTURE_2D, g_FontTextureId);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, g_pText->format->BytesPerPixel, g_pText->w, g_pText->h, 0, textFormat, GL_UNSIGNED_BYTE, g_pText->pixels);

    // ...
}

DrawText() 函数

// this function is called each frame
void DrawText()
{
    SDL_Rect sourceRect;
    sourceRect.x = 0;
    sourceRect.y = 0;
    sourceRect.h = 10;
    sourceRect.w = 173;

    // DestRect is null so the rect is drawn at 0,0
    SDL_BlitSurface(g_pText, &sourceRect, g_pSurfaceDisplay, NULL);

    glBindTexture(GL_TEXTURE_2D, g_FontTextureId);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBegin( GL_QUADS );

        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(0.0f, 0.0f);

        glTexCoord2f(0.0f, 1.0f);
        glVertex2f(0.0f, 10.0f);

        glTexCoord2f(1.0f, 1.0f);
        glVertex2f(173.0f, 10.0f);

        glTexCoord2f(1.0f, 0.0f);
        glVertex2f(173.0f, 0.0f);

    glEnd();
    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);
}

【问题讨论】:

  • 很抱歉没有指定它。它是一个 SDL_Color g_textColor = {255, 0, 0, 0}; (我尝试了是否指定 alpha 值,但我得到了相同的结果)。
  • 如果您不使用 SDL 位机,为什么还要使用 SDL_DisplayFormatAlpha()
  • @genpfault 这是我的问题之一。我不确定如何将整个 SDL_Blit 与 TTF_RenderUTF8_Blend 一起使用,并且我尝试了与我阅读的内容不同的东西。但是,我显然没有正确使用某些东西,这就是为什么我需要一些帮助。我需要有人能指出我做错了什么。

标签: c++ opengl sdl sdl-ttf


【解决方案1】:

你犯了一个相当普遍的错误。它在 OpenGL 端。

当您在DrawText() 中渲染纹理四边形时,您启用了 OpenGL 的混合功能,但您从未指定混合功能(即如何混合)!

您需要此代码在 OpenGL 中启用常规 alpha 混合:

glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

这个信息以前在 OpenGL 网站上,但我现在找不到了。

这应该会阻止它出现纯红色。其他人工作的原因是因为它们不是 alpha 混合的,它们实际上只是没有 alpha 的红黑图像,所以混合功能无关紧要。但是混合后的颜色只包含红色,并带有一个 alpha 通道以使其不那么红。

我注意到您的程序中还有其他一些小问题。

DrawText() 函数中,您使用SDL 对表面进行位图处理 使用OpenGL 进行渲染。使用 OpenGL 时不应使用常规 SDL 位图;它不起作用。所以这条线不应该在那里:

SDL_BlitSurface(g_pText, &sourceRect, g_pSurfaceDisplay, NULL);

另外,这行内存泄漏:

g_pText = SDL_DisplayFormatAlpha( TTF_RenderUTF8_Blended(...) );

TTF_RenderUTF8_Blended() 返回一个指向SDL_Surface 的指针,该指针必须用SDL_FreeSurface() 释放。由于您将它传递给SDL_DisplayFormatAlpha(),因此您会忘记它,并且它永远不会被释放(因此内存泄漏)。

好消息是这里不需要SDL_DisplayFormatAlpha,因为TTF_RenderUTF8_Blended 无论如何都会返回一个带有alpha 通道的32 位表面!所以你可以将这一行改写为:

g_pText = TTF_RenderUTF8_Blended(g_pFont, "My first Text!", g_textColor);

【讨论】:

  • 太棒了,我刚刚测试了它,它工作得很好。也感谢您的解释,有时当您只是想解决问题时,事情会相互堆积,很难找到。
  • 没问题,这是一个容易犯的错误。 glBlendFunc 有点复杂,但你在这里看到的方式是你 99% 的时间使用的方式。就像我说的,这些信息曾经出现在 OpenGL 的常见问题解答中,但现在没有了。
猜你喜欢
  • 2013-06-10
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-12
相关资源
最近更新 更多