CS409/CS809 Tutorial 9: Constructing 3D Models from Vertexes

Setting up an OpenGL Project with the Obj Library of Files

1.      Start Microsoft Visual Studio 2013.  Select File / New / Project.  Under “Project Type”, choose Templates / Visual C++. Then choose a Win32 Console Application.  Change the name to Tutorial9 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 the Tutorial9.zip and ObjLibrary.zip files to your project directory.

4.      Unzip the 2 zip files.  You will have a folder called ObjLibrary and 14 other files.

5.      In Visual C++, go to Project/Add Existing Item… and select main9.cpp (and holding control, continue to select), Sleep.h, Sleep.cpp, and GetGlut.h.

6.      Ensure that Solution Explorer is visible (View / Solution Explorer). In the Solution Explorer, select Tutorial9 (the project name) and right click it.  Choose Add / New Filter.  A new folder icon should appear in the Solution Explorer.  Name it ObjLibrary.  (This creates an imaginary folder in the project, but it would not create a Windows folder on the computer).

7.      In the Solution Explorer, right click on the ObjLibrary folder icon and select Add / Existing item.  Go into the ObjLibrary folder on Windows and select all files.  The files should appear in the Solution Explorer inside the ObjLibrary folder.  You should get 26 files, although you will not be using most of them for this tutorial.

8.      Compile and run the original program.  You should see 2 windows: a text console and a graphical window labeled “Constructing Models”.  There is a set of positive X/Y/Z axes and a wire-frame cube in the middle of this second window.  Exit the windows.  Closing the text window will close the graphical window, and usually vice versa.

9.      For the remainder of the instructions, it is assumed that you compile and run regularly so that you can see what each change does.

Make a Tetrahedron Model in Your Program

10.  Add this code to the display function:
  glBegin(GL_TRIANGLES);
       // front
       glVertex3d( 0.0, 2.0,  0.0);
       glVertex3d(-1.0, 0.0,  1.0);
       glVertex3d( 1.0, 0.0,  1.0);
  glEnd();
You should see a large white triangle mostly inside the purple wireframe cube.  This is the front face of our tetrahedron.

11.  Add this code to the display function immediately before the glEnd line for the tetrahedron:
       // right
       glVertex3d( 0.0, 2.0,  0.0);
       glVertex3d( 1.0, 0.0,  1.0);
       glVertex3d( 0.0, 0.0, -1.0);
       // left
       glVertex3d( 0.0, 2.0,  0.0);
       glVertex3d( 0.0, 0.0, -1.0);
       glVertex3d(-1.0, 0.0,  1.0);
       // bottom
       glVertex3d( 1.0, 0.0,  1.0);
       glVertex3d(-1.0, 0.0,  1.0);
       glVertex3d( 0.0, 0.0, -1.0);
The triangle should now be a large white tetrahedron at the origin.

12.  Change the scale of the white tetrahedron to only half as big.  Remember to Push/Pop the matrix.

Apply a Texture to the Tetrahedron

13.  Add an #include for "ObjLibrary/TextureManager.h"
#include "ObjLibrary/TextureManager.h"
Add a
using directive for ObjLibrary after the using directive for std:
using namespace ObjLibrary;

14.  Before the code that draws the white tetrahedron, use the glEnable function to enable textures:
  glEnable(GL_TEXTURE_2D);
After the code that displays the white tetrahedron, use the glDisable function to disable textures
  glDisable(GL_TEXTURE_2D);

15.  After enabling textures, use the activate function in the TextureManager namespace to activate the "tetrahedron.bmp" file:
  TextureManager::activate("tetrahedron.bmp");
There is no need to ever deactivate a texture.  OpenGL always has exactly one active texture and activating another one replaces it.  If textures are not enabled, the active texture is ignored.

16.  Replace the code to draw the triangle strip with the following:
  glBegin(GL_TRIANGLES);
       // front
       glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
       glTexCoord2d(0.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
       glTexCoord2d(0.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
       // right
       glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
       glTexCoord2d(0.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
       glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
       // left
       glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
       glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
       glTexCoord2d(1.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
       // bottom
       glTexCoord2d(1.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
       glTexCoord2d(1.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
       glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
  glEnd();
Make sure that the drawing colour is set to white when you use textures.  Otherwise your textures will display incorrectly.

17.  Use pushMatrix, glTranslate, and popMatrix to move the tetrahedron from (0, 0, 0) to (0, 0, -3).

Create a DisplayList for the Tetrahedron

18.  Add an #include for "ObjLibrary/DisplayList.h"
#include "ObjLibrary/DisplayList.h"

19.  Declare a global variable (before the main function) of the DisplayList type:
DisplayList tetrahedron_list;

20.  In the init function, call the activate function in the texture_manager namespace for each texture you will use to load them into video memory.  If you do not do this, the display list will reload the same texture each time it is drawn.  In this case, we want to activate the tetrahedron.bmp  texture:
  TextureManager::activate("tetrahedron.bmp");

21.  Immediately after the activate line in the init function, use the begin and end function in the DisplayList class to define the display list.  Any drawing commands between these two calls will be stored in video memory instead of being executed.  Move the code to draw the tetrahedron from the draw function to between these commands:
  tetrahedron_list.begin();
       glEnable(GL_TEXTURE_2D);
       TextureManager::activate("tetrahedron.bmp");
       glColor3d(1.0, 1.0, 1.0);
       glBegin(GL_TRIANGLES);
            // front
            glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
            glTexCoord2d(0.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
            glTexCoord2d(0.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
            // right
            glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
            glTexCoord2d(0.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
            glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
            // left
            glTexCoord2d(0.5, 0.0); glVertex3d( 0.0, 2.0,  0.0);
            glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
            glTexCoord2d(1.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
            // bottom
            glTexCoord2d(1.0, 1.0); glVertex3d( 1.0, 0.0,  1.0);
            glTexCoord2d(1.0, 0.0); glVertex3d(-1.0, 0.0,  1.0);
            glTexCoord2d(0.5, 1.0); glVertex3d( 0.0, 0.0, -1.0);
       glEnd();
       glDisable(GL_TEXTURE_2D);
  tetrahedron_list.end();

22.  In the display function, use the draw function in the DisplayList class to display the tetrahedron:
       tetrahedron_list.draw();
You will still need the
pushMatrix, glTranslate, and popMatrix commands.

23.  Make an initTetrahedron function that loads the tetrahedron.bmp texture and initializes the tetrahedron_list display list.  Call this function from init after initDisplay.  Remember to add a function prototype.

Exercises

24.  Change the program to draw a total of twenty (20) tetrahedron along the negative Z axis, starting at the (0.0, 0.0, -1.0) and ending at (0.0, 0.0, -20.0).  Do this by drawing the tetrahedron display list more than once, rather than by copying the code to initialize the display list.

25.  Rotate each tetrahedron by 30 degrees more around the positive Y axis than the previous one, by putting in a glRotate* command between glTranslate* and glScale*, before the command to draw the tetrahedron display list.  The glRotate* function measures angles in degrees.  The * should be replaced by f or d.

26.  Add a command to move the camera downward when the [S] key is pressed and upward when the [W] key is pressed.  This will allow you to tsee the tops and botoms of model more easily.

27.  Construct a square facing up and texture it with the crate_top.bmp texture.  Use glBegin(GL_QUADS) to faces with 4 vertexes.  Hint: Use -1.0 and 1.0 as the vertex coordinates and 0.0 and 1.0 as the teture coordinates.

28.  Expand the square to an entire cube.  Put the crate_top.bmp texture on all 6 faces.

29.  Put your cube in a display list and display it at position (-3.0, 0.0, 0.0).  Then make the cube spin.  This will allow you to see all 4 sides of the cube.

30.  Change the cube to have the crate_side.bmp texture on the sides and the crate_bottom.bmp texture on the sides.  The side textures should always be the same way up.  Hint: You cannot change the texture between glBegin and glEnd, so you will have to have a begin/end pair for each texture.  If your textures are oriented correctly, the wood on the sides of the cube should be the greyest at the bottom and the crossbars should go from the top-left to the bottom-right ( \ ).  If the texture is the wrong way, you will have to change which texture coordinates are assigned to which vertexes.  Hint: The T (or V) texture cooridnate (second) should be 0.0 when Y is 1.0 and 1.0 when Y is -1.0.