Jannis Jorre Jannis Jorre - 1 month ago 9
Python Question

PyOpenGL glLookAt behaves weirdly after first call, with same parameters

I am currently programming a small game using PyOpenGL for school (Python wasn't my choice...).

I seem to cannot wrap my head around the funcionality of the "camera". I figured that the most intuitional approach for my case is the

gluLookAt(...)
function. I want to look at my character in third person. Since my game is tile-based and logically two-dimensional, the Y-Coordinate should never change. Following is the code that I think matters (basically everything that I do with OpenGL).

This is what is called once, initially to set up OpenGL:

# set the perspective
fieldOfView = 45 # degrees
aspectRatio = 1800 / 1000 # given as parameters to constructor previously
gluPerspective(fieldOfView, aspectRatio, 0.1, 50.0)

# things in the back are covered by things in front of them
glEnable(GL_DEPTH_TEST)


This is what is being called on every update:

# Clear Buffers
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

# render the objects in the map and ground where needed
self.renderAllObjects() # in here glBegin(..), glEnd(),
# glColor3fv(...) and glVertex3fv(...)
# are the only used OpenGL functions
# eye coords
eX = 19.5
eY = 3
eZ = 1.5

# center/lookat coords
cX = 12.5
cY = 1
cZ = 1.5

gluLookAt(eX, eY, eZ, cX, cY, cZ, 0, 1, 0)


When the first update is run, everything works as espected, but once I call the update function again, we are placed at some other coordinate, that seems to be in some way relative to the previous coordinate of the camera.

Online I found the functions:


  • glMatrixMode(...)
    with GL_MODELVIEW and GL_PERSPECTIVE

  • glLoadIdentity()



It was said that
glLoadIdentity()
is to be called before every
gluLookAt(...)
-call. But once I do that, I only get a black screen.

Also playing around places to put
glMatrixMode(...)
did not solve anything.

I also tried changing the order of loading objects and camera, but it seems that my current order is the right one.

Any help would be much appreciated. I am a total OpenGL newbie. Sadly after hours of research I could not wrap my head around this.

Answer

Once before you gluPerspective you should:

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(fieldOfView, aspectRatio, 0.1, 50.0)

This sets the projection matrix.

Then each time you render the frame you set up the model-view matrix:

glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(eX, eY, eZ, cX, cY, cZ, 0, 1, 0)

The projection matrix and the model-view matrix are separate state stored by the GL. So in order for glLoadInentity and gluLookAt not to override the projection matrix, you have to use glMatrixMode to designate which of the matrices you're currently working with.

Also you should set the model-view matrix (gluLookAt) before you render the objects (self.renderAllObjects).