如何在pyopengl中使用鼠标旋转立方体 [英] How to rotate a cube using mouse in pyopengl
问题描述
我知道问题出在哪里,但我想不出解决方案.问题是旋转是在固定在立方体上的轴上应用的,所以如果你旋转一个轴 Pi 弧度,那么另一个轴看起来就像鼠标控件被反转.我想让它点击鼠标左键,然后向右移动鼠标向右旋转立方体,向左移动立方体向左旋转,等等.请帮忙.
导入pygame从 pygame.locals 导入 *从 OpenGL.GL 导入 *从 OpenGL.GLU 导入 *顶点 = ((-1, -1, -1), (-1, 1, -1), (-1, 1, 1), (-1, -1, 1), (1, -1, -1), (1, 1, -1), (1, 1, 1), (1, -1, 1))边 = ((0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7))人脸 = ((0, 1, 2 , 3),(4, 5, 6, 7),(0, 4, 7, 3),(1, 5, 6, 2),(2, 6, 7,3),(1, 5, 4, 0))# ==============================================================================# 顶点 = ((1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1,1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1))# 边 = ((0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4)), (6, 7), (5, 1), (5, 4), (5, 7))# ==============================================================================定义立方体():glBegin(GL_QUADS)面对面:对于面顶点:glColor3fv((1, 0, 1))glVertex3fv(顶点[顶点])glEnd()glBegin(GL_LINES)glColor3fv((1, 1, 1))对于边缘中的边缘:对于边缘中的顶点:glVertex3fv(顶点[顶点])glEnd()定义主():pygame.init()屏幕 = (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 = 假为真:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:pygame.quit()如果 event.type == pygame.KEYDOWN:如果 event.key == pygame.K_LEFT:glTranslatef(-1, 0, 0)如果 event.key == pygame.K_RIGHT:glTranslatef(1, 0, 0)如果 event.key == pygame.K_UP:glTranslatef(0, 1, 0)如果 event.key == pygame.K_DOWN:glTranslatef(0, -1, 0)如果 event.type == pygame.MOUSEMOTION:如果 button_down == 真:glRotatef(event.rel[1], 1, 0, 0)glRotatef(event.rel[0], 0, 1, 0)打印(事件.rel)对于 pygame.mouse.get_pressed() 中的事件:打印(pygame.mouse.get_pressed())如果 pygame.mouse.get_pressed()[0] == 1:button_down = 真elif pygame.mouse.get_pressed()[0] == 0:button_down = 假glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)立方体()pygame.display.flip()pygame.time.wait(10)主要的()
导入pygame从 pygame.locals 导入 *从 OpenGL.GL 导入 *从 OpenGL.GLU 导入 *顶点 = ((-1, -1, -1), (-1, 1, -1), (-1, 1, 1), (-1, -1, 1), (1, -1, -1), (1, 1, -1), (1, 1, 1), (1, -1, 1))边 = ((0, 1), (0, 3), (0, 4), (1, 2), (1, 5), (2, 3), (2, 6), (3, 7), (4, 5), (4, 7), (5, 6), (6, 7))人脸 = ((0, 1, 2 , 3),(4, 5, 6, 7),(0, 4, 7, 3),(1, 5, 6, 2),(2, 6, 7,3),(1, 5, 4, 0))# ==============================================================================# 顶点 = ((1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1,1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1))# 边 = ((0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 7), (6, 3), (6, 4)), (6, 7), (5, 1), (5, 4), (5, 7))# ==============================================================================定义立方体():glBegin(GL_QUADS)面对面:对于面顶点:glColor3fv((1, 0, 1))glVertex3fv(顶点[顶点])glEnd()glBegin(GL_LINES)glColor3fv((1, 1, 1))对于边缘中的边缘:对于边缘中的顶点:glVertex3fv(顶点[顶点])glEnd()定义主():pygame.init()屏幕 = (1600, 1200)display = pygame.display.set_mode(screen, DOUBLEBUF|OPENGL)glMatrixMode(GL_PROJECTION)gluPerspective(45, (screen[0]/screen[1]), 0.1, 500)button_down = 假glMatrixMode(GL_MODELVIEW)modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)为真:glPushMatrix()glLoadIdentity()对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:pygame.quit()如果 event.type == pygame.KEYDOWN:如果 event.key == pygame.K_LEFT:glTranslatef(-1, 0, 0)如果 event.key == pygame.K_RIGHT:glTranslatef(1, 0, 0)如果 event.key == pygame.K_UP:glTranslatef(0, 1, 0)如果 event.key == pygame.K_DOWN:glTranslatef(0, -1, 0)如果 event.type == pygame.MOUSEMOTION:如果 button_down == 真:glRotatef(event.rel[1], 1, 0, 0)glRotatef(event.rel[0], 0, 1, 0)打印(事件.rel)对于 pygame.mouse.get_pressed() 中的事件:打印(pygame.mouse.get_pressed())如果 pygame.mouse.get_pressed()[0] == 1:button_down = 真elif pygame.mouse.get_pressed()[0] == 0:button_down = 假glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)glMultMatrixf(modelMatrix)modelMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)glLoadIdentity()glTranslatef(0, 0, -5)glMultMatrixf(modelMatrix)立方体()glPopMatrix()pygame.display.flip()pygame.time.wait(10)主要的()
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()
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:
- Store the model view matrix and lad the identity matrix:
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)
- Load the identity matrix set the view matrix and multiply the model view matrix:
glLoadIdentity()
glTranslatef(0, 0, -5)
glMultMatrixf(modelMatrix)
- Draw the model and restore the current matrix
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()
这篇关于如何在pyopengl中使用鼠标旋转立方体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!