Rotating the scene

I’ve made a simple 3d OpenGL (LWJGL) program which renders a square ground, a square random entity and a character that is a cube. I’ve got it so the character renders first and stays in the same place, then a translation is performed on everything other than the main character to manipulate the scene in order to appear as if the character is either rotating or moving across the scene with you directly behind them. The other items in the scene are the floor and square.
The translation I’ve used works well. It takes the main character’s coordinates and negates them in order to calculate how far and in what direction the scene is moved. The problem is the rotate. If I put the rotate before the translation, the rotation seems to be applied, although the character continues to walk in its original direction (almost diagonally) and if I perform the rotation after the translation, no matter how far I walk away from the original origin, it continues to rotate around it and not the new origin.

I hope the code tags work on here. :x

The Player and Entity classes just contain the x, y and z coordinates along with the get and sets.


import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;


class Game
{
	protected int WIDTH = 800;
	protected int HEIGHT = 600;
	private float angle = 0.0f;
	public Player player = new Player();
	public Entity entity = new Entity();
	
	Game()
	{
		entity.setX(3.0f);
		entity.setZ(-40.0f);
	}
	
	public void init()
	{
		try
		{
			Display.setDisplayMode(new DisplayMode(WIDTH,HEIGHT));
			Display.create();
		}
		catch(LWJGLException e)
		{
			e.printStackTrace();
			System.exit(0);
		}
	}
	
	public void initGL()
	{
		float aspectRatio;
		if(HEIGHT > WIDTH)
			aspectRatio = (float)HEIGHT/(float)WIDTH;
		else
			aspectRatio = (float)WIDTH/(float)HEIGHT;
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		GL11.glFrontFace(GL11.GL_CCW);
		
		GL11.glClearColor(0.0f,0.1f,0.0f,1.0f);
		
		GL11.glViewport(0,0,WIDTH,HEIGHT);
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GLU.gluPerspective(45,aspectRatio,1,-100);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
	}
	
	public void logic()
	{
		while(!Display.isCloseRequested())
		{
			if(Keyboard.isKeyDown(Keyboard.KEY_A))
				player.setX(player.getX() - 0.01f);
			else if(Keyboard.isKeyDown(Keyboard.KEY_D))
				player.setX(player.getX() + 0.01f);
			else if(Keyboard.isKeyDown(Keyboard.KEY_W))
				player.setZ(player.getZ() - 0.01f);
			else if(Keyboard.isKeyDown(Keyboard.KEY_S))
				player.setZ(player.getZ() + 0.01f);
			else if(Keyboard.isKeyDown(Keyboard.KEY_SPACE))
				player.setY(player.getY() + 0.01f);
			else if(Keyboard.isKeyDown(Keyboard.KEY_E))
			{
				angle += 0.1f;
				if(angle > 360.0f)
					angle = 0.0f;
			}
			else if(Keyboard.isKeyDown(Keyboard.KEY_Q))
			{
				angle -= 0.1f;
				if(angle < 0.0f)
					angle = 360.0f;
			}
			render();
		}
	}
	
	public void render()
	{
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		GL11.glPushMatrix();
			GL11.glTranslatef(-5.0f,-12.0f,-40.0f);
			GL11.glPushMatrix();
				GL11.glBegin(GL11.GL_QUADS);
					GL11.glColor3f(1.0f,0.0f,0.0f);
					GL11.glVertex3f(0.0f,0.0f,0.0f);
					GL11.glVertex3f(10.0f,0.0f,0.0f);
					GL11.glVertex3f(10.0f,10.0f,0.0f);
					GL11.glVertex3f(0.0f,10.0f,0.0f);
				
					GL11.glColor3f(0.0f,1.0f,0.0f);
					GL11.glVertex3f(10.0f,0.0f,0.0f);
					GL11.glVertex3f(10.0f,0.0f,10.0f);
					GL11.glVertex3f(10.0f,10.0f,10.0f);
					GL11.glVertex3f(10.0f,10.0f,0.0f);
					
					GL11.glColor3f(1.0f,0.0f,0.0f);
					GL11.glVertex3f(10.0f,0.0f,10.0f);
					GL11.glVertex3f(0.0f,0.0f,10.0f);
					GL11.glVertex3f(0.0f,10.0f,10.0f);
					GL11.glVertex3f(10.0f,10.0f,10.0f);
					
					GL11.glColor3f(0.0f,1.0f,0.0f);
					GL11.glVertex3f(0.0f,0.0f,10.0f);
					GL11.glVertex3f(0.0f,0.0f,0.0f);
					GL11.glVertex3f(0.0f,10.0f,0.0f);
					GL11.glVertex3f(0.0f,10.0f,10.0f);
					
					GL11.glColor3f(0.0f,1.0f,1.0f);
					GL11.glVertex3f(0.0f,10.0f,0.0f);
					GL11.glVertex3f(10.0f,10.0f,0.0f);
					GL11.glVertex3f(10.0f,10.0f,10.0f);
					GL11.glVertex3f(0.0f,10.0f,10.0f);
				GL11.glEnd();
			GL11.glPopMatrix();
			GL11.glTranslatef(-player.getX(),-player.getY(),-player.getZ());
			GL11.glRotatef(angle,0.0f,1.0f,0.0f);
			GL11.glPushMatrix();
				GL11.glBegin(GL11.GL_QUADS);
					GL11.glColor3f(0.0f,0.3f,0.0f);
					GL11.glVertex3f(-50.0f,0.0f,50.0f);
					GL11.glColor3f(0.0f,0.8f,0.0f);
					GL11.glVertex3f(50.0f,0.0f,50.0f);
					GL11.glColor3f(0.0f,0.3f,0.0f);
					GL11.glVertex3f(50.0f,0.0f,-50.0f);
					GL11.glColor3f(0.0f,0.8f,0.0f);
					GL11.glVertex3f(-50.0f,0.0f,-50.0f);
				GL11.glEnd();
			GL11.glPopMatrix();
			GL11.glPushMatrix();
				GL11.glBegin(GL11.GL_QUADS);
					GL11.glColor3f(1.0f,0.0f,1.0f);
					GL11.glVertex3f(entity.getX() + 0.0f,0.0f,entity.getZ() + 0.0f);
					GL11.glVertex3f(entity.getX() + 10.0f,0.0f,entity.getZ() + 0.0f);
					GL11.glVertex3f(entity.getX() + 10.0f,10.0f,entity.getZ() + 0.0f);
					GL11.glVertex3f(entity.getX() + 0.0f,10.0f,entity.getZ() + 0.0f);
				GL11.glEnd();
			GL11.glPopMatrix();
		GL11.glPopMatrix();
		Display.update();
	}
	
	public void cleanup()
	{
		Display.destroy();
	}
	
	public static void main(String[] args)
	{
		Game game = new Game();
		game.init();
		game.initGL();
		game.logic();
		game.cleanup();
	}
}

If anyone can show me how I can make it so the character rotates around the new origin I would really appreciate it.

Thanks,
Paul

Does anyone get what I mean? Basically I have scene and a character. I put my character in the right place and give it coordinates, then I use glTranslate to move the scene underneath it. This works but the rotation around the y axis seems to continue to rotate around the original origin.

Then change the order of the glRotate - ie before the two glTranslatef commands.
By the way, you are glPushmatrix and glPopmatrix before every glBegin. This is completely unnecessary as you are not manipulating the model matrix on each draw.

Thanks for the response. Yeah, I tried changing the order of the glTranslate and the glRotate, but what it seems to do is rotate the scene, but makes the character continues to move forwards (when ‘w’ is pressed) in the original direction. So it appears to move diagonally.

Sorry about the shameless self bump, but I don’t think I really know enough about what I’m doing. I’ve heard of a technique of moving your camera through a scene with translations and rotations using this origin vector, up vector and forward vector, but I’m not sure what it’s called. Could anybody who knows perhaps tell me what it is and if possible any research material?

Thanks in advance

How do you handle the camera in terms of looking around/left/right/up/down?
Your player movement would need to do something similar and from the set of rotations you would build a model matrix which would encode the rotations and translation of the player. You could do this with euler angles or even better via quaternions.