A printable (pdf) version of this lab is available here.

CS4735 Computer Graphics

Lab 5  Oct. 16, 2006

 

Purpose:  To gain an understanding of how OpenGL draws 3D mesh objects, and how one can create meshes.

 

1. As for all previous labs, log in to a Linux workstation in ITD415, and create a subdirectory in your UNIX subdirectory space called (e.g.) “L5”.

 

2.  Download the “drawmesh.tar” file from the CS4735 “Examples” web site into your L5 subdirectory (use e.g. mozilla). 

 

3.  untar the drawmesh.tar file to get the original source code back.

 

4.  Edit the “displayMesh.cpp” file to (a) create a Mesh object, (b) load the BASICBAR.3VN file into a mesh object (use the readFile(...) method), and (c) draw the mesh object.  Definitions for the required methods are given in the mesh.h file.  Type “make” to invoke the Makefile, which will, in turn, compile and link the source code.  This should result in an executable file called “drawmesh”, which, when invoked (by typing ./drawmesh at the command line) should draw a basic barn shape on the screen as shown below in Figure 1.

Figure 1.  BASICBAR.3VN mesh file plotted on the screen.

 

5.  Modify your “displayMesh.cpp” to draw other 3VN files.  For example, draw the WINEGLAS.3VN mesh that draws a wine glass.  Experiment with the lighting parameters to make the object look more “glassy”.  Changes to the camera and eye setup will be required to get reasonable views of the different objects.  Start with changes to the “half-height of the window” winHt. 

 

6.  Add a method called makePrism(PolyLine P, float H) to your mesh.h and mesh.cpp code (as part of the Mesh class) to define a method that takes as input a polyline P of points, and a height H, and creates the mesh for a prism with P as its base (in the x-y plane).  Follow the suggestions in section 6.3.1 (pp.300-301, and pp. 310-311) of the text.  Test your makePrism(...) method with the polygon shown in Figure 2 below with H = 2.0. 

                                                (a)                                                        (b)

 

                                                                                    (c)

Figure 2.  (a) A test base polygon for the makePrism(...) method, (b) prism drawn in 3D, (c) result of drawing the prism using OpenGL mesh object (with up = (0, 0, 1)).

 

When drawn, the prism should look like that show in Figure 2 (c) above. 

 

Hints: 

1.  The number of vertices in a prism = 2N for N = number of vertices in the base polyline.  Vertices are numbered 0, ..., N-1 for the base polyline, and N, ..., 2N-1 for the “cap” polyline.

 

2.  The number of faces is N+2.  For the first N faces, we define the jth wall, (j = 0, ..., N-1), a face with four vertices is created having indices j, next (j), next(j) + N and j + N.  next(j) = (j + 1) modulo N takes care of the wraparound from the (N-1)st to the zeroth vertex.

 

3.  The last two faces are formed from the base polygon and cap polygon.

 

4.  The pseudo-code for makePrism is as follows:

 

void Mesh::makePrism( PolyLine P, float H)

{  // Make a prism of height H from a polyline

   // See Hill, E.F., pp. 310-311. 

   // Depends on Point2 and PolyLine classes (see mesh.h).

  int N = P.num;

... define number of vertices, normals and faces ...

  pt = new Point3[2*N];       // array of 2N vertices

  norm = new Vector3[N + 2];  // array of N+2 normals to faces

  face = new Face[N + 2];     // array of N+2 faces

  // make the vertex list

 ... needs a loop

  // make the face list, and construct the normals list at the same time

  int indx[4];  // each face has four vertices

  int next;     // next vertex = j + 1 modulo N

  Vector3 fn;   // normal to one face

  int normindx = 0; // index to normals

  for(int f = 0; f < N; f++)  // define all vertical faces (and normals)

  { 

... define the indx vector containing the index to each point in counterclockwise order ...

    norm[normindx] = newell4(indx);  // normal to one face

    face[f].nVerts = 4;  // each vertical face has four vertices

    face[f].vert = new VertexID[4];

    for(int j = 0; j < 4; j++)   // store the four vertex indices

    {                            // and four normal indices

      face[f].vert[j].vertIndex = indx[j];

      face[f].vert[j].normIndex = normindx;

    }

    normindx = normindx + 1;

  }

// define the bottom face (trace vertices CCW from outside looking in

    indx[0] = 0; indx[1] = N-1; indx[2] = N-2; indx[3] = N-3;  // CCW from 0

    norm[normindx] = newell4(indx);  // normal to bottom face

    face[N].nVerts = N;  // bottom face has N vertices

    face[N].vert = new VertexID[N];

... need a loop to store the N vertex indices and N normal indices ...

    normindx = normindx + 1;

  // define the top face

    indx[0] = N; indx[1] = N+1 ;   // take first four vertices

    indx[2] = N+2; indx[3] = N+3;  // to define normal to face

    norm[normindx] = newell4(indx);  // normal to top face

    face[N+1].nVerts = N;  // top face has N vertices

    face[N+1].vert = new VertexID[N];

... need a loop to store the N vertex indices and N normal indices ...

}     

 

7.  Save your prism mesh as a file called PRISM1.3VN using the provided writeMesh(...) method.

 

8.  If you have time, test that you prism mesh generator works for a different prism, defined as shown in Figure 3 below.

                                                (a)                                                                    (b)

Figure 3.  (a) A second base polygon for the makePrism(...) method, (b) prism drawn in 3D.