2016-10-11 7 views
1

J'essaie d'apprendre PyOpenGL, mais je ne suis pas sûr de savoir comment utiliser gluLookAt pour déplacer la caméra. J'ai une image qui s'affiche, mais je pense qu'il me manque quelque chose qui me permet d'utiliser gluLookAt? En ce qui concerne les murs entrants, je ne sais pas où le problème pourrait être. J'ai découpé les shaders et le code de texture, parce que je ne pense pas que c'est pertinent, mais si c'est le cas, je peux le poster.Comment utiliser gluLookAt dans PyOpenGL?

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

Le gluLookAt dans la boucle principale du jeu ne semble pas faire quoi que ce soit, peu importe quels paramètres je modifie. Changer camX avec les touches n'affecte rien, il continue à regarder la surface tout droit. D'après ce que je comprends, les trois premières entrées à gluLookAt devraient être l'emplacement de la "caméra", correct? Donc, si vous regardez l'origine et que la position X de la caméra est en mouvement, elle devrait tourner et bouger la surface, n'est-ce pas? Y at-il quelque chose de spécial à faire lors de la configuration de l'objet pour lui permettre de fonctionner avec gluLookAt? Dois-je faire quelque chose après l'avoir appelé pour appliquer la transformation à quelque chose? A-t-il besoin d'être dans le code de dessin de l'objet ou du gameLoop?

+0

Je n'ai pas utilisé pyopengl moi-même. Cependant, autant que je sache, gluLookAt fonctionne sur la pile de matrice. Vos shaders accèdent-ils au sommet de la pile de matrices (par exemple, 'gl_ModelViewMatrix' ou' gl_ModelViewProjectionMatrix')? De plus, je ne vois aucun appel 'glViewport' ou' gluPerspective'. 'gluLookAt' ne fera probablement pas ce que vous voulez sans appels à ceux quelque part dans votre code. Bonne chance! – cxw

Répondre

2

La bibliothèque GLU doit être utilisée avec le pipeline à fonction fixe. Cela ne fonctionne pas avec OpenGL moderne, lorsque vous utilisez des vertex shaders (du moins, à moins que vous ne travailliez sur des profils de compatibilité, mais il semble que vous ne le fassiez pas). Au lieu de cela, vous allez créer la matrice équivalente et l'utiliser comme faisant partie de l'un de vos uniformes.

Le code source GLM pour la fonction équivalente est disponible sur GitHub in glm/glm/gtc/matrix_transform.inl, in the function lookAtRH. Utilisez cette fonction pour créer votre matrice, multipliez-la par d'autres composants de votre matrice de vues et définissez-la comme un uniforme dans votre vertex shader.

+0

Il semble que chaque fois que je rencontre un hic, c'est à cause d'un exemple ou d'un tutoriel faisant Legacy OpenGL sans me le dire. Merci, je vais essayer de comprendre le LookAt GLM. Comment utiliser GLM en Python? C'est le problème que j'ai rencontré auparavant, qui m'a finalement amené à trouver GLULookAt –

+0

Vous ne pouvez pas utiliser GLM en Python, mais GLM est sous licence MIT et vous pouvez réimplémenter 'gluLookAt()' en Python. –

+0

Donc, je suis censé utiliser gluLookAt alors? Je suis confus à nouveau. –