Перекрашивание текстур SDL2

Итак, у меня есть изображение спрайта и маска спрайта:

спрайт изображение
маска спрайт

(маска на самом деле представляет собой палитровое изображение, где каждое значение представляет собой отдельную область перекрашивания, 0 — синий, который не перекрашивается)

Эти области будут перекрашены в любой произвольный цвет.

Каков наилучший способ реализовать это, предполагая, что изображение спрайта кэшируется / предварительно загружается как SDL_Texture? Мне дали несколько подсказок, например, рендеринг в текстуру, альфа-смешение, но ни один из них не соответствует всем «требованиям»

2

Решение

Я могу думать двумя способами, чтобы достичь этого:

Вы можете отделить каждую область перекрашивания от маски в нескольких текстурах, таким образом, каждая текстура маски будет иметь только два цвета: один будет прозрачным (альфа = 0), а другой — белым (255,255,255,255). Затем каждый раз, когда вам нужно перекрасить, вы устанавливаете цветовой мод для каждой маски на нужные и комбинируете с исходной текстурой, например так:

SDL_SetRenderTarget(r, destiny);
SDL_SetBlendMod(r, SDL_BLENDMODE_NONE);
SDL_RenderCopy(r, source, destiny);
SDL_SetBlendMod(r, SDL_BLENDMODE_BLEND);
for(/* Each mask as m*/){ */
SDL_SetColorMod(m, c[i].r, c[i].g, c[i].b);
SDL_RenderCopy(r, source, destiny);
}

Другой способ состоит в том, чтобы сделать эту комбинацию вручную, чтобы избежать предыдущего разделения, сопоставляя каждую цветовую область с конечным цветом в некотором массиве или хэш-карте и проходя через пиксель маски и изображения и перекрашивая, если вам нужно. Этот способ проще реализовать, если вы используете поверхности, а затем конвертируете в текстуру, но вы можете сделать оба пути, поэтому я объясню это в псевдокоде:

s: source;
d: destiny;
m: mask;
c: [0x00ff00: 0xff000000, 0x0000ff: 0xdeadbeef];
for(i=0; i< s.pixels.size(); ++i){
if(c.count(m.pixels[i])){
destiny = (c[m.pixels[i]]+s.pixels[i])/2;
} else {
destiny = s.pixels[i];
}
}

В обоих примерах я использовал общую функцию смешивания для объединения, но вы можете попробовать другие, я думаю, что add также может быть хорошей альтернативой.

2

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