首页 > 解决方案 > 如何在 pygame 和 pyopengl 中独立旋转 2 个对象

问题描述

我正在尝试独立旋转 2 个对象,但是当我运行代码时,两个对象都以相同的方向旋转,请在此处输入代码

在这里我保存矩阵并在立方体下旋转一个正方形

def rotate_square():
    glColor3f(1,1,1)
    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    glRotatef(45,0,1,0)
    glBegin(GL_LINES)
    glVertex3fv(v1);
    glVertex3fv(v2);
    glVertex3fv(v1);
    glVertex3fv(v3);
    glVertex3fv(v3);
    glVertex3fv(v4);
    glVertex3fv(v2);
    glVertex3fv(v4);
    glEnd()
    glPopMatrix()

主功能

def main():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, DOUBLEBUF|OPENGL)
    resize(*SCREEN_SIZE)
    print(glGetString(GL_VERSION))
    gluLookAt(0, 0, -6, 0, 0, 0, 0, 1, 0)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

旋转立方体

        glRotatef(1,0,1,0)
        glutWireCube(2)
        rotate_square()
        pygame.display.flip()
        pygame.time.wait(10)

标签: pythonopenglpygamecoordinate-transformationpyopengl

解决方案


请注意,按glBegin/glEnd序列绘制,固定函数管道矩阵堆栈和每个顶点光模型的固定函数管道,几十年来已被弃用。阅读Fixed Function Pipeline并查看Vertex Specification and Shader了解最先进的渲染方式。

无论如何,通常物体由模型矩阵变换,然后场景由视图矩阵和投影矩阵变换。
可悲的是,在已弃用的 OpenGL 固定功能管道中,模型矩阵和视图矩阵是连接在一起的,不能那么容易地单独处理。

您必须通过其自己的模型矩阵转换每个对象以独立旋转它们。创建 4*4 矩阵并通过单位矩阵对其进行初始化:

model1 = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
model2 = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]

要操作模型矩阵,请将它们加载到矩阵堆栈中glLoadMatrix。然后操作它们,最后通过以下方式读取结果glGetFloatv(GL_MODELVIEW_MATRIX)

glPushMatrix()
glLoadMatrixf(model1)
glRotatef(1,0,1,0)
model1 = glGetFloatv(GL_MODELVIEW_MATRIX)
glPopMatrix()

如果必须应用模型矩阵,则可以将其乘以矩阵堆栈glMultMatrix

glPushMatrix()
glMultMatrixf(model1)
glutWireCube(2)
glPopMatrix()

最终代码可能如下所示:

model1 = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
model2 = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
def rotate_square():
    global model2

    glPushMatrix()
    glLoadMatrixf(model2)
    glRotatef(5,0,1,0)
    model2 = glGetFloatv(GL_MODELVIEW_MATRIX)
    glPopMatrix()

    glColor3f(1,1,1)

    glMatrixMode(GL_MODELVIEW)
    glPushMatrix()
    glMultMatrixf(model2)
    glBegin(GL_LINES)
    glVertex3fv(v1)
    glVertex3fv(v2)
    glVertex3fv(v1)
    glVertex3fv(v3)
    glVertex3fv(v3)
    glVertex3fv(v4)
    glVertex3fv(v2)
    glVertex3fv(v4)
    glEnd()
    glPopMatrix()
def main():
    global model1

    # [...]

    while True:

        # [...]

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()
        glLoadMatrixf(model1)
        glRotatef(1,0,1,0)
        model1 = glGetFloatv(GL_MODELVIEW_MATRIX)
        glPopMatrix()

        glPushMatrix()
        glMultMatrixf(model1)
        glutWireCube(2)
        glPopMatrix()

        rotate_square()

        pygame.display.flip()
        pygame.time.wait(10)

推荐阅读