Sunday 27 March 2016

Demo App with ModelView Matrix

GL_PROJECTION matrix is used to define the frustum. This frustum determines which objects or portions of objects will be clipped out. Also, it determines how the 3D scene is projected onto the screen. 
OpenGL provides 2 functions for GL_PROJECTION transformation. glFrustum() is to produce a perspective projection, and glOrtho() is to produce a orthographic (parallel) projection. Both functions require 6 parameters to specify 6 clipping planes; leftrightbottomtopnear and far planes. 8 vertices of the viewing frustum are shown in the following image.

OpenGL Perspective Viewing Frustum
The vertices of the far (back) plane can be simply calculated by the ratio of similar triangles, for example, the left of the far plane is;

OpenGL Orthographic Frustum
For orthographic projection, this ratio will be 1, so the leftrightbottomand top values of the far plane will be same as on the near plane.
You may also use gluPerspective() and gluOrtho2D() functions with less number of parameters. gluPerspective() requires only 4 parameters; vertical field of view (FOV), the aspect ratio of width to height and the distances to near and far clipping planes. The equivalent conversion from gluPerspective() to glFrustum() is described in the following code.

// This creates a symmetric frustum.
// It converts to 6 params (l, r, b, t, n, f) for glFrustum()
// from given 4 params (fovy, aspect, near, far)
void makeFrustum(double fovY, double aspectRatio, double front, double back)
{
    const double DEG2RAD = 3.14159265 / 180;

    double tangent = tan(fovY/2 * DEG2RAD);   // tangent of half fovY
    double height = front * tangent;          // half height of near plane
    double width = height * aspectRatio;      // half width of near plane

    // params: left, right, bottom, top, near, far
    glFrustum(-width, width, -height, height, front, back);
}


An example of an asymmetric frustum
However, you have to use glFrustum() directly if you need to create a non-symmetrical viewing volume. For example, if you want to render a wide scene into 2 adjoining screens, you can break down the frustum into 2 asymmetric frustums (left and right). Then, render the scene with each frustum.

Texture Matrix (GL_TEXTURE)

Texture coordinates (strq) are multiplied by GL_TEXTURE matrix before any texture mapping. By default it is the identity, so texture will be mapped to objects exactly where you assigned the texture coordinates. By modifying GL_TEXTURE, you can slide, rotate, stretch, and shrink the texture.

// rotate texture around X-axis
glMatrixMode(GL_TEXTURE);
glRotatef(angle, 1, 0, 0);

Color Matrix (GL_COLOR)

The color components (rgba) are multiplied by GL_COLOR matrix. It can be used for color space conversion and color component swaping. GL_COLOR matrix is not commonly used and is requiredGL_ARB_imaging extension.

Other Matrix Routines

glPushMatrix() : 
push the current matrix into the current matrix stack.
glPopMatrix() : 
pop the current matrix from the current matrix stack.
glLoadIdentity() : 
set the current matrix to the identity matrix.
glLoadMatrix{fd}(m) : 
replace the current matrix with the matrix m.
glLoadTransposeMatrix{fd}(m) : 
replace the current matrix with the row-major ordered matrix m.
glMultMatrix{fd}(m) : 
multiply the current matrix by the matrix m, and update the result to the current matrix.
glMultTransposeMatrix{fd}(m) : 
multiply the current matrix by the row-major ordered matrix m, and update the result to the current matrix.
glGetFloatv(GL_MODELVIEW_MATRIX, m) : 
return 16 values of GL_MODELVIEW matrix to m.

Demo:

Source Code: Download Here