OpenGL Axis Rotations

SOLVED
See my last post for details.

I am programming a 3x3 puzzle cube (aka Rubik’s Cube) and I am having some difficulty with axis rotations.
When i press “X” i have the rotX increase by 90 degrees, the same goes for Y, and Z. You can only rotate on one axis at a time.
The problem is, I wish for my cube to rotate relative to my perspective. An example of what happens now is if i rotate 90 degrees on the X axis, then try rotating on the Y axis, the cube turns on (what i see to be) the Z axis.


		GL11.glRotatef(rotX, 1.0f, 0.0f, 0.0f);
		GL11.glRotatef(rotY, 0.0f, 1.0f, 0.0f);
		GL11.glRotatef(rotZ, 0.0f, 0.0f, 1.0f);

If you wish to demo the program: File Beam
Controls:
1 - turn red
2 - turn orange
3 - turn blue
4 - turn green
5 - turn yellow
6 - turn white
X - rotate on “X” axis
Y - rotate on “Y” axis
Z - rotate on “Z” axis
Left Shift - Hold to turn / rotate opposite direction.
Right Shift - Reset cube.
Escape - Exit.
Enter - Scramble cube.
Backspace - Undo last move (includes scramble moves).

I get a NullPointerException in org.lwjgl.opengl.GL11.glShadeModel() at line 160 in rubikEngine.Engine.initGL()
I also get a RuntimeException saying “Image based resources must be loaded as part of init() or the game loop. They cannot be loaded before initialisation.” (haha they misspelled initialization) This was thrown inside the Slick library at line 426 in rubikEngine.Engine.loadTextures()

Hope that helped :smiley:

The game worked fine here on W7.

To op: I see what you mean by that weird rotation thingy, it does seem like when you rotate around the x-axis, the y and z axis switch places with each other.
I haven’t worked with opengl that much before, but wouldn’t it be better to just have one glRotatef call? Like glRotatef(1.0f, rotX, rotY, rotZ); or something like that.

The NPE might have been caused by your video card not supporting smooth shading, i removed it and re-uploaded. My The Slick texture loader is bound to fail sometimes, if it does it just loads with basic GL11.glColor3f() calls instead of texture binding, so that should be fine.

Maybe, but from what I understand is that glRotatef(angle, x,y,z) where angle is the angle of rotation, and x,y,z is either 1.0f or 0.0f, depending if you want to rotate that angle on that axis. The problem is that the angle for each axis is not the same, say maybe I want to rotate 90 degrees on the X-axis, but 180 degrees on the Y-axis.

Maybe, I just heard somewhere that you should minimize your calls to opengl. I should probably let someone more experienced answer this though :wink:

Haha now I get an NPE at the next line, glClearColor(), and the same Slick exception.
Wow, my computer is the crappiest thing ever :confused:

I have been reading, and I’m coming across “quaternions” frequently and “gimbal lock”. Any help with this?

Are Google and Wikipedia broken again?

Absolutely not, like i said, I have been reading, a TON. The thing is I don’t know how to implement it in OpenGL.

I have come up with some code that to me seems that it should work, but does not and does work.

if(rotating){
	currentSpeed = rotationSpeed;
	quatRotationChange.setFromAxisAngle(new Vector4f(turnX, turnY, turnZ, (isPrime? -1:1) * currentSpeed));		
	Quaternion.mul(quatCurrentRotation, quatRotationChange, quatCurrentRotation);
	quatCurrentRotation.normalise();
	createMatrixBuffer();
}		
		
GL11.glLoadIdentity();
GL11.glTranslatef(0f, 0f, -10f);

createMatrixBuffer();
GL11.glMultMatrix(matrixBuffer);

createMatrixBuffer method is this:

private void createMatrixBuffer(){
	float w,x,y,z;
	w = quatCurrentRotation.w;
	x = quatCurrentRotation.x;
	y = quatCurrentRotation.y;
	z = quatCurrentRotation.z;
	Matrix4f m = new Matrix4f();
		
	m.m00 = sq(w) + sq(x) - sq(y) - sq(z);
	m.m01 = 2 * x * y + 2 * w * z;
	m.m02 = 2 * x * z - 2 * w * y;
	m.m03 = 0;

	m.m10 = 2 * x * y - 2 * w * z;
	m.m11 = sq(w) - sq(x) + sq(y) - sq(z);
	m.m12 = 2 * y * z + 2 * w * x;
	m.m13 = 0;
	
	m.m20 = 2 * x * z + 2 * w * y;
	m.m21 = 2 * y * z - 2 * w * x;
	m.m22 = sq(w) - sq(x) - sq(y) + sq(z);
	m.m23 = 0;

	m.m30 = 0;
	m.m31 = 0;
	m.m32 = 0;
	m.m33 = sq(w) + sq(x) + sq(y) + sq(z);
		
	matrixBuffer.clear();
	m.store(matrixBuffer);
	matrixBuffer.flip();
}
	
private float sq(float x){
	return x*x;
}

I used the formula found Here