简体   繁体   中英

Projection and View Matrix

Edit

I have determined it's not a problem with my matrices, rather glGetUniformLocation not finding the requested variable

Edit 2

I've fixed the above mistake and unit matrices now work. So the error goes back to my matrices now I think.


I am having some issues getting my projection and view matrices correct. I have checked them against several examples and don't know where I am going wrong. I see nothing on screen unless I disable the shader.

I calculate the model matrix like so:

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;

I calculate the view matrix like so:

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

Then I pass them into the shader eventually like so:

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

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

and finally my shader:

Vertex:

#version 330

layout (location = 0) in vec3 position;

uniform mat4 view;
uniform mat4 proj;

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

Fragment:

#version 330

out vec4 gl_FragColor;

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

And to cover all bases here are my methods for calculating the dot product and the cross product:

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

Edit:

Looking at your source I noticed something, you're voxel.draw() function is called after you disable your attrib array, meaning nothing is being sent to your shader when you call the function. If i'm not mistaken, it should be this:

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!
}

Another note: I know you don't want to use glm, but i HIGHLY recommend using it. Here is your entire chunk of code using 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
);

Bingo! My view matrix was wrong. Notice how I was setting the last column all to yz ...

Here's my amended view matrix:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM