轉自:http://www.c-jump.com/bcc/common/Talk3/Math/GLM/GLM.html
Course list http://www.c-jump.com/bcc/
OpenGL Mathematics (GLM)
- OpenGL Mathematics (GLM)
- Vector and Matrix Constructors
- Matrix transformation
- Identity Matrix
- Matrix transformation functions
- Other Matrix functions
- glm::value_ptr
- glm::value_ptr example
- Matrix columns
- Scaling matrix example
- glm::translate
- glm::rotate
- glm::scale
- Matrix multiplication is not commutative
- Scale*Transform vs. Transform*Scale
1. OpenGL Mathematics (GLM)
-
OpenGL Mathematics (GLM) is a C++ mathematics library based on the OpenGL Shading Language (GLSL) specification.
-
GLM emulates GLSL's approach to vector/matrix operations whenever possible.
-
To use GLM, include glm/glm.hpp. Example from GLM manual:
#include <glm/glm.hpp> int foo() { glm::vec4 Position = glm::vec4( glm::vec3( 0.0 ), 1.0 ); glm::mat4 Model = glm::mat4( 1.0 ); Model[3] = glm::vec4( 1.0, 1.0, 0.0, 1.0 ); glm::vec4 Transformed = Model * Position; return 0; }
2. Vector and Matrix Constructors
-
From GLSL specification 5.4.2:
-
If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the constructed vector to that scalar's value:
glm::vec4 Position = glm::vec4( glm::vec3( 0.0 ), 1.0 );
-
If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix's diagonal, with the remaining components initialized to 0.0f
glm::mat4 Model = glm::mat4( 1.0 );
-
3. Matrix transformation
-
Matrix transformation is an extension of GLM. Example from GLM manual:
#include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> int foo() { glm::vec4 Position = glm::vec4( glm::vec3( 0.0f ), 1.0f ); glm::mat4 Model = glm::translate( glm::mat4( 1.0f ), glm::vec3( 1.0f ) ); glm::vec4 Transformed = Model * Position; return 0; }
4. Identity Matrix
-
glm::mat4 constructor that takes only a single value constructs a diagonal matrix:
glm::mat4 m4( 1.0f ); // construct identity matrix
-
The matrix has all zeros except for 1.0f set along the diagonal from the upper-left to the lower-right.
-
The default constructor glm::mat4() creates diagonal matrix with 1.0f diagonal, that is, the identity matrix:
glm::mat4 m4; // construct identity matrix
5. Matrix transformation functions
-
glm::mat4 glm::rotate( glm::mat4 const& m, float angle, glm::vec3 const& axis ); glm::mat4 glm::scale( glm::mat4 const& m, glm::vec3 const& factors ); glm::mat4 glm::translate( glm::mat4 const& m, glm::vec3 const& translation );
6. Other Matrix functions
-
See official GLM documentation for other functions:
glm::frustum() glm::ortho() glm::lookAt() glm::perspective() glm::project(
7. glm::value_ptr
-
glm::value_ptr takes any of the core template types. It returns a pointer to the memory layout of the object. For example, given
glm::mat4 m4( 1.0f ); // construct identity matrix
expressions
glm::value_ptr( m4 ) &m4[0][0]
are equivalent.
-
value_ptr() returns a direct pointer to the matrix data in column-major order, making it useful for uploading data to OpenGL.
8. glm::value_ptr example
-
Uploading data to OpenGL example:
#include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> void f () { glm::vec3 aVector( 3 ); glm::mat4 someMatrix( 1.0f ); glUniform3fv( uniformLoc, 1, glm::value_ptr( aVector ) ); glUniformMatrix4fv( uniformMatrixLoc, 1, GL_FALSE, glm::value_ptr( someMatrix ) ); }
9. Matrix columns
-
Each row and column in glm::mat4 is zero-based:
glm::mat4 m4( 1.0f ); // construct identity matrix m4[ 0 ] // column zero m4[ 0 ].x // same as m4[ 0 ][ 0 ] m4[ 0 ].y // same as m4[ 0 ][ 1 ] m4[ 0 ].z // same as m4[ 0 ][ 2 ] m4[ 0 ].w // same as m4[ 0 ][ 3 ]
-
Each column of matrix glm::mat4 is a vec4.
-
To set the entire column, e.g. for translation,
glm::mat4 m4( 1.0f ); // construct identity matrix m4[ 3 ] = glm::vec4( vec3( x, y, z ), 1.0f );
Related: see Chapter 6. Objects in Motion, Translation article from Learning Modern 3D Graphics Programming tutorial
10. Scaling matrix example
-
Example of setting matrix m4 for scaling:
glm::vec3 scale( sx, sy, sx ); glm::mat4 m4( 1.0f ); // construct identity matrix m4[0].x = scale.x; m4[1].y = scale.y; m4[2].z = scale.z;
11. glm::translate
-
When using glm::translate( X, vec3 ), you are multiplying
X * glm::translate( Identity, vec3 )
-
This means translate first, then X
12. glm::rotate
-
When using glm::rotate( X, vec3 ), you are multiplying
X * glm::rotate( Identity, vec3 )
-
This means rotate first, then X
13. glm::scale
-
When using glm::scale( X, vec3 ), you are multiplying
X * glm::scale( Identity, vec3 )
-
For example,
glm::mat4 transMatrix = glm::translate( glm::mat4( 1.0f ), glm::vec3( 0.0f, -0.5f, 0.0f ) ); planeModel->mM = glm::scale( // Scale first transMatrix, // Translate second glm::vec3( 100.0f, 100.0f, 100.0f ) );
-
Far all GLM transformation API, see GLM_GTC_matrix_transform at glm.g-truc.net
14. Matrix multiplication is not commutative
-
So the conventional Model-View-Projection should be multiplied in reverse:
glm::mat4 MVP = Projection * View * Model;
-
This means that Model transformation happens first, then View, and Projection is last.
15. Scale*Transform vs. Transform*Scale
-
Those are not the same!
-
See Chapter 6. Objects in Motion article from Learning Modern 3D Graphics Programming tutorial for details,