re: gluLookAt oddity

Hi there.

I’m implementing a 3D centipede game (for practice) and I’ve struck an oddity. I use glLookAt to place the camera at the end of the playing field (keyboard controls haven’t been implemented yet), yet when display(GLDrawable draw) is called it treats the camera position as (0,0). The code goes thus:

[i]public void display(GLAutoDrawable draw) {
GL gl = draw.getGL();
GLU glu = new GLU();
char piece;

	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	gl.glLoadIdentity();
	glu.gluLookAt(19.0, 0.0, 100.0, 19.0, 0.0, 0.0, 0.0, 1.0, 0.0);

//	drawGun(gl);
	drawGround(gl);
	for (float i = 0; i < rows ; i++) {
		for (float j = 0 ; j < cols ; j++) {
			piece = pa.get((int)i,(int)j);
			if (piece == Run.MUSHROOM) drawShroom(gl, i, -j);
			else if (piece == Run.HIT_MUSHROOM) drawHit(gl, i, -j);
			else if (piece == Segment.RIGHT || piece == Segment.LEFT) drawSeg(gl, i, -j);
			else if (piece == Run.NAPALM) drawNapalm(gl, i, -j);
		}
	}
	gl.glFlush();
}[/i]

where the first call in each draw* method is a call to this:

private final void moveToLocation(GL gl, float row, float column) {
gl.glLoadIdentity();
gl.glTranslatef(row, 0, column);
}

So what I get is a nice, colourful rendering rotated and translated improperly. Is this a gluLookAt problem, or do I have to manually re-translate each object???

I don’t immediately know what’s wrong, but I advise you to take a look at http://nehe.gamedev.net/, they’re great tutorials on OpenGL.
gl !

Just a guess, but nowhere in your code snippet do you set the matrix mode, so I wonder which matrix would be modified by your API calls?

[EDIT]
http://www.opengl.org/sdk/docs/man/xhtml/glMatrixMode.xml

mabraham is probably right, but do you also ever push the camera’s matrix (the one generated by gluLookAt() which is automatically set for you when you call it) using glPushMatrix()? If you don’t do that, the glLoadIdentity() call in moveToLocation(…) will just overwrite it, and then set the position to appear as if the camera were at the origin. I’ve looked through the posted code and I’m 99% sure my eyes haven’t failed me and that you do indeed need to push the matrix after the look at call. Also make sure to pop it off when you’re done rendering.

yeah I tried pushing and popping, but it made no difference. The camera is in the right mode too…

Its wierd. I was under the assumption that reloading the identity matrix then translating would move the next object to that location, (irrespective of gluLookAt) and that the gluLookAt affects which objects are within the clipping plane (by providing the origin that the clipping planes are relevant to…) Yet my objects seem to only want to base their location relevant to the camera.

Have you tried removing the glLoadIdentity call in your moveToLocation function?
I think each of your draw* methods should start with a push, then call moveToLocation, and at the end of the draw* methods should be a pop.

That way, each of your draw methods will have a clean gluLookAt() matrix to work with. If you gluLookAt() first, and then glLoadIdentity, you’ve undone your glLookAt().

That kinda works - the mushroom patch is now off to the far left of the clipping plane, but I have to invert the row and column variables to get the orientation correct. I can leave the row and variable correct and rotate the whole scene 90 degrees, but still wind up with various objects being translated outside of the game square…

it makes more sense to swap the row and column variables. Mathematically, changing rows in a matrix will graphically move what you’re looking at along the y (or z in your case, which I’m not sure why you chose, since z is usually depth), and changing the column in a matrix is similar to changing the x. I’m not sure how clear I was on that, oh well.

It sounds like you’re building your matrices the wrong way. I suggest you go find some tutorial, or maybe the nehe tutorials may help you, although I don’t think they use gluLookAt().

I think this would be a good approximation of how the code should flow:


glMatrixMode(GL.GL_MODELVIEW);						// Select The Modelview Matrix
glLoadIdentity();									// Reset The Modelview Matrix
gluLookAt(...)

//object A
glPushMatrix()
glTranslate( <position of objectA> )
glBegin(...)
  //draw objectA
glEnd()
glPopMatrix()

//object B
glPushMatrix()
glTranslate( <position of objectB> )
glBegin(...)
  //draw objectA
glEnd()
glPopMatrix()

// ..ad infinitum


Mind all the pushes and pops.