2. OpenGL Window Reshaping (Version 2.0)
Posted on : 25-03-2010 | By : Swiftless | In : OpenGL
Tags: glut, OpenGL, programming, reshaping, tutorial, window
12
Introduction
In a poorly written OpenGL application, you may notice that when you resize your window, your geometry will not transform to match the size and aspect ratio of your new window size. Your geometry may stay the same size even though the window is smaller or larger and what we want is for our geometry to scale with our window. This is because when GLUT sets up our window, it will initially set some default values for us, but GLUT doesn’t keep track of this information as the window changes, and for good reasons, every application has different needs, and there are no default magic values for everyone.
To fix this, we need to tell GLUT how we want our scene to be rendered, and to do so, we need to understand a little more about OpenGL matrices, and matrices in 3D applications in general. Now there are three main matrices in OpenGL, those being the Projection Matrix, Model View Matrix and the Texture Matrix.
Projection Matrix
The Projection Matrix, just like most matrices in 3D is a 4×4 matrix. This matrix provides the information needed to map a 3D scene to a 2D plane. In the case of OpenGL, this 2D plane is known as our Colour Buffer and this stores the image that we see rendered to our GLUT window, although rendering of the Colour Buffer to a window is not required for off-screen rending. In order to set up our Projection Matrix, we need to tell OpenGL the angle in degrees of our field of view, the aspect ratio for our window which will be our 2D rendering plane, and the near and far planes that bound our render.
Model View Matrix
The next main matrix is the Model View Matrix, which is also known as your Transformation Matrix. This matrix tells us the location and rotation of our geometry placement at any point in time. If you want to move an object, you will be modifying your Model View Matrix, without even knowing it.
Texture Matrix
The Texture Matrix is something you usually don’t want to touch. This is similar to the Model View Matrix as it is also a Transformation Matrix, but it is used for manipulation the position and rotation of textures in texture space. Personally I have only ever used this as a spare matrix when passing information through to GLSL shaders, but in fixed function rendering (standard OpenGL), you won’t want to touch this unless you have a specific reason.
Coding
So let’s now take a look at setting up how to reshape our window.
If you are following through my tutorials, each one will build upon another, and this one builds on top of the first tutorial on creating a window with GLUT. So for this tutorial you will want to open up the code from the previous tutorial.
Now go ahead, and create a new method called “reshape” which takes in two integer values and returns a void. The two incoming parameters will be sent via GLUT, and will contain the width and the height of the window at the point in time that it is called.
It should look something like this:
void reshape (int width, int height) {
}
Then down inside the main method, we need to let GLUT know which method to use for our reshaping, this is done almost identically to how we told GLUT to use our display() method. After the line:
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
Add the line:
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for rendering
Now that GLUT knows which method to call, let’s fill it in so that it actually does something.
The first thing we are going to do is tell OpenGL the size of our viewport (the 2D plane) that we want to render to. We are going to tell OpenGL to start at (0, 0), which corresponds to the bottom left of our window, and then we will tell it to take the size (width, height), which will give us the top right of our window.
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
Once we have setup the size of our viewport, we need to switch to our Projection Matrix so that we can setup how our scene is rendered.
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
Now that we are in the correct mode, we are going to reset our Projection Matrix to the identity matrix so that we don’t cause any artefacts.
Forgetting to reset matrices is a big cause of unusual rendering as OpenGL adds on the previous matrix every time something is called. In the case of setting the Projection Matrix, it would be like trying to apply the projection on to the current projection.
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
Now we are ready for the core of this method. The following line will setup the parameters for our view, such as the field of view, aspect ratio and the near and far planes. The first variable that I am going to set is the field of view (FOV), which I am going to set to 60 degrees. This gives us a viewing angle of 30 degrees to the left, and 30 degrees to the right.
The next value after that is the aspect ratio of our window, which is calculated by dividing the width of our window by the height. The last two values are the near and far plane, and I am going to set them to 1.0 and 100.0 respectively. This means that anything with a position less than 1.0 unit (away from the camera) won’t be drawn and anything with a position greater than 100.0 units (away from the camera) won’t be drawn.
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
The very last thing we need to do in our method is switch back to the Model View Matrix. If we forget to do this, then we will be trying to position our geometry according to our Projection Matrix, and we do not want this.
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
And that should do it, just make sure everything compiles, and when we add some geometry, you can see this method in action.
It doesn’t seem like much, but this is an extremely important method. You will want absolute control over your field of view, and near and far planes in most applications you write.
If you have any questions, please email me at swiftless@gmail.com
#include <GL/glew.h> // Include the GLEW header file
#include <GL/glut.h> // Include the GLUT header file
void display (void) {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); // Clear the background of our window to red
glClear(GL_COLOR_BUFFER_BIT); //Clear the colour buffer (more buffers later on)
glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations
glFlush(); // Flush the OpenGL buffers to the window
}
void reshape (int width, int height) {
glViewport(0, 0, (GLsizei)width, (GLsizei)height); // Set our viewport to the size of our window
glMatrixMode(GL_PROJECTION); // Switch to the projection matrix so that we can manipulate how our scene is viewed
glLoadIdentity(); // Reset the projection matrix to the identity matrix so that we don't get any artifacts (cleaning up)
gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0); // Set the Field of view angle (in degrees), the aspect ratio of our window, and the new and far planes
glMatrixMode(GL_MODELVIEW); // Switch back to the model view matrix, so that we can start drawing shapes correctly
}
int main (int argc, char **argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode (GLUT_SINGLE); // Set up a basic display buffer (only single buffered for now)
glutInitWindowSize (500, 500); // Set the width and height of the window
glutInitWindowPosition (100, 100); // Set the position of the window
glutCreateWindow ("You’re first OpenGL Window"); // Set the title for the window
glutDisplayFunc(display); // Tell GLUT to use the method "display" for rendering
glutReshapeFunc(reshape); // Tell GLUT to use the method "reshape" for rendering
glutMainLoop(); // Enter GLUT's main loop
}Related posts:







“we are going to reset our Projection Matrix to the identity matrix ” .. what is an identity matrix? did you explain that in last tutorial?
Hi Imrn,
These tutorials are meant to be more on OpenGL and Computer Graphics, not so much on the maths. If you want to know in detail about the different matrices then I suggest you look around.
The identity matrix is just an empty matrix with 1′s along the diagonal.
Cheers,
Swiftless
Hi,
I’m following your tutorial with Ubuntu Linux. All the programs are working perfectly, but compiling them has been a little tricky.
Of course, I know I have to include “GL/glut.h” and link “-l glut”. It worked perfectly in chapter 1.
Now, gluPerspective() is not declared in “glut.h”, it is declared in “glu.h” and my compiler complains about it. I also have to link “-l GLU” to compile the program described here.
I don’t know how things work in Windows, but I believe “GL/glu.h” should be included in the programs.
Hope it helps.
Hey Juan,
I target these tutorials a lot more towards Windows developers because thats where a majority of people come from. However I personally am a fan of OSX development, which also requires manual linking when using gcc, but I tend to stick to using Frameworks these days which are OSX only. I used to include “GL/glu.h” in my applications, but find that I don’t need to anymore as it’s included in other header files that I use (on Windows anyway). It’s good to hear you got it working though.
Cheers,
Swiftless
hi
I have a doubt in this document.
In this reshape function you used two matrix(projection and modal )
what is the necessity to use like this?
Great tutorial!
One ponint to mention: fov is in y direction
Hi, I just wanted to say that this is probably the best opengl tutorial on the web, thanks!
Tutorials are very helpful.
i tried all practically.. working fine.
Hi Expora,
Most of the methods we create for use with GLUT are void methods, yes. Meaning they don’t return a value.
Also, the method “reshape” can be called whatever you like, as long as it takes the same types of parameters.
I’m not sure what you mean about the int’s. Do you just want to know what they are? An int is short for integer, and an integer is just a whole numer (no decimal points).
Cheers,
Swiftless
Hello there!! Quick question: Methods always use void at the beginning? also do you assing the reshape name on your own or does it means something in GLUT? Also I would like to know what exactly int. I mean I’d like to know what I’m writing so I can go do things of my own someday
Thanks,
Expora
hi..i m still gettin errors even if i follow ur methods..is there any alernative..??please tell me the possible errors
Hi Anjana,
You shouldn’t be getting any errors if you completed the first tutorial successfully. What errors do you get?
Cheers,
Swiftless