4

を使用してテキストをレンダリングするTTF_RenderUTF8_Blendedと、画面上に塗りつぶされた長方形が表示されます。色は選択した色によって異なります。私の場合、長方形は赤です。

TTF_RenderUTF8_Blended を使用した結果

私の質問

私は何が欠けていますか?で生成されたサーフェスから適切なアルファ値を取得していないようですが、SDL_DisplayFormatAlpha(TTF_RenderUTF8_Blended( ... ))そうですか? 誰かが問題を認識または知っていますか?

追加情報

私が使用するTTF_RenderUTF8_SolidTTF_RenderUTF8_Shaded、テキストが適切に描画されている場合、もちろんブレンドされていません。

画面に他のテクスチャも描画しているので、テキストを最後に描画して、ブレンディングで現在のサーフェスが考慮されるようにします。

編集:SDL_Color g_textColor = {255, 0, 0, 0}; <-- アルファ値の有無にかかわらず試してみましたが、同じ結果が得られました。

あまり詳細を削除せずにコードを要約しようとしました。「g_」で始まる変数はグローバルです。

Init() 関数

// 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);
}
4

1 に答える 1

4

あなたはよくある間違いを犯しました。それはOpenGLの終わりにあります。

でテクスチャクワッドをレンダリングすると、DrawText()OpenGL のブレンド機能が有効になりますが、ブレンド機能 (つまり、ブレンド方法) は指定されません!

OpenGL で通常のアルファ ブレンディングを有効にするには、次のコードが必要です。

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

この情報は以前は OpenGL の Web サイトにありましたが、現在は見つかりません。

それはそれが真っ赤になるのを止めるはずです。他の人が機能した理由は、それらがアルファブレンドされていないためです。実際には、アルファのない黒地に赤の画像であるため、ブレンド機能は重要ではありません. ただし、ブレンドされたものには赤色のみが含まれており、アルファチャンネルを使用して赤みを抑えています。

ただし、プログラムには他にもいくつかの小さな問題があることに気付きました。

この関数では、SDLDrawText()使用してサーフェスをブリッティングし、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()、それを見失い、解放されることはありません(したがって、メモリリークが発生します)。

良いニュースは、とにかくアルファ チャネルを持つ 32 ビット サーフェスを返すSDL_DisplayFormatAlphaため、ここでは必要ないということです! TTF_RenderUTF8_Blendedしたがって、この行を次のように書き換えることができます。

g_pText = TTF_RenderUTF8_Blended(g_pFont, "My first Text!", g_textColor);
于 2012-10-07T02:20:44.060 に答える