C++ SDL2:生成完全透明的纹理
如何使用SDL_CreateTexture创建透明纹理?默认情况下,我使用以下代码创建texure:C++ SDL2:生成完全透明的纹理,c++,opengl,sdl,graphic,C++,Opengl,Sdl,Graphic,如何使用SDL_CreateTexture创建透明纹理?默认情况下,我使用以下代码创建texure: SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET, x, y); 然后我在这个纹理上画画,将输出重定向到这个纹理。然而,在最后,我想在屏幕上呈现的任何(未更新的)像素都是黑色的 我尝试了不同的方法来使用: SDL_RenderClear(_Renderer); 甚至在绘制和创建纹理时,
SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET, x, y);
然后我在这个纹理上画画,将输出重定向到这个纹理。然而,在最后,我想在屏幕上呈现的任何(未更新的)像素都是黑色的
我尝试了不同的方法来使用:
SDL_RenderClear(_Renderer);
甚至在绘制和创建纹理时,使用不同的混合模式绘制透明矩形,但结果仍然是不透明纹理:/
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);
这段代码总是独立于我将为混合和alpha设置的内容生成非透明纹理
结果是:
也许还有其他一些简单的方法可以在SDL2中创建透明的空纹理,比如x/y大小的完全透明的png,但是在文件中加载这样的图像有点毫无意义://- 首先,需要设置渲染器混合模式:
SDL_SetRenderDrawBlendMode(渲染器,SDL_BLENDMODE_混合)代码>
- 其次,需要设置纹理混合模式:
SDL\u SetTextureBlendMode(纹理[i],SDL\u BLENDMODE\u blend)代码>
#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;
}
#包括
#包括
#包括
void fillTexture(SDL_渲染器*渲染器,SDL_纹理*纹理,int r,int g,int b,int a)
{
SDL_SetRenderTarget(渲染器、纹理);
SDL_SetRenderDrawBlendMode(渲染器,SDL_BLENDMODE_无);
SDL_SetRenderDrawColor(渲染器,r、g、b、a);
SDL_RenderFillRect(渲染器,空);
}
无效准备渲染(SDL_渲染器*渲染器)
{
SDL_SetRenderTarget(渲染器,NULL);
SDL_SetRenderDrawBlendMode(渲染器,SDL_BLENDMODE_混合);
SDL_SetRenderDrawColor(渲染器,128、128、128、255);
}
无效检查错误()
{
const char*sdlError=SDL_GetError();
if(sdlError&&*sdlError)
{
::std::cout Nope:/color和alpha混合,并且混合始终会导致颜色(取决于使用的值)不透明texture@LemonekSDL\u BLENDMODE\u NONE
会发生什么变化?最好是原始(SDL\u BLENDMODE\u BLEND
)和更新版本的屏幕截图。(很遗憾,我目前无法尝试SDL…)@Lemonek我终于没有时间研究这个问题了,我发现你不仅需要为渲染器设置混合模式,还需要为纹理设置混合模式。我相应地更改了这个答案并添加了工作示例。很好-它开始工作了-我不知道我需要另外设置混合模式纹理,独立于渲染器混合模式。这s正在为使用标志SDL_TEXTUREACCESS_TARGET创建的所有纹理工作,是否有一些简单的方法可以在该标志和SDL_TEXTUREACCESS_流之间切换???能够渲染到纹理,然后使用SDL_TextureLock访问该纹理?顺便说一句-感谢您的支持support@Lemonek嘿,我也不知道,直到我写了那段代码,它一点用都没有d我在文档中注意到了-…关于切换访问标志-首先,我想再次指出,我对SDL2的经验是零,目前你可以添加上面的程序。无论如何,从文档和谷歌,我认为这是不可能的。但是,有多种方法可以实现你想要的;你可以使用SDL_Surface和SDL_SetAlpha()表示透明(或半透明)。[链接](www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsetalpha.html)这与OpenGL有什么关系?它可能是在OpenGL之上分层的,但这里没有任何与OpenGL相关的东西可以回答:-\