首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何成功地处理OpenGL的gluLookAt功能?

如何成功地处理OpenGL的gluLookAt功能?
EN

Stack Overflow用户
提问于 2016-01-21 23:22:32
回答 1查看 1.2K关注 0票数 0

尝试在我的python和pygame 3D OpenGL游戏中实现3D漫游相机是我一直在做的事情,但我遇到了一个障碍。每次我尝试使用gluLookAt函数时,相机就会抓狂,在x和z坐标迅速增加的同时,从负坐标切换到正坐标。我正在尝试的游戏只是一个平坦的表面,你走来走去。我已经实现了所有的移动控制,但不是相机。

以下是那些不想阅读我所有代码的人的一些总结代码:

代码语言:javascript
复制
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)))

如果上面的代码无法解决这个问题,下面是我的完整代码:

代码语言:javascript
复制
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()

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2019-09-27 21:11:37

首先,我不知道你是出于什么原因使用游戏的。OpenGL和GLUT (OpenGL Utility )结合在一起,几乎所有你可能需要的3D图形(尤其是在初学者级别)。所以,如果你想从3D图形开始,过剩几乎就是你所需要的一切。

关于gluLookAt函数:该函数本身包含9个参数,如果您想控制摄像机的位置,则需要使用前三个参数操作:

代码语言:javascript
复制
gluLookAt(eyeX, eyeY, eyeZ, ...)

若要将相机围绕对象旋转(位于0、0、0处),您需要更改eyeX、eyeY和eyeZ,以便它们的平方之和为1(或其他值,取决于相机距离对象的距离):

代码语言:javascript
复制
eyeX^2 + eyeY^2 + eyeZ^2 = 1

这是需要满足的,因为这是一个三维球体的方程。

首先,您可以将eyeY变量设置为0,这样相机将只在物体周围的平面上旋转。那么,我们需要满足这一说法:

代码语言:javascript
复制
eyeX^2 + eyeZ^2 = 1

这是一个球面投影到2D -一个圆的方程。

让我们介绍一个角度α,它将代表我们的相机的位置。为了控制相机如何围绕物体旋转,我们将改变这个角度。

)

所以现在,我们需要把这个角度转换成坐标,用于OpenGL的函数中。

这可以用三角函数来完成。Sin(α)将表示我们的Z轴值,Cos(α) -我们的X轴值.这段代码会将我们的角度转换为坐标:

代码语言:javascript
复制
eyeZ = math.sin(alpha)
eyeX = math.cos(alpha)

所以现在我们只需要使用gluLookAt函数:

代码语言:javascript
复制
gluLookAt(eyeX, 0, eyeZ, 0, 0, 0, 0, 1, 0)

要移动相机,你需要以任何你喜欢的方式改变α角度。

要做更复杂的相机管理,你将需要解决的不是圆等式,而是球相等,并使用两个角度,而不是一个。

这是一项艰巨的任务,但我可以推荐您查看TRON项目(https://github.com/leviathan117/TRON/)。这是一个面向初学者的3D图形Python库,它已经编写了许多这些任务,所以您可以使用库本身或者打开库的代码从内部查看一切如何工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34936303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档