Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my translation matrix needs to be transposed?

I'm working on a small graphics engine using OpenGL and I'm having some issues with my translation matrix. I'm using OpenGL 3.3, GLSL and C++. The situation is this: I have defined a small cube which I want to render on screen. The cube uses it's own coordinate system, so I created a model matrix to be able to transform the cube. To make it myself a bit easier I started out with just a translation matrix as the cube's model matrix and after a bit of coding I've managed to make everything work and the cube appears on the screen. Nothing all to special, but there is one thing about my translation matrix that I find a bit odd.

Now as far as I know, a translation matrix is defined as follows:

1, 0, 0, x 0, 1, 0, y 0, 0, 1, z 0, 0, 0, 1 

However, this does not work for me. When I define my translation matrix this way, nothing appears on the screen. It only works when I define my translation matrix like this:

1, 0, 0, 0 0, 1, 0, 0 0, 0, 1, 0 x, y, z, 1 

Now I've been over my code several times to find out why this is the case, but I can't seem to find out why or am I just wrong and does a translation matrix needs to be defined like the transposed one here above?

My matrices are defined as a one-dimensional array going from left to right, top to bottom.

Here is some of my code that might help:

//this is called just before cube is being rendered void DisplayObject::updateMatrices() {     modelMatrix = identityMatrix();     modelMatrix = modelMatrix * translateMatrix( xPos, yPos, zPos );      /* update modelview-projection matrix */     mvpMatrix = modelMatrix * (*projMatrix); }  //this creates my translation matrix which causes the cube to disappear const Matrix4 translateMatrix( float x, float y, float z ) {     Matrix4 tranMatrix = identityMatrix();      tranMatrix.data[3]  = x;     tranMatrix.data[7]  = y;     tranMatrix.data[11] = z;      return Matrix4(tranMatrix); } 

This is my simple test vertex shader:

#version 150 core  in vec3 vPos;  uniform mat4 mvpMatrix;  void main() {     gl_Position = mvpMatrix * vec4(vPos, 1.0); } 

I've also did tests to check if my matrix multiplication works and it does. I * randomMatrix is still just randomMatrix

I hope you guys can help. Thanks

EDIT:

This is how I send the matrix data to OpenGL:

void DisplayObject::render() {     updateMatrices();      glBindVertexArray(vaoID);     glUseProgram(progID);     glUniformMatrix4fv( glGetUniformLocation(progID, "mvpMatrix"), 1, GL_FALSE, &mvpMatrix.data[0] );     glDrawElements(GL_TRIANGLES, bufferSize[index], GL_UNSIGNED_INT, 0); } 

mvpMatrix.data is a std::vector:

like image 591
Krienie Avatar asked Nov 08 '12 16:11

Krienie


People also ask

What does the transpose of a matrix tell us?

In linear algebra, the transpose of a matrix is an operator which flips a matrix over its diagonal; that is, it switches the row and column indices of the matrix A by producing another matrix, often denoted by AT (among other notations).

What is the purpose of transpose?

The TRANSPOSE function returns a vertical range of cells as a horizontal range, or vice versa. The TRANSPOSE function must be entered as an array formula in a range that has the same number of rows and columns, respectively, as the source range has columns and rows.

What is the condition for transpose of a matrix?

The new matrix obtained by interchanging the rows and columns of the original matrix is called as the transpose of the matrix. If A = [aij] be an m × n matrix, then the matrix obtained by interchanging the rows and columns of A would be the transpose of A. of It is denoted by A′or (AT).


2 Answers

For OpenGL

1, 0, 0, 0 0, 1, 0, 0 0, 0, 1, 0 x, y, z, 1 

Is the correct Translation Matrix. Why? Opengl Uses column-major matrix ordering. Which is the Transpose of the Matrix you initially presented, which is in row-major ordering. Row major is used in most math text-books and also DirectX, so it is a common point of confusion for those new to OpenGL.

See: http://www.mindcontrol.org/~hplus/graphics/matrix-layout.html

like image 199
Stephan van den Heuvel Avatar answered Sep 23 '22 04:09

Stephan van den Heuvel


You cannot swap matrices in a matrix multiplication, so A*B is different from B*A. You have to transpose B before swapping the matrices.

A * B = t(B) * A 

try

void DisplayObject::updateMatrices() {     modelMatrix = identityMatrix();     modelMatrix = translateMatrix( xPos, yPos, zPos ) * modelMatrix;      /* update modelview-projection matrix */     mvpMatrix = modelMatrix * (*projMatrix); } 
like image 31
Gianluca Ghettini Avatar answered Sep 24 '22 04:09

Gianluca Ghettini