Объект сбрасывается при двух поворотах - PullRequest
0 голосов
/ 07 августа 2020
• 1000 *
glPushMatrix()
if self.selected_angle == 0:
    glRotatef(angle[0], 1, 0, 0)
elif self.selected_angle == 1:
    glRotatef(angle[1], 0, 1, 0)
elif self.selected_angle == 2:
    glRotatef(angle[2], 0, 0, 1)
model.render()
glPopMatrix()
if keys[K_o]:
    selected_angle = 0
    angle[0] += 1
if keys[K_i]:
    selected_angle = 0
    angle[0] -= 1
if keys[K_k]:
    selected_angle = 1
    angle[1] += 1
if keys[K_j]:
    selected_angle = 1
    angle[1] -= 1
if keys[K_m]:
    selected_angle = 2
    angle[2] += 1
if keys[K_n]:
    selected_angle = 2
    angle[2] -= 1

1 Ответ

0 голосов
/ 09 августа 2020

Короткий ответ: удалите вызовы glPushMatrix и glPopMatrix. PopMatrix отменяет изменения, внесенные вами после PushMatrix.

Вы предоставили только небольшую часть своего кода, поэтому я создал пример, включающий ваш код. Если удалить вызовы Push \ PopMatrix, код работает правильно. При включенных вызовах Push \ Pop куб возвращается в исходное положение после остановки вращения.

Также - я заметил, что ключевые события в вашем коде увеличивают угол на каждом l oop, поэтому вращение фактически ускоряется при удерживании клавиши. Я не знаю, было ли это намеренно, но я оставил это.

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *

verticies = (
(1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),
(1, -1, 1),(1, 1, 1),(-1, -1, 1),(-1, 1, 1)
)

edges = (
(0,1),(0,3),(0,4),(2,1),(2,3),(2,7),
(6,3),(6,4),(6,7),(5,1),(5,4),(5,7)
)

class CCube():
    def render(self):  # draw cube
        glBegin(GL_LINES)
        for edge in edges:
            for vertex in edge:
                glVertex3fv(verticies[vertex])
        glEnd()
    def DoRotate(self, selected_angle):  # rotate cube
        self.selected_angle = selected_angle
        #glPushMatrix()  # save state
        if self.selected_angle == 0:
            glRotatef(angle[0], 1, 0, 0)
        elif self.selected_angle == 1:
            glRotatef(angle[1], 0, 1, 0)
        elif self.selected_angle == 2:
            glRotatef(angle[2], 0, 0, 1)
        self.render()  #draw cube
        #glPopMatrix()   # revert state


angle=[0,0,0] # initial angle speed

def main():
    pygame.init()
    display = (800,600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)

    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)

    glTranslatef(0.0,0.0, -5) # move cube into screen

    cc = CCube()
    
    while True:
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)  # clear screen
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        keys = pygame.key.get_pressed()
        selected_angle = -1
        if keys[K_o]:
            selected_angle = 0
            angle[0] += 1
        if keys[K_i]:
            selected_angle = 0
            angle[0] -= 1
        if keys[K_k]:
            selected_angle = 1
            angle[1] += 1
        if keys[K_j]:
            selected_angle = 1
            angle[1] -= 1
        if keys[K_m]:
            selected_angle = 2
            angle[2] += 1
        if keys[K_n]:
            selected_angle = 2
            angle[2] -= 1
        if (selected_angle > -1): CCube().DoRotate(selected_angle)  # rotate if key pressed
        
        cc.render()  # draw cube
        #glRotatef(1, 3, 1, 1)
        #Cube()
        pygame.display.flip()
        pygame.time.Clock().tick(30) # max FPS

main()

Если вы хотите сохранить push \ pop, вы можете использовать этот код. Он устанавливает угол объекта непосредственно перед рисованием.

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *

verticies = (
(1, -1, -1),(1, 1, -1),(-1, 1, -1),(-1, -1, -1),
(1, -1, 1),(1, 1, 1),(-1, -1, 1),(-1, 1, 1)
)

edges = (
(0,1),(0,3),(0,4),(2,1),(2,3),(2,7),
(6,3),(6,4),(6,7),(5,1),(5,4),(5,7)
)

class CCube():
    def render(self):  # draw cube
        glBegin(GL_LINES)
        for edge in edges:
            for vertex in edge:
                glVertex3fv(verticies[vertex])
        glEnd()
        
    def DoRotate(self): # rotate cube
        glPushMatrix()  # save state
        glRotatef(angle[0], 1, 0, 0)
        glRotatef(angle[1], 0, 1, 0)
        glRotatef(angle[2], 0, 0, 1)
        self.render()   # draw cube
        glPopMatrix()   # revert state
        

angle=[0,0,0] # initial angle speed

def main():
    pygame.init()
    display = (800,600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)

    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)

    glTranslatef(0.0,0.0, -5) # move cube into screen

    cc = CCube()
    
    while True:
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)  # clear screen
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        keys = pygame.key.get_pressed()
        if keys[K_o]: angle[0] += 1
        if keys[K_i]: angle[0] -= 1
        if keys[K_k]: angle[1] += 1
        if keys[K_j]: angle[1] -= 1
        if keys[K_m]: angle[2] += 1
        if keys[K_n]: angle[2] -= 1
        cc.DoRotate()  # draw cube
        pygame.display.flip()
        pygame.time.Clock().tick(30) # max FPS

main()

Обратите внимание, что я использовал этот пример для начала с: https://pythonprogramming.net/opengl-rotating-cube-example-pyopengl-tutorial/

...