Учитывая одноканальное растровое изображение (альфа от 0 до 255), представленное unsigned char[], каковы способы создания из него SDL_Texture? Растровое изображение не содержит дополнительных данных.

Ответ

auto* surf = SDL_CreateRGBSurfaceFrom(bitmap, width, height, 8, width, 0, 0, 0, 0);
SDL_Color colors[256];
{
    Uint8 v = 0;
    for(SDL_Color& color: colors) {
        color.r = color.g = color.b = 0xFF;
        color.a = v++;
    }
}
SDL_SetPaletteColors(surf->format->palette, colors, 0, 256);
auto* texture = SDL_CreateTextureFromSurface(sdl.renderer, surf);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);

Исходный вопрос

Насколько я понимаю, это делается путем первого вызова SDL_CreateRGBSurfaceFrom(bitmap, width, height, depth, pitch, r, g, b, amasks).

1) Один (грязный) способ, который я пробовал, создавал копию исходного растрового изображения, представленного unsigned[], где каждое целое число по умолчанию было 0xFFFFFF00, а затем вызов:
SDL_CreateRGBSurfaceFrom(bitmap, width, height, 32, 4 * width, 0xff000000, 0xff0000, 0xff00, 0xff) сделал это за меня. (непрозрачный - белый и снова становится прозрачным, потому что использовался 0xFF).

Но мне нужен был другой способ, потому что для этого требовалось дополнительное выделение памяти и странный цикл for.

auto pixelsNum = width * height;
auto bitmap = new unsigned[pixelsNum];
for(auto i = 0; i < pixelsNum; ++i) {
    bitmap[i] = tmpBitmap[i] | 0xffffff00;
}


2) Второй способ, который я пробовал, заключался в использовании глубины = 8, и поэтому мне не нужно было выделять какое-либо новое растровое изображение, а вместо этого (нужен?) SDL_Pallete.

auto surf = SDL_CreateRGBSurfaceFrom(bitmap, width, height, 8, width, 0, 0, 0, 0xff);
SDL_Color colors[256];
for(int i = 0; i < 256; ++i) {
    colors[i].r = colors[i].g = colors[i].b = 0xff;
    colors[i].a = i;
}
SDL_SetPaletteColors(surf->format->palette, colors, 0, 256);

Это намного дешевле в памяти и постоянно.

Так что мне интересно, есть ли лучший способ
Спасибо.

2
iwat0qs 8 Июл 2016 в 21:25
C ++ - это не C, это не C ++!
 – 
too honest for this site
8 Июл 2016 в 21:42
1
Я знаю, что это не так. Но SDL - это C, и если бы кто-нибудь дал мне решение исключительно на C, это сработало бы для меня.
 – 
iwat0qs
8 Июл 2016 в 21:53
Я только что проверил правку и увидел, что вы изначально пометили его both . Мне это кажется нормальным, поскольку этот вопрос технически касается SDL, а не C ++. Не обращайте внимания на мой предыдущий комментарий.
 – 
Dan Bechard
8 Июл 2016 в 22:39

1 ответ

Лучший ответ

SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0xff); достаточно, чтобы была только альфа. Однако при преобразовании в текстуру средство визуализации будет пытаться выбрать ближайший формат, поддерживаемый оборудованием для графической обработки, и какое-то время аппаратная поддержка палитры отсутствовала. Результирующая текстура, скорее всего, будет иметь формат SDL_PIXELFORMAT_ARGB8888 независимо от вашего подхода. Я не вижу поддержки в SDL для 1-канальных текстур, но это все еще возможно при прямом использовании текстур opengl (например, SDL_GL_BindTexture). Конечно, это заставит вас придерживаться одной конкретной реализации SDL_Renderer.

1
keltar 9 Июл 2016 в 09:37
Я просмотрел значения формата пикселей, и доступны только index8 (пользовательская палитра) и RGB332. Я пойду с поддоном :)
 – 
iwat0qs
9 Июл 2016 в 15:40