2D openGL 绘制的线条不能完全适应像素栅格。

3
我正在使用OpenGL绘制类似于LED VU仪表的东西。结果应与此垂直栏相似:Animated vumeters。不幸的是,我的绘图空间受到限制,我必须恰好适合18个条形。这将导致条之间的间距为3.6像素。当绘制时,这会导致线之间的间隙存在可见差异,因为间隙宽度为2或1像素。我正在寻找一种解决方案以使用子像素渲染,然后通过某种抗锯齿方法“伪造”线条,使所有间隙呈现相同的宽度。这是到目前为止的代码:
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH, GL_NICEST);
for (int i = 0; i < 18; ++i) {
            float bBottom = barBottom + i*3.6f;
            glBegin(GL_LINES);
            glLineWidth(2);
            glVertex2f(bRight,bBottom);
            glVertex2f(bLeft,bBottom);
            glEnd();
}
glDisable(GL_LINE_SMOOTH);

很遗憾,启用线条平滑功能没有产生明显的效果。有什么建议吗?

1
将像素值四舍五入为整数。 - Matt Ball
2
GL_LINE_SMOOTH 并不被所有实现支持。我同意 @Matt Ball 的观点,你应该将线条舍入到整数像素,并在顶部绘制边界线或留下一个间隙(在这种情况下大约为10px)。 - gavinb
3个回答

4

两个想法:

  1. 将所有的条形图绘制到一个大的屏幕外纹理中,使得间隙和宽度都相等,然后使用双线性过滤将结果传送到所需的屏幕位置和大小。

  2. 让艺术家绘制所有完全照亮的条形图,以使其看起来好看,然后从每个条形图顶部向下绘制带有 alpha 通道的黑色矩形来暗化图像的所需部分。


1

使用多重采样(多重采样规格)。

此外,我会使用四边形(而不是线条)来渲染这些块。


0

如果您无法为OpenGl上下文启用抗锯齿,可以模拟它 - 对于这样简单的图形来说很容易。当您需要绘制高度为10.6像素的矩形时,请先用其颜色绘制10个像素,然后再用中间颜色(矩形颜色的0.6和背景颜色的0.4)绘制单像素线。


1
根据显示器的子像素对齐,这只能在一个方向上工作,最有可能是垂直方向。OpenGL并不适用于此类事情,即高质量矢量图形。它首先是为了将3D细分对象的三角形推送到屏幕上而设计的。 - datenwolf
从未听说过“显示器的亚像素对齐”,这是什么? - alxx
LCD屏幕上单个红/绿/蓝点的布局——它们不在同一位置。这主要用于高质量字体抗锯齿(ClearType等)。 - Kos
我不明白为什么需要关注抗锯齿的子像素点。你也无法获取那些信息。 - alxx
1
这就是次像素对齐的重要性所在:http://www.antigrain.com/research/font_rasterization/index.html#FONT_RASTERIZATION 此外,您还可以从显示器的EDID中检索其次像素对齐。 - datenwolf
1
@alxx 不要这么狭隘。这不仅仅是关于文本的问题,而是关于将几何图形放置在分数像素位置上的问题。它适用于所有形式的几何图形。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接