Reputation: 67
I know what the problem is but i cannot figure out a solution. The problem is that the rotation is applied with the axis fixed on the cube so that if you turn one axis Pi radians then the other axis will look like the mouse controls are inverted. I want it to make it so clicking left mouse button and then moving the mouse to the right rotates the cube to the right, moving it to the left rotates the cube to the left, etc. Please help.
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
vertices = ((-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), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7))
faces = ((0, 1, 2 , 3),(4, 5, 6, 7),(0, 4, 7, 3),(1, 5, 6, 2),(2, 6, 7, 3),(1, 5, 4, 0))
# =============================================================================
# vertices = ((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))
# =============================================================================
def Cube():
glBegin(GL_QUADS)
for face in faces:
for vertex in face:
glColor3fv((1, 0, 1))
glVertex3fv(vertices[vertex])
glEnd()
glBegin(GL_LINES)
glColor3fv((1, 1, 1))
for edge in edges:
for vertex in edge:
glVertex3fv(vertices[vertex])
glEnd()
def Main():
pygame.init()
screen = (1600, 1200)
display = pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)
gluPerspective(45, (screen[0] / screen[1]), 0.1, 500)
glTranslatef(0, 0, -5)
button_down = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
glTranslatef(-1, 0, 0)
if event.key == pygame.K_RIGHT:
glTranslatef(1, 0, 0)
if event.key == pygame.K_UP:
glTranslatef(0, 1, 0)
if event.key == pygame.K_DOWN:
glTranslatef(0, -1, 0)
if event.type == pygame.MOUSEMOTION:
if button_down == True:
glRotatef(event.rel[1], 1, 0, 0)
glRotatef(event.rel[0], 0, 1, 0)
print(event.rel)
for event in pygame.mouse.get_pressed():
print(pygame.mouse.get_pressed())
if pygame.mouse.get_pressed()[0] == 1:
button_down = True
elif pygame.mouse.get_pressed()[0] == 0:
button_down = False
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
Cube()
pygame.display.flip()
pygame.time.wait(10)
Main()
Upvotes: 3
Views: 2667
Reputation: 210918
Operations like glTranslated
and glRotate
define a new matrix and multiply the current matrix by the new matrix.
finalmatrix = matrix1 * matrix2 * matrix3
If you want to apply the operations to the current model transformations than you have to do it in the reverse order.
finalmatrix = matrix3 * matrix2 * matrix1
In Legacy OpenGL, there are different current matrices (see glMatrixMode
). The matrices are organized on a stack. The matrices can be pushe on and popped from the stack by glPushMatrix
/ glPopMatrix
. This can be used to save and restore the matrices.
Apply the projection matrix to the projection matrix stack (GL_PROJECTION
):
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (screen[0] / screen[1]), 0.1, 500)
Switch to the model view matrix and store the current matrix to a variable modelMatrix
at the begin this is the identity matrix
:
glMatrixMode(GL_MODELVIEW)
modelMatrix= glGetFloatv(GL_MODELVIEW_MATRIX)
In the loop:
glPushMatrix()
glLoadIdentity()
Do the new transformation (glTranslatef
/ glRotatef
)
Multiply the stored model view matrix and get then new final model view matrix
glMultMatrixf(modelMatrix)
modelMatrix= glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()
glTranslatef(0, 0, -5)
glMultMatrixf(modelMatrix)
Cube()
glPopMatrix()
See the example:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
vertices = ((-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), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7))
faces = ((0, 1, 2 , 3),(4, 5, 6, 7),(0, 4, 7, 3),(1, 5, 6, 2),(2, 6, 7, 3),(1, 5, 4, 0))
# =============================================================================
# vertices = ((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))
# =============================================================================
def Cube():
glBegin(GL_QUADS)
for face in faces:
for vertex in face:
glColor3fv((1, 0, 1))
glVertex3fv(vertices[vertex])
glEnd()
glBegin(GL_LINES)
glColor3fv((1, 1, 1))
for edge in edges:
for vertex in edge:
glVertex3fv(vertices[vertex])
glEnd()
def Main():
pygame.init()
screen = (1600, 1200)
display = pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (screen[0] / screen[1]), 0.1, 500)
button_down = False
glMatrixMode(GL_MODELVIEW)
modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
while True:
glPushMatrix()
glLoadIdentity()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
glTranslatef(-1, 0, 0)
if event.key == pygame.K_RIGHT:
glTranslatef(1, 0, 0)
if event.key == pygame.K_UP:
glTranslatef(0, 1, 0)
if event.key == pygame.K_DOWN:
glTranslatef(0, -1, 0)
if event.type == pygame.MOUSEMOTION:
if button_down == True:
glRotatef(event.rel[1], 1, 0, 0)
glRotatef(event.rel[0], 0, 1, 0)
print(event.rel)
for event in pygame.mouse.get_pressed():
print(pygame.mouse.get_pressed())
if pygame.mouse.get_pressed()[0] == 1:
button_down = True
elif pygame.mouse.get_pressed()[0] == 0:
button_down = False
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glMultMatrixf(modelMatrix)
modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()
glTranslatef(0, 0, -5)
glMultMatrixf(modelMatrix)
Cube()
glPopMatrix()
pygame.display.flip()
pygame.time.wait(10)
Main()
Upvotes: 2