Professional Documents
Culture Documents
OpenGL Handbook
For Beginners
This Handbook provides basics of OpenGL and describes different functions of OpenGL in detail with the help of pseudo-codes. It also provides few sample OpenGL programs.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
SDMCET/CSE/OpenGL Handbook/v3.0
Page
Visual Visual
Studio Studio
NET NET
Note:
If you plan on giving your OpenGL program to your friends for running on Windows platform, you must also include the glut32.dll file with your program. If they don't have this file in the same directory as your application or in their C:\WINDOWS\system folder, then the program will not run.
SDMCET/CSE/OpenGL Handbook/v3.0
1. Goto File New Project. Then the New Project Dialog will appear.
2. In the Project Types pane, select Visual C++ Projects. Then select Win32 Console Project in the Templates pane. Name your project and click OK. The Win32 Application Wizard dialog will appear.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
3. Click the Application Settings tab on the left, and check the Empty Project box. Then click Finish.
SDMCET/CSE/OpenGL Handbook/v3.0
4.
Add Source Code: Adding source files to the project should be familiar to you. There are two facts you should know, however. When you include GLUT in a program, it automatically includes the rest of the OpenGL header files. So explicitly having: #include <GL/gl.h> #include <GL/glu.h> In either Linux or Windows isn't necessary, provided you include GLUT. In short, you only need to do this: #include <GL/glut.h> Do not use a backslash in the preprocessor #include. #include <GL\glut.h> No!
5.
Modify Project Properties: Before compiling your project, you need to set up Visual Studio's linker so it knows where to find GLUT. To do this, you must open the Property Pages dialog for your project. There are two ways to do this: a. Use Visual Studio's menu option (Project Properties)
SDMCET/CSE/OpenGL Handbook/v3.0
Page
b. OR: Use the Solution Explorer located in the upper right corner. Right-click your project's name as shown and select Properties.
6. Using either of the above options, the Property Pages dialog will open. Once it appears, do the following: a. From the Configuration: list box, select All Configurations:
b. In the left pane, select the Linker sub-tree and then the Input option. Add the following code to the Additional Dependencies text box in the right pane:
SDMCET/CSE/OpenGL Handbook/v3.0
Page
Now Visual Studio knows where to find GLUT. c. This step is optional. If you want to prevent your program from opening a console window in addition to your GLUT window when it is run, select the Command Line option in the left pane. Then add the following code to the Additional Options: text box: Copy & Paste: /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup
SDMCET/CSE/OpenGL Handbook/v3.0
Page
Visual Studio thinks it's still building a normal console application, which is why a console window will appear if you run your program from inside Visual Studio or by double-clicking its icon. The /SUBSYSTEM: WINDOWS command tells Visual Studio this is a windowed application, which means a console window isn't necessary. However, when Visual Studio makes windowed applications, it wants to start program execution from WinMain() or wWinMain(), which you haven't defined. Setting the /ENTRY:mainCRTStartup flag tells Visual Studio to start execution at the usual main() instead.
Note:
If you choose to disable the console window, remember that you won't be able to see any console output from your program using printf(), cout, cerr, etc. So, if you plan on having users run your program from a DOS prompt and console output needs to be seen, do not disable the console window. Now your program is ready for development in an excellent IDE while still being portable.
SDMCET/CSE/OpenGL Handbook/v3.0
10
1. Download the latest version of Dev C++ from the following link:
SDMCET/CSE/OpenGL Handbook/v3.0
Page
11
Select Empty Project. You can specify any useful name to your project in Name: Text field. For example, here the sample project is named as CG LAB Click Ok. 5. Now Go to ProjectProject Options. Click Ok. You will get a window as below:
Click on Parameters Tab and add the following line in the Linker Text Area: -lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32
SDMCET/CSE/OpenGL Handbook/v3.0
Page
12
Now you have successfully configured your project. 6. In the solution explorer window, which is situated on left of your screen, named as CG LAB (your project name), right click and click on New File.
This step will create a space for you to write the OpenGL Programs. 7. After typing the program, compile the program using Ctrl +F9. 8. Run the program using Ctrl + F10.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
13
3.1 Initialization:
The first thing we need to do is to call the glutInit() procedure. It should be called before any other GLUT routine because it initializes the GLUT library. The parameters to glutInit() should be the same as those of main(), specifically main(int argcp, char** argv) and glutInit(&argc, argv) , where argc is a pointer to the program's unmodified argcp variable from main. Upon return, the value pointed to by argcp will be updated, and argv is the program's unmodified argv variable from main. Like argcp, the data for argv will be updated. The next thing we need to do is call the glutInitDisplayMode() procedure to specify the display mode for a window. You must first decide whether you want to use an RGBA (GLUT_RGBA) or color-index (GLUT_INDEX) color model. The RGBA mode stores its color buffers as red, green, blue, and alpha color components. The fourth color component, alpha, corresponds to the notion of opacity. An alpha value of 1.0 implies complete opacity, and an alpha value of 0.0 implies complete transparency. Color-index mode, in contrast, stores color buffers in indices. Your decision on color mode should be based on hardware availability and what your application requires. More colors can usually be simultaneously represented with RGBA mode than with color-index mode. And for special effects, such as shading, lighting, and fog, RGBA mode provides more flexibility. In general, use RGBA mode whenever possible. If not specified by the programmer, RGBA mode is the default mode in OpenGL. Another decision you need to make when setting up the display mode is whether you want to use single buffering (GLUT_SINGLE) or double buffering (GLUT_DOUBLE) scheme. Applications that use both front and back color buffers are double-buffered. Smooth animation is accomplished by rendering into only the back buffer (which isn't displayed), then causing the front and back buffers to be swapped. If you aren't using animation, stick with single buffering, which is the default buffering scheme in OpenGL. Finally, you must decide if you want to use a depth buffer (GLUT_DEPTH), a stencil buffer (GLUT_STENCIL) and/or an accumulation buffer (GLUT_ACCUM). The depth buffer stores a depth value for each pixel. By using a "depth test", the depth buffer can be used to display objects with a smaller depth value in front of objects with a larger
SDMCET/CSE/OpenGL Handbook/v3.0
Page
14
depth value. The second buffer, the stencil buffer is used to restrict drawing to certain portions of the screen, just as a cardboard stencil can be used with a can of spray paint to make a printed image. Finally, the accumulation buffer is used for accumulating a series of images into a final composed image. None of these are default buffers. We need to create the characteristics of our window. A call to glutInitWindowSize() will be used to specify the size, in pixels, of your initial window. The arguments indicate t he height and width (in pixels) of the requested window. Similarly, glutInitWindowPosition() is used to specify the screen location for the upper-left corner of your initial window. The arguments- x and y, indicate the location of the window relative to the entire display.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
15
3.6.1 Points:
A point is represented by a single vertex. Vertices specified by the user as twodimensional (only x- and y-coordinates) are assigned a z-coordinate equal to zero. To control the size of a rendered point, use glPointSize() and supply the desired size in pixels as the argument. The default is as 1 pixel by 1 pixel point. If the width specified is 2.0, the point will be a square of 2 by 2 pixels. glVertex*() is used to describe a point, but it is only effective between a glBegin() and a glEnd() pair. The argument passed to glBegin() determines what sort of geometric primitive is constructed from the vertices.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
16
Eg :
3.6.2 Lines:
In OpenGL, the term line refers to a line segment, not the mathematician's version that extends to infinity in both directions. The easiest way to specify a line is in terms of the vertices at the endpoints. As with the points above, the argument passed to glBegin() tells it what to do with the vertices. The options for lines include: a. GL_LINES: Draws a series of unconnected line segments drawn between each set of vertices. An extraneous vertex is ignored. b. GL_LINE_STRIP: Draws a line segment from the first vertex to the last. Lines can intersect arbitrarily. c. GL_LINE_LOOP : Same as GL_STRIP, except that a final line segment is drawn from the last vertex back to the first. With OpenGL, the description of the shape of an object being drawn is independent of the description of its color. When a particular geometric object is drawn, it's drawn using the currently specified coloring scheme. In general, an OpenGL programmer first sets the color, using glColor*() and then draws the objects. Until the color is changed, all objects are drawn in that color or using that color scheme. Example:
glBegin(GL_LINES); glColor3f(1.0, 1.0, 0.0); // yellow glVertex2(-1.0, 1,0); glVertex2f(2.0, 2.0); glColor3f(1.0, 0.0, 0.0); // red glVertex2f(0.0, 0.0); glVertex2f(1.0, -1.0); glVertex2f(-2.0, -2.0); glEnd();
SDMCET/CSE/OpenGL Handbook/v3.0
Page
17
3.6.3 Polygons:
Polygons are the areas enclosed by single closed loops of line segments, where the line segments are specified by the vertices at their endpoints. Polygons are typically drawn with the pixels in the interior filled in, but you can also draw them as outlines or a set of points. In OpenGL, there are a few restrictions on what constitutes a primitive polygon. For example, the edges of a polygon cannot intersect and they must be convex (no indentations). There are special functions for a three-sided (triangle) and four-sided (quadrilateral) polygons, glBegin(GL_TRIANGLES) and glBegin(GL_QUADS) , respectively. However, the general case of a polygon can be defined using glBegin(GL_POLYGON). Example: glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 0.0); // yellow glVertex2f(0.0, 0.0); glVertex2f(0.0, 3.0); glVertex2f(4.0, 3.0); glVertex2f(6.0,1.5); glVertex2f(4.0, 0.0) ;
glEnd();
SDMCET/CSE/OpenGL Handbook/v3.0
Page
18
19
glBegin(GL_QUAD); glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0); glVertex2f(1.0, 1.0); glVertex2f(0.0, 1.0); glEnd(); glTranslate(-1.5, 0.0, 0.0); // move object glEndList(); It is important to note that OpenGL functions are not necessarily executed as soon as they are issued. It is necessary to call the function glFlush() to ensure that all previously issued functions are executed. glFlush() is generally called at the end of a sequence of drawing functions to ensure all objects in the scene are drawn before beginning to accept user input.
3.9 Color:
Drawing on a computer screen is different from drawing o paper in that the paper starts out white, and all you have to do is draw the picture. On the computer, the memory holding the picture is usually filled with the last picture you drew, so you typically need to clear it to some background color before you start to draw the new scene. To change the background color, we call glClearColor() and specify the color we have chosen for the background. The default clearing color is (0,0,0,0) which is black. A subsequent call to glClear() will clear the specified buffers to their current clearing values. To clear the color buffer use the argument GL_COLOR_BUFFER_BIT. To set a color, use the function glColor3f(). It takes three floating point parameters which are between 0.0 and 1.0. The parameters are, in order, the red, green, and blue components of the color. You can think of these as specifying a "mix" of colors, where 0.0 means don't use any of this color and 1.0 means use that entire component. For example, glColor3f(1.0, 0.0, 0.0) makes the brightest red that the system can draw, with no green or blue components. All zeros make black (an absence of colored light) and all ones makes white (a presence of all colored light). Eight common colors and their functions are: a. b. c. d. e. f. g. glColor3f(0.0, glColor3f(1.0, glColor3f(0.0, glColor3f(1.0, glColor3f(0.0, glColor3f(1.0, glColor3f(0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0); 0.0); 0.0); 0.0); 1.0); 1.0); 1.0); //black //red //green //yellow //blue //magenta //cyan
SDMCET/CSE/OpenGL Handbook/v3.0
Page
20
//white
3.10 Menu:
GLUT supports simple cascading pop-up menus. They are designed to let a user select various modes within a program. The functionality is simple and minimalistic and is meant to be that way. Do not mistake GLUT's pop-up menu facility with an attempt to create a full-featured user interface. It is illegal to create or destroy menus, or change, add, or remove menu items while a menu (and any cascaded sub-menus) is in use (that is, popped up). The popup menus can be arranged in a hierarchy of menus, sub-menus, sub-sub-menus, and so on. Since a sub-menu identifier must be passed as an argument to the GLUT functions that create the parent menu, the menu must be created from the bottom up. For example, assume we want to create a main menu with entries Option A or Submenu1, where the sub-menu has entries of Options B, C, or Submenu2, where the sub-sub-menu has Options D and E. Submenu identifiers must be declared for each of our menu entries. This is a unique integer value will be assigned as the menus are called by glutCreateMenu() . Start with the lowest level menu and pass as an argument the callback function, menuCB, which defines menu selection options. To create the lowest level menu and its entries: sub2 = glutCreateMenu(menuCB); glutAddMenuEntry("Option D", 4); glutAddMenuEntry("Option E", 5); Then go up one more level and do the same thing for Submenu1: sub1 = glutCreateMenu(menuCB); glutAddMenuEntry("Option B", 2); glutAddMenuEntry("Option C", 3); glutAddSubMenu("SubMenu2", sub2); Finally, we need to go the same thing for the highest level menu: glutCreateMenu(menuCB); glutAddMenuEntry("Option A", 1); glutAddSubMenu("SubMenu1", sub1); glutAddMenuEntry("Quit", 6);
SDMCET/CSE/OpenGL Handbook/v3.0
Page
21
These menu options can now be used in the callback function menuCB to process the users menu choice.
void menuCB(int item) { switch (item) { case 1: /* do whatever option A does */ break; case 2: /* do whatever option B does */ break; . . . } }
3.11 Mouse:
GLUT supports interaction with the computer mouse that is triggered when one of the three typical buttons is presses. A mouse callback function can be initiated when a given mouse button is pressed or released. The function glutMouseFunc() is used to specify the callback function to use when a specified button is given state at a certain location. The buttons are defined as GL_LEFT_BUTTON, GL_RIGHT_BUTTON, or GL_MIDDLE_BUTTON and the states for that button are either GLUT_DOWN (when pressed) or GLUT_UP (when released). Finally, x and y callback parameters indicate the location (in window-relative coordinates) of the mouse at the time of the event. Just as with the menu options above, the callback function can use a switch statement with multiple variations of mouse buttons, actions and locations to do some pretty nifty things. For example, we could use the mouse to cause an object within certain x and y ranges to rotate 90 degrees to the right with a click of the right button, to rotate 90 degrees to the left with a click of the left button, and to flip upside down with a click of the middle button.
3.12 Keyboard:
GLUT interaction using keyboard inputs is handled very similarly to those with the mouse. The function glutKeyboardFunc() is used to run the callback function specified and pass as parameters, the ASCII code of the pressed key, and the x and y coordinates of the mouse cursor at the time of the event. Special keys can also be used as triggers. The key passed to the callback function, in this case, takes one of the following values (defined in glut.h). a. b. c. d. GLUT_KEY_UP GLUT_KEY_RIGHT GLUT_KEY_DOWN GLUT_KEY_PAGE_UP Up Arrow Key Right Arrow Key Down Arrow Key Page Up Key
SDMCET/CSE/OpenGL Handbook/v3.0
Page
22
e. f. g. h.
// save the current transformation state desired viewing volume here */ // call the procedure to draw object 1 // call the procedure to draw object 2 // call the procedure to draw object 3 // restore to previous transformation state
Calls to glPushName(), glPopName(), and glLoadName() are ignored if you're not in selection mode. So you might want to simplify your code by using these calls throughout your drawing code, and then use the same drawing code for both selection and normal rendering modes.
3.14 Picking:
You can use the selection process to select specific objects for further manipulation. To do this, you use a special picking matrix in conjunction with the projection matrix to restrict drawing to a small region of the viewport, typically near the cursor. Then you allow for some form of input, such as clicking a mouse button to initiate selection mode. With selection mode established and with the special picking matrix used, objects that are drawn near the cursor causes selection hits. Thus, during picking you're typically determining which objects are drawn near the cursor.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
23
Before calling the standard projection matrix (such as glOrtho() or glFrustum()), we need to use the utility routine gluPickMatrix() to multiply the specified projection matrix by a special picking matrix. The center of the picking region is passed as x and y values (in window coordinates), typically the cursor location. A width and height are also specified which define the picking region in screen coordinates. You can think of the width and height values as the sensitivity of the picking device. You should also specify a viewport. Use glGetIntegerv(GL_VIEWPORT, viewport) to get the current values for the viewport array. For example, to create a 5x5 pixel picking region near the cursor location, use gluPickMatrix((GLdouble) x, (GLdouble) y, 5.0, 5.0, viewport); You will probably want to save the contents of the current projection matrix before any manipulation, so the sequence of operations may look like this: glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPickMatrix( . . .); glFrustum(); //... draw scene for picking; perform picking; process picking glPopMatrix();
3.15 Hits:
In selection mode, we can use the name stack and mouse interaction to keep track of which objects are selected and process them accordingly. When you enter selection mode, OpenGL initializes a pointer to the beginning of the selection array. We can then use mouse input values, such as GL_DOWN and GL_LEFT_BUTTON, to determine if a hit should be recorded and update the hit record with each mouse input. Each time a hit record is written into the array, the pointer is updated accordingly. The hit records are accumulated in the array until glRendermode(GL_RENDER) is called. As noted above, the return value for this function is the number of hits in the array. This can then be passed to another procedure, along with the array itself to act on the selected pieces.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
24
23. void main(int argc, char** argv) 24. { /* Standard GLUT initialization */ 25. glutInit(&argc,argv); 26. glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */ 27. glutInitWindowSize(300,300); /* 300 x 300 pixel window */ 28. 29. 30. glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Line Draw"); /* window title */ glutDisplayFunc(display); /* display callback invoked
SDMCET/CSE/OpenGL Handbook/v3.0
Page
25
myinit(); glutMainLoop();
Output :
Program-2: To Generate a Sierpinski Gasket using Randomly Generating Points. Source Code:
/* Two-Dimensional Sierpinski Gasket */ /* Generated Using Randomly Selected Vertices */ #include<stdio.h> #include<stdlib.h> #include <GL/glut.h> void myinit() { /* attributes */ glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */ glColor3f(1.0, 0.0, 0.0); /* draw in red */ /* set up viewing */ /* 500 x 500 window with origin lower left */ glMatrixMode(GL_PROJECTION); glLoadIdentity();
SDMCET/CSE/OpenGL Handbook/v3.0
Page
26
gluOrtho2D(0.0, 50.0, 0.0, 50.0); glMatrixMode(GL_MODELVIEW); } void display( void ) { GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; /* A triangle */ int j, k; int rand(); /* standard random number generator */ GLfloat p[2] ={7.5,5.0}; /* An arbitrary initial point inside traingle */ glClear(GL_COLOR_BUFFER_BIT); /*clear the window */ /* compute and plots 5000 new points */ glBegin(GL_POINTS); for( k=0; k<50000; k++) { j=rand()%3; /* pick a vertex at random */ /* Compute point halfway between selected vertex and old point */ p[0] = (p[0]+vertices[j][0])/2.0; p[1] = (p[1]+vertices[j][1])/2.0; /* plot new point */ glVertex2fv(p); } glEnd(); glFlush(); /* clear buffers */ } void main(int argc, char** argv) { /* Standard GLUT initialization */ glutInit(&argc,argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);/* default, not needed */ glutInitWindowSize(500,500); /* 500 x 500 pixel window */ glutInitWindowPosition(0,0); /* place window top left on display */ glutCreateWindow("Sierpinski Gasket"); /* window title */ glutDisplayFunc(display); /* display callback invoked when window opened */
SDMCET/CSE/OpenGL Handbook/v3.0
Page
27
Output:
SDMCET/CSE/OpenGL Handbook/v3.0
Page
28
Chapter 5 References
1. 2. 3. 4. 5. 6.
http://www.opengl.org/ http://user.xmission.com/~nate/glut/glut-3.7.6-bin.zip http://www.bloodshed.net/dev/devcpp.html http://www.nigels.com/glt/devpak/ http://www.cs.uccs.edu/~semwal/man.html "Interactive Computer Graphics - A Top Down Approach Using OpenGL", 5th Edition, Edward Angel, Addison-Wesley 2009 "OpenGL - A Primer, 3rd Edition, Edward Angel http://en.wikipedia.org/wiki/OpenGL
7. 8.
SDMCET/CSE/OpenGL Handbook/v3.0
Page
29