0
votes

I've been following the open.gl tutorials without using the the GLM library because reasons (stubbornness and C). I can't get the view and projection matrices to work properly.

Here's the relevant vertex shader code,

#version 150 core

in vec3 size;
in vec3 color;
in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

uniform vec3 pos;
uniform float angle;

uniform vec3 camPos;
uniform vec3 camTarget;

const float fov=90, ratio=4.0/3.0, near=1.0, far=10.0;

mat4 projection ()
{
    float t = tan(radians(fov)),
          l = ratio * t;
    return mat4(
        vec4(near/l, 0.0,    0.0,                    0.0),
        vec4(0.0,    near/t, 0.0,                    0.0),
        vec4(0.0,    0.0,    -(far+near)/(far-near), -(2*far*near)/(far-near)),
        vec4(0.0,    0.0,    -1.0,                   0.0)
    );
}

mat4 rotZ(float theta)
{
    return mat4(
        vec4(cos(theta), -sin(theta),  0.0, 0.0),
        vec4(sin(theta),  cos(theta),  0.0, 0.0),
        vec4(0.0,         0.0,         1.0, 0.0),
        vec4(0.0,         0.0,         0.0, 1.0)
    );
}

mat4 translate(vec3 translation)
{
    return mat4(
        vec4(1.0,            0.0,            0.0,            0.0),
        vec4(0.0,            1.0,            0.0,            0.0),
        vec4(0.0,            0.0,            1.0,            0.0),
        vec4(translation.x, translation.y, translation.z, 1.0)
    );
}

mat4 lookAtRH(vec3 eye, vec3 target)
{
    vec3 zaxis = normalize(target - eye);    // The "forward" vector.
    vec3 xaxis = normalize(cross(vec3(0.0,0.0,1.0), zaxis));// The "right" vector.
    vec3 yaxis = normalize(cross(zaxis, xaxis));     // The "up" vector.

    mat4 axis = {
        vec4(xaxis.x, yaxis.x, zaxis.x, 0),
        vec4(xaxis.y, yaxis.y, zaxis.y, 0),
        vec4(xaxis.z, yaxis.z, zaxis.z, 0),
        vec4(dot(xaxis,-eye),       dot(yaxis,-eye),       dot(zaxis,-eye),     1)
    };

    return axis;
}

void main()
{
    Color = color;
    Texcoord = texcoord;

    mat4 model = translate(pos) * rotZ(angle);
    mat4 view = lookAtRH(camPos, camTarget);

    gl_Position = projection() * view * model * vec4(size, 1.0);
}

From tweaking things around it seems as if the view matrix is correct, but the projection matrix is causing the dodgyness.

2

2 Answers

0
votes

First I must remark that it is a very bad idea to do this directly in the shaders.

However, if you really want to, you can do this. You should be aware that the GLSL matrix constructors work with column vectors. Your projection matrix is thuse specified transposed (however, your translation matrix is correct).

-1
votes

EDIT: If you want pure C, here is nice lib for math (+ you can check the code :) ) https://github.com/datenwolf/linmath.h

Never do something like that :) Creating matrices in shader is very bad idea...

Vertex shader is executed for each vertex. So if you pass to shader thousand vertices you calculate new matrices thousand times. I think there's nothing more to explain :)

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
... // somewhere
glm::mat4 projection = glm::perspective(45.0f, float(window_width) / window_height, 0.1f, 100.0f);
glm::mat4 world(1.0f); // world/model matrix
glm::mat4 view(1.0f);  // view/camera matrix
glm::mat4 mvp = projection * view * model;
... // inside the main loop
glUniformMatrix4fv(glGetUniformLocation(program, "mvpMatrix"), 1, GL_FALSE, &mvp[0][0]);
draw_mesh();

It's really cool and optimised :)