如何使用OpenGL避免透明度重叠?

时间:2013-01-04 09:48:09

标签: ios opengl-es transparency alpha overlap

我正在开发iOS上的手写应用程序。我从iOS文档中找到了由OpenGL ES实现的示例项目“GLPaint”,并对其进行了一些修改。

我跟踪触摸点并计算点之间的曲线,并单独绘制曲线图像,使其看起来像手指经过的位置。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData); // burshData is from CGImage, it is 

// vertexBuffer is generated based on the calculated points, it's just a sequence of point where need to draw image.
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer); 
glDrawArrays(GL_POINTS, 0, vertexCount);

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

我得到的是一条看起来相当不错的实线。但现在我想绘制半透明高光而不是实线。因此,我使用50%透明度替换粒子图像而不更改代码。

Result of 50% transparency particle image

Result of 50% transparency particle image

混合有问题。

What I need

What I need

我使用半透明度粒子图像绘制三个点,交叉区域应保持50%的透明度。

解决方案是什么?

3 个答案:

答案 0 :(得分:6)

我可能两年后回答了这个问题,但我希望它能帮助那些来这里寻找解决方案的人,就像发生在我身上一样。

您需要为每个cirle分配不同的z值。这种差异有多大或多小并不重要,我们只需要他们不要严格相等。

首先,禁用在颜色缓冲区glColorMask(false,false,false,false)中写入,然后正常绘制圆圈。 Z缓冲区将根据需要进行更新,但不会绘制圆圈。

然后,在颜色缓冲区(glColorMask(true,true,true,true))中启用写入并将depthFunc设置为LEQUAL(glDepthFunc(GL_LEQUAL))。只有最近的圆形像素才会通过深度测试(将其设置为LEQUAL而不是EQUAL会处理一些罕见但可能的浮点近似误差)。启用混合并再次绘制它们将生成所需的图像,没有透明度重叠。

答案 1 :(得分:0)

您必须更改混合功能。你可以玩:

glBlendFunc(GL_SRC_ALPHA,GL_ONE);

也许是(GL_ONE, GL_ONE),忘记了如何处理你的案子,但解决方案就在那个功能中。

http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml

答案 2 :(得分:0)

最新答复,但希望对其他人有用。

避免这种效果的另一种方法是在绘制透明圆之前(例如,执行GrabPass)获取颜色缓冲区,然后手动读取并与圆片段着色器中的不透明缓冲区混合。