Computer Graphics Lab Introduction To Opengl and Glut Prerequisites
Computer Graphics Lab Introduction To Opengl and Glut Prerequisites
Fall 2010
Prerequisites
To begin this lab, the student is assumed to be able to: - Build a C++ project.
Objectives
By the end of this lab, the student should be able to: - Describe the purpose of OpenGL and GLUT. - Build a C++ project that uses OpenGL and GLUT. - Build a basic GLUT-based program. - Handle events using GLUT callback functions. - Differentiate between single and double buffering.
What is OpenGL?
OpenGL stands for Open Graphics Library. It is a cross-platform application programming interface for developing 2D and 3D graphics applications. It alleviates the complexity of writing code for different platforms and different hardware graphics accelerators by specifying a standard set of functions to be used by the application programmer and to be implemented by the platform. Usually, an OpenGL package is distributed with OpenGL Utility library (GLU), which uses OpenGL functions to provide higher level drawing functions.
What is GLUT?
GLUT (different from GLU) stands for OpenGL Utility Toolkit. It provides utility functions to simplify the development of OpenGL applications. Provided functions include functions to create and manage windows, implement double buffering, handle keyboard and mouse events and draw basic shapes. A function belonging to base OpenGL is prefixed by gl (e.g. glClear). A function belonging to GLU is prefixed by glu (e.g. gluPerspective). A function belonging to GLUT is prefixed by glut (e.g. glutCreateWindow).
The main function creates the window in the initialization step and then enters an infinite loop waiting for events which are reported through messages. Once a message is received, the callback function is invoked. This function intercepts the message, determines the event and handles it. Pseudo-code of the above setup is described in code 1. Main Function { Create and Initialize Window While(1) { Check Messages If(Message Received) { CallBackFunction(message) } } } Callback Function(message) { If message represents a keyboard event keyboardEventHandler() Else If message represents a mouse event mouseEventHandler() } Code 1 : Pseudo-code of a typical Windows program
In Windows, the setup described above can be implemented using WIN32 API functions. However, that implementation is tedious (in addition to that it has to be completely rewritten for other platforms)1. GLUT simplifies building an OpenGL application by providing functions for initialization, main loop and registration of callback functions that handle events. Activity 1 shows a basic GLUT application. As you can see the main function has to perform three tasks: 1- Initialization: In the initialization step, display settings and window settings are specified. Then the window is created. 2- Registering call back functions: In this step the main specifies the functions to be called when certain event occurs. Here we register a rendering function to be called when the window needs to be redrawn. To do this a pointer to the rendering function is passed to glutDisplayFunc. As you can see our rendering function does nothing more than clearing the screen. More callback functions will be seen later. 3- Entering main loop:
The code we develop in the labs can be compiled and run on any platform that supports OpenGL and for which an implementation of GLUT exists. That includes Windows, Linux and Mac OS X.
Lab #1
2/6
Once setup is complete, the application is ready to enter the main loop and start waiting for events. This is done by calling glutMainLoop.
Animation
For this lab we will consider rotation around Z-axis (The axis perpendicular to the screen) More axis screen). about 3D coordinates, rotation and other transformations will be shown later. Activity 4 uses left and right arrow keys to rotate a teapot around the Z axis. Rotation is done by Z-axis. calling glRotatef before calling glutWireTeapot. Note that transforma . transformations are cumulative. Meaning that, for example, if you call glRotatef twice with two angles of 30 and 40, any objects drawn later will be rotated by 70. Therefore we have to clear previous transformations by calling glLoadIdentity the reason behind this name will be clear as we study glLoadIdentity, transformations. screen This application runs in full-screen mode. This is achieved by calling glutFullScreen during initialization. . Build and run activity 4. Try rotating the teapot using arrow keys. You should notice that the screen flickers as the teapot rotates. This is because the color buffer (whose contents are displayed on the screen also called frame buffer) is repeatedly cleared screen, ) and drawn. To solve this problem we resort to double buffering. Double buffering technique utilizes two color buffers: a front buffer and a back buffer. Drawing commands affect the back buffer while the contents of the front buffer are displayed on the screen. At the end of the rendering function, the buffers are swapp , swapped. The back buffer becomes the front buffer and consequently its contents are displayed on the screen while the formerly front buffer becomes the back buffer which will be used for rendering the next frame. This is illustrated in figure 1.
Fortunately, GLUT simplifies double buffering. All you have to do is to replace GLUT_SINGLE display mode with GLUT_DOUBLE and replace the call to glFlush with a call to glutSwapBuffers.
Lab #1
4/6
Try using double buffering and notice the difference. Now suppose we want the teapot to rotate continuously regardless of the keyboard input. We might think of writing something like: while(true) { g_Theta += 1.0f; glutPostRedisplay(); } The problem is that we cannot respond to an event by executing an infinite loop (Why?). Instead, we would like to add an else to If(Message Received) statement in code 1. To make it look like code 2. If(Message Received) { } else { g_Theta += 1.0f; glutPostRedisplay(); } Code 2 : Modified main loop Fortunately, GLUT allows us to do this by passing a function to glutIdleFunc. The idle callback function will be called when there are no other events. This is the function where you should carry out your application logic. Activity 5 shows how to use idle callback function to continuously animate an object. Activity 6 shows how to use time functions to guarantee a fixed rotation speed regardless of the rate at which the idle callback function is called.
Requirement
Write a program that draws a teapot that always points to the mouse. Use glutMotionFunc and glutPassiveMotionFunc to handle mouse motion. HINT: the callback functions of
We did not explicitly specify these files but they are included by glut.h This will not only enable you to run OpenGL 1.2+ projects but, more importantly, will boost the performance of OpenGL games.
3
Lab #1
5/6
these two events receive, as parameters, two integers representing mouse location in screen coordinates ((0,0) is the top-left point).
Search how to implement initialization and main loop using Win32 API. Then, provide your own implementation of glutInit, glutCreateWindow, glutXFunc and glutMainLoop.
The way we handled keyboard in activity 4 in not convenient for interactive applications and games. We want the teapot to rotate smoothly as in activities 5 and 6. Also, we dont want the brief delay that occurs before the teapot makes its second rotation step. Try to find out how we can use glutKeyboardUpFunc and glutSpecialUpFunc to achieve this. You will need this for your project.
Lab #1
6/6