在 OpenGL 中围绕坐标旋转四边形

Rotating a quad around a coordinate in OpenGL

我目前正在使用 Python 和 OpenGL 编写主要飞行显示器。 由于我对 OpenGL 的经验为零 (并且一般的编码经验很少) 我确实在最简单的功能实现方面遇到了困难,但直到现在我才做到这一点:

我现在的问题是根据滚动数据围绕视口中心点(400x240)旋转人工horizon。 我的视口是 800x480,四边形代表人造 horizon,大小为 1000x2880.

显示音高数据很容易,因为 1 度等于 viewport/horizon 纹理上的 8 个像素。

Numbers.p_offset = -Data.pitch*8,我可以将其添加到四边形的所有四个 y-coordinates。

def horizon():

    glBindTexture(GL_TEXTURE_2D, horizontexture)

    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_TEXTURE_2D)
    glColor4f(1, 1, 1, 1)

    glBegin(GL_QUADS)
    glTexCoord2f(0, 1); glVertex2f(-100, -1200+Numbers.p_offset)
    glTexCoord2f(1, 1); glVertex2f(900, -1200+Numbers.p_offset)
    glTexCoord2f(1, 0); glVertex2f(900, 1680+Numbers.p_offset)
    glTexCoord2f(0, 0); glVertex2f(-100, 1680+Numbers.p_offset)
    glEnd()

    glDisable(GL_TEXTURE_2D)

不容易的是显示滚动数据 (-180° 到 180°),因为滚动的变化会改变 x- y-coordinate 的四边形。首先,需要应用俯仰偏移 (以保持四边形的垂直 center-line 在视口的中心) 然后旋转对应于滚动。我无法弄清楚如何计算偏移滚动会导致的数学问题,所以我正在寻找一种解决方案,了解如何使用我还不知道的一些 OpenGL 功能来实现它。

我发现的所有教程和 questions/answers 都专门询问如何围绕其自身的中心点而不是另一个坐标旋转四边形。


问题:如何在 OpenGL 和 Python 中的正交投影中围绕特定坐标旋转四边形?

首先你必须定义枢轴:

pivot_x = (900 + (-100)) / 2
pivot_y = (-1200 + 1680) / 2

如果你想围绕一个枢轴旋转一个对象,那么你必须:

  • 以这种方式平移对象,即枢轴在原点 (0, 0, 0) 上:glTranslatef(-pivot_x, -pivot_y, 0)

  • 在视图的xy平面中旋转对象:glRotate(angle, 0, 0, 1)

  • 以枢轴回到其原始位置的方式平移矩形:glTranslatef(pivot_x, pivot_y, 0)

由于像glTranslated and glRotated这样的操作定义了一个新矩阵并将其与当前矩阵相乘,因此必须以相反的顺序执行此指令。
使用glPushMatrix / glPopMatrix保存和恢复操作前后的当前矩阵。例如:

def horizon():

    pivot_x = (900 + (-100)) / 2
    pivot_y = (-1200 + 1680) / 2
    glPushMatrix()

    # rotate around pivot (roll)
    glTranslatef(pivot_x, pivot_y, 0)
    glRotatef(angle, 0, 0, 1)
    glTranslatef(-pivot_x, -pivot_y, 0)

    # apply pitch
    glTranslatef(0, Numbers.p_offset, 0)

    glBindTexture(GL_TEXTURE_2D, horizontexture)

    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_TEXTURE_2D)
    glColor4f(1, 1, 1, 1)

    glBegin(GL_QUADS)
    glTexCoord2f(0, 1); glVertex2f(-100, -1200)
    glTexCoord2f(1, 1); glVertex2f(900, -1200)
    glTexCoord2f(1, 0); glVertex2f(900, 1680)
    glTexCoord2f(0, 0); glVertex2f(-100, 1680)
    glEnd()

    glDisable(GL_TEXTURE_2D)

    glPopMatrix()

(另见 and