I'm trying to troubleshoot a problem with my simple OpenGL test program, which I've written in C. I've written some math routines to do the matrix manipulation, but even after copying known working perspective functions, I cannot get anything to appear on screen.
The program is simply:
The only geometry is a simple cube centered around the origin, here is the render loop:
int renderer_draw_frame(float delta_time)
{
glClearColor(0.2f, 0.3f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(prog);
/* bind textures */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tile_tex);
glUniform1i(glGetUniformLocation(spo_prog(spo), "Tex1"), 0);
vec3f eye = { 0.0f, 0.0f, 3.0f };
vec3f target = { 0.0f, 0.0f, 0.0f };
vec3f up = { 0.0f, 1.0f, 0.0f };
mat4f model_mat = mat4f_translate(0.0f, 0.0f, 0.0f);
mat4f view_mat = look_at(eye, target, up);
proj_mat = mat4f_projection(45.0f, (float)win_width / (float)win_height, 0.1f, 100.0f);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, &model_mat.f[0]);
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view_mat.f[0]);
glUniformMatrix4fv(projLoc, 1, GL_FALSE, &proj_mat.f[0]);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
return 0;
}
mat4f and vec3f is just this:
typedef struct mat4f mat4f;
struct mat4f
{
float f[4 * 4];
};
typedef struct vec3f vec3f;
struct vec3f
{
float x;
float y;
float z;
};
The math routines in question:
#define M4(m,i,j) m.f[mat4f_idx(i,j)]
#define PI 3.14159265359f
mat4f mat4f_projection(float fov, float ratio, float near, float far)
{
float d2r = PI / 180.0f;
float ys = 1.0f / tanf(d2r * fov / 2.0f);
float xs = ys / ratio;
float nf = near - far;
mat4f r = { 0 };
M4(r, 0, 0) = xs;
M4(r, 1, 1) = ys;
M4(r, 2, 2) = (far + near) / nf;
M4(r, 2, 3) = -1.0f;
M4(r, 3, 2) = 2 * far * near / nf;
return r;
}
mat4f look_at(vec3f eye, vec3f center, vec3f up)
{
vec3f zaxis = vec3f_normalize(vec3f_subv(eye, center));
vec3f xaxis = vec3f_normalize(vec3f_crossp(vec3f_normalize(up), zaxis));
vec3f yaxis = vec3f_crossp(zaxis,xaxis);
mat4f trans = mat4f_id(1.0f, 1.0f, 1.0f, 1.0f);
M4(trans, 0, 3) = -eye.x;
M4(trans, 1, 3) = -eye.y;
M4(trans, 2, 3) = -eye.z;
mat4f rot = mat4f_id(1.0f, 1.0f, 1.0f, 1.0f);
M4(rot, 0, 0) = xaxis.x;
M4(rot, 0, 1) = xaxis.y;
M4(rot, 0, 2) = xaxis.z;
M4(rot, 1, 0) = yaxis.x;
M4(rot, 1, 1) = yaxis.y;
M4(rot, 1, 2) = yaxis.z;
M4(rot, 2, 0) = zaxis.x;
M4(rot, 2, 1) = zaxis.y;
M4(rot, 2, 2) = zaxis.z;
return mat4f_mul(rot, trans);
}
Finally, the simple vertex shader:
#version 330 core
layout (location = 0) in vec3 position; //attrib pos 0
layout (location = 1) in vec2 texCoord; //attrib pos 1
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoord = vec2(texCoord.x, 1.0f - texCoord.y);
}
Here is what I see:
If I change the shader as so:
void main()
{
gl_Position = view * model * vec4(position, 1.0f);
TexCoord = vec2(texCoord.x, 1.0f - texCoord.y);
}
I see:
Why does it completely disappear in projection view? I've tried changed the view look at parameter but I can't ever see anything through projection view. I've tried several different implementations, currently gluPerspective (the one above is pretty much that function copied).
I've been at this all night and I can't seem to get a grasp on what went wrong. Can someone gives me some pointers on where to go next?
mat4f_idx(i,j)
? \$\endgroup\$uint8_t mat4f_idx(uint8_t i, uint8_t j) { return (i * 4) + j; }
I found what could be causing it, -nan in the projection matrix output. I thought it was my math that was wrong this whole time, but it looks like an aspect ratio value of 0 caused by uninitialized width and height variables. \$\endgroup\$