Model View Projection Matrix

The Model matrix

This model, just as our beloved red triangle, is defined by a set of vertices. The X,Y,Z coordinates of these vertices are defined relative to the object’s center : that is, if a vertex is at (0,0,0), it is at the center of the object.

We can sum this up with the following diagram :

The View matrix

We went from World Space (all vertices defined relatively to the center of the world, as we made so in the previous section) to Camera Space (all vertices defined relatively to the camera).

Here’s the compulsory diagram :

The Projection matrix

We’re now in Camera Space. This means that after all theses transformations, a vertex that happens to have x==0 and y==0 should be rendered at the center of the screen.

And the final diagram :

Parallelepiped

p

void Parallelepiped::init()
{
glm::vec3 pu = p + u;
glm::vec3 pv = p + v;
glm::vec3 pw = p + w;
glm::vec3 puv = p + u + v;
glm::vec3 pvw = p + v + w;
glm::vec3 puw = p + u + w;
glm::vec3 puvw = p + u + v + w;

// Front face
vbo.addData(&p[0], sizeof(glm::vec3));
vbo.addData(&pu[0], sizeof(glm::vec3));
vbo.addData(&puw[0], sizeof(glm::vec3));
vbo.addData(&p[0], sizeof(glm::vec3));
vbo.addData(&puw[0], sizeof(glm::vec3));
vbo.addData(&pw[0], sizeof(glm::vec3));

// Back face
vbo.addData(&puv[0], sizeof(glm::vec3));
vbo.addData(&pv[0], sizeof(glm::vec3));
vbo.addData(&pvw[0], sizeof(glm::vec3));
vbo.addData(&puv[0], sizeof(glm::vec3));
vbo.addData(&pvw[0], sizeof(glm::vec3));
vbo.addData(&puvw[0], sizeof(glm::vec3));

// Left face
vbo.addData(&pv[0], sizeof(glm::vec3));
vbo.addData(&p[0], sizeof(glm::vec3));
vbo.addData(&pw[0], sizeof(glm::vec3));
vbo.addData(&pv[0], sizeof(glm::vec3));
vbo.addData(&pw[0], sizeof(glm::vec3));
vbo.addData(&pvw[0], sizeof(glm::vec3));

// Right face
vbo.addData(&pu[0], sizeof(glm::vec3));
vbo.addData(&puv[0], sizeof(glm::vec3));
vbo.addData(&puvw[0], sizeof(glm::vec3));
vbo.addData(&pu[0], sizeof(glm::vec3));
vbo.addData(&puvw[0], sizeof(glm::vec3));
vbo.addData(&puw[0], sizeof(glm::vec3));

// Top face
vbo.addData(&pw[0], sizeof(glm::vec3));
vbo.addData(&puw[0], sizeof(glm::vec3));
vbo.addData(&puvw[0], sizeof(glm::vec3));
vbo.addData(&pw[0], sizeof(glm::vec3));
vbo.addData(&puvw[0], sizeof(glm::vec3));
vbo.addData(&pvw[0], sizeof(glm::vec3));

// Bottom face
vbo.addData(&puv[0], sizeof(glm::vec3));
vbo.addData(&pu[0], sizeof(glm::vec3));
vbo.addData(&p[0], sizeof(glm::vec3));
vbo.addData(&puv[0], sizeof(glm::vec3));
vbo.addData(&p[0], sizeof(glm::vec3));
vbo.addData(&pv[0], sizeof(glm::vec3));

numVertices = 36;

// create VBO
vbo.createVBO();
vbo.bindVBO();
vbo.uploadDataToGPU(GL_STATIC_DRAW);

// create a VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

isLoaded = true;
}

Quad

q

void Quad::init()
{
glm::vec3 left = glm::cross(n, u);
glm::vec3 uppercenter = (u * height/2.0f) + p;
glm::vec3 tl = uppercenter + (left * width/2.0f);
glm::vec3 tr = uppercenter – (left * width/2.0f);
glm::vec3 bl = tl – (u * height);
glm::vec3 br = tr – (u * height);

// face 1
vbo.addData(&bl[0], sizeof(glm::vec3)); // vertex position
vbo.addData(&color[0], sizeof(glm::vec3)); // vertex color
vbo.addData(&br[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));
vbo.addData(&tr[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));

// face 2
vbo.addData(&bl[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));
vbo.addData(&tr[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));
vbo.addData(&tl[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));

numVertices = 6;

// VAO & VBOs
vbo.createVBO();
vbo.bindVBO();
vbo.uploadDataToGPU(GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

int iDataStride = 2 * sizeof(glm::vec3); // vertex & color only
int iDataOffset = 0;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec3);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);

isLoaded = true;
}

Triangle

void Triangle::init()
{
 glm::vec3 t1 = p + v1;
glm::vec3 t2 = p + v2;
glm::vec3 t3 = p + v3;

// face 1
vbo.addData(&t1[0], sizeof(glm::vec3)); // vertex position
vbo.addData(&color[0], sizeof(glm::vec3)); // vertex color
vbo.addData(&t2[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));
vbo.addData(&t3[0], sizeof(glm::vec3));
vbo.addData(&color[0], sizeof(glm::vec3));

numVertices = 3;

// VAO & VBOs
vbo.createVBO();
vbo.bindVBO();
vbo.uploadDataToGPU(GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

int iDataStride = 2 * sizeof(glm::vec3); // vertex & color only
int iDataOffset = 0;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec3);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);

isLoaded = true;
}