I'm trying to rotate an object with button in 3d space When i rotate the object in y-axis after rotating it in x-axis the position got reset to before i rotate it in the first place
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
The short answer is: Remove the glPushMatrix and glPopMatrix calls. PopMatrix reverts the changes you made since PushMatrix.
You only provided a small part of you code, so I created an example including your code. If the Push\PopMatrix calls are removed, the code works correctly. With the Push\Pop calls included, the cube reverts back to it's original position after rotation stops.
Also - I noticed that the key events in your code increase the angle at each loop, so the rotation actually accelerates when holding down the key. I don't know if this was intentional, but I left it in.
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()
If you want to keep the push\pop, you can use this code. It sets the object angle just before drawing.
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()
Note that I used this example to start with: https://pythonprogramming.net/opengl-rotating-cube-example-pyopengl-tutorial/