SDL2: создание полностью прозрачной текстуры

Как с помощью SDL_CreateTexture создать прозрачную текстуру? По умолчанию я создаю texure с таким кодом:

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

А потом я рисую эту текстуру, перенаправляя вывод на эту текстуру. Однако в конце я хочу отобразить на экране любой (не обновленный) пиксель черного цвета.

Я пробовал разные способы с использованием:

 SDL_RenderClear(_Renderer);

или даже с рисованием и созданной текстурой с рисованием прозрачного Rect с различными режимами наложения, но все, что у меня было в результате, было все еще непрозрачной текстурой: /

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

Этот код всегда создает непрозрачную текстуру независимо от того, что я установлю для смешивания и альфа

Результат:

введите описание изображения здесь

Может быть, есть какой-то другой простой способ создать прозрачную пустую текстуру в SDL2, что-то вроде полностью прозрачного png размера x / y, но загрузка с таким изображением в файле немного бессмысленна: /

8

Решение

  • Во-первых, вам нужно установить режим смешивания рендерера: SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);,
  • Во-вторых, вам нужно установить режим наложения текстур: SDL_SetTextureBlendMode(textures[i], SDL_BLENDMODE_BLEND);,

Вот рабочий пример, который я создал. Вы можете использовать клавиши A и S, чтобы изменить альфа-канал третьей текстуры, которая невидима при запуске приложения.

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

РЕДАКТИРОВАТЬ: полностью переписать ответ, оригинальный в основном содержал смешанный режим рендерера.

12

Другие решения


По вопросам рекламы [email protected]