Projection matrix gives me a weird look of teapot

81 Views Asked by At

I am testing projection matrix with Ortho() function and Perspective() function, and view matrix with LookAt() function provided by my instructor. After making matrices, I passed them into the shader. I am testing all of these with glut provided wire models like glutWireTeapot(), glutWireCube(), or glutWireSphere(). However, even though with proper arguments I think, the application shows me weird looks.

void keyboard(unsigned char key, int x, int y)
{
    // ToDo
    if(key == 'p') {
        isPerspective = true;
    }
    else if (key == 'o') {
        isPerspective = false;
    }
    else if(key == 'm') {
        currentobject = (currentobject + 1) % numObjects;
    }

    glutPostRedisplay();
}

This is my keyboard callback (to change projection mode and the 3d model).

void renderScene(void) 
{
    // ToDo
    glUseProgram(p);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    viewMatrix = LookAt(vec4(0, 0, 5, 1), vec4(0.0, 0.0, 0.0, 1), vec4(0.0, 1.0, 0.0, 0.0));

    if (!isPerspective) {
        projMatrix = Ortho(-1.0, 1.0, -1.0, 1.0, -1, 10);
    }
    else {
        projMatrix = Perspective(45, 1.0, -2, 10);
    }

    glUniformMatrix4fv(glGetUniformLocation(p, "Proj"), 1, GL_FALSE, projMatrix);
    glUniformMatrix4fv(glGetUniformLocation(p, "Mv"), 1, GL_FALSE, viewMatrix);

    // x-axis (Red)
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(1.0, 0.0, 0.0);
    glEnd();

    // y-axis (Green)
    glColor3f(0.0, 1.0, 0.0);
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 1.0, 0.0);
    glEnd();

    // z-axis (Blue)
    glColor3f(0.0, 0.0, 1.0);
    glBegin(GL_LINES);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 1.0);
    glEnd();

    glColor3f(1, 0, 0);

    switch (currentobject) {
    case 0:
        glutWireTeapot(0.5);
        break;
    case 1:
        glutWireCube(0.5);
        break;
    case 2:
        glutWireSphere(0.5, 20, 20);
        break;
    }

    glutSwapBuffers();
    glUseProgram(0);
}

And this is my display callback. In this case, both orthogonal and perspective projection give me weird looks.

perspective projection:

perspective projection

orthogonal projection:

orthogonal projection

void init()
{
    // Create shader program
    p = createGLSLProgram("../vshader.vert", NULL, "../fshader.frag");

    glEnable(GL_DEPTH_TEST);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

This is my init function.

GLuint createGLSLProgram(char *vs, char *gs, char *fs) 
{
    GLuint v, g, f, p;
    
    if( !vs && !gs && !fs ) return 0;
        
    p = glCreateProgram();
    
    if( vs ) 
    {
        v = loadShader( GL_VERTEX_SHADER, vs );
        glAttachShader(p,v);
    }
    if( gs )
    {
        g = loadShader( GL_GEOMETRY_SHADER_EXT, gs );
        glAttachShader(p,g);
    }
    if( fs )
    {
        f = loadShader( GL_FRAGMENT_SHADER, fs );
        glAttachShader(p,f);
    }

    glLinkProgram(p);

    // validating program
    GLint status;
    glGetProgramiv(p, GL_LINK_STATUS, &status);
    if(status == GL_FALSE)
    {
        GLint sizeLog;
        glGetProgramiv(p, GL_INFO_LOG_LENGTH, &sizeLog);
        char *log = new char[sizeLog + 1];
        glGetProgramInfoLog(p, sizeLog, NULL, log);
        std::cout << "Program Link Error: " << log << std::endl;
        delete [] log;
        assert( false );
    }
    
    glValidateProgram(p);
    glGetProgramiv(p, GL_VALIDATE_STATUS, &status);

    if (status == GL_FALSE)
    {
        std::cerr << "Error validating program: "<< p << std::endl;
        assert( false );
    }

    // validation passed.. therefore, we will use this program
    glUseProgram(p);

    return p;
}

This is createGLSLProgram function called in init()


int main(int argc, char **argv) {

    // init GLUT and create Window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(600,600);
    glutCreateWindow("COSE436 - Assignment 1");

    // register callbacks
    glutDisplayFunc(renderScene);
    // glutIdleFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutKeyboardFunc(keyboard);
    glutIdleFunc(idle);


    glewInit();
    if (glewIsSupported("GL_VERSION_3_3"))
        printf("Ready for OpenGL 3.3\n");
    else {
        printf("OpenGL 3.3 is not supported\n");
        exit(1);
    }

    init();

    // enter GLUT event processing cycle
    glutMainLoop();

    return 1;
}

This is my main function.

void idle()
{
    glutPostRedisplay();
}

This is my idle function.

#version 140
#extension GL_ARB_compatibility: enable

out vec4 color;

uniform mat4 Mv;  // Model-view matrix
uniform mat4 Proj; // Projection matrix

void main() 
{
    // Combine model-view and projection matrices
    gl_Position =  Proj * Mv * gl_Vertex; // vertices -> Mv -> Proj
    color = gl_Color;
}
#version 140
#extension GL_ARB_compatibility: enable

in  vec4 color;
out vec4 fColor;

void main() 
{ 
    fColor = color;
} 

This is my vshader.vert and fshader.frag respectively (which are referenced by p)

inline
mat4 LookAt( const vec4& eye, const vec4& at, const vec4& up )
{
    vec4 n = normalize(eye - at);
    vec4 u = vec4(normalize(cross(up,n)), 0.0);
    vec4 v = vec4(normalize(cross(n,u)), 0.0);
    vec4 t = vec4(0.0, 0.0, 0.0, 1.0);
    mat4 c = mat4(u, v, n, t);
    return c * Translate( -eye );
}

inline
mat4 Ortho( const GLfloat left, const GLfloat right,
        const GLfloat bottom, const GLfloat top,
        const GLfloat zNear, const GLfloat zFar )
{
    mat4 c;
    c[0][0] = 2.0/(right - left);
    c[1][1] = 2.0/(top - bottom);
    c[2][2] = 2.0/(zNear - zFar);
    c[3][3] = 1.0;
    c[0][3] = -(right + left)/(right - left);
    c[1][3] = -(top + bottom)/(top - bottom);
    c[2][3] = -(zFar + zNear)/(zFar - zNear);
    return c;
}

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

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

This is the provided functions.

I tried changing the values of arguments in LookAt(), Perspective(), and Ortho(). Then orthogonal projection sometimes looks ok but perspective projection never shows me a good result. Also, I tried changing the production order specified in vshader.vert into gl_Vertex * Mv * Proj or gl_Vertex * Proj * Mv or Mv * Proj * gl_vertex.

0

There are 0 best solutions below