Пиксельный формат текстуры SDL2 и цветовая маска поверхности

Я пытаюсь создать SDL_Surface для манипулирования пикселями, однако что-то идет не так при установке цветовых масок поверхности, поскольку цвета неверны при заполнении цветового буфера (см. комментарии, я пытаюсь интерпретировать u8vec4 как цвет RGBA):

const int win_width = 640;
const int win_height = 480;
std::vector<glm::u8vec4> colors{ win_width * win_height, glm::u8vec4{ 0, 0, 0, 0 } };

SDL_Surface* render_surface = SDL_CreateRGBSurfaceFrom(&colors[0], win_width, win_height, 32,
    sizeof(glm::u8vec4) * win_width, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);

SDL_Texture* render_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, 
    SDL_TEXTUREACCESS_STREAMING, win_width, win_height);

// { 255, 0, 0, 255 } = Red
// { 255, 0, 0, 100 } = Darker red, alpha seems to be working
// { 0, 255, 0, 255 } = Purple!? Should be green?
// { 0, 0, 255, 255 } = Yellow, expecting blue
std::fill(colors.begin(), colors.end(), glm::u8vec4{ 0, 0, 0, 255 }); // Red
SDL_UpdateTexture(render_texture, nullptr, render_surface->pixels, render_surface->pitch);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, render_texture, nullptr, nullptr);
SDL_RenderPresent(renderer);

person SiimKallas    schedule 30.05.2014    source источник
comment
Читая значения цветов справа налево (ABGR), я могу представить, что они приводят к цветам, которые вы описываете.   -  person Jongware    schedule 30.05.2014


Ответы (1)


Вы должны попробовать установить битмакс в соответствии с порядком байтов. Вот как я это делаю:

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    const uint32_t R_MASK = 0xff000000;
    const uint32_t G_MASK = 0x00ff0000;
    const uint32_t B_MASK = 0x0000ff00;
    const uint32_t A_MASK = 0x000000ff;
#else
    const uint32_t R_MASK = 0x000000ff;
    const uint32_t G_MASK = 0x0000ff00;
    const uint32_t B_MASK = 0x00ff0000;
    const uint32_t A_MASK = 0xff000000;
#endif

В вашем случае вы получили цветовые маски наоборот.


Я думаю, что Jongware прав, что формат ABGR.

// { 255, 0, 0, 100 } = Darker red, alpha seems to be working

Я предполагаю, что здесь альфа кажется правильной, потому что фон черный, и, уменьшив количество красного до 100, он будет естественным образом сливаться с фоном.

Я также думаю, что вы не установили SDL_BlendMode

person olevegard    schedule 31.05.2014
comment
Используя SDL_PIXELFORMAT_ABGR8888, эти маски (с прямым порядком байтов) и SDL_SetTextureBlendMode(..., SDL_BLENDMODE_BLEND) заставили его работать. - person SiimKallas; 31.05.2014