struct v4
{
f32 x, y, z, w;
};
void ProjectionTestUsingFOV_InMeters(f32 windowWidth, f32 windowHeight)
{
//These are assumed to be in camera space, with camera looking down positive z axis (left handed coordinate system)
v4 squareVerts_meters[6] =
{
v4{2.0f, 1.0f, 3.0f, 1.0f},
v4{2.4f, 1.0f, 2.0f, 1.0f},
v4{4.0f, 1.0f, 3.0f, 1.0f},
v4{2.0f, -0.5f, 3.0f, 1.0f},
v4{2.4f, -0.5f, 2.0f, 1.0f},
v4{4.0f, -0.5f, 3.0f, 1.0f}
};
//Where we will store clip space coordinates
v4 squareVerts_openGLClipSpace[6];
{//Projection transform which will convert x, y and z to clip space as well as store original z value in clip space w
f32 fov = glm::radians(90.0f);
f32 aspectRatio = 16.0f/9.0f;
f32 tanHalfFov = TanR(fov / 2.0f);
f32 xScale = 1.0f / (tanHalfFov * aspectRatio);
f32 yScale = 1.0f / tanHalfFov;
f32 farClip = 100.0f;
f32 nearClip = 1.0f;
//These equations were calculated assuming camera z values are positive
f32 a = (-farClip - nearClip) / (nearClip - farClip);
f32 b = (2.0f * farClip * nearClip) / (nearClip - farClip);
for(i32 vertI{}; vertI < 6; ++vertI)
{
squareVerts_openGLClipSpace[vertI].x = squareVerts_meters[vertI].x * xScale;
squareVerts_openGLClipSpace[vertI].y = squareVerts_meters[vertI].y * yScale;
squareVerts_openGLClipSpace[vertI].z = squareVerts_meters[vertI].z * a + b;
squareVerts_openGLClipSpace[vertI].w = squareVerts_meters[vertI].z;
};
};
//Send down newly projected verts to openGL
GLfloat verts[] =
{
squareVerts_openGLClipSpace[0].x, squareVerts_openGLClipSpace[0].y, squareVerts_openGLClipSpace[0].z, squareVerts_openGLClipSpace[0].w,
1.0f, 0.0f, 0.0f,
squareVerts_openGLClipSpace[1].x, squareVerts_openGLClipSpace[1].y, squareVerts_openGLClipSpace[1].z, squareVerts_openGLClipSpace[1].w,
0.0f, 1.0f, 0.0f,
squareVerts_openGLClipSpace[2].x, squareVerts_openGLClipSpace[2].y, squareVerts_openGLClipSpace[2].z, squareVerts_openGLClipSpace[2].w,
1.0f, 0.0f, 0.0f,
squareVerts_openGLClipSpace[3].x, squareVerts_openGLClipSpace[3].y, squareVerts_openGLClipSpace[3].z, squareVerts_openGLClipSpace[3].w,
1.0f, 0.0f, 0.0f,
squareVerts_openGLClipSpace[4].x, squareVerts_openGLClipSpace[4].y, squareVerts_openGLClipSpace[4].z, squareVerts_openGLClipSpace[4].w,
0.0f, 1.0f, 0.0f,
squareVerts_openGLClipSpace[5].x, squareVerts_openGLClipSpace[5].y, squareVerts_openGLClipSpace[5].z, squareVerts_openGLClipSpace[5].w,
1.0f, 0.0f, 0.0f
};
GLuint bufferID;
glGenBuffers(1, &bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, (char*)(sizeof(GLfloat)*3));
GLushort indicies[] =
{
0, 1, 3, 3, 1, 4, 1, 2, 4, 2, 5, 4
};
GLuint indexBufferID;
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
glDisable(GL_TEXTURE_2D);
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
glEnable(GL_TEXTURE_2D);
};