SDL_Surface alpha混合

时间:2014-06-23 15:08:47

标签: alpha sdl-2

在构建我自己的图形引擎时,我需要有alpha混合的可能性(在SDL_Surface上)。这是一些测试代码:

(...)/test2/test2_1.cpp :
#include"../render_SDL/ME_render.h"

int main(int argc, char* argv[])
{
    Init();
    SDL_Window* w = SDL_CreateWindow("Test", 50, 50, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
    ME_Objects o;
    ME_Rect r1(50, 100, 300, 200, ME_RGBA(0, 0, 255, 255));
    ME_Rect r2(200, 150, 250, 350, ME_RGBA(255, 0, 0, 127));
    o.Add(&r1);
    o.Add(&r2);
    SDL_Surface *s1 = SDL_GetWindowSurface(w);
    SDL_SetSurfaceBlendMode(s1, SDL_BLENDMODE_BLEND);
    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 *s = SDL_CreateRGBSurface(0, 800, 600, 32, rmask, gmask, bmask, amask);
    SDL_SetSurfaceBlendMode(s, SDL_BLENDMODE_BLEND);
    o.ME_Rects[0].Render(s, 0, 0);
    o.ME_Rects[1].Render(s, 0, 0);
    ME_IMG i1(200, 250, "koncepcja.png");
    o.Add(&i1);
    ME_Line l1(10, 10, 160, 200, ME_RGBA(0, 255, 0, 255));
    o.Add(&l1);
    o.ME_IMGs[0].Load();
    o.UpdateBasicData(2, 0);
    o.ME_IMGs[0].Render(s, 0, 0);
    o.ME_Lines[0].Render(s, 0, 0);
    SDL_Rect scr = {0, 0, 800, 600};
    SDL_BlitSurface(s, NULL, s1, &scr);
    SDL_UpdateWindowSurface(w);
    Uint8 _r, _g, _b, _a;
    SDL_GetRGBA(((Uint32*)s1->pixels)[(151*s1->w)+201], s1->format, &_r, &_g, &_b, &_a);
    std::cout<<"RGBA: "<<(int)_r<<' '<<(int)_g<<' '<<(int)_b<<' '<<(int)_a<<'\n';
    bool running = true;
    while(running)
    {
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
            case SDL_QUIT:
                running = false;
            case SDL_WINDOWEVENT:
                if(event.window.event==SDL_WINDOWEVENT_RESIZED)
                {
                     s1 = SDL_GetWindowSurface(w);
                     SDL_BlitSurface(s, NULL, s1, &scr);
                     SDL_UpdateWindowSurface(w);
                }
            }
        }
    }
    SDL_DestroyWindow(w);
    char _resp;
    std::cin>>_resp;
    Quit();
    return 0;
}
(...)/render_SDL/ME_render.h :
(...)
bool ME_Rect::Render(void* surface, uintmax_t scrposx1, uintmax_t scrposy1)
{
    for(uintmax_t i = x1-scrposx1; i<x2-scrposx1; ++i)  for(uintmax_t j = y1-scrposx1; j<y2-scrposx1; ++j)  ((Uint32*)(((SDL_Surface*)surface)->pixels))[(j*((SDL_Surface*)surface)->w)+i] = SDL_MapRGBA(((SDL_Surface*)surface)->format, color.r, color.g, color.b, color.a);
    return true;
}
(...)

所以我直接设置每个像素值。但是,尽管将矩形r2的alpha值设置为127,但此矩形(在屏幕上)并不透明 - 它的颜色为深红色而不依赖于背景颜色(黑色区域)与r1 - 蓝色矩形)。我检查了输出。它显示:

RGBA: 127 0 0 255

而非预期结果:

RGBA: 127 0 255 255

如何正确进行Alpha混合?

1 个答案:

答案 0 :(得分:0)

我终于通过创建额外的表面(矩形r2的尺寸)并用颜色(透明红色)填充它来解决问题。然后我将它blitted到表面s(其中存储了整个屏幕内容),然后我将表面s发送到s1(窗口表面)。 alpha混合有效!