前几天公司扔给我一个刚跳走的“大牛”的代码,看的实在让我捉急。逻辑非常混乱,代码模块化做的不到位,让人怀疑是否知道什么是面向对象。(应该是所有程序员看别人代码都这样的通病吧,自己的修为尚浅,也许别人看我的也是一头包,哈哈)
正题:
//——————————————————————————————————————————
在使用openGL中的fbo时,很容易遇到“二次混合”的问题。二次混合从本质上来讲是混合顺序错误。
如下图:
这是一个很让人纠结的问题。仅通过调节混合方式是不能真正地解决的。只有适当的取近似结果、事先策划混合顺序,避免出现很严重的问题。
分享我遇到过的一些问题,以及解决方案:
首先是如果不采取任何措施,采用默认混合方式,会出现字体模糊的问题。
这种现象是在图片有像素透明度不为1或0时会出现,因为多次混合的缘故导致最终颜色出现偏差。
解决办法是在绘制FBO时,关闭混合,绘制内容结束后再恢复默认混合。
ofDisableAlphaBlending(); // 关闭混合
bookContent.draw(rtContent);
ofEnableAlphaBlending(); // 打开混合
效果:
但是,
假如在FBO里面出现了多张图片叠加的情况,这种方法就不适用了。
问题如下:
这种时候,
解决办法有两个,一是图片素材不要有(0, 1 )的透明度像素,适用正常混合进行混合,二是采用近似混合方式:
神代码:
// mainFbo.begin(); ofClear(0); glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); text1.draw(x,y); glDisable (GL_BLEND); mainFbo.end(); /* ... ... */ // 绘制FBO glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); mainFbo.draw(x, y); glDisable(GL_BLEND); ofEnableAlphaBlending();
这样的混合方式算是比较折中的方式了,一般来说不会出现问题,(比如三层嵌套就会出问题,而且FBO内部的底色会失真)
FBO套FBO,层层套下来。但是这样效率会很低很低,而且修改混合状态会影响全局混合方式,如果有一处遗忘了恢复状态,会影响其他内容的绘制。尤其是接手别人的项目的时候,如果他们的项目框架设计的不合理,很容易出现各种诡异的问题。。。。。。。。。内心已经在画诅咒圈圈...
总体来说,效果还是不错的。但是如果要做的完美,还是建议做好规划,避免出现这种棘手的情况。