SDL + SDL_ttf:透明混合文本?

Mar*_*aux 6 c++ string rendering sdl

我想在SDL_Surface给定的alpha通道上渲染一个消除锯齿的字符串.

我发现有可能呈现:

  • 带有Blended字符串渲染方法变体的消除锯齿的字符串(即:)TTR_RenderText_Blended.但后来我无法透明化.
  • 使用该Shaded方法的抗锯齿字符串.但后来有一个坚实的背景.背景和绘制的字符串可以变得透明,但实时背景仍然存在.传递它透明的背景颜色也是不可能的.
  • 一个非消除锯齿的字符串,我可以像Solid变量一样透明.但它没有消除锯齿.

谢谢

Qua*_*key 11

我知道我在这一点上有点晚了:/

根据SDL文档SDL_SetAlpha:

请注意,不能组合每像素和每表面alpha; 如果可用,则始终使用每像素alpha.

所以定期SDL_BlitSurface/ SDL_SetAlpha不会在这里工作.但这是可以完成的:

仅使用SDL的示例

我能想到alpha混合TTF_RenderText_Blended输出的唯一方法是使用OpenGL,或者调整表面中每个像素的alpha值.

通过调整每像素alpha值

您可以通过将每像素alpha值缩放[0, 255]到新范围来执行此操作[0, alpha]:

// Changes a surface's alpha value, by altering per-pixel alpha if necessary.
void SetSurfaceAlpha (SDL_Surface *surface, Uint8 alpha)
{
    SDL_PixelFormat* fmt = surface->format;

    // If surface has no alpha channel, just set the surface alpha.
    if( fmt->Amask == 0 ) {
        SDL_SetAlpha( surface, SDL_SRCALPHA, alpha );
    }
    // Else change the alpha of each pixel.
    else {
        unsigned bpp = fmt->BytesPerPixel;
        // Scaling factor to clamp alpha to [0, alpha].
        float scale = alpha / 255.0f;

        SDL_LockSurface(surface);

        for (int y = 0; y < surface->h; ++y) 
        for (int x = 0; x < surface->w; ++x) {
            // Get a pointer to the current pixel.
            Uint32* pixel_ptr = (Uint32 *)( 
                    (Uint8 *)surface->pixels
                    + y * surface->pitch
                    + x * bpp
                    );

            // Get the old pixel components.
            Uint8 r, g, b, a;
            SDL_GetRGBA( *pixel_ptr, fmt, &r, &g, &b, &a );

            // Set the pixel with the new alpha.
            *pixel_ptr = SDL_MapRGBA( fmt, r, g, b, scale * a );
        }   

        SDL_UnlockSurface(surface);
    }       
}           
Run Code Online (Sandbox Code Playgroud)

我知道它看起来很可怕,但它非常简单.关键在这里:

*pixel_ptr = SDL_MapRGBA( fmt, r, g, b, scale * a );
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

text_surface = TTF_RenderText_Blended( font, "Hello World!", color );
SetSurfaceAlpha( text_surface, 128 );
Run Code Online (Sandbox Code Playgroud)

使用OpenGL

如果使用OpenGL,事情就容易多了.假设您将SDL_Surfacefrom 转换TTF_RenderText_Blended为GL纹理,您可以使用:

glColor4f( 1.0, 1.0, 1.0, Alpha );
Run Code Online (Sandbox Code Playgroud)

在纹理四边形上渲染之前.

但不要忘记先启用alpha混合!

glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
Run Code Online (Sandbox Code Playgroud)


Vic*_*rzo -2

为什么不使用位图字体?您可以构建带有 Alpha 通道的 png 图像。我认为 SDL_ttf 适用于相同的系统,它构建一个图像并在内部使用位图字体。