ECS175

ECS 175 Introduction to Computer Graphics

Spring Quarter 2000




Assignment 4: Texture Mapping and Surface Modeling


Due Date: Thursday, June 8, 2000

This assignment will complete the basic OpenGL implementation built during the first three projects by adding texture mapping capabilities. Furthermore, this assignment asks you to implement a program module (outside of GL) that can read in the control net of a tensor product Bezier patch and render an approximation to the patch, with correct normal vectors and texture coordinates.

Input to the Geometry Pipeline

To allow mapping a (two-dimensional) texture onto a polygon, texture coordinates have to be added to the properties stored in each vertex. In OpenGL, texture coordinates are specified using the glTexCoord2f call, which sets the current texture coordinate that is then used for all subsequent vertices. Texture coordinates are given in their own coordinate space, and are not modified by any vertex transformations.

Texture Map Specification

Texture maps are rectangular arrays of color values used to modify the final colors of generated primitives on a per-pixel basis. Textures are specified using the glTexImage2D function. The glTexImage2D call allows a plethora of internal and external texture storage formats; for this assignment, only the GL_RGB, GL_UNSIGNED_BYTE external mode has to be supported. The internal storage mode used is up to your implementations.

Texture Sizes and Coordinates

OpenGL restricts the sizes of textures to be powers of two (both in width and height). Texture coordinates are normalized, such that a coordinate (0, 0) always maps to the lower-left corner of the current texture image; (1, 1) always maps to the upper-right corner of the current texture image, no matter its size. Texture coordinates can lie outside the [0, 1] interval; if that is the case, OpenGL offers two strategies to wrap them back into the interval: The wrapping modes can be set for both coordinate axes independently.

Texture Value Look-up

After the interpolated texture coordinates have been wrapped to the interval [0, 1] using one of the above methods, they are scaled to the sizes of the current texture image, and the texture value is computed. There are two different methods to compute a texture value:

Pixel Color Modulation

After a texture value has been computed for a pixel using the above methods, this color is used to modulate the interpolated pixel color. OpenGL supports several different modulation formulas, the only one your implementations have to support is GL_MODULATE. This formula computes the final pixel color by multiplying the pixel's interpolated color and texture color.

OpenGL Functions to Implement

The following is a brief list of functions you have to implement to enable texture mapping for your graphics libraries:
glEnable(GL_TEXTURE_2D)
glDisable(GL_TEXTURE_2D)
This pair of calls enables / disables texture mapping.
glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels)
This function specifies the texture to use when rendering subsequent primitives. The parameters are:
target
Is always GL_TEXTURE_2D.
level
Is always zero.
internalFormat
Is always GL_RGB.
width
height
border
Specify the size of the supplied texture. width and height have to be powers of two, border is always zero.
format
Specifies the format of the supplied data. It is always GL_RGB.
type
Specifies the type of the supplied data. It is always GL_UNSIGED_BYTE.
pixels
A pointer to a rectangular array of texels, each one in the specified format. With the parameters as given, each texel consists of three unsigned chars containing the texel's red, green and blue value, in that order. A color component value of zero means no intensity, a value of 255 means full intensity.
glTexParameteri(target, pname, param)
Specifies several parameters needed for texture mapping. The target parameter is always GL_TEXTURE_2D. The possible values for pname are:
GL_TEXTURE_WRAP_S
GL_TEXTURE_WRAP_T
Set the texture coordinate wrapping mode for the s or t coordinate, respectively. The value of param can be either GL_CLAMP or GL_REPEAT.
GL_TEXTURE_MIN_FILTER
GL_TEXTURE_MAG_FILTER
Set the texture value computation mode. The value of param can be either GL_NEAREST (to enable nearest-neighbour sampling) or GL_LINEAR (to enable bi-linear interpolation). Your implementations do not have to distinguish between texture minification and magnification, and can use the last mode set for any of the two parameters.
glTexEnvi(target, pname, param)
This function sets, among other things, the texture modulation mode. target is always GL_TEXTURE_2D, pname is always GL_TEXTURE_ENV_MODE, and param is always GL_MODULATE. The call with these parameters sets the texture function to modulation, which is the only function your libraries have to support.
glTexCoord2f(s, t)
Sets the current texture coordinate used for all subsequent vertices. This value is neither transformed nor wrapped until the scan-conversion stage.

Surface Modeling

You have to write a program module (outside of OpenGL) that renders an approximation of a parametric tensor-product Bezier patch by evaluating the Bezier polynomial over a rectangular grid and drawing the resulting triangles. Your programs have to be able to handle patches of arbitrary degrees in both directions, and to calculate correct normal vectors for any parameter value. The control net is specified as a rectangular array of (degreeU + 1) * (degreeV + 1) points in model coordinates. The module will read the control net, construct the Bezier patch, and evaluate it over a grid of parameter values. The number of evaluation points in the grid should be settable by the user. The resulting triangles, together with correct normal vectors and texture coordinates for each vertex (use the parameter values as texture coordinates) are then passed to the OpenGL pipeline for rendering. The Bezier module should not affect any OpenGL state variables (except for normals and texture coordinates), such that a patch is always rendered with the current settings for materials, textures and light sources. You should use deCasteljau's algorithm to evaluate the Bezier polynomials.

Changes to the Scanner

These are the new commands the scanner has to understand to allow texture mapping and surface modeling:
textureLoad filename
Loads a texture from an image file and sets it as the current texture. The most straightforward image file format one could think of is the binary ppm format; your programs have to be able to understand this.
textureWrapS clamp
textureWrapS repeat
textureWrapT clamp
textureWrapT repeat
These command set the texture coordinate wrapping modes for the two texture coordinate directions.
textureSampling nearestNeighbour
textureSampling bilinear
These commands set the texture sampling mode
texcoord s, t
Sets the current texture coordinate.
bezierPatch degreeU, degreeV
This command starts the definition of a parametric tensor-product Bezier patch. The next (degreeU + 1) * (degreeV + 1) commands specify the control net in u-major order.
control x, y, z
Specifies a control point of a Bezier patch. These can only appear directly after a bezierPatch command.