Implementing my own matrix and transformations...

Hi guys, I’m studying graphics programming at university at the moment, and some work I’ve been given is implementing my own transformations for rotating, translating and scaling.

It’s all been going quite well, I’m using homogeneous coordinates and glMultMatrix() to do everything, but now I’ve hit a problem. If I perform a rotation on x, y and z using glRotatef, it isn’t the same as doing a rotation on x, y and z using my rotateN functions. But if I perform the rotations on only one axis, then they function the same. I have no idea what I should do to debug this.

I’ll show the problem I’m having with an example.


	glMultMatrixf(Mat4::translate(x, y, z).data);
	glMultMatrixf(Mat4::scale(0.5, 0.5, 0.5).data);

	bool use_gl = true;

	if (use_gl)
	{
		glRotatef(angle, 1, 1, 1);
		angle += elapsedTime * 100;
	}
	else
	{
		glMultMatrixf(Mat4::rotateX(angle).data);
		glMultMatrixf(Mat4::rotateY(angle).data);
		glMultMatrixf(Mat4::rotateZ(angle).data);
		angle += elapsedTime;
	}

	glMultMatrixf(Mat4::translate(-x, -y, -z).data);

The code in the use_gl block doesn’t product the same output as the else block.

In case anyone’s wondering, the reason I’m increasing the angle by 100 times more in the use_gl block is that, for some reason, when I don’t do that, the rotation speeds are very different.

I’ve also notced that I can’t pass in a constant angle to my rotateN functions. So if I pass 45 as the angle to glRotatef, it’s not the same as passing 45 to glRotatef. The basic layout for my rotate functions is like so:


Mat4 Mat4::rotateZ(float degree)
{
	Mat4 result;

	const float c = cos(degree);
	const float s = sin(degree);

	result(0, 0) = c;
	result(1, 0) = -s;
	result(0, 1) = s;
	result(1, 1) = c;

	return result;
}

And I can’t see why that wouldn’t let me rotate on the Z axis by 45 degrees.

I hope someone can help me with this. Sorry it’s such a long post! If anyone could point me in the right direction, or give me an idea where I should be looking, that would be great.

Thanks,

Nathan.

The code in the use_gl block doesn’t product the same output as the else block.

Nor should it. glRotatef takes an angle and an axis. That is, a 3D vector representing the axis that will be rotated around. It does not do 3 rotations the way your code does.

Thanks for the reply.

To make sure I’m understanding you correctly, would glRotate3f(45, 1, 1, 1) be equivalent to translating it on x, rotating on x, translating back to origin, translating it to y, rotating on y, etc?

To make sure I’m understanding you correctly, would glRotate3f(45, 1, 1, 1) be equivalent to translating it on x, rotating on x, translating back to origin, translating it to y, rotating on y, etc?

No. It is a rotation about the given axis. That’s what the “1, 1, 1” is in your function call: a vector direction. This is the axis that will be rotated around.

It only rotates about the X axis if you pass the X axis as the axis of rotation (eg: “1, 0, 0”). And that’s not because it does a 0 Y and Z axis rotations; it’s because (1, 0, 0) is the X axis vector.

If you want to rotate around the axis 45-degrees between the X and Y axes, then you use (0.707, 0.707, 0.0).

Ah! That’s much clearer. Thanks Alfonse!

Would you be able to enlighten me as to why calling glRotate(45, 1, 0, 0) will rotate on the X axis by 45 degrees, but calling my Mat4::rotateX(45).data function wouldn’t rotate by 45 degrees?

Edit: Nevermind, I was being silly. I wasn’t converting 45 into degrees.