Project 6: Bezier Patches and Textures
In this project you will need to create a flag that waves in the wind. The project is due on Friday, November 16th. The assignment will be introduced in the lab by Sid on Tuesday, November 13th, starting at 3:30pm.
1. Create a Flag with Bezier Patches (60 points)
Create a single-colored flag based on two connected (along a horizontal or vertical edge) Bezier patches. You will need to accomplish the following things:
- Create a set of control points for two seamlessly (G1 continuity) connected Bezier patches. This Java app might help, but does not display the control points numerically. The control points are not allowed to all lie in one plane: the flag needs to have visible curvature. (10 points)
- Use uniform tessellation to produce a uniformly colored (use a bright color of your choice) triangle or quad mesh with at least 100 triangles/quads per patch. (20 points)
- Compute the normals for the vertices of the mesh as the cross product of the partial derivatives at each vertex. (10 points) You only need to compute normals for one side of the flag, the one the camera looks at.
- Illuminate the flag: set suitable ambient, diffuse and specular material reflection coefficients for the flag to give it a color other than black, white or gray. Place a light source in your scene (in camera coordinates) that illuminates the flag. Tweak material and light source parameters so that the curvature of the flag is clearly visible (10 points).
- Integrate your mouse control functions to spin the flag around its center. Rotations of the flag should not move the light source: the light source needs to remain fixed in camera space. (10 points)
- G1 continuity is similar to C1, but tangents just have to be parallel, don't need to have equal length.
- Ignore what happens when the user rotates the flag to look at the other side of it: due to the normals pointing in the wrong direction, lighting will be wrong, and if back face culling is on, the back side will be invisible.
- Do not use any of the curve generating OpenGL routines for this part of the assignment (i.e., glMap, glEvalCoord, glMapGrid, glEvalMesh). These are reserved for the extra credit problem.
2. Add a Texture to the Flag (40 Points)
Add a texture image to the flag, which stretches across its entire area.
To familiarize yourself with texture mapping in OpenGL, we provide a sample program which loads a PPM file and uses it as a texture for a quad. You can cut and paste code from it into your homework project.
You will get points for the following accomplishments:
- Set the color of all your mesh polygons to bright white (glColor3f(1.0, 1.0, 1.0)), because this color will be multiplied with your texel colors. (5 points)
- Compute and set texture coordinates in a range of 0 to 1 for the vertices of your mesh with the glTexCoord2f command. Note that this range needs to extend across both patches: the bottom left corner of your flag should have texture coordinates (0,0), the top right corner should be (1,1). (10 points)
- Download this, this or this UCSD logo image in PPM format, which can be read with the code in the above mentioned sample program. Or download/create a different image of your choice. Texture-map your flag image to the Bezier patches. (20 points)
- Add support for the 't' key on the keyboard: hitting it should switch between the textured and the solid colored flag from part 1. (5 points)
Note: Use the following settings for your texture after your first glBindTexture for correct lighting, filtering, and texture repeat mode settings:
// Make sure no bytes are padded: glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Select GL_MODULATE to mix texture with color for shading: glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Use bilinear filtering for higher visual quality: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Set the wrap mode (but it doesn't make a difference in this project): glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
3. Extra Credit: Animate the Flag and Accelerate Rendering (10 points)
Animate the Flag
Make the flag look like it waves in the wind by doing the following things:
- Use mathematical functions (e.g., sin, cos, or polynomial functions) to move the control points in two dimensions, to make the flag appear as if it waves in the wind. Use random numbers where appropriate to make the motion less uniform. You can choose to leave the control points at one end of the flag fixed to appear as if the flag is attached to a mast pole. (3 points)
- Support the number keys 1 through 9 to change the wind speed from 'no wind' to 'hurricane', which should gradually speed up the waving. (2 points)
Speed up Rendering
- Use OpenGL's NURBS support functions to speed up rendering of the flag. Support the 'a' key to toggle acceleration on and off, which switches between rendering the flag with and without OpenGL's NURBS functions. (3 points)
- Display the frame rate (frames per second) in the text window (or in the graphics window if you can) once every second. Increase the tessellation level (i.e., the number of polygons used to render your flag) until you get a significant speedup between accelerated and non-accelerated version of your flag. (2 point)
Note: OpenGL provides accelerated functions (e.g., glMap, glEvalCoord, glMapGrid, glEvalMesh, gluNewNurbsRenderer) to support the rendering of NURBS curves and patches. NURBS curves are supersets of Bezier patches. The OpenGL Red Book provides a good explanation with sample code for how to use these functions, and there is also a useful PDF document on this topic, as well as a web page on GLU's NURBS support functions.