Короткий ответ: удалите вызовы 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/