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:

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.