如何在 PyOpenGL 中使用 gluLookAt?

How to use gluLookAt in PyOpenGL?

我正在尝试学习 PyOpenGL,但我不确定如何使用 gluLookAt 来移动相机。我有一张图片显示,但我想我可能遗漏了一些允许我使用 gluLookAt 的东西?传入墙 o'text,我不确定问题出在哪里。我删除了着色器和纹理代码,因为我 认为 它不相关,但如果它是相关的,我可以 post 它。

import sys
import ctypes
import numpy

from OpenGL import GL, GLU
from OpenGL.GL import shaders
from OpenGL.arrays import vbo

import pygame
from numpy import array

class OpenGLSprite():
    def __init__(self,_sprite='',_vertexShader = None, _fragmentShader = None):
        if not isinstance(_sprite, pygame.Surface):
            self.sprite = pygame.image.load(_sprite)
        else: self.sprite = _sprite

        vertexData = numpy.array([
             # X    Y   Z   U,   V
            -1.0, -1.0, 0, 0.0, 0.0,
            -1.0,  1.0, 0, 0.0, 1.0,
             1.0,  1.0, 0, 1.0, 1.0,

             1.0,  1.0, 0, 1.0, 1.0,
             1.0, -1.0, 0, 1.0, 0.0,
            -1.0, -1.0, 0, 0.0, 0.0,

            ], dtype=numpy.float32)

        self.loadTexture()
        self.buildShaders(_vertexShader, _fragmentShader)

        self.VAO = GL.glGenVertexArrays(1)
        GL.glBindVertexArray(self.VAO)

        self.VBO = GL.glGenBuffers(1)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.VBO)
        GL.glBufferData(GL.GL_ARRAY_BUFFER, vertexData.nbytes, vertexData,
            GL.GL_STATIC_DRAW)

        positionAttrib = GL.glGetAttribLocation(self.shaderProgram, 'position')
        coordsAttrib = GL.glGetAttribLocation(self.shaderProgram, 'texCoords')

        GL.glEnableVertexAttribArray(0)
        GL.glEnableVertexAttribArray(1)
        GL.glVertexAttribPointer(positionAttrib, 3, GL.GL_FLOAT, GL.GL_FALSE, 20,
            None)
        # the last parameter is a pointer
        GL.glVertexAttribPointer(coordsAttrib, 2, GL.GL_FLOAT, GL.GL_TRUE, 20,
            ctypes.c_void_p(12))

        # load texture and assign texture unit for shaders
        self.texUnitUniform = GL.glGetUniformLocation(self.shaderProgram, 'texUnit')

        # Finished
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
        GL.glBindVertexArray(0)

    def render(self):
        GL.glClearColor(0, 0, 0, 1)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        # active shader program
        GL.glUseProgram(self.shaderProgram)

        try:
            # Activate texture
            GL.glActiveTexture(GL.GL_TEXTURE0)
            GL.glBindTexture(GL.GL_TEXTURE_2D, self.texture)
            GL.glUniform1i(self.texUnitUniform, 0)

            # Activate array
            GL.glBindVertexArray(self.VAO)

            # draw triangle
            GL.glDrawArrays(GL.GL_TRIANGLES, 0, 6)
        finally:
            GL.glBindVertexArray(0)
            GL.glUseProgram(0)


def main():
    pygame.init()
    screen = pygame.display.set_mode((640,480),pygame.OPENGL|pygame.DOUBLEBUF)
    GL.glClearColor(0.5, 0.5, 0.5, 1.0)

    camX = 0.0
    camZ = 3.0

    sprite = OpenGLSprite('logo-bluebg-square.png')

    status = 0

    while status == 0:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                status = 1
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    status = 1
                if event.key == pygame.K_LEFT:
                    camX -= 0.1
                if event.key == pygame.K_LEFT:
                    camX += 0.1

        GLU.gluLookAt(camX,0.0,camZ,
                      0.0,0.0,0.0,
                      0.0,1.0,0.0)

        sprite.render()

        pygame.display.flip()

    return 0

if __name__ == '__main__': 
    main()

无论我修改什么参数,主游戏循环中的 gluLookAt 似乎没有做任何事情。用键改变 camX 不会影响任何东西,它只是一直在直视表面。据我了解,gluLookAt 的前三个输入应该是 "Camera" 的位置,对吗?所以如果它正在寻找原点并且相机的 X 位置在移动,它应该在旋转和移动表面,对吗?在设置对象以允许它与 gluLookAt 一起工作时,我必须做一些特别的事情吗?在调用它以将转换应用到某物之后我是否必须做某事?是否需要在对象的绘制代码中,或者gameLoop中?

GLU 库用于固定功能管道。当您使用顶点着色器时,它不适用于现代 OpenGL(至少,除非您正在做兼容性配置文件,但看起来您没有这样做)。相反,您将创建等效矩阵,并将其用作您的一件制服的一部分。

等效函数的 GLM 源代码可在 GitHub in glm/glm/gtc/matrix_transform.inl, in the function lookAtRH 上获得。使用此函数创建您的矩阵,将其乘以视图矩阵的任何其他组件,并将其设置为顶点着色器中的统一。