glMatrixMode(GL_PROJECTION) ?

Could anyone give me a clear explanation why this occurs. In my code

#include <iostream>
#include <GL/glut.h>

int Window_Width(500), Window_Height(500);
double X_mouse, Y_mouse;

// Glut functions
void setup();
void Mouse_Movement(int x, int y);
void Display();
void glutIdle();
void Reshape(int, int);

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
	glutInitWindowSize(Window_Width, Window_Height);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Camera Test");
	setup();
	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutIdleFunc(glutIdle);
	glutPassiveMotionFunc(Mouse_Movement);

	glutMainLoop();
	return 0;
}

void setup()
{
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glEnable(GL_DEPTH_TEST);
	
}

void Mouse_Movement(int x, int y)
{
	// X & Y coordinates in Viewport space (2D)
	X_mouse = (double)x;
	Y_mouse = (double)y;
}

void Display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
	/*glMatrixMode(GL_PROJECTION);
	glLoadIdentity();*/

	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_TRIANGLES);
		glVertex3f(-0.5, 0.0, 0.0);
		glVertex3f( 0.5, 0.0, 0.0);
		glVertex3f( 0.0, 0.5, 0.0);
	glEnd();
	glutSwapBuffers();  
}

void Reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (float)w/(float)h, 0.1, 500.0);
	glMatrixMode(GL_MODELVIEW);
}

void glutIdle()
{
	glutPostRedisplay();
}

There is nothing drawn but if I uncomment glMatrixMode(GL_PROJECTION) in Display function, the triangle will be drawn. I have a lot of examples work without inserting glMatrixMode(GL_PROJECTION) inside the display function.

because in your commented code, you have glLoadIdentity() after glMatrixMode(GL_PROJECTION), which discards changes you’ve made with gluPerspective(…) call in Reshape() function and makes projection matrix identity. you need a perspective or orthographic projection set up in order to draw something on screen.

So, should I remove matrix identity that follows projection matrix in Reshape function?

Hi CroCodile, in the Reshape function you are setting up the projection matrix and you first switch to the projection matrix: glMatrixMode(GL_PROJECTION); and then initialize it with an identity matrix. This is to clear (or initialize) the projection matrix to a default (identity) state. Then you setup the projection matrix with glOrtho(…) for orthographic or gluPerspective(…) for perspective.

Croc, The call to gluPerspective() creates a cool perspective matrix (Googl gluPerspective), and then multiplies that into the current matrix from the right (object) side. When you setMatrixMode(projection), you choose the projection matrix to be current. Then you set it to unity (the starting place, like zero, for a transformation) and then put the gluPerspective into it by multiplication. So that way you have that cool perspective matrix stored in your projection (instead of just unity there). If you go back in the display loop and set it back to just unity, then you undo the perspective, and offend the depth test and clipping volume, since your projection then puts your object at z = zero, which is one edge of the clipping volume as well as a depth limit. I would turn off depth test until things aren’t disappearing when they shouldn’t, or you may get a lot of black screen.

You shouldn’t touch the projection matrix unless you want to change your wide-angle-ness of view, or reshape your window. Moving the camera and / or objects should be done with the model/view matrix. Set it to identity first, then do your scaling, rotating and moving. All OpenGL transforms only multiply a matrix from the right side, which is from the object’s perspective. You have to multiply from the left to do anything from the camera’s perspective, and that has to be done by hand with loadmatrix afterwards. The order I like to set my modelView matrix is: camera, lights, action, meaning start with identity, then rotate and move the camera, set the lights, then rotate and move the objects, pushing and popping the matrix between objects that need independent rotation and translation. If the camera doesn’t move between frames, then you can skip setting its position and orientation by using push and pop appropriately for lights and objects. I hope that helps!

@ wmchiew & Roaoul,
Thank you for being helpful and informative. I’m sorry for giving you guys hard time. I’m still confused. What is exactly the problem in the following code and how can I solve it?

#include <iostream>
#include <GL/glut.h>
 
int Window_Width(500), Window_Height(500);
 
// Glut functions
void setup();
void Display();
void glutIdle();
void Reshape(int, int);
 
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
	glutInitWindowSize(Window_Width, Window_Height);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Camera Test");
	setup();
	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutIdleFunc(glutIdle);
 
	glutMainLoop();
	return 0;
}
 
void setup()
{
	glClearColor(1.0, 1.0, 1.0, 0.0);
}
 

 
void Display()
{
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_TRIANGLES);
		glVertex3f(-10.0, 0.0, 0.0);
		glVertex3f( 10.0, 0.0, 0.0);
		glVertex3f( 0.0, 10.0, 0.0);
	glEnd();
	glutSwapBuffers();  
}
 
void Reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (float)w/(float)h, 1, 500.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
 
void glutIdle()
{
	glutPostRedisplay();
}

The problem is that all vertices of the triangle have a Z coordinate of zero, which means that it’s in front of the near plane and coincident with the viewpoint.

With a typical perspective projection, anything which you want to appear on screen has to have a Z coordinate between -zNear and -zFar after transformation by the model-view matrix (which in this case is the identity matrix, so the Z coordinates of the original vertices have to lie inside that range).

to add on, your triangle is outside the “viewing range” of your camera. To see the triangle, you can either move the triangle (through rewriting the coordinates or applying transformations within your modelview matrix) or move the camera (using gluLookAt(…) to configure your camera)

hope this helps

I’ve changed it to the following

 void Display()
{
    
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_TRIANGLES);
    glVertex3f(-10.0, 0.0, -1.0);
    glVertex3f( 10.0, 0.0, -1.0);
    glVertex3f( 0.0, 10.0, -1.0);
	glEnd();
	glutSwapBuffers();  
}

It still doesn’t work.

did you get anything other than a blank screen?
i am guessing your triangle vertices are too far apart, hence u might only be rendering one part of the triangle.

@wmchiew,
It is just a black screen. What is the problem?

It worked. Thanks the problem was irrelevant to MatrixMode. It was something to do with Xcode.

that’s great you figured out the problem :slight_smile: good luck

@wmchiew,
thank you for being helpful. Now, I understood the problem more than before. It was a coincidence. I was drawing a triangle and by using glScalef(), I’ve noticed that the triangle disappeared because I was using glIdleFunc(). What I noticed that the scale function scales something that already scaled, consequently, the triangle disappeared. To overcome this problem, I used glPushMatrix() or ModelView and glLoadIdentitiy(). I got it now.