CS 457/557 -- Winter Quarter 2023

Project #7B

100 Points

Due: March 10

This project is an alternative to the Geometry Shader Project #7 for those who do not have access to a system that can handle Geometry Shaders. All others must do the Geometry Shader Project #7.

If you think you did this project in CS 450/550, note that this one is different!

Texture Mapping with Shader-based Distortion

This page was last updated: February 26, 2023


The goal of this project is to map a texture (your choice) to an object (your choice) and then distort it in some way. Use shaders to change a vertex's s and t coordinates. What you do here is up to you, but make it more than trivial. But, whatever you do, make it so that you could not do the same thing with rigid body rotates, scales, or translates. That is, the distortion must be different all over the object. You can't just slide the texture around or up/down the object.

A Possibility: Use shaders to change a vertex's s coordinates as a function of its t coordinate, or vice versa.


  1. Read in a texture image. The choice of image is up to you. Use the BmpToTexture( ) function to read it in. Some older graphics cards require the dimensions of this image be powers of two. So, if the texture on your object looks weird, try making the object dimensions come out to powers of two.

  2. Create a 3D object that has texture coordinates (s,t) at the vertices, specified by glTexCoord2f( ) calls before each call to glVertex3f( ). The OsuSphere works very well and would be a good place to start even if you are planning to eventually use something else.

  3. Under control of the Time variable, animate the distortion of the s and t coordinates in the vertex shader.

  4. Apply the texture in the fragment shader.


Use the Teach system to turn in your:

  1. .cpp file
  2. A one-page PDF with a title, your name, your email address, a nice screen shot from your program, and the link to the video demonstrating that your project does what the requirements ask for. Narrate your video so that you can tell us what it is doing.

Files You Might Want

Click here to get the BmpToTexture( ) function. (It is already in your sample code.)

Click here to get the worldtex.bmp file.

Click here to get the OsuSphere( ) function.

Timing Your Scene Animation

Here is a good way to animate:

Set a constant called something like MS_PER_CYCLE that specifies the number of milliseconds per animation cycle. Then, in your Idle Function, query the number of milliseconds since your program started and turn that into a floating point number between 0. and 1. that indicates how far through the animation cycle you are. So, in Animate, you might say:

#define MS_PER_CYCLE	10000
. . .
int ms = glutGet( GLUT_ELAPSED_TIME );
Time = (float)ms / (float)MS_PER_CYCLE;		// [0.,1.)

Remember Everything That Needs to Be Setup!

In the global variables:

unsigned char * Texture;	// the texels
unsigned int    WorldTex;	// the texture object
unsigned int	MyObjectList;	// the display list object

Setting up the Texture:

At the end of InitGraphics( ), read the texture and create a texture object from it:

int width, height;
Texture = BmpToTexture( (char *)"worldtex.bmp", &width, &height );
if( Texture == NULL )
        fprintf( stderr, "Cannot open texture '%s'\n", "worldtex.bmp" );
        fprintf( stderr, "Width = %d ; Height = %d\n", width, height );

glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glGenTextures( 1, &WorldTex );
glBindTexture( GL_TEXTURE_2D, WorldTex );
glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, Texture );

Setting up the Object Display List:

Then, after that in InitGraphics( ):

glGenLists( 1, &MyObjectList );
glNewList( MyObject, GL_COMPILE );
	OsuSphere( 2.f, 30, 30 );	// or something else, such as reading an OBJ file
glEndList( );

In Display( ):

Pattern->Use( );
glActiveTexture( GL_TEXTURE6 );		 // use texture unit 6
glBindTexture( GL_TEXTURE_2D, WorldTex );
Pattern->SetUniformVariable( "uTime", Time );
Pattern->SetUniformVariable( "uTexUnit", 6 );
glCallList( MyObjectList );
Pattern->Use( 0 );			// or Pattern->UnUse( )

Something to Notice

If you do use the sphere with the Earth texture, so that it looks like a globe, you will find that orthographic looks nicer than perspective. You can see more of the sphere this way. Try it.


Item Points
Correctly draw the normal-texture object 40
Correctly draw the distorted-texture object 30
Correctly animate the distorted-texture object 30
Potential Total 100