无法使视图(lookat)和投影(透视)矩阵正常工作

时间:2013-12-25 21:28:58

标签: c opengl math glsl vertex-shader

我一直在关注open.gl教程而不使用GLM库因为原因(固执和C)。 我无法使视图和投影矩阵正常工作。

这是相关的顶点着色器代码,

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

从调整周围的东西看起来好像视图矩阵是正确的,但投影矩阵导致了狡猾。

2 个答案:

答案 0 :(得分:0)

首先,我必须指出,在着色器中直接执行此操作是一个非常糟糕的主意。

但是,如果你真的想,你可以这样做。您应该知道GLSL矩阵构造函数使用列向量。您的投影矩阵是指定的转置(但是,您的转换矩阵是正确的)。

答案 1 :(得分:-1)

编辑:如果你想要纯C,这里有很好的数学库(+你可以检查代码:))https://github.com/datenwolf/linmath.h

永远不要做那样的事情:)在着色器中创建矩阵是非常糟糕的想法......

为每个顶点执行顶点着色器。因此,如果您传递到着色器千个顶点,则计算新矩阵数千次。我想没有什么可以解释的了:))

#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();

真的很酷并且优化了:)