通过 gldrawarrays 和 GL_POINTS 溺水时得到带有白色边框的点

Posted

技术标签:

【中文标题】通过 gldrawarrays 和 GL_POINTS 溺水时得到带有白色边框的点【英文标题】:Got points with white borders when drowning circle via gldrawarrays and GL_POINTS 【发布时间】:2013-08-26 10:46:26 【问题描述】:

我正在尝试使用 glDrawArrays 和 GL_POINTS 使用 OpenGL 绘制一个圆。我的圆圈绘制正确,但每个点都有一个白色边框(见截图)。

代码如下:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

Color* color = (Color*)colors;

glEnableClientState(GL_VERTEX_ARRAY);
pointSize *= this->GetScale();

glPointSize(pointSize);
glColor4f(color->r/255.0f, color->g/255.0f, color->b/255.0f, 1.0f);

glVertexPointer(2, GL_FLOAT, 0, verts);
glDrawArrays(GL_POINTS, 0, count);
glDisableClientState(GL_VERTEX_ARRAY);

我认为,混合模式有问题,但我找不到正确的模式。有什么建议吗?

【问题讨论】:

【参考方案1】:

我相信 GL_POINT_SMOOTH 旨在与饱和度混合 glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE) 一起使用,因为 alpha 被计算为精灵重叠的像素的一部分。深度缓冲区也可能会干扰渲染。

对于更精确的圆,我建议使用三角形条,甚至是单个纹理或(如果使用着色器,在片段着色器中隐式着色)四边形。

【讨论】:

正确的 glBlendFunc 和禁用的深度蒙版解决了我的问题。谢谢。【参考方案2】:

有趣的是,我实际上是 explained this yesterday(尽管使用 GL_POLYGON_SMOOTH 代替)。但是,问题是一样的。

GL_LINE_SMOOTHGL_POLYGON_SMOOTHGL_POINT_SMOOTH 都存在一个导致这些混合伪影的主要问题。当您使用这些抗锯齿技术进行绘制时,锯齿边缘会与帧缓冲区中的现有像素混合在一起。这会产生顺序相关的情况,只能通过从后到前对基元进行排序并由于过度绘制而对性能造成潜在的严重影响来解决。

当您看到这些白色像素时,真正发生的是混叠边缘正在与您的颜色缓冲区中唯一的东西混合,直到那时(清晰的颜色)。

如果你真的坚持在这种情况下使用点平滑,你应该绘制所有点两次。为获得最佳结果,您可能希望在第一遍时颠倒绘制它们的顺序,并使用glDepthMask (GL_FALSE) 禁用深度写入,然后在第二遍时重新启用深度写入。显然,从性能的角度来看这会很糟糕,但这些非全场景抗锯齿技术一开始就很不理想。

【讨论】:

正确的 glBlendFunc 和禁用的深度蒙版解决了我的问题。谢谢。

以上是关于通过 gldrawarrays 和 GL_POINTS 溺水时得到带有白色边框的点的主要内容,如果未能解决你的问题,请参考以下文章

glDrawArrays 和 glDrawElements

我应该使用几个 glDrawArrays() 还是将所有顶点收集到一个大 glDrawArrays 调用?

在 Opengl ES 中在 FBO 上调用多个 glReadPixels 和 glDrawArrays

PyOpenGL - 最小 glDrawArrays 示例

glDrawArrays 导致内存不足

glDrawArrays上的OpenGL Segfaulting