0
votes

I have a program that simply draws a cube. When applying transformation such as rotation scaling etc the program works. When I attempt to apply any perspective matrix such as perspective, frustum, or ortho the cube becomes very distorted in undefined ways. What I am getting confused about is why the program works fine when using the other transformations, but breaks when applying any sort of perspective view.

Additionally, when I change the GL_TRUE parameter to GL_FALSE in glUniformMatrix4fv the cube stops moving around the screen, but still has strange distortion. Here is the display function. Just applying perspective gives that same distortion.

void display()
{
    vec4 e2 = { 0.0, 0.0, 1.0, 0.0};
    vec4 at = { 0.0, 0.0, 0.0, 0.0 };
    vec4 up = { 0.0, 1.0, 0.0, 0.0 }; 

    mat4 rx = RotateX(theta);
    mat4 ry = RotateY(theta);
    mat4 ps = Perspective(zoom*45.0, aspect, 0.5, 10.0);
    mat4 rxry = multiplymat4(rx, ry);

    mat4 mv = LookAt(e2, at, up); 
    glUniformMatrix4fv( ModelView, 1, GL_TRUE, &mv.m[0][0] );

    mat4 p = multiplymat4(rxry,ps);
    glUniformMatrix4fv(projection, 1, GL_TRUE, &p.m[0][0]);
} 

I do not believe it is in my perspective function since ortho and frustum does the same thing, but the perspective code is below.

mat4 Perspective(float fovy, float aspect, float zNear, float zFar)
{
    float top = tan(fovy*DegreesToRadians/2) * zNear;
    float right = top * aspect;

    mat4 c = ZERO_MATRIX;
    c.m[0][0] = zNear/right;
    c.m[1][1] = zNear/top;
    c.m[2][2] = -(zFar + zNear)/(zFar - zNear);
    c.m[2][3] = -2.0*zFar*zNear/(zFar - zNear);
    c.m[3][2] = -1.0;
    c.m[3][3] = 0.0;
    return c;
}

And the vertex shader

#version 120

attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 color;

uniform mat4 ModelView;
uniform mat4 projection;

void
main()
{
    gl_Position = projection*ModelView*vPosition/vPosition.w;
    color = vec4( vColor);
}
2
You're never using your perspective matrix. You assign the result of Perspective() to the local variable ps in the display() function, and the variable is not used anywhere in the rest of the function.Reto Koradi
Typo when copying the code. Fixed now.TJGreen

2 Answers

0
votes

I can spot two places where it seems me it is wrong.

1) you are multiplying your perspective matrix with rotational matrix. Why? if you want to do camera movements, they must be done in lookAt matrix. So, I suggest this simple code:

mat4 ps = Perspective(zoom*45.0, aspect, 0.5, 10.0);
glUniformMatrix4fv(projection, 1, GL_TRUE, &ps.m[0][0]);

2) Perspective divide is done automatically by GPU, in this way, it seems me you vertex shader is wrong too:

gl_Position = projection*ModelView*vPosition;
color = vec4( vColor);
0
votes

Matrix multiplication order matters, and from what I see your p matrix should be

mat4 p = multiplymat4(ps, rxry);

Though logically rotation belongs to the view matrix.

Also, / vPosition.w likely does nothing in the shader, since w equals 1.0 unless you actually supplied 4-dimensional position data. Nor do you need a perspective divide in your vertex shader.