Здравствуйте.
Случилось как-то мне родить некое поделие: $subj (берёшь мышь или планшет типа wacom, рисуешь по-кадрово и получается в итоге анимация). Вроде как работает, делает что нужно и т.д.. Написано на Си с использованием X-ов (если компилировать под *nix) + OpenGL.
В программе реализованы слои и некий аналог «Symbol» из Adobe Flash. Как происходит отображение слоёв и этого аналога «Symbol» (все текстуры и картинки в RGBA формате):
1. Созданный фрэймбуффер, полученный из glGenFramebuffersEXT, очищаю в цвет (0.0, 0.0, 0.0, 0.0). К этому фрэймбуфферу цепляю текстуру.
2. GL_BLEND включён, glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
3. Иду по всем слоям, начиная с нижнего слоя, и загружаю картинку из данного слоя в текстуру и отрисовываю квадрат с этой текстурой.
4. После завершения всех слоёв, выставляю glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) и отрисовываю фон цветом (0.7, 0.7, 0.7, 1.0), «белый лист бумаги» - квадрат цветом (1.0, 1.0, 1.0, 1.0), и прикреплённую к тому фрэймбуфферу текстуру.
Для аналога «Symbol» сначала выполняются такие же шаги (внутри него тоже есть слои), но кладутся они (в кратце) в отдельную текстуру. Потом, когда дело в отрисовке всей сцены доходит до слоя, где находится этот «Symbol», просто отрисовывается его текстура.
Всё бы ничего, но такой алгоритм отрисовки не подходит. Ибо если на картинку с альфой 1.0 ложится картинка с альфой < 1.0, то получается итоговая текстура с альфой < 1.0 и на шаге 4 видно сквозь картинку задний фон. А если отрисовывать ещё и «Symbol», то получается двойной alpha-blending и картинка из «Symbol» получается темнее, чем должна быть на самом деле.
Вот и встаёт вопрос, как же сделать правильную отрисовку? Есть идеи? Например, gimp даёт правильные результаты, но в суть его отрисовки я ещё не вникал, потому что он-то не маленький и боюсь закопаться в нём с головой.