尝试在我的python和pygame 3D OpenGL游戏中实现3D漫游相机是我一直在做的事情,但我遇到了一个障碍。每次我尝试使用gluLookAt函数时,相机就会抓狂,在x和z坐标迅速增加的同时,从负坐标切换到正坐标。我正在尝试的游戏只是一个平坦的表面,你走来走去。我已经实现了所有的移动控制,但不是相机。
以下是那些不想阅读我所有代码的人的一些总结代码:
while True:
matrix = glGetDoublev(GL_MODELVIEW_MATRIX)
camera_x = matrix[3][0]
camera_y = matrix[3][1]
camera_z = matrix[3][2]
# the 3-6 ones are what the camera is looking at
gluLookAt(camera_x, camera_y, camera_z, 0, 0, 0, 0, 1, 0)
print("({}, {}, {})".format(int(-camera_x), int(-camera_y), int(-camera_z)))如果上面的代码无法解决这个问题,下面是我的完整代码:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import os
speed = .5
def enviroment():
glBegin(GL_QUADS)
for surface in surfaces:
for vertex in surface:
glColor3fv((1, 0, 0))
glVertex3fv(verticies[vertex])
glEnd()
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glColor3fv((0, 1, 1))
glVertex3fv(verticies[vertex])
glEnd()
def main():
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
gluPerspective(45, (display[0] / display[1]), 0.1, 400)
glTranslatef(0.0, -3, -150)
glRotatef(0, 0, 0, 0)
while True:
press = pygame.key.get_pressed()
matrix = glGetDoublev(GL_MODELVIEW_MATRIX)
camera_x = matrix[3][0]
camera_y = matrix[3][1]
camera_z = matrix[3][2]
# the 3-6 ones are what the camera is looking at
gluLookAt(camera_x, camera_y, camera_z, 0, 0, 0, 0, 1, 0)
print("({}, {}, {})".format(int(-camera_x), int(-camera_y), int(-camera_z)))
if press[pygame.K_UP]:
glTranslatef(0, -speed, 0)
elif press[pygame.K_DOWN]:
glTranslatef(0, speed, 0)
elif press[pygame.K_w]:
glTranslatef(0, 0, speed)
elif press[pygame.K_s]:
glTranslatef(0, 0, -speed)
elif press[pygame.K_a]:
glTranslatef(speed, 0, 0)
elif press[pygame.K_d]:
glTranslatef(-speed, 0, 0)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
elif event.type == KEYDOWN:
if event.key == K_UP:
glTranslatef(0, -speed, 0)
elif event.key == K_DOWN:
glTranslatef(0, speed, 0)
elif event.key == K_w:
glTranslatef(0, 0, speed)
elif event.key == K_s:
glTranslatef(0, 0, -speed)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
enviroment()
pygame.display.flip()
pygame.time.wait(10)
main()任何帮助都将不胜感激!
发布于 2019-09-27 21:11:37
首先,我不知道你是出于什么原因使用游戏的。OpenGL和GLUT (OpenGL Utility )结合在一起,几乎所有你可能需要的3D图形(尤其是在初学者级别)。所以,如果你想从3D图形开始,过剩几乎就是你所需要的一切。
关于gluLookAt函数:该函数本身包含9个参数,如果您想控制摄像机的位置,则需要使用前三个参数操作:
gluLookAt(eyeX, eyeY, eyeZ, ...)若要将相机围绕对象旋转(位于0、0、0处),您需要更改eyeX、eyeY和eyeZ,以便它们的平方之和为1(或其他值,取决于相机距离对象的距离):
eyeX^2 + eyeY^2 + eyeZ^2 = 1这是需要满足的,因为这是一个三维球体的方程。
首先,您可以将eyeY变量设置为0,这样相机将只在物体周围的平面上旋转。那么,我们需要满足这一说法:
eyeX^2 + eyeZ^2 = 1这是一个球面投影到2D -一个圆的方程。
让我们介绍一个角度α,它将代表我们的相机的位置。为了控制相机如何围绕物体旋转,我们将改变这个角度。
所以现在,我们需要把这个角度转换成坐标,用于OpenGL的函数中。
这可以用三角函数来完成。Sin(α)将表示我们的Z轴值,Cos(α) -我们的X轴值.这段代码会将我们的角度转换为坐标:
eyeZ = math.sin(alpha)
eyeX = math.cos(alpha)所以现在我们只需要使用gluLookAt函数:
gluLookAt(eyeX, 0, eyeZ, 0, 0, 0, 0, 1, 0)要移动相机,你需要以任何你喜欢的方式改变α角度。
要做更复杂的相机管理,你将需要解决的不是圆等式,而是球相等,并使用两个角度,而不是一个。
这是一项艰巨的任务,但我可以推荐您查看TRON项目(https://github.com/leviathan117/TRON/)。这是一个面向初学者的3D图形Python库,它已经编写了许多这些任务,所以您可以使用库本身或者打开库的代码从内部查看一切如何工作。
https://stackoverflow.com/questions/34936303
复制相似问题