进行 2 次旋转时对象会重置
Object get reset when doing 2 rotation
我正在尝试使用 3d 按钮旋转对象 space
当我在 x 轴上旋转对象后在 y 轴上旋转对象时
在我首先旋转它之前,位置已重置
angle = [0, 0, 0]
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
简短的回答是:删除 glPushMatrix 和 glPopMatrix 调用。 PopMatrix 还原自 PushMatrix 以来所做的更改。
您只提供了一小部分代码,因此我创建了一个包含您的代码的示例。如果删除了 Push\PopMatrix 调用,则代码可以正常工作。包含 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, 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/
我正在尝试使用 3d 按钮旋转对象 space 当我在 x 轴上旋转对象后在 y 轴上旋转对象时 在我首先旋转它之前,位置已重置
angle = [0, 0, 0]
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
简短的回答是:删除 glPushMatrix 和 glPopMatrix 调用。 PopMatrix 还原自 PushMatrix 以来所做的更改。
您只提供了一小部分代码,因此我创建了一个包含您的代码的示例。如果删除了 Push\PopMatrix 调用,则代码可以正常工作。包含 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, 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/