【问题标题】:Strange OpenGL pixelation behavior奇怪的 OpenGL 像素化行为
【发布时间】:2017-08-02 20:52:26
【问题描述】:

我正在使用 PyOpenGL 和 GLUT 来绘制一个在圆形中移动的正方形。绘制正方形后我不清除屏幕,因为我想要拖尾效果。出于某种原因,已经绘制的方块会在绘制新的方块时移动。

请注意,正方形笔划中多余的像素不是问题。事实上,正方形的轨迹不是静态的。

Here是一个效果例子

我正在提供我认为相关的代码。首先,我用来初始化窗口的代码:

glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(width, height)

其次,这段代码在每个方块被绘制之前被调用一次。

glLoadIdentity()
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, width, 0.0, height, 0.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

三、正方形的实际绘制

def rect_fill(x, y, w, h):
    glBegin(GL_QUADS)
    glVertex2f(x, y)
    glVertex2f(x + w, y)
    glVertex2f(x + w, y + h)
    glVertex2f(x, y + h)
    glEnd()

def rect_stroke(x, y, w, h, lw):
    lw = lw / 2
    glBegin(GL_LINES)
    glVertex2f(x - lw, y)
    glVertex2f(x + w + lw, y)

    glVertex2f(x + w, y - lw)
    glVertex2f(x + w, y + h + lw)

    glVertex2f(x + w + lw, y + h)
    glVertex2f(x - lw, y + h)

    glVertex2f(x, y + h + lw)
    glVertex2f(x, y - lw)
    glEnd()

我已经有一段时间了,还没有找到有类似问题的人。感谢您的帮助。

【问题讨论】:

  • 除非width == heightlw 对于 x 轴和 y 轴不会相同。
  • 我已经编辑了问题以澄清额外的像素不是问题。
  • 为什么投反对票?如果您投反对票,请发表评论。

标签: opengl glut pyopengl vsync


【解决方案1】:

问题在于行

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)

GLUT_DOUBLE 启用双缓冲。双缓冲提供了两个完整的颜色缓冲区用于绘图。一个缓冲区被显示,而另一个缓冲区正在被绘制。绘制完成后,交换两个缓冲区,以便正在查看的缓冲区现在用于绘制。

这就是导致两个不同方块效果之间奇怪变化的原因。

【讨论】:

  • 您能否详细说明双缓冲如何导致这些伪影?最有可能发生这些额外像素是因为在笔画渲染期间计算偏移量时没有考虑纵横比(或者您没有考虑像素中心,这是无法判断的,因为您没有显示哪些参数你打电话给rect_stroke)。
  • 所以,我的问题不在于多余的像素。事实上,绘制的正方形轨迹不是静态的。这显然是“抖动”或“抖动”,我认为这很奇怪,因为那些方块已经被绘制出来,并且没有被进一步修改。双缓冲区是原因,因为会绘制一个正方形,然后缓冲区会交换,我看不到我绘制的第一个正方形。也就是说,每个方块只能在一个缓冲区上,但不能同时在两个缓冲区上。
  • 我同意@EnricoBorba。 “抖动”效果是由于在交替缓冲区中绘制而不清除它们。这可以通过将每个已绘制的缓冲区存储在纹理中并在新正方形之前的每一帧中绘制此纹理来避免。这样可以启用双缓冲。
  • 我觉得拥有所有这些纹理会破坏效率。我看不出有加倍缓冲的理由,因为我想保留所有以前的帧。所以,我对图形不太熟悉,但是我禁用双缓冲有太多问题吗?
  • @EnricoBorba:这里有一个快速实验:在程序运行时调整窗口大小。这不是关于双缓冲与不是双缓冲,而是您假设主窗口帧缓冲区的持久性。提示:不是。 主窗口帧缓冲区可能被清除/损坏/等。在帧更新之间的任何时间。 让程序正确运行的唯一方法是绘制到纹理或屏幕外渲染缓冲区(使用帧缓冲区对象),这保证是持久的,而且在全部。
猜你喜欢
  • 1970-01-01
  • 2013-07-18
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
相关资源
最近更新 更多