Lab – Week 5

Working with Shaders – Goals

  • Revisit the high level structure of a basic OpenGL program.
  • Understand how geometric objects are represented.

Note, if you are using your own computer, you need to make sure that you have the glew libraries installed. Also, if your computer does not run OpenGL 3.2 or later, you will either need to update your graphics card driver, or use a different version of the shader code. If you are not certain which version you are running, you can try using the OpenGL Extensions Viewer

Resources (Also see OpenGL section on links page)

Directions

  • Download and run the new Cube Code (in the fileshare). It is a (another) simple program that displays a cube. By pressing the “x”, “y”, and “z” keys on the keyboard, you can rotate the cube about the x, y, and z axies. Press “r” to reset. Note, the rotation about x is always performed first, followed by y, then z.

  • In class, we will go over the high level structure of the Cube program. It is your job to understand this structure. More details will be covered over the coming weeks.
  • Pay particular attention to the details of the Cube class. Your assignment here is to create two more geometric shapes: a Disk shape and another shape of your choice (e.g. sphere, cylinder, cone, torus). We will work through the implementation of the Disk in class.

    Ideally, it would be good to have at least one person in the class implement each type of object so that we can then share and use in later labs.

    A rotated disk. The colors show the triangle structure. A disk created using GL_TRIANGLE_FAN instead of GL_TRIANGLES (see
    discussion below).
    A flaming cylinder!

    Comments on the Disk class:

    • If you want to vary the number of slices in the disk, you will need to have pointers to the arrays in Disk.h since the size of these arrays is not fixed:
      vec4 *points;
      vec4 *colors;
      vec4 *normals;
    • The arrays will have to be created in the constructor.
    • In main.cpp, the init method will need to take into account that the arrays names are pointers, e.g.
      int csize = sizeof((*myDisk.points))* myDisk.numVertices; 
             // If you can figure out a better way to do this, let me know!
      ...
      glBufferSubData( GL_ARRAY_BUFFER, 0, csize, *(myDisk.points) );
      glBufferSubData( GL_ARRAY_BUFFER, csize, csize, *(myDisk.colors) );
      ...
    • The cube is created using GL_TRIANGLES (e.g. see OpenGL primitives) where the arrays (points, colors, normals) are a sequence of three vec4 structs per triangle. If you want, you can instead use GL_TRIANGLE_FAN, which is a much more efficient way of storing the vertices. However, one cannot have each triangle colored distinctly, as in the picture above (left), because each now vertex is shared by more than one triangle (yet can have only one color associated with it). The closest one can get is the image on the right.

      If you use the GL_TRIANGLE_FAN primitive, you will also need to change the command in the display method of main.cpp to be

      glDrawArrays( GL_TRIANGLE_FAN, 0, myDisk.numVertices );

      rather than

      glDrawArrays( GL_TRIANGLES, 0, myDisk.numVertices );

    FYI: One generally does not generate complex organic models directly in openGL. Instead the models are either scanned (e.g., to create ply files, see the The Stanford 3D Scanning Repository) or are modeled in programs such as Maya (and exported, e.g., to obj format). The ply and obj formats can then be read into your OpenGL program. One can find C++ libraries which will read ply and obj files, or you can write your own.


    Dragon (available in ply)
    Click here for larger version.

    Bunny (available in ply)

No later noon on Thursday of Week 6, demonstrate your program in lab (once with the disk and once with another object, or display them together!) and submit your code to the fileshare.