关于C#:SDL2:生成完全透明的纹理

SDL2: Generate fully transparent texture

如何使用SDL_CreateTexture创建透明纹理?默认情况下,我使用以下代码创建texure:

1
SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET, x, y);

然后,我很痛苦地将输出重定向到该纹理。但是最后我想在屏幕上渲染任何(未更新的)像素是黑色。

我尝试过使用of:

的不同方式

1
 SDL_RenderClear(_Renderer);

甚至在绘制时以及在使用不同混合模式绘制透明Rect的创建纹理上进行绘制,但结果是我仍然只有非透明纹理:/

1
2
3
4
   SDL_Rect rect={0,0,Width,Height};
   SDL_SetRenderDrawBlendMode(_Renderer,SDL_BLENDMODE_BLEND);
   SDL_SetRenderDrawColor(_Renderer,255,255,255,0);
   SDL_RenderFillRect(_Renderer,&rect);

更具体地说:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    //this->texDefault.get()->get() = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET, x, y);
    SDL_SetRenderTarget(_Renderer.get()->get(), this->texDefault.get()->get());
    SDL_SetRenderDrawBlendMode(this->_Renderer.get()->get(),SDL_BLENDMODE_NONE);
    SDL_SetRenderDrawColor(this->_Renderer.get()->get(),255,0,255,0);
    SDL_RenderClear(this->_Renderer.get()->get());
    //SDL_Rect rect={0,0,Width,Height};
    //SDL_SetRenderDrawColor(this->_Renderer.get()->get(),255,255,255,255);
    //SDL_RenderFillRect(this->_Renderer.get()->get(),&rect);
    //SDL_RenderClear(this->_Renderer.get()->get());
    //SDL_SetRenderDrawBlendMode(this->_Renderer.get()->get(),SDL_BLENDMODE_NONE);
    SDL_SetRenderTarget(_Renderer.get()->get(), NULL);
    SDL_Rect rect= {relTop+Top,relLeft+Left,Height,Width};
    SDL_SetRenderDrawBlendMode(this->_Renderer.get()->get(),SDL_BLENDMODE_BLEND);
    SDL_RenderCopy(this->_Renderer.get()->get(), this->texDefault->get(), NULL, &rect);

此代码始终独立生成非透明纹理,我将为融合和alpha设置

结果是:

enter


  • 首先,您需要设置渲染器混合模式:SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
  • 其次,您需要设置纹理混合模式:SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND);

这是我创建的工作示例。您可以使用键A和S更改第三种纹理的Alpha通道,该通道在应用程序启动时不可见。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <iostream>
#include <vector>
#include <SDL.h>

void fillTexture(SDL_Renderer *renderer, SDL_Texture *texture, int r, int g, int b, int a)
{
    SDL_SetRenderTarget(renderer, texture);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
    SDL_SetRenderDrawColor(renderer, r, g, b, a);
    SDL_RenderFillRect(renderer, NULL);
}

void prepareForRendering(SDL_Renderer *renderer)
{
    SDL_SetRenderTarget(renderer, NULL);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
}

void checkSdlError()
{
    const char *sdlError = SDL_GetError();
    if(sdlError && *sdlError)
    {
        ::std::cout <<"SDL ERROR:" << sdlError << ::std::endl;
    }
}

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_HAPTIC);

    SDL_Window *window = SDL_CreateWindow("SDL test",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        320, 240,
        SDL_WINDOW_OPENGL);
    SDL_Renderer *renderer = SDL_CreateRenderer(
        window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);

    const int width = 50;
    const int height = 50;

    ::std::vector<SDL_Texture*> textures;

    SDL_Texture *redTexture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
    textures.push_back(redTexture);

    SDL_Texture *greenTexture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
    textures.push_back(greenTexture);

    SDL_Texture *purpleTexture = SDL_CreateTexture(renderer,
        SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
    textures.push_back(purpleTexture);

    // Here is setting the blend mode for each and every used texture:
    for(int i = 0; i < textures.size(); ++i)
    {
        SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND);
    }

    int purpleAlpha = 0;

    fillTexture(renderer, redTexture, 255, 0, 0, 255);
    fillTexture(renderer, greenTexture, 0, 255, 0, 128);
    fillTexture(renderer, purpleTexture, 255, 0, 255, purpleAlpha);

    prepareForRendering(renderer);

    bool running = true;
    while(running)
    {
        SDL_Rect rect;
        rect.w = width;
        rect.h = height;

        SDL_RenderClear(renderer);

        rect.x = 50;
        rect.y = 50;
        SDL_RenderCopy(renderer, redTexture, NULL, &rect);

        rect.x = 75;
        rect.y = 70;
        SDL_RenderCopy(renderer, greenTexture, NULL, &rect);

        rect.x = 75;
        rect.y = 30;
        SDL_RenderCopy(renderer, purpleTexture, NULL, &rect);

        SDL_RenderPresent(renderer);

        // Process events
        {
            SDL_Event event;
            while(SDL_PollEvent(&event) == 1)
            {
                if(event.type == SDL_QUIT)
                {
                    running = false;
                }
                else if(event.type == SDL_KEYDOWN)
                {
                    switch(event.key.keysym.sym)
                    {
                    case SDLK_ESCAPE:
                        running = false;
                        break;
                    case SDLK_a:
                        purpleAlpha = ::std::max(purpleAlpha - 32, 0);
                        fillTexture(renderer, purpleTexture, 255, 0, 255, purpleAlpha);
                        prepareForRendering(renderer);
                        ::std::cout <<"Alpha:" << purpleAlpha << ::std::endl;
                        break;
                    case SDLK_s:
                        purpleAlpha = ::std::min(purpleAlpha + 32, 255);
                        fillTexture(renderer, purpleTexture, 255, 0, 255, purpleAlpha);
                        prepareForRendering(renderer);
                        ::std::cout <<"Alpha:" << purpleAlpha << ::std::endl;
                        break;
                    }
                }
            }

            checkSdlError();
        }
    }

    for(int i = 0; i < textures.size(); ++i)
    {
        SDL_DestroyTexture(textures[i]);
    }
    textures.clear();

    SDL_DestroyRenderer(renderer);
    renderer = NULL;
    SDL_DestroyWindow(window);
    window = NULL;

    SDL_Quit();

    checkSdlError();

    return 0;
}

编辑:完全重写了答案,原来的一个基本上包含了渲染器的混合模式。