Объяснение того, как OpenGL управляет своими матрицами преобразования - PullRequest
1 голос
/ 28 апреля 2020

Я программирую в Python с помощью модуля PyOpenGL. Я начал работать над модулем камеры для манипулирования полем зрения, но я застрял с функцией gluLookAt (). Моя проблема в том, что когда я нажимаю клавишу sh для перевода камеры, она работает нормально, но не останавливается, когда я отпускаю клавишу. Я думаю, что это может быть потому, что я должен повторно инициализировать матрицу преобразования или что-то в этом роде. Я видел, что я должен использовать pu sh и pop матрицы, или загружать где-нибудь единичную матрицу, но сейчас я очень озадачен тем, что OpenGL делает именно с матрицей, которую, как я полагаю, дает gluLookAt () .

Вот мой код:

import pygame
from pygame.locals import *
import numpy as np
import glm
from math import * 
from OpenGL.GLU import *
from OpenGL.GL import *

class camera:
    def __init__(self, position, angles, target):
        self.position = glm.vec3(position[0], position[1], position[2])
        self.front = glm.normalize(self.position - glm.vec3(target[0], target[1], target[2]))
        self.upVector = glm.normalize(glm.cross(self.front, glm.normalize(glm.cross(self.front, glm.vec3(0, 1, 0)))))
    def update(self):
        glMatrixMode(GL_MODELVIEW)
        gluLookAt(self.position[0], self.position[1], self.position[2], self.position[0] + self.front[0],
        self.position[1] + self.front[1], self.position[2] + self.front[2], self.upVector[0], self.upVector[1], self.upVector[2])        

    def getPos(self):
        return self.position

    def translateCamera(self, vector):
        self.position = self.position + vector

    def keyboardControl(self):
        keys = pygame.key.get_pressed()
        if keys[K_LALT] and keys[K_F4]:
            pygame.quit()
            quit()
        if keys[K_w] and not isSprinting:
            self.position += self.front * 0.02085
        if keys[K_s]:
            self.position -= self.front * 0.02085
        if keys[K_d]:
            self.position += glm.normalize(glm.cross(self.front, self.upVector)) * 0.02085
        if keys[K_a]:
            self.position -= glm.normalize(glm.cross(self.front, self.upVector)) * 0.02085

Камера продолжает отклоняться, когда я даю go ключа, и я думаю, возможно, так как я не сбрасываю матрицу где-то, она просто продолжает применять матрицу, заданную функцией gluLookAt () снова и снова.

Я также пробовал кое-что с GLM, и мне удалось создать матрицу преобразования, которую я хотел, с помощью glm.lookAt (), но я не знаю, как передать его так, чтобы OpenGL обрабатывал его.

Как использовать glPushMatrix и glPopMatrix? И когда мне нужно использовать glLoadIdentity?

1 Ответ

0 голосов
/ 28 апреля 2020

Камера продолжает отклоняться, когда я даю go ключа, и я думаю, что, возможно, поскольку я не сбрасываю матрицу где-то, она просто продолжает применять матрицу, заданную gluLookAt() снова и снова.

gluLookAt не просто устанавливает матрицу, если определяет матрицу и умножает текущую матрицу на новую матрицу.
Обратите внимание на все операции с матрицами, такие как glRotate, glScale, glTranslate et c. умножьте матрицу на текущую матрицу.

Загрузите Идентификационную матрицу , на glLoadIdentity, перед gluLookAt:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(
    self.position[0], self.position[1], self.position[2],
    self.position[0] + self.front[0], self.position[1] + self.front[1], self.position[2] + self.front[2], 
    self.upVector[0], self.upVector[1], self.upVector[2])        

Я также попробовал кое-что с GLM, и мне удалось создать матрицу преобразования, которую я хотел с glm.lookAt(), но я не знаю, как передать это, поэтому OpenGL обрабатывает это.

Используйте glLoadMatrix и glm.value_ptr для загрузки матрицы:

viewMatrix = glm.lookAt(self.position, self.position + self.front, self.upVector)
vieMatList = [viewMatrix[i][j] for i in range(4) for j in range(4)]
glMatrixMode(GL_MODELVIEW)
glLoadMatrixf(vieMatList)

Обратите внимание, что матрицу можно умножить на текущую матрицу на glMultMatrix.

...