SDL2: Create a fully transparent texture

How to use SDL_CreateTexture to create a transparent texture? By default, I create texure with this code:

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

And then I learn this texture with redirecting the output to this texture. However, at the end, what I want to display on the screen is that any (raw) pixel is black.

I tried different ways to use:

  SDL_RenderClear(_Renderer); 

or even with a drawing and created texture with transparent Rect painting with various blending modes, but all that I had as a result was still an opaque texture: /

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

More specific:

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

This code always produces an opaque texture independence that I will set for blending and alpha

Result:

enter image description here

Maybe there is another easy way to create a transparent empty texture in SDL2, something like a fully transparent x / y png, but loading with such an image in a file is a little pointless: /

+7
c ++ sdl opengl graphic
source share
1 answer
  • First you need to set the rendering blending mode: SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); .
  • Secondly, you need to set the texture blending mode: SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND); .

Here is a working example that I created. You can use the A and S keys to change the alpha channel of the third texture, which is invisible at the beginning of the application.

 #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; } 

EDIT: the answer is completely rewritten, the original basically contains a renderer blending mode.

+11
source share

All Articles