4

是否可以设置一个 OpenGL 场景以实现像素完美的渲染和像素块传输?我注意到通过以下方式设置场景:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, width, height, 0.0, 0.0, 1.0);

然后使用以下方法绘制一个像素:

glBegin(GL_POINTS);
glVertex2i(0, 0);
glEnd();

并非始终将其绘制在每个硬件配置的左上角像素上(有时它位于左侧一个像素,或左上角下方一个像素)。我意识到这可能是由于图形驱动程序对 OpenGL 的不同实现,但是有没有办法让它左上角的像素是(0,0),右下角是(width-1,height-1 ) 始终如一?这似乎很奇怪,这不是标准化的东西......

我见过一些使用 (0.375, 0.375) 或 (0.5, 0.5) 的翻译的“黑客”,但这似乎也解决了某些配置而不是其他配置。

4

2 回答 2

7

编辑:当当,这是翻译。更新。

您还必须考虑像素也有大小。这就是“翻译黑客”的目的。如果最左边的像素应该有一个中心坐标0.0,那么它的左边界就在-0.5- ,这就是剪裁平面应该在的位置。类似地,如果最右边的像素应该有一个中心坐标width - 1,那么它的右边界在(width - 1) + 0.5- 并且那是该剪切平面应该在的位置。

所以试试:

glOrtho(-0.5, (width - 1) + 0.5, (height - 1) + 0.5, -0.5, 0.0, 1.0);

所以这就是翻译的来源。

于 2013-01-30T21:33:11.570 回答
1

在第一次检查时,它似乎应该可以工作,并且如果实现偏移了一个像素,我怀疑它们可能不符合规范。然而,这也可能是由于视图被颠倒了,并且一些不准确性逐渐出现并导致舍入问题。我不相信是这样,但如果我想做像素完美的渲染,我不会从引入不必要的变换开始。

无论如何,我很可能会完全避免使用固定功能管道,只需确保使用我自己的变换计算顶点着色器中的正确坐标。所以这是我的第一个建议——现代可编程管道让您可以更好地控制正在发生的事情。

如果做不到这一点,至少尝试以正确的方式渲染事物,看看这是否会使您所针对的各种平台更加一致。

或者,我认为这有点骇人听闻,但有时这些东西是必要的 - 你可以检查它,并使用变换相应地偏移你的坐标(即绘制一个像素并将其读回以查看它是否以正确的方式结束地方,如果没有,它去了哪里)。当然,您可能只是在加剧问题。

我不会在这里过多地摆弄子像素偏移,您更有可能只是介绍更多像素不再按您想要的 1:1 映射的情况。

于 2013-01-30T16:56:19.300 回答