GLM MATRIX (COLUMN-MAJOR ORDER)

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, 2.0f, 3.0f));
// (1.0, 0.0, 0.0, 1.0)
// (0.0, 1.0, 0.0, 2.0)
// (0.0, 0.0, 1.0, 3.0)
// (0.0, 0.0, 0.0, 1.0)

printf(“%f %f %f %f\n”, Model[0][0], Model[1][0], Model[2][0], Model[3][0]);
printf(“%f %f %f %f\n”, Model[0][1], Model[1][1], Model[2][1], Model[3][1]);
printf(“%f %f %f %f\n”, Model[0][2], Model[1][2], Model[2][2], Model[3][2]);
printf(“%f %f %f %f\n”, Model[0][3], Model[1][3], Model[2][3], Model[3][3]);

glm::vec4 Transformed = Model * Position; // P’ (1, 2, 3) = Model * P (0, 0, 0) (OpenGL uses Column-Major Order) RHS

return 0;
}

Affine Space

Affine Space (아핀공간) – 벡터공간에 점을 추가한 공간
http://mathworld.wolfram.com/AffineSpace.html

벡터와 벡터 간의 덧셈/뺄셈 -> 벡터 생성
스칼라와 벡터의 곱셈/나눗셈 -> 벡터 생성
벡터와 점의 덧셈/뺄셈 -> 점 생성
점과 점 간의 뺄셈 -> 벡터 생성
점과 점 간의 덧셈은 허용되지 않는다.
아핀공간에서 점의 덧셈은 각 점들 앞의 계수의 합이 1일 때에만 허용되고 이처럼 계수의 합이 1이 되는 경우를 Affine Sum(아핀합)이라 한다.

Homogeneous Coordinate (동차좌표) – 어떤 목적을 위해 한 차원의 좌표(n)을 추가한 좌표 (n+1)로 표현을 하는 것
http://mathworld.wolfram.com/HomogeneousCoordinates.html

4차원 동차 좌표 (x,y,z,w) => 3차원 좌표 (x/w , y/w , z/w)
만약 w == 1, (x,y,z,1)은 position이다.
만약 w == 0, (x,y,z,0)은 vector이다.

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;
}