Въпрос относно Renderer::drawImage()
В предложеното решение, ако има opacity < 255 извикваме SDL_SetTextureAlphaMod преди (сетваме новото opacity) и след (връщаме на 255) извикването на SDL_RenderCopyEx .
Ако съм разбрал правилно, идеята е че промяната на alpha е "скъпа" операция и искаме да го правим само тогава, когато е необходимо.
Днес разгледах кода на SDL и не успях да открия потвърждение на горното.
SDL_Texture e flyweight object, не много по-различeн от нашите DrawParams, а промяната на alpha на практика е просто сетване на един Uint8 от тази структура през SDL_SetTextureAlphaMod:
texture->a = alpha;
По-нататък alpha стойността не се използва извън SDL_Texture и се подава заедно с всички останали параметри надолу към "желязото", което предполага, че при "рисуването" винаги се използва текущата ѝ стойност.
Ако горното е вярно, не виждам причина, поради която да не се опрости рисуването до следните две безусловни операции:
1. Сетване на alpha с SDL_SetTextureAlphaMod винаги, без значение каква е новата и старата ѝ стойност
2. Рисуване с SDL_RenderCopyEx
Opacity-то би трябвало винаги да е правилното, тъй като всяка картинка си имa свои DrawParams.
void Renderer::drawImage(SDL_Texture* const texture, const DrawParams& drawParams) const {
if (EXIT_SUCCESS != texture::setAlphaTexture(texture, drawParams.opacity)) { //change opacity
// "Texture::setAlphaTexture() failed for rsrcId: ", drawParams.rsrcId
}
draw(texture, drawParams);
}
Какво изпускам?
Благодаря за отговора!
Прегледах отново кода на SDL в контекста на коментарите ти.
native e пойнтър към SDL_Texture, създаден заедно с основната текстура от SDL_CreateTexture и - доколкото разбирам, определя вътрешната структура на данните (Pixel Format). Рекурсивното извикване на SDL_SetTextureAlphaMod само ъпдейтва alphat-a ѝ, без да прави модификации по данните или да извиква други методи.
CHECK_TEXTURE_MAGIC е "прост" валидиращ макрос:
В проекта модифицирането на opacity става през Widget::setOpacity където има проверка за blending mode-a и предложената промяна не се отразява на това. Ако модифицираме индиректно DrawingParams#opacity на Widget-a, извикването на SDL_RenderCopyEx просто ще върне грешка, която ние логваме.
Това е безспорно така.
Смяната на аlpha изглежда "евтина" операция според кода на SDL_SetTextureAlphaMod, но остава овърхеда от извикването ѝ.
Разликата е дали искаме да контролираме това от нашия код (никакво или с двойно извикване на setAlpha) или винаги да викаме setAlpha и да оставим валидациите и оптимизациите на SDL библиотеката.
Прав си, да.
Ако мога да върна времето назад, когато преподавах лекцията - най-вероятно щях да избера твоя подход.
Причината е, че дори и с няколко микрона по-бавен - той е по-интуитивен и най-вече е beginner friendly.
При по-малко количество информация - аудиторията има по-голям шанс да го разбере.
Нищо де. От положителна страна накарах курсистите да се замислят, че flyweight + shared source (image) не е само "цветя и рози" :)
Поздрави
Като за финал по темата ще вметна, че на разположение имаме и този метод: SDL_GetTextureAlphaMod - code, с който можем да проверим текущата стойност на alpha mod-a на текстурата и да го сравним със стойността от DrawParams. Честно казано, очаквах в SDL_SetTextureAlphaMod да има подобна проверка, но явно авторите са преценили, че ъпдейта на alpha-та е достатъчно лек, за да се налага подобна оптимизация.