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设置
结果是:
也许还有其他一些简单的方法可以在SDL2中创建透明的空纹理,例如x / y大小的完全透明的png,但是在文件中加载具有此类图像的文件是毫无意义的:/
-
首先,您需要设置渲染器混合模式:
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; } |
编辑:完全重写了答案,原来的一个基本上包含了渲染器的混合模式。