您可以使用
glRotate绕轴旋转一定量,该量由鼠标的相对移动(
pygame.mouse.get_rel())给出:
mouseMove = pygame.mouse.get_rel()glRotatef(mouseMove[0]*0.1, 0.0, 1.0, 0.0)
但这不会令您满意,因为如果鼠标离开窗口,该解决方案将无法再使用。
您必须将
pygame.mouse.set_pos()每一帧的鼠标居中在屏幕中间。通过
pygame.MOUSEMOTION事件获取鼠标移动。例如:
# init mouse movement and center mouse on screendisplayCenter = [scree.get_size()[i] // 2 for i in range(2)]mouseMove = [0, 0]pygame.mouse.set_pos(displayCenter)paused = Falserun = Truewhile run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: run = False if event.key == pygame.K_PAUSE or event.key == pygame.K_p: paused = not paused pygame.mouse.set_pos(displayCenter) if event.type == pygame.MOUSEMOTION: mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)] if not paused: pygame.mouse.set_pos(displayCenter)
注意,该 *** 作类似于
glRotate
并
glTranslate设置一个矩阵,然后将当前矩阵乘以新矩阵。
currentMatrix = currentMatrix * newMatrix
这对于模型动画和变换是完美的,但是对于第一人称移动来说,这是错误的方式,在这种情况下,必须更改相机的位置和视角。
viewMatrix = viewTransformMatrix * viewMatrix
做这样的 *** 作
glGetFloatv(GL_MODELVIEW_MATRIX)和
glMultMatrixf。在主循环之前
通过初始化视图矩阵,
gluLookAt并通过将视图矩阵加载到变量(
viewMatrix)
glGetFloatv(GL_MODELVIEW_MATRIX)。
在每个帧的主循环中:
- 加载身份矩阵(
glLoadIdentity
) - 做新的转换到视图(
glRotatef
,glTranslatef
) - 将当前视图矩阵乘以
viewMatrix
(glMultMatrixf
) 将新的视图矩阵加载到
viewMatrix
下一帧glMatrixMode(GL_MODELVIEW)
[…]
gluLookAt(0, -8, 0, 0, 0, 0, 0, 0, 1)
viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()run = True
while run:# [...]# init the view matrixglLoadIdentity()# apply the movment if keypress[pygame.K_w]: glTranslatef(0,0,0.1)if keypress[pygame.K_s]: glTranslatef(0,0,-0.1)if keypress[pygame.K_d]: glTranslatef(-0.1,0,0)if keypress[pygame.K_a]: glTranslatef(0.1,0,0)# apply the roationglRotatef(mouseMove[0]*0.1, 0.0, 1.0, 0.0)# multiply the current matrix by the get the new view matrix and store the final vie matrix glMultMatrixf(viewMatrix)viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
为了向上和向下查找,您必须绕x轴进行最终旋转。旋转的枢轴取决于角度。必须对角度进行求和,并且必须在视图矩阵之后应用旋转,否则运动会根据角度改变(“高度”)水平。
viewMatrix = viewTransformMatrix * viewMatrixfinlalMatrix = lookUpDownMatrix * viewMatrix
为此,您必须汇总上下旋转矩阵并将其乘以
viewMatrix
up_down_angle = 0.0run = Truewhile run: # [...] # init model view matrix glLoadIdentity() # apply the look up and down up_down_angle += mouseMove[1]*0.1 glRotatef(up_down_angle, 1.0, 0.0, 0.0) # init the view matrix glPushMatrix() glLoadIdentity() # calculate new `viewMatrix` # [...] # apply view matrix glPopMatrix() glMultMatrixf(viewMatrix)
请参见以下示例程序,该程序演示了该过程。
请注意,该程序 将鼠标保持在 窗口 的中央 ,因此您不能再“移动”鼠标。因此, 可以通过ESC
或停止return
应用程序。
可以 通过pause
或暂停p
应用程序。暂停应用程序时, 鼠标不会居中 于窗口。
import pygamefrom pygame.locals import *from OpenGL.GL import *from OpenGL.GLU import *import mathpygame.init()display = (400, 300)scree = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)glEnable(GL_DEPTH_TEST)glEnable(GL_LIGHTING)glShadeModel(GL_SMOOTH)glEnable(GL_COLOR_MATERIAL)glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)glEnable(GL_LIGHT0)glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])sphere = gluNewQuadric()glMatrixMode(GL_PROJECTION)gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)glMatrixMode(GL_MODELVIEW)gluLookAt(0, -8, 0, 0, 0, 0, 0, 0, 1)viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)glLoadIdentity()# init mouse movement and center mouse on screendisplayCenter = [scree.get_size()[i] // 2 for i in range(2)]mouseMove = [0, 0]pygame.mouse.set_pos(displayCenter)up_down_angle = 0.0paused = Falserun = Truewhile run: for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN: run = False if event.key == pygame.K_PAUSE or event.key == pygame.K_p: paused = not paused pygame.mouse.set_pos(displayCenter) if not paused: if event.type == pygame.MOUSEMOTION: mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)] pygame.mouse.set_pos(displayCenter) if not paused: # get keys keypress = pygame.key.get_pressed() #mouseMove = pygame.mouse.get_rel() # init model view matrix glLoadIdentity() # apply the look up and down up_down_angle += mouseMove[1]*0.1 glRotatef(up_down_angle, 1.0, 0.0, 0.0) # init the view matrix glPushMatrix() glLoadIdentity() # apply the movment if keypress[pygame.K_w]: glTranslatef(0,0,0.1) if keypress[pygame.K_s]: glTranslatef(0,0,-0.1) if keypress[pygame.K_d]: glTranslatef(-0.1,0,0) if keypress[pygame.K_a]: glTranslatef(0.1,0,0) # apply the left and right rotation glRotatef(mouseMove[0]*0.1, 0.0, 1.0, 0.0) # multiply the current matrix by the get the new view matrix and store the final vie matrix glMultMatrixf(viewMatrix) viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX) # apply view matrix glPopMatrix() glMultMatrixf(viewMatrix) glLightfv(GL_LIGHT0, GL_POSITION, [1, -1, 1, 0]) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) glPushMatrix() glColor4f(0.5, 0.5, 0.5, 1) glBegin(GL_QUADS) glVertex3f(-10, -10, -2) glVertex3f(10, -10, -2) glVertex3f(10, 10, -2) glVertex3f(-10, 10, -2) glEnd() glTranslatef(-1.5, 0, 0) glColor4f(0.5, 0.2, 0.2, 1) gluSphere(sphere, 1.0, 32, 16) glTranslatef(3, 0, 0) glColor4f(0.2, 0.2, 0.5, 1) gluSphere(sphere, 1.0, 32, 16) glPopMatrix() pygame.display.flip() pygame.time.wait(10)pygame.quit()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)