Struggling with matrices in OpenGL

Snipping this as I've changed the code; See my next big post please
Last edited on
You only pasted the link to the "wrong" image, not to the "right" image.

Could the problem be that you're confusing the order of operations? Taking a rectangle and translating then rotating its corners gives one result, but rotating then translating them gives a different result.
Last edited on
Oh, the right/wrong images are combined into one link (it's one tall image)

Yes from my understanding, the order indeed matters on the rotation/translation -- but I believe the mesh should orbit the origin at whatever vector the translate was, if it were in the wrong order -- either way, the mesh should still translate in some fashion, mine is like...clipping itself oddly instead of translating? Just tried reversing the order and the odd clipping is still occurring, rather than any kind of actual translation. I'm assuming my Translate function is either wrong, or I'm doing something wrong with the passed in Mat in the vertex shader.
I don't know if this is the problem, but have you considered turning your matrix from row major to column major?
I abandoned one tutorial source in favor of another -- I have Matrix4x4's and it's 3D now instead.

So far I've got a ground plane and a box at the far end, and if everything remains at the origin, everything seems to look correct...-ish. (Looks like the ground is rendering over top of the box at the bottom, covering up some pixels.)

https://i.imgur.com/AImrnNb.png

My main problem is when I try to move the View's XY or Z. Rotate seems to look good, but when I move, instead of moving forward, everything distorts, and the clip planes seem to move too.. (far flip plane starts coming to me, and the near clip plane starts moving away, it seems)

https://i.imgur.com/LOdwIvm.png

Am I missing a step in my overall process? This is what I'm doing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Do once in Init
1. Calculate Projection_Matrix


// All of the following do every frame (for now)
2. SetViewOrientation
2a. Fills out translation matrix (passed in posX,posY,posZ and add into 4th column)
2b. Fills out rotation matrix (passed in rotX rotY rotZ)
2c. Multiply results:  rotationmat * translationmat = World_Transform

3. SetObjectOrientation
3a. Fill out translation matrix
3b. Fill out rotation matrix
3c. Multiply results:  translationmat * rotationmat = Object_Transform
// Note: Guide recommended to reverse order and put translationmat first.  However, I've tried swapping orders to no avail
3d. Multiply:  World_Transform * Object_Transform = Combined_Transform

// Lastly:
4. Multiply:  Combined_Transform * Projection_Matrix = Final_Matrix
5. Send Final_Matrix to GLSL shader in glUniformMatrix4fv()


If this order appears right, then my problem must be in one of the functions' calculations. :(

Debugging matrix data is quite hard for me, since I'm unsure if the data within them is correct or incorrect. (I can only know if the data was never set, or if it had garbage data.)

Thanks for any guidance.
I haven't done this in a long time but if memory serves, when I did it, I had to move the object to (0,0,0) position, rotate it, then move it to the desired position (not actually draw it or anything, or actually move it, but the math version of this process coded efficiently).

You may be doing this and me not remembering what the set orientation commands do.

to debug it, I would draw a dumb arrow in 3-d (keep it simple, a line and a cone kind of thing) and then try to move it and have it pointing in some direction to test your code.

remember too that there are anomalies in rotations and translations. Straight up / spin / fall back flat ... what direction are you pointing? Its lost in the trig zeros, your angle can't be found.
Hi again jonnin,

You may be doing this and me not remembering what the set orientation commands do.

As far as what the set orientation commands do, in this case they're custom written, as I wanted to avoid using GLM. I used a nice guide from 1990, which really has been great for 99% of the needed matrix operations: http://www.fastgraph.com/makegames/3drotation/3dsrce.html

remember too that there are anomalies in rotations and translations. Straight up / spin / fall back flat ... what direction are you pointing?

The camera initially starts at identity, so I'm thinking it's not that. If I stay at the origin and only alter my RotX,RotY,RotZ, everything looks fine, even while rotated, but if I translate, things start warping.

So my first thought was that something's wrong with Translate... but it's the most trivial matrix function of them all, so I'm not sure how I could've messed that up:
1
2
3
4
5
6
7
8
void _FillTranslationMatrix(float* a, float x, float y, float z)
{
	// Fill out a translation matrix
	a[0] = 1.0f;	a[1] = 0.0f;	a[2] = 0.0f;	a[3] = x;
	a[4] = 0.0f;	a[5] = 1.0f;	a[6] = 0.0f;	a[7] = y;
	a[8] = 0.0f;	a[9] = 0.0f;	a[10] = 1.0f;	a[11] = z;
	a[12] = 0.0f;	a[13] = 0.0f;	a[14] = 0.0f;	a[15] = 1.0f;
}

(And then matrix multiply with the rotation matrix. And since rotating the models or view looks correct, I'm assuming my rotation function is ok.)

It's either something related to translating, OR, it's something related to my Set Projection function.

In the link I mentioned, it actually didn't have a Set Projection function -- so I looked elsewhere online for it. I found it, but I'm wondering if this function is assuming that worldUp is 0,1,0. I'm using a worldUp of 0,0,1. The way I'm accomplishing this and still rendering in OpenGL is just swapping the Y and Z in the shader when I send the matrix to it. Just for fun, I un-swapped them to see what happens... my view turned upside-down and things still warp as I translate forward.

So yeah, I'm thinking the math in this function is making an assumption of what the worldUp is, and maybe that's why things are warping?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void SetProjectionPerspective(float fov, float aspect_ratio, float near, float far)
{
	float degrees_to_radians = _pi / 180.0f;
	float sy = 1.0f / tan(degrees_to_radians * fov / 2.0f);
	float sx = sy / aspect_ratio;
	float nmf = near - far;
	float form1 = (far + near) / nmf;
	float form2 = 2.0f * far * near / nmf;

	// Fill out the matrix
	float* p = m_perspective_matrix;
	p[0] = sx;		p[1] = 0.0f;	p[2] = 0.0f;	p[3] = 0.0f;
	p[4] = 0.0f;	p[5] = sy;		p[6] = 0.0f;	p[7] = 0.0f;
	p[8] = 0.0f;	p[9] = 0.0f;	p[10] = form1;	p[11] = 1.0f;
	p[12] = 0.0f;	p[13] = 0.0f;	p[14] = form2;	p[15] = 1.0f;
}


I tried messing with the values in the matrices, but not really knowing how it works, I haven't yet produced anything that looks correct. (Usually, everything just disappears when I mess with it.)
Last edited on
Just throwing this out there: I understand that you want to avoid GLM and the helpful perspective-related functions that it provides, but what you could do is write simple standalone tests to compare the result of your function's execution with the result of an equivalent GLM function execution. And this is easy to test because GLM is a headers-only library, and the standalone tests wouldn't require any OpenGL calls or window contexts.

Edit:
Maybe the image in this link helps you?
https://computergraphics.stackexchange.com/questions/6365/inverse-value-in-a-perspective-matrix

It looks like p[11] and p[14] are switched, are you consistent in this throughout your code? (this "flipping" across the y=-x axis). Looking at your translation matrix, it appears you might not be, but I'm guessing here.

Poteto mentioned changing from row major to column major form, but I see no follow-up on that, so this might be a source of confusion.

Edit 2: Looking at this link,
https://www.glprogramming.com/red/appendixf.html
Ignore the fact that it's the old method of GL calls (that you shouldn't use anymore), the math is the same.

They use the vertical {x, y, z} in their translation matrix, but then their perspective matrix has a -1 on the bottom row. I think this discrepancy might be important to you. But maybe I'm way off -- I know the basic of matrices from my linear algebra classes, but never really bothered learning how perspective works.
Last edited on
Topic archived. No new replies allowed.