In this homework you will modify your OpenGL mesh viewer so that it loads and displays textures on the objects. You will also add an animated water-like surface.
Homework 6 is due on Tuesday Nov. 17 at 11:59 pm
For this lab we will add two new sections to the Separator block:
Texture2 {
filename cubetex.png
}
TextureCoordinate2 {
point [
0.140625 0.902344,
0.140625 0.554668,
...
]
}
The first section specifies the texture for the current Separator. The second section provides a list of UV-coordinates similar to the way Coordinate3 provides a list of XYZ-coordinates.
We will also add a section to the IndexedFaceSet subsection:
IndexedFaceSet {
coordIndex [ ... ]
textureCoordIndex [
0, 1, 2, 3, -1,
4, 5, 6, 7, -1,
...
]
}
This assigns a UV texture coordinate to each vertex of each face. Texture coordinate (0,0) is the upper-left corner of the texture image, and (1,1) is the lower-right corner.
This format is derived from the VRML 1.0 output of Blender. It should be valid OpenInventor, but your mileage may vary.
I can't figure out how to get Blender to produce normal vectors, and without normals, materials and lights are sort of useless so the sample files do not have them. Thus you should remove all of your lab4 code relating to lighting, materials, etc.
To use textures in OpenGL, you need to perform these steps:
Textures provided in this lab are in the PNG format. To read them you'll probably want to use libpng. See readpng.c / readpng.h for an example. Of course, you'll want to free the libpng data structures when you're done with them. And remember, when using these libpng functions you'll need to link with the "-lpng" flag. Note that libpng returns an array of rows, whereas OpenGL expects a big block of data. You'll have to do some conversion.
You can also convert the images to another format that you think is more convenient to load. (See for example the pngtopnm utility.)
NOTE: The .iv files we give you don't specify any object or camera rotations. Therefore, you should see the 'front' of the objects when you run your program. You can use mouse rotation to verify that your texture-mapping is consistent with the above image.
Below the object, add an animated surface. This surface should reflect an image called sky.png. To do this, you need to enable OpenGL's "sphere mapping" code:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T);
This uses the position and normal of each vertex to compute new reflected texture coordinates (S and T). Conceptually, the sky texture is mapped onto a very large sphere surrounding the sphere-mapped object, and the point where the normal vector intersects with this sphere is used by OpenGL to determine texture coordinates.
For OpenGL to compute texture coordinates, you need to specify normals correctly; see Normal.nb for an example. You can compute the surface however you want, as long as it moves. Try to make it look cool. Use GLUT's idleFunc to implement the animation. Note that GL_TEXTURE_GEN_{S,T} should be disabled while you're rendering the textured object from the previous section, since those texture coordinates are given rather than computed from normals.
You can use GLU's NURBS surface functions to generate the surface if you'd like. It will generate normals for you too. A much easier choice is to simply have height be a sinusoidal function of radius; in this case you can compute normals analytically.
NOTE: You aren't required to put leaves on your animated sphere-mapped surface.
Your program should be similar to the one from homework 4:
oglTexRenderer <xRes> <yRes> < <iv-file>
Include a README file with your code saying what you did, how to compile it, and anything else you think we need to know.
There are some sample objects in the data directory.
Here are some ideas for extra credit.
I'm open to suggestions.