本文介绍了SDL2:生成完全透明的纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How using SDL_CreateTexture create transparent texture? By default I'm creating texure with such code:

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

然后我对这种纹理感到厌烦,重定向输出到这个纹理。

And then I'm paining on this texture with redirecting output to this texture. However at the end what I want to render this on screen any (nonupdated) pixel is black.

我尝试了不同的方式使用:

I have tried different ways with using of:

 SDL_RenderClear(_Renderer);

甚至与绘图和创建纹理与绘画透明矩形不同的混合模式,但我有结果仍然是不透明的纹理:/

or even with drawing and on created texture with painting transparent Rect with different blending modes but all I had as a result was still nontransparent 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);

更具体的:

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

这段代码总是产生不透明的Texture独立的,我将为混合和alpha

This code is always producing nontransparent Texture independenty what i will set for blending and alpha

结果是:

也许还有一些其他简单的方法来创建透明的空纹理在SDL2像x / y尺寸完全透明的png,但加载有这样的图像在文件是有点无意义:/

Maybe there is some other simple method to create transparent empty texture in SDL2 something like x/y-sized fully transparent png but loading having such image in file is little bit pointless :/

推荐答案


  • 首先,需要设置渲染器混合模式: SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

  • 其次,您需要设置纹理混合模式: SDL_SetTextureBlendMode(textures [i],SDL_BLENDMODE_BLEND);

    • First, you need to set renderer blend mode: SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);.
    • Second, you need to set texture blend mode: SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND);.
    • 这是我创建的工作示例。您可以使用键A和S来更改第三个纹理的Alpha通道,在应用程序开始时是不可见的。

      Here is working example I created. You can use keys A and S to change alpha channel of third texture, which is invisible at start 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;
      }
      

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

      Completely rewritten the answer, original one basically contained blend mode of renderer.

      这篇关于SDL2:生成完全透明的纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 22:00