I'm trying to learn PyOpenGL, but I'm not sure how to use gluLookAt to move the camera. I've got an image displaying, but I think I might be missing something that allows me to use gluLookAt? Incoming wall o'text, I'm not sure where the problem might be. I've cut out the shaders and the texture code, because I don't think it's relevant, but if it is, I can post it.
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()
The gluLookAt in the main game loop doesn't seem to do anything, no matter what parameters I modify. Changing camX with the keys isn't affecting anything, it just keeps looking at the surface straight on. From what I understand, the first three inputs to gluLookAt should be the location of the "Camera", correct? So if it's looking to the origin and the X position of the camera is moving, it should be rotating and moving the surface, right? Is there something special I have to do when setting up the object to allow it to work with gluLookAt? Do I have to do something after calling it to apply the transform to something? Does it need to be in the drawing code of the object, or the gameLoop?
The GLU library is for use with the fixed-function pipeline. It doesn't work with modern OpenGL, when you're using vertex shaders (at least, not unless you're doing compatibility-profile stuff, but it looks like you're not doing that). Instead, you will create the equivalent matrix, and use it as part of one of your uniforms.
The GLM source code for the equivalent function is available on GitHub in glm/glm/gtc/matrix_transform.inl, in the function lookAtRH. Use this function to create your matrix, multiply it by any other components of your view matrix, and set it as a uniform in your vertex shader.