投影和视图矩阵

时间:2013-05-15 18:07:23

标签: c++ opengl matrix

修改

我已经确定我的矩阵不是问题,而是glGetUniformLocation找不到请求的变量

编辑2

我已修复了上述错误,单位矩阵现在可以正常工作。所以我想现在错误会回到我的矩阵。


我在进行投影和查看矩阵时遇到了一些问题。我已经针对几个例子检查了它们,并且不知道我哪里出错了。除非我禁用着色器,否则我在屏幕上看不到任何内容。

我像这样计算模型矩阵:

float aspect = (float)width / std::max(1.0f, (float)height);
float top = tan(Maths::toRadian(FOV * 0.5f)) * near;
float bottom = -top;
float right = top * aspect;
float left = -right;

projMatrix.reset();
projMatrix(0, 0) = (2.0f * near) / (right - left);
projMatrix(1, 1) = (2.0f * near) / (top - bottom);
projMatrix(2, 2) = -(far + near) / (far - near);
projMatrix(2, 3) = -1.0f;
projMatrix(3, 2) = (-2.0f * far * near) / (far - near);
projMatrix(3, 3) = 0.0f;

我像这样计算视图矩阵:

Camera::Camera(const Maths::Vector3& pos)
    : position(pos), target(0.0f, 0.0f, 0.0f), up(0.0f, 1.0f, 0.0f) {
    target.normalize();
    up.normalize();
}

Maths::Matrix4 Camera::getMatrix() const {
    Maths::Matrix4 mat;
    Maths::Vector3 z = position - target;
    Maths::Vector3 x = Maths::crossProduct(up, z);
    Maths::Vector3 y = Maths::crossProduct(z, x);

    z.normalize();
    x.normalize();

    mat(0, 0) = x.x; mat(0, 1) = y.x; mat(0, 2) = y.z;
    mat(1, 0) = x.y; mat(1, 1) = y.y; mat(1, 2) = y.z;
    mat(2, 0) = x.z; mat(1, 2) = y.z; mat(2, 2) = y.z;

    mat(3, 0) = -Maths::dotProduct(x, position);
    mat(3, 1) = -Maths::dotProduct(y, position);
    mat(3, 2) = -Maths::dotProduct(z, position);

    return mat;
}

然后我最终将它们传递到着色器中:

glGetUniformLocation(viewMatrix, "view");
glGetUniformLocation(projMatrix, "proj");

glUniformMatrix4fv(viewMatrix, 1, GL_TRUE, view.asArray());
glUniformMatrix4fv(projMatrix, 1, GL_TRUE, proj.asArray());

最后是我的着色器:

顶点:

#version 330

layout (location = 0) in vec3 position;

uniform mat4 view;
uniform mat4 proj;

void main()
{
    gl_Position = proj * view * vec4(position, 1.0);
};

片段:

#version 330

out vec4 gl_FragColor;

void main()
{
    gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
} 

这里涵盖所有基础是我计算点积和叉积的方法:

float dotProduct(const Vector3& a, const Vector3& b) {
    return a.x * b.x + a.y * b.y + a.z * b.z;
}

Vector3 crossProduct(const Vector3& a, const Vector3& b) {
    return Vector3(a.y * b.z - a.z * b.y,
                   a.z * b.x - a.x * b.z,
                   a.x * b.y - a.y * b.z);
}

2 个答案:

答案 0 :(得分:2)

编辑:

查看您的来源我发现了一些内容,您在禁用attrib数组后调用了voxel.draw()函数,这意味着在调用函数时没有任何内容发送到着色器。如果我没有弄错的话,应该是这样的:

void Engine::draw() {
    light.enable();

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, triangle);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    //glDisableVertexAttribArray(0); disable attrib array before calling draw?

    voxel.draw();
    glDisableVertexAttribArray(0); //NOW disable it, so your draw function works!
}

另一个注意事项:我知道你不想使用glm,但我 HIGHLY 建议使用它。以下是使用glm的整个代码块:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
//projection matrix
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
//camera matrix
glm::mat4 View = glm::lookAt(
    glm::vec3(4,3,3),   //camera is at (4,3,3) in world
    glm::vec3(0,0,0),   //look at origin
    glm::vec3(0,1,0)    //head up
);

答案 1 :(得分:2)

宾果!我的观点矩阵错了。请注意我是如何将最后一列设置为y.z ...

这是我修改过的视图矩阵:

Maths::Matrix4 mat;
Maths::Vector3 z = Maths::normalize(target - position);
Maths::Vector3 x = Maths::normalize(Maths::crossProduct(z, up));
Maths::Vector3 y = Maths::crossProduct(x, z);

mat(0, 0) = x.x; mat(0, 1) = y.x; mat(0, 2) = -z.x;
mat(1, 0) = x.y; mat(1, 1) = y.y; mat(1, 2) = -z.y;
mat(2, 0) = x.z; mat(1, 2) = y.z; mat(2, 2) = -z.z;

mat(3, 0) = -Maths::dotProduct(x, position);
mat(3, 1) = -Maths::dotProduct(y, position);
mat(3, 2) = Maths::dotProduct(z, position);