CS409 / CS 809 Tutorial 1: OpenGL
1. Start Microsoft Visual Studio 2015. Select File / New / Project…. Under the list on the left, choose Installed / Templates / Visual C++. Then choose a Win32 Console Application. Change the name to Tutorial1 or some suitable name and change the location to a hard drive located on the computer (typically C or D). You will need to remember this location for steps 3 and 5. Make sure the “Create folder for project” checkbox is not checked and that the “Add to source control” is not checked. Click OK.
· If the Chose Location window keeps popping up again, you aren’t allowed to save files at the location you chose. Select a different location, such as the desktop.
· Do not put your program on one of the external drives like H. The connection is slow, and your program may not compile correctly.
2. Click Next> or Application Settings (they go to the same place). Check the “Empty Project” box. Make sure the “Security development lifecycle check” is not checked. Click Finish.
3. Go to http://www2.cs.uregina.ca/~anima/409/Terms/201810/Tutorials/index.html and download main1.cpp, Sleep.h, and Sleep.cpp to your program directory.
4. In Visual C++, go to Project/Add Existing Item… and select main1.cpp.
5. Download FreeGLUT for Windows. The official website has source code and a Linux makefile, which isn't much use on Windows. Rather than search the internet for a binary (compiled) version, you can download it from the course website at http://www2.cs.uregina.ca/~anima/409/Terms/201810/Tutorials/freeglut.zip. Extract the files to your project folder.
· If you are using a Windows computer with 7-Zip (such as the CL 105 computers), the easiest way to do this is by right-clicking on the file in Windows Explorer and selecting 7-Zip / Extract Here.
6. Ensure that Solution Explorer is visible (View / Solution Explorer). Double-click main1.cpp to open it.
7. Go to Project / Add Existing Item… and add glut.h to your project. This should stop Visual Studio from marking all the OpenGL functions as errors.
8. Compile and run the original program (using the green triangle on the third line just before “Local Windows Debugger”). Be patient. Eventually, you should see 2 windows: a text console and a graphical window labeled “First OpenGL Program”. There is a white polygon (square) in the middle of this second window. Exit the windows. Closing the text window will close the graphical window, and sometimes vice versa.
· You may see a pop-up window that says "This project is out of date:". If so, click "Yes". This tells Visual Studio to compile your program before trying to run it.
9.
In the display function, add a line before the glBegin
line that says
glColor3f(1.0f,
0.5f, 0.0f); // float, range [0.0f, 1.0f]
The three numbers are values from 0.0 to 1.0 for red,
green, and blue color components. Compile and run your program. The square
should now be orange.
10. Repeat step 8 with each of the lines
glColor3d(1.0,
0.5, 0.0); // double, range [0.0, 1.0]
glColor3ub(255,
128, 0); // unsigned byte, range [0, 255]
The results should be the same. Choose the one of the three glColor*
lines that you like and keep that one.
11. Change the x component (first number) of the first and fourth glVertex2f
commands to –0.3f. The lines should now appear as:
glVertex2f(-0.3f,
-0.5f);
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.3f, 0.5f);
Compile and run the program; the square should be replaced by a rectangle right
of center.
12. Repeat step 10 with the x component as 0.0f. The rectangle grows smaller.
13. Duplicate the first glVertex2f lines. In the original (still first) line, change the x component
to –0.5f and the y component to 0.0f. The five lines should appear as:
glVertex2f(-0.5f,
0.0f);
glVertex2f(
0.0f, -0.5f);
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f( 0.0f, 0.5f);
Compile and run the program. The orange rectangle
should now be a pentagon.
· Note: the vertices of the pentagon are given in counterclockwise order; use this order for any kind of polygon.
14. Duplicate everything from glColor3f to glEnd, inclusive, and place the copy after the original glEnd. In the copy, change the glColor3* line to green and remove the first two glVertex2f lines. Change the remaining lines to have coordinates (1.0f, 1.0f), (-1.0f, 1.0f), and (0.0f, -1.0f). Compile and run the program. There should be a big green triangle on the screen with just a small corner of the orange pentagon visible.
15. Move the triangle display code (including its glColor3* line) above the pentagon display code (including its glColor3* line). Compile and run the program. The pentagon should be in front of the triangle.
16. Add a function called idle to your program above the display
function:
void idle ()
{
// tell OpenGL to redisplay the window
glutPostRedisplay();
}
Add a prototype for the idle function immediately
before the prototype for the display function. A prototype looks like the first line of the function but
with a semi-colon at the end:
void idle ();
· Try to keep your function prototypes in the same order as the functions themselves. It is less confusing in the long term.
17. In the main function, add a call to glutIdleFunc immediately before the call
to glutDisplayFunc.
glutIdleFunc(idle);
18. Compile and run your program. It should appear the same but occupy all available CPU time on one processor. You may need to close the text window to stop it.
· If the X doesn't work (depends on your computer), the problem is that the program is too busy to notice your input. The glutMainLoop function in main keeps calling functions as needed, and it always thinks there is another function to call. Whenever idle runs, glutPostRedisplay is called, which makes glutMainLoop call display again. Then, when display is finished, glutMainLoop calls idle again. Thus, it keeps running display, idle, display, idle, display, idle… as fast as possible and never has time to do anything else.
19. Create a global floating point variable named pentagonDegrees with an initial value of 0.0. Place it after the prototype
declarations, but before the main function.
float pentagonDegrees
= 0.0f;
The angle will be increased every time OpenGL is idle.
In the idle function, before glutPostRedisplay, insert the following:
pentagonDegrees +=
2.0f;
if(pentagonDegrees >= 360.0f)
pentagonDegrees -= 360.0f;
20. Add the line
glMatrixMode(GL_MODELVIEW);
at the beginning of the display function.
This tells OpenGL that we want our matrix commands (below) to apply to the
modelview matrix, which is the normal one and controls where things appear on
the screen.
21. Add the lines
glPushMatrix(); //
saves existing top matrix
glRotatef(pentagonDegrees, 0.0f, 0.0f, 1.0f);
immediately before the code to draw the pentagon. Indent the code to draw the
pentagon by one tab. After the code to draw the pentagon, add the line
glPopMatrix(); //
restores matrix from glPushMatrix
· You can indent code by selecting in and typing [TAB]. To un-indent code, type [SHIFT] + [TAB].
22. Compile and run the program. The orange pentagon should rotate so fast that it looks like the rotation in each frame is random.
23. We will slow the animation down by making OpenGL wait 1/100 of a
second between displaying each frame. Go to Project / Add Existing Item… and
add Sleep.h and Sleep.cpp to your project. At the top of your main1.cpp file, add
#include
"Sleep.h"
In your idle function, before glutPostRedisplay, add the line
sleep(0.01); //
wait for 0.01 seconds
Compile and run the program. The orange pentagon
should rotate a sensible speed and the X button in the corner should work
again.
24. Create two new global floating point variables, named xPosition
(with an initial value of 0.0) and xIncrement (with an initial value of 0.01).
float xPosition =
0.0f;
float xIncrement = 0.01f;
In the idle function, insert the following after the code for pentagonDegrees:
xPosition +=
xIncrement;
if(xPosition > 1.0f || xPosition < -1.0f)
xIncrement = -xIncrement;
25. Add the lines
glPushMatrix();
glTranslatef(0.0f, 0.75f, 0.0f);
glScalef(0.25f,
0.25f, 0.25f);
immediately before the code to draw the triangle. After the code to draw the
triangle, add the line
glPopMatrix();
The green triangle should be one quarter (because of glScaled) of its
previous size and near the top of the screen (because of glTranslated).
26. Change the glTranslated line to move the triangle based on the xPosition variable:
glTranslatef(xPosition,
0.75f, 0.0f);
The three parameters are how far to move in the X, Y, and Z directions. Since
we are working in 2D, we aren't using Z.
27. Compile and run the program. The green triangle should now move back and forth across the top of the screen.
28. Add function keyboard to your program above the idle function:
void keyboard (unsigned
char key, int x, int y)
{
switch(key)
{
case 'R':
case 'r':
xPosition = 0.0;
break;
case 27: // on [ESC]
exit(0); // normal exit
break;
}
}
Add a prototype for this function with the other
function prototypes:
void keyboard (unsigned
char key, int x, int y);
29. In the main function, add a call to glutKeyboardFunc to handle keyboard
input of ASCII keys immediately before the call to glutIdleFunc:
glutKeyboardFunc(keyboard);
Compile and run your program. You should be able to reset the triangle to its
starting position with the [R] key and exit the program with the [ESC] key.
30. Comment out updating to position in the idle function.
// xPosition += xIncrement;
// if(xPosition > 1 || xPosition < -1)
// xIncrement = -xIncrement;
31. Add function special to your program above idle:
void special (int
special_key, int x, int y)
{
switch(special_key)
{
case GLUT_KEY_LEFT:
xPosition -= xIncrement;
break;
case GLUT_KEY_RIGHT:
xPosition += xIncrement;
break;
}
}
Add a prototype for this function with the other
function prototypes:
void special (int
special_key, int x, int y);
32. In the main function, add a call to glutSpecialFunc to handle the special
keys, such as the arrow keys, after the call to glutKeyboardFunc:
glutSpecialFunc(special);
Compile and run your program. You should be able to move the green triangle
back and forth with the left and right arrow keys.
33. Change the program so that the 'A'/'a' key causes the triangle to move left and the 'D'/'d' key causes it to move right. Thus the user can use [A] instead of left arrow and [D] instead of right arrow. Note: These keys have to be handled by the keyboard function rather than the special function.
34. Change the program so that the 'W'/'w' key causes the triangle to move up (increase its Y value) and the 'S'/'s' key cause it to move down (decrease its Y value). The triangle should start at a Y position of 0.75.
· Note: You will need Y variables similar to your X variables.
· Note: The glTranslated command takes three parameters, which are movement in the X, Y, and Z directions. You should be able to move the triangle in both the X and Y directions using one glTranslated command.
35. Change the program so that the orange pentagon does not spin automatically. Instead, it should spin clockwise (decrease pentagonDegrees) when the right arrow is pressed and it should spin counterclockwise (increase pentagonDegrees) when the left arrow is pressed.
· Note: Make a degreesIncrement variable similar to the xIncrement variable. It will need a larger value, such as 2.0f.
· Note: The arrow keys should no longer move the triangle.
36. Change the program so that the orange pentagon is replaced by a purple hexagon.
· Note: A hexagon has six vertices.
· Note: You can find the RGB colour components for any colour (such as purple) by doing an Internet search for RGB purple.
· It is strongly recommended that you draw a hexagon on paper, label the points with (X, Y) values, and then enter the points in order around the hexagon. If you just edit the points at random, you may put the vertices in an unnatural order, which will cause it to display incorrectly.
37. Change the program so that the green triangle is replaced by a brown octagon. You can choose any shade of brown.
· Note: An octagon has eight vertices.