reibisch's picture

Handling transformations outside of GL

Hi guys,

I've been developing 3D software for a variety of scientific visualization applications for several years (almost always with OpenGL, and using OpenTK nearly exclusively for the last year or two). During that time, I've relied on OpenGL to handle my modelview transformations for me. Yesterday I thought I should at least make an attempt to keep up with OGL3.0+ and instead do the MV calcs myself rather than rely on translate/rotate/etc. Besides, I figure having access to the world coordinates of my objects should make a whole raft of geometry operations easier.

This is essentially a boiled down version of a very simple render function that is working as intended. It moves the camera back from the origin, then performs a few rotations to align the camera, then moves the viewpoint of the camera to some position. It then draws a short line down the X-axis starting at the world origin. Simple stuff.

this.perspectiveMatrix = OpenTK.Matrix4.CreatePerspectiveFieldOfView(this.FieldOfViewRadians, (float)this.viewportWidth / (float)this.viewportHeight, this.nearPlane, this.farPlane);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref this.perspectiveMatrix);
GL.MatrixMode(MatrixMode.Modelview);
 
GL.Translate(0.0f, 0.0f, -15.0f * this.zoomFactor);
GL.Rotate(-90.0f, 1.0f, 0.0f, 0.0f);
GL.Rotate(this.rotation.Y, 1, 0, 0);
GL.Rotate(this.rotation.X, 0, 0, 1);
GL.Translate(this.position);
 
GL.Begin(BeginMode.Lines);
GL.Color(1.0, 1.0, 1.0);
GL.Vertex3(0, 0, 0);
GL.Vertex3(1, 0, 0);
GL.End();

For the sake of completeness (though my issue more has to do with theory than specifics), the values I used were:

this.FieldOfViewRadians = 0.785f;
this.viewportWidth = 1080;
this.viewportHeight = 580;
this.nearPlane = 0.1f;
this.farPlane = 1000.0f;
this.zoomFactor = 4.5f;
this.rotation = new Vector3(45.0f, 45.0f, 0.0);
this.position = new Vector3(0.0, 0.0, 0.0);

in my naivity, I expected to be able to replace the above transformation code with the following:

this.perspectiveMatrix = OpenTK.Matrix4.CreatePerspectiveFieldOfView(this.FieldOfViewRadians, (float)this.viewportWidth / (float)this.viewportHeight, this.nearPlane, this.farPlane);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref this.perspectiveMatrix);
GL.MatrixMode(MatrixMode.Modelview);
 
Matrix4d mv = Matrix4d.Identity;
mv = Matrix4d.CreateTranslation(0, 0, -15 * this.zoomFactor) * mv;
mv = Matrix4d.CreateRotationX(MathHelper.DegreesToRadians(90)) * mv;
mv = Matrix4d.CreateRotationX(MathHelper.DegreesToRadians(this.rotation.Y)) * mv;
mv = Matrix4d.CreateRotationZ(MathHelper.DegreesToRadians(this.rotation.Y)) * mv;
mv = Matrix4d.CreateTranslation(this.position.X, this.position.Y, this.position.Z) * mv;
 
GL.Begin(BeginMode.Lines);
GL.Color(1.0, 1.0, 1.0);
GL.Vertex3(Vector4d.Transform(new Vector4d(0, 0, 0, 0), mv).Xyz);
GL.Vertex3(Vector4d.Transform(new Vector4d(1, 0, 0, 0), mv).Xyz);
GL.End();

My naivity relied on my understanding of how the ModelView matrix was formed and used, which was apparently quite wrong. I thought that the modelview was formed through sequential transformations, which, if then applied to geometry (say my line vertices) would result in a modified vector could then be passed via GL.Vertex to be further tweaked by the projection matrix.

Can anyone spot where I've gone wrong?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
migueltk's picture

Hello, ...

A vector4d unit is equal to:

X = 1
Y = 1
Z = 1
W = 1

then a vector4d from a Vector3D is equal to:

vector4d.X = vector3d.X
vector4d.Y = vector3d.Y
vector4d.Z = vector3d.Z
vector4d.W = 1

Your code should look like:

            GL.Begin(BeginMode.Lines);
            GL.Color3(1.0, 1.0, 1.0);
            GL.Vertex3(Vector4d.Transform(new Vector4d(0, 0, 0, 1), mv).Xyz);
            GL.Vertex3(Vector4d.Transform(new Vector4d(1, 0, 0, 1), mv).Xyz);
            GL.End();

Remember, you are indicating a position and you only need three coordinates.

Regards, ...

reibisch's picture

Sigh. You're absolutely right!

I was on autopilot when entering those vectors and forgot all about that.

Thank you so much :)