简体   繁体   English

如何成功处理OpenGL的gluLookAt函数?

[英]How do I deal with OpenGL's function of gluLookAt successfully?

Trying to implement a 3D roaming camera in my python and pygame 3D OpenGL game is something I've been trying to do, but I hit a roadblock. 我一直在尝试在python和pygame 3D OpenGL游戏中实现3D漫游相机,但遇到了障碍。 Every time I try to use the gluLookAt function, the camera just freaks out and yanks around while the x and z coordinates increase rapidly and switching from negative to positive. 每次我尝试使用gluLookAt函数时,相机都会摇晃并晃动,而x和z坐标会迅速增加,并从负变为正。 The game I am trying to make is just a flat surface that you walk around and on. 我尝试制作的游戏只是您在周围走来走去的平面。 I have all controls implemented for moving around, but not the camera. 我已实现了所有用于移动的控件,但没有实现照相机。

Here is some summarized code for those who don't want to read all my coding: 对于那些不想阅读我所有代码的人,这是一些摘要代码:

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)))

If the problem cannot be solved with the code above, here is my full(ish) code: 如果上述代码无法解决问题,请使用以下完整代码:

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()

Any help would be appreciated! 任何帮助,将不胜感激!

First of all, I don't see for what reasons you use pygame. 首先,我不知道您使用pygame的原因。 OpenGL and GLUT (OpenGL Utility Toolkit) combined have almost everything you might need for 3D graphics in them (especially at the beginner's level). OpenGL和GLUT(OpenGL实用工具包)的组合几乎包含了3D图形所需的所有功能(尤其是在初学者的水平上)。 So if you want to start in 3D graphics - GLUT is pretty much everything you need. 因此,如果您要开始使用3D图形-GLUT几乎是您所需要的一切。

About gluLookAt function: The function itself takes 9 parameters and if you want to control the camera's position - you need to operate with the first three: 关于gluLookAt函数:该函数本身gluLookAt 9个参数,如果要控制摄像机的位置-您需要使用前三个参数进行操作:

gluLookAt(eyeX, eyeY, eyeZ, ...)

To rotate the camera around the object (stationed at 0, 0, 0) you need to change the eyeX, eyeY, and eyeZ so that the sum of their squares would be 1 (or some other value, depending on how far from the object the camera should be): 要围绕对象(位于0、0、0处)旋转相机,您需要更改eyeX,eyeY和eyeZ,以便它们的平方和为1(或其他值,具体取决于距对象的距离)相机应该是):

eyeX^2 + eyeY^2 + eyeZ^2 = 1

This is needed to be satisfied because this is an equation of a sphere in 3D. 这是3D球体的方程,因此需要满足。

To start, you can set eyeY variable to 0, so that the camera would rotate in a plane around the object only. 首先,可以将eyeY变量设置为0,以使相机仅在围绕对象的平面内旋转。 Then we need to satisfy this statement: 然后,我们需要满足以下声明:

eyeX^2 + eyeZ^2 = 1

This is an equation of a projection of a sphere to 2D - a circle 这是球体到2D的投影方程-圆

Let us introduce an angle α, which will represent our camera's position. 让我们介绍一个角度α,它将代表摄像机的位置。 To control how the camera revolves around the object, we will change this angle. 为了控制相机如何围绕对象旋转,我们将更改此角度。

Angle image ( the image is viewed from above ) 角度图像( 从上方查看图像

So now, we need to convert this angle to coordinates, to use in OpenGL's function. 所以现在,我们需要将此角度转换为坐标,以用于OpenGL函数。

This can be done using trigonometric functions. 这可以使用三角函数来完成。 Sin(α) will represent our Z-axis value, Cos(α) - our X-axis value. Sin(α)将代表我们的Z轴值,Cos(α)-我们的X轴值。 This code would convert our angle to coordinates: 此代码会将我们的角度转换为坐标:

eyeZ = math.sin(alpha)
eyeX = math.cos(alpha)

So now we just need to use gluLookAt function: 所以现在我们只需要使用gluLookAt函数:

gluLookAt(eyeX, 0, eyeZ, 0, 0, 0, 0, 1, 0)

To move the camera you need to change the α angle in any way you prefer. 要移动相机,您需要以自己喜欢的任何方式更改α角度。

To do more complex camera management you will need to solve not the circle equality, but the sphere equality and use two angles instead of one. 要进行更复杂的相机管理,您将需要解决的不是圆等式,而是球体等式,并使用两个角度而不是一个角度。

This is a hard task, but I can recommend you to see the TRON project ( https://github.com/leviathan117/TRON/ ). 这是一项艰巨的任务,但是我建议您看一下TRON项目( https://github.com/leviathan117/TRON/ )。 This is a 3D graphics Python library for beginners, and it has lots of these tasks already written, so you can either use the library itself or open the library's code to see how everything works from the inside. 这是一个面向初学者的3D图形Python库,它已经编写了许多此类任务,因此您可以使用该库本身,也可以打开该库的代码以从内部了解一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM