Final Project Presentations

Meet Monday at 3 p.m. in the Digital Arts Lab to present your final projects.  Bring working code, images, video, and presentation files as appropriate to present your research, design, code, and final product.

Please contact me if for some reason you are not able to attend.

Projects are officially due by that time.

Friday, April 24: L-Systems, Terrain, and a Short Quiz

No lecture today. Read over the following about L-Systems:

  • L-Systems Wikipedia Article:  Make sure to note the basic system setup (variables, constants, start, and rules).  From there, it’s pretty simple — variables are replaced iteratively based on the rules until a long string is generated.  When drawing, the symbols equate to drawing or turning at an angle usually.  ”[" denotes "pushing" the transformation matrix, and "]” denotes popping the transformation matrix.
  • Polygon Gardens:  This has some nice 3D examples (basically the rotation is just a bit more complicated).

Read over the following on terrain generation:

  • Perlin Noise: One of the now classic ways to generate terrain is the use of Perlin noise.  Ken Perlin presents a nice overview of some of the techniques that he developed in these notes.
  • Fractal Terrain: Concepts of fractal systems are also used with terrain generation.  This presents some nice introductory ideas.
  • Focus on Terrain: This article presents a nice overview on using Perlin noise at multi-levels for terrain generation.  Continue reading through “heightmap combination.”
  • Landform: This chapter presents a fairly comprehensive overview of “land-forming” in general.  Read through it, and also take a quick look over the whole book which presents more related material on vegetation, water, atmosphere, and synthesizing it all together.

Answer the following questions and submit your answers on one page Monday for a quiz grade:

1)  What major change in the rendering pipeline did OpenGL 2.x introduce?  Draw a diagram to explain the differences between the two approaches.

2) Give two examples of possible “vertex shader” operations.

3) Give two examples of possible “fragment shader” operations.

4) Provide a code sample (may come from book examples) that implements diffuse and specular lighting from a Phong lighting model in a GL (vertex) shader.

5) What very important change is introduced with the very recent OpenGL 3.1 specification?

Wednesday, April 22: Changes in OpenGL Architecture

No lecture today.  Complete the following web exercise sometime before Thursday, April 23.

Turn to Chapter 15, and read pages 515-517.  Stop for a moment on Figure 15.1.  This is an important diagram showing the “fixed functionality” “rendering pipeline” of OpenGL 1.x.  Basically, “fixed functionality” means that the steps to figure out what, where, and how to draw are pre-determined.  A few can be turned-on and off, but one pretty much has to have all those steps process one way or another to get your objects drawn as pixels that you can see.  ”Rendering pipeline” just means the set of steps that are performed computationally to take objects from your scene graph, figure out their coordinate transformations, light/shade materials, and actually start drawing pixels that can be seen.

Let’s take a look at the process for a moment.  Transformation uses the MODELVIEW matrix to get our coordinates into the needed viewing coordinates.  Lighting (if enabled) uses the Phong lighting model discussed in class on a per-vertex basis.  Texture coordinates (u,v coord) are determined so that colors may be mapped from them to vertices and the “surfaces” in between the vertices.  Clipping is performed based on the PROJECTION matrix (setup by glOrtho or glPerspective).  Basic points, lines, etc. are “rasterized” or drawn.  Fragments are essentially sections of surfaces between the vertices that may be drawn as actual pixels if not behind another object, etc.  Texturing completes the transfer of color from image maps (gl textures), etc. The total color for pixels is computed, fog, and anti-aliasing are computed, as well as several other possible steps if requested.

Read pages 518-521 for more detail on each section.

Now for the new!

OpenGL 2.0 introduced a whole new “paradigm” (way of thinking).  It replaced major chunks of the rendering pipeline with two main chunks that are “programmable” for flexibility.  It’s been specified for a while, but it did take hardware manufacturer’s a while to fully support it.  It’s fairly well supported at this point.

Compare Figure 15.3 on page 522 with Figure 15.1.  Notice that it’s all still there, but several steps have been lumped into “vertex shader”, and several steps have been lumped into “fragment shader.”  Basically, the dark gray boxes are the flexible, programmable portions.  Rather than having to do the original steps with the basic Phong lighting model from OpenGL 1.x (in Figure 15.1), you can replace all of the vertex operations with your own!  Your own transformation, your own lighting, and your own texturing.  Clipping is still pretty much clipping, so it gets performed.  Basic rasterization gets performed, then there’s another programmable chunk — the fragment shader.  This lets you control how fragments will be rendered with your own texturing, color sum, etc.

Read through pages 523-526 for more detail on how you can replace these steps.

Now, this added flexibility is great, but it is different.  A lot of people wanted to through away the traditional OpenGL 1.x model and just go with the programmable model.  A lot of people didn’t, though, so they both are available in OpenGL 2.0.  As mentioned last exercise, though, coming with the very latest spec from March 2009, OpenGL 3.1 deprecates the traditional fixed-function setup.  This means it should now be avoided, as this and future releases will no longer support it!

Overall, there are two great things that these two programmable shader blocks have brought.  The first is more advanced shaders.  You can write your own shaders in the OpenGL Shading Language (looks pretty much like C code).  Secondly, people have started using these programmable blocks to perform other calculations, including non-graphics calculations that they just want to run faster.  (This is leading to the very neat idea of OpenCL, which is geared toward providing the power of the GPU to programmers for other uses).

Read pages 526-527 for a simple intro to the OpenGL Shading Language.

Glance over the rest of the chapter.  If you are choosing the OpenGL Shading Language option for your final project, read this section in more detail, as it leads nicely into the next chapter that introduces writing your own shaders.  There are some very nice examples in the beginning of Chapter 16 for a basic diffuse lighting shader, etc. that are great to get a start understanding GLSL.

Lastly for today, let’s take a quick look at boids.  They’re a great way to do some very neat animations and simulated behavior with a few simple rules.  Looking at some of the crowds around NAB, I think humans do the flocking thing, too.  :-)

Read over the brief Wikipedia entry on boids for a nice quick summation of the three basic rules for flocking.

Finally, read Craig Reynold’s page on boids.  He’s done a lot with flocking, and he has made a nice page to explain and demo the key concepts.  This should help those who have chosen this project a lot!

Monday, April 20: More Advanced OpenGL

This web exercise is posted in lieu of lecture today.  We’ll be discussing more advanced features of OpenGL.  Because of the continuing desire to add more features to real-time rendering applications such as games, virtual reality, visualization, etc., the basic setup of OpenGL was “out-grown” in a sense.  We’ll look at that some today.  Here’s a general look at the progression.

1)  Basic drawing so far (Open GL 1.x style) requires “glBegin() — geometry — glEnd()” and a lot of passing vertex information about our geometry to the card.  This is flexible but unfortunately slow when there are a lot of vertices.  This is an “immediate mode” style — pass info and draw it as soon as possible.

2)  Display lists are a “step-up” from that in speed.  A display list “compiles” all of our vertices into one display list.  This is stored in the graphics hardware’s memory for faster access.  Any time we wish to draw a certain object, we choose a display list and tell OpenGL to draw it (glNewList, glEndList, glCallList).  [Read the first section of Chapter 11 -- "Display Lists"; especially, see "Converting to Display Lists" beginning on page 426].  This is faster, but we can’t change it once it’s loaded on the card.

3) Vertex arrays are a step-up from that in flexibility.  We store all of our vertices in an array in our program.  Then we hand a pointer to that array to OpenGL using glVertexPointer().  Once OpenGL has that pointer, a glDrawArrays() command will cause OpenGL to render our geometry with the type specified.  [Read "Vertex Arrays" in Chapter 11, starting on page 428.  For a quick-look, read the code on page 431, and look at what is "commented-out" verses the glVertexPointer() and glDrawArrays() commands that replace the commented code].

4) Vertex Buffer Objects (VBO) are the newest and best way in terms of speed and flexibility for us to pass geometry to the card and have it processed most effciently [See table 11.2 on page 446 for a quick comparison, and read "Vertex Buffer Objects" beginning on page 450; the Wikipedia entry is also helpful and brief].  VBOs are a way of storing a group of vertices on the card (a buffer object) and choosing from among them via binding to be able to work with the individual groups.  The buffers are created with glGenBuffers.  Then, similar to textures from Chapter 8, we’ll bind to a particular one before drawing using glBindBuffer().  [As a quick review from our chapter 8 material, remember that an image color map, a.k.a. texture, was loaded into a section of memory -- often using something like gltLoadTGA().  Then the texture was generated with glTexImage2D.  Lastly, glBindTexture() was used to tell OpenGL which texture map to use when rendering.  Essentially several textures are stored in the graphics memory for efficiency and chosen when needed].  We’ll do a similar thing with VBOs — create the buffer object full of geometry of a certain type, then bind it, then call glDrawElements() to actually ask OpenGL to draw the object.

Read over the summary on page 455 — it gives a good quick review of these three setups that go past our basic glBegin/glEnd:   display lists, vertex arrays, and vertex buffer objects.

For further motivation, we need to talk about the changes in OpenGL.  For the most part, we have been using a drawing setup that has been supported since OpenGL 1.0 and is supported by OpenGL 2.0 (even though this introduces a big change in the rendering pipeline which we’ll discuss more later) and is even technically supported by OpenGL 3.0.  OpenGL 3.1, however, deprecates (basically says — “don’t use this anymore as it will no longer be supported”) the simple drawing style we’ve been using — glBegin/glEnd and “per-vertex” operations.  With this in mind, we need to switch to using VBOs for our code to be future-compatible.  [See the Wikipedia entry on OpenGL and read the final paragraphs for further information on the transition between versions; read here for a summary of the OpenGL 3.0 release;  read here for a summary of the OpenGL 3.1 release which "breaks" a.k.a. "deprecates" some of the earlier drawing modes as mentioned --this was just specified in March, which means it will not be implemented for several months at the minimum].

The idea behind OpenGL 3.0 is to continue the flexibility added by the programmable vertex and fragment shaders of OpenGL 2.0 (that we briefly mentioned at the end of the last lecture and will discuss more a bit later) but also streamline functionality for new, more powerful hardware with lots of features.  In short, the fixed-function, immediate mode method of passing basic drawing commands in order is “going away.”  The new idea is to store objects (geometry, etc.) on the card, access them when needed, and pass them through two steps — vertex operations and fragment operations (basically areas of pixels to be drawn in the buffer that relate to the surfaces between the vertices).

Read over this tutorial.
It’s a nice “intro” to VBOs that is a good supplement to your book.

In summary, getting all the information to our graphics hardware and executing it from there in a more flexible setup is the way that OpenGL and other graphics implementations are moving.  From our end, we need to become comfortable with no longer using glBegin/end, displaylists, and vertex arrays, but instead replace them with vertex buffer objects (VBOs).  We’ll also need to become more comfortable with “shaders” which basically replace the traditional OpenGL operations for figuring out what color and how bright to draw pixels that belong to our geometry, but we’ll talk about that more later.  With that in mind, we’ll talk about the shifts in OpenGL 2.x and 3.x more later and also discuss some material related to your projects.

[As a side note, all of the project proposals seemed fine.  Most needed more specific information, though.  Those considering the "game" options of whatever flavor should particularly take time to understand this information.  For best implementation, VBOs should be used].

Check the blog regularly this week for further updates.

Final Project (tentatively due Monday, May 4).

Click here for description.  Plan to meet at some point on the due date in the Digital Arts lab to present your work.

A quiz is most likely

on Friday.  Material to review:  Basics of OpenGL, libraries, basic C/C++ program structure, transformations, drawing basic GL types, ideas of the camera and projections in GL.

Lighting and Shading in OpenGL

Here is some basic information on lighting models that we’ll need to know to understand lighting and shading in OpenGL, and we should also be familiar with these in general for computer graphics.

A few possibly helpful tips for the project…

C file handling

C file tutorial

C++ file handing

glutMouseFunc

Glut mouse tutorial

A favor, please…

If you are around tomorrow (Thur), please work for a bit on your homework or projects in the DA lab between 5-7 p.m. It is a good opportunity to show some of your work and discuss it. People will be visiting and may ask a question or two, but that’s it — nice and simple, and you get the reward of the satisfaction of showing off your hard work and also making me happy. :-)

There will also be some other fun stuff from the CIS arena being displayed which you can check-out for fun!

Project #2: Due Monday, April 6.

Write an OpenGL-based “.obj viewer” (in C or Python) that will load and display simple .obj files containing vertices and faces (texture and normals not necessary);  it should also have a “camera” that is moveable using the keyboard and/or mouse (move the camera — not the “world” in this project).  Code should be completely of your own creation for this project; if you do use any resources during your attempts to understand and create your own viewer — credit them with links on your blog.  The images should be rendered smoothly using double buffering while updating the camera position.  Post images or video from your working code by the project due date.  Submit your .zip archive with working source, images, .obj files, Maya model, etc. via email.  Come prepared to present your work in class.

1)  Load and display this simple .obj file.

2)  Load and display a second .obj file of your choice.

3)  Load and display a third .obj file — one created by a simple model you make in Maya and export to a .obj file.

Bonus:

a) Have a mode where your camera imitates the “Maya camera.”

b) Have your code also implement texture and/or normal reading from standard .obj files.

c) Implement other interesting and useful features of your choice.

←Older