Introduction to Computer Graphics, jgfoster/2022
Source Code and Demos
This page contains links to source code for the programs that are used as examples in this book. In the web site download of the book, the source code examples can be found in the folder named source. This page also contains a list of links to all of the "live demos" that are used in the book; they can be found in the folder named demos.
(Note: Examples and demos for HTML canvas graphics, three.js, and WebGL are html files, which can be opened in a web browser. Many of the html programs use images. In certain browers, the html programs that use images will not work when the html files are loaded from a local hard drive. That is, they will fail in some web browsers when run from the source or demo folder in the web site download of this book. The programs should work OK when loaded from a web server.)
1. Java Graphics2D Examples
There are a few examples in Section 2.4 and Section 2.5 that use Java's 2D graphics API. In the web site download, the source code for these examples can be found in the folder named java2d inside the source folder. Each example is a single file that can be compiled to produce an application; no additional Java files are needed.
- HierarchicalModeling2D.java — shows a simple animated scene, with a moving cart and rotating windmills, that uses hierarchical modeling. In this version of the program, the hierarchy is implemented procedurally, using subroutines to draw the objects in the scene.
- SceneGraphAPI2D.java — shows the same scene as the previous example, but this time implemented using a scene graph data structure. The scene graph is implemented using static nested classes in the main class.
- GraphicsStarter.java and AnimationStarter.java draw simple static and animated scenes, respectively, and are meant to be used as a framework for experimenting with Java graphics. EventsStarter.java is a similar framework for working with mouse and key events in a graphics program.
- PaintDemo.java draws a polygon that can be filled with either a gradient or a texture image, and lets you adjust their properties. This is just a demo of Java paints. The image files QueenOfHearts.png and TinySmiley.png are part of this program and must be in the same location as the compiled Java class files when the program is run.
- JavaPixelManipulation.java is a demo that manipulates colors of individual pixels in a BufferedImage. The user can draw a simple picture or load an image from a file. A "Smudge" tool smears out pixel colors, and filters modify the image by performing averaging operations on the pixel colors in the image.
2. HTML Canvas 2D Examples
The 2D canvas API is discussed in Section 2.6, and several examples are mentioned in that section. Canvas examples are written as web pages, and you can look at the web page in a browser to see what it does. However, you are also meant to read the source code. And the first four examples are meant to be used as a basis for your own experimentation. (Note that all of the live demos in Chapter 2 use the canvas API, but you are not necessarily meant to understand the source code of the demos.) In the web site download of this book, you can find these examples in the canvas2d folder inside the source folder.
- GraphicsStarter.html is a minimal framework for drawing on an HTML canvas. It includes examples of drawing text and various shapes.
- GraphicsPlusStarter.html adds a few convenience functions to the previous example, including a function for setting up a coordinate system on the canvas and functions to draw shapes such as lines and ovals that are not included in the basic API. It includes examples of using transforms
- AnimationStarter.html adds animation to the previous example and includes a simple example using hierarchical modeling.
- EventsStarter.html is a minimal framework for using keyboard and mouse events with a canvas, with some examples of basic event handling.
- SimplePaintProgram.html lets the user draw using simple shapes. There is also a "smudge" tool that lets the user smudge the drawing as if it is drawn in wet paint; this is an example of pixel manipulation in the HTML canvas API. The program shows how to use an "off-screen canvas." The demo program c2/SimplePaintDemo.html is a version of this program that uses an "overlay canvas" instead of an off-screen canvas.
3. Scalable Vector Graphics Examples
Section 2.7 discusses SVG, a scene description language for 2D vector graphics. Several examples were discussed in that section. These examples can be opened in a web browser to see the images they produce. View the source code for the web page to see the program that produces the image. You can also open the files in a text editor to read the source. Some of the examples produce animated images. Old browsers can't show SVG images, but any browser that works with the rest of this textbook should be able to view them. (Note that Internet Explorer, at least through version 11, will not show SVG animation; it will show a static image instead.) These examples can be found in the svg folder inside the source folder.
- first-svg-example.svg is a very short first example that just draws a few basic shapes.
- svg-starter.svg shows the basic document structure for an SVG image, includes examples of most of the basic shapes, and has a lot of comments to explain what is going on.
- svg-face.svg is a very simple first example of grouping.
- svg-hierarchy.svg is an example of hierarchical modeling that makes a model of a wheel and a model of a cart that uses two wheels as components. The image shows a wheel and four copies of the cart. The wheel and cart models are also used in the cart-and-windmill animation at the end of this list.
- first-svg-animation.svg contains examples of simple animation, keyframe animation, and transform animation.
- hierarchical-animation.svg shows a simple animated hierarchical model.
- cart-and-windmill.svg is a more complex example of hierarchical modeling in SVG. The scene is an animation that shows a "cart" moving down a road as windmills turn in the background. The animation is the same as the one implemented in the Java example java2d/HierarchicalModeling2D.java and in the JavaScript demo c2/cart-and-windmills.html.
4. OpenGL 1.1 Examples
OpenGL 1.1 is the topic of Chapter 3 and Chapter 4. Examples in those chapters primarily use the C API for OpenGL. However, the Java API, JOGL, is also discussed. Most program examples are available in both the C and the Java APIs. The JOGL versions can be found in the directory named jogl inside the source directory. The C versions, which use the GLUT library to create and manage OpenGL windows, can be found in the directory named glut inside source. (Many of these programs use a "camera" API defined in jogl/Camera.java for Java and in glut/camera.c and glut/camera.h for C.)
The OpenGL demos in the book are written using glsim.js, a JavaScript library that implements a small subset of the C API for OpenGL 1.1. Information about glsim can be found in glsim/glsim-doc.html. Some of the program examples are available in HTML versions that use the glsim library. They can be found in the glsim directory inside source.
- glut/first-triangle.c, jogl/FirstTriangle.java and glsim/first-triangle.html are C, Java, and JavaScript versions of the very first OpenGL example: a triangle whose vertices are assigned the colors red, green, and blue. You can use this example as a starting point for trying out some basic 2D drawing commands. From Section 3.1.
- glut/unlit-cube.c, jogl/UnlitCube.java, and glsim/unlit-cube.html are C, Java, and JavaScript versions of a program that draws a cube using modeling transformations applied to a square. There is no lighting in this program, and it uses a basic orthographic projection, so the image is not realistic. From Section 3.2.
- glut/opengl-cart-and-windmill-2d.c (for C), jogl/CartAndWindmillJogl2D.java (for Java), and glsim/opengl-cart-and-windmill.html (for JavaScript) are versions of an example of hierarchical modeling and animation in two dimensions with OpenGL 1.1. It illustrates 2D graphics in OpenGL as well as the use of glPushMatrix and glPopMatrix for hierarchical modeling. The animation is almost the same as the one implemented in the Java Graphics2D example java2d/HierarchicalModeling2D.java and in the HTML canvas graphics demo c2/cart-and-windmills.html. From Section 3.2.
- glut/camera.c and the corresponding header file glut/camera.h for C, or jogl/Camera.java for JOGL, implement a "camera" API for use with OpenGL 1.1. This is a library for use in other programs, not itself a complete program. The corresponding API for JavaScript is part of my GLSim library, glsim/glsim.js. A camera is used in most of the following examples. Discussed in Section 3.3.
- glut/ifs-polyhedron-viewer.c and jogl/IFSPolyhedronViewer.java are C and Java versions of a program that lets the user view polyhedra that are defined as indexed face sets. The polyhedra models are defined in jogl/Polyhedron.java for Java and in glut/polyhedron.c and glut/polyhedron.h for C. This program also requires the camera API discussed in the previous item. From Section 3.4.
- glut/cubes-with-vertex-arrays.c, jogl/CubesWithVertexArrays.java, and the JavaScript version glsim/cubes-with-vertex-arrays.html demonstrate drawing using glDrawArrays and glDrawElements. From Section 3.4.
- glut/color-cube-of-spheres.c and jogl/ColorCubeOfSpheres.java draw a large number of spheres using a variety of rendering methods, and show the time that it takes to render the image. The point is to compare render times for different rendering methods, including display lists, glDrawArrays, and vertex buffer objects. The reader is not expected to understand all of the code in this program. From Section 3.4.
- glut/glut-starter.c, jogl/JoglStarter.java, and glsim/glsim-starter.html are "starter" files for writing OpenGL 1.1 applications using C, Java, and my JavaScript OpenGL simulator. These programs don't draw anything, but they have function/method stubs for drawing as well as for mouse and keyboard interaction and animation. Discussed in Section 3.6
- glut/four-lights.c and jogl/FourLights.java are an example of using light sources and material properties. The program demonstrates multiple, moving light sources and lets the user turn the lights on and off to see the effect. The demo glsim/fout-lights-demo.html is a JavaScript version of the same program. From Section 4.2.
- glut/texture-demo.c is a C program that shows a variety of textures on a variety of objects. It depends on the files glut/textured-shapes.c and glut/textured-shapes.h, and on the folder glut/textures that contains the texture images used by the program. The Java version is jogl/TextureDemo.java, and it requires jogl/TexturedShapes.java, as well as the image folder jogl/textures. From Section 4.3.
- glut/texture-from-color-buffer.c and jogl/TextureFromColorBuffer.java demonstrate the technique of copying an image from the color buffer using the function glCopyTexImage2D(). Draws an animated 2D scene and then uses it as a texture on various objects. Requires the same textured shape libraries mentioned in the previous item. From Section 4.3.
- glut/texture-objects.c is a small program to demonstrate the use of texture objects to handle multiple textures. It is available for C only. From Section 4.3.
5. Three.js Examples
Three.js is a JavaScript library for 3D graphics on Web pages, using WebGL and the HTML canvas. It is discussed in Chapter 5. The examples can be found in the folder named threejs, inside the source folder of the web site download. All of the examples use the JavaScript file threejs/three.min.js, which is a "minified" version of the library, not meant for human readers. The original version, threejs/three.js is also available. The version is three.js Release 89. Three.js is an open-source project. It can be downloaded from threejs.org.
- threejs/full-window.html — Three.js is typically used to write programs that fill the browser window and continually run an animation. This example shows how to do that, but my other examples do not follow the same pattern. The animation shows colored balls bouncing around inside a translucent box. The user can rotate the scene with the mouse. From Section 5.1
- threejs/modeling-starter.html — A starter program for experimenting with building and animating a scene graph model with three.js. The user can rotate the model using the keyboard. It includes a simple example. From Section 5.1
- threejs/diskworld-1.html — Shows an animated model of a simple "car" driving around the edge of a disk, with "trees" made from a cylinder and a cone. Based on the previous sample program. From Section 5.1
- threejs/MeshFaceMaterial.html — Shows how to use a MeshFaceMaterial on a cube and on a pyramid whose geometry is constructed by hand as an indexed face set. From Section 5.2
- threejs/textured-pyramid.html — Shows the same pyramid as the previous example, with a texture. Shows how to define texture coordinates for a three.js geometry. From Section 5.2
- threejs/curves-and-surfaces.html — Creates several surfaces using a parametric surface, tube geometry, lathing, and extrusion. From Section 5.2
- threejs/json-model-viewer.html — Displays models that are loaded from files in the JSON format used by three.js. I exported one of the models from Blender. The others are from the three.js download. (See the demo c5/mesh-animation.html to see animated versions of two of the models.) From Section 5.2
- threejs/anaglyph.html — Uses an AnaglyphEffect to show a scene meant to be viewed with red/cyan 3D glasses. Aside from the anaglyph effect, the program is a copy of threejs/full-window.html. From Section 5.3
- threejs/skybox.html — Demonstrates using a cubemap texture to make a skybox. From Section 5.3
- threejs/reflection.html — A demonstration of using an environment map to simulate the reflection by an object of its environment. The environment is a skybox. From Section 5.3
- threejs/refraction.html — A demonstration of simulated refraction. This example is almost identical to the previous example, except for using refraction rather than reflection. From Section 5.3
6. WebGL Examples
WebGL is the version of OpenGL for use on Web pages. It is discussed in Chapter 6 and Chapter 7. The sample programs can be found in a folder named webgl, inside the source folder of the web site download. The sample programs for WebGL are HTML files. Run the programs by opening them in a Web browser. View the source code in a text editor or using a "View Source" command in a web browser. Part of a WebGL program is written in JavaScript. The other part consists of a vertex shader and a fragment shader written in GLSL. Many of these examples rely on scripts that are in the same webgl directory. In particular, the 3D examples use the glMatrix library (Subsection 7.1.1).
- webgl/webgl-rgb-triangle.html — The standard OpenGL example rendered using WebGL: a triangle whose vertices are red, green, and blue, where the colors of interior pixels are computed by interpolating colors from the vertices. Demonstrates the use of attributes and varying variables. From Section 6.2
- webgl/shape-stamper.html — The user "stamps" shapes onto the canvas by clicking it with the mouse. Properties of the shape are determined by a set of pop-up menus. Demonstrates the use of uniform variables, the preserveDrawingBuffer option on the WebGL context, and a simple coordinate transformation in the vertex shader. From Section 6.2
- webgl/moving-points.html — A set of circles moves around in the canvas, bouncing off the edges. Shows how to use the POINTS primitive in WebGL and introduces the discard statement in the fragment shader. From Section 6.2
- webgl/simple-texture.html — A very minimal texture example. It just applies a texture image to a triangle. From Section 6.4.
- webgl/texture-from-pixels.html — Shows how to load a texture from an array that contains the pixel color component values for the texture. (Also demonstrates the difference between a gl.LINEAR and a gl.NEAREST magnification filter.) From Section 6.4.
- webgl/cubemap-fisheye.html — Loads a cubemap texture, but uses it in a 2D context to imitate a picture taken with a fisheye lens. 2D texture coordinates are first mapped onto a sphere to get the direction vector that is used to sample the cubemap. From Section 6.4.
- webgl/simple-hierarchy2D.html — Demonstrates using 2D modeling transformations in WebGL and GLSL, with some simple animated hierarchical objects. Transforms are implemented in JavaScript as objects of type AffineTransform2D, defined in the file webgl/AffineTransform2D.js. From Section 6.5.
- webgl/glmatrix-cube-unlit.html — A first example of doing 3D graphics directly in WebGL, with no lighting. From Section 7.1.
- webgl/cube-with-simple-rotator.html — Demonstrates the use of a SimpleRotator (defined in webgl/simple-rotator.js) to do mouse rotation. From Section 7.1.
- webgl/cube-with-trackball-rotator.html — Demonstrates the use of a TrackballRotator (defined in webgl/trackball-rotator.js) to do mouse rotation. This is almost identical to the previous example. From Section 7.1.
- webgl/cube-with-basic-lighting.html — A first example of implementing lighting directly in WebGL. Adds lighting to webgl/glmatrix-cube-unlit.html. The lighting in this case uses only diffuse color and a directional light from the direction of the viewer. From Section 7.2.
- webgl/basic-specular-lighting.html — A first implementation of specular reflection. From Section 7.2.
- webgl/basic-specular-lighting-Phong.html — A second implementation of specular reflection, using Phong shading (with the lighting calculations in the fragment shader). Aside from moving the calculation to the fragment shader, this example is identical to the previous example. From Section 7.2.
- webgl/parametric-function-grapher.html — Lets the user graph a parametric surface, given by equations x(u,v), y(u,v), and z(u,v) entered by the user. A relatively complex program, it illustrates GLSL data structures, two-sided lighting, and polygon offset. From Section 7.2.
- webgl/spotlights.html — A demo of spotlights, with three colored spotlights. The user can change the cutoff angle and spot exponent. From Section 7.2
- webgl/diskworld-2.html — A relatively complex program with hierarchical modeling and several kinds of lighting, including moving lights, spotlights, and light attenuation. This is the same scene as the three.js example threejs/diskworld-1.html, with added lighting features. From Section 7.2.
- webgl/texture-transform.html — Animated texture images, using glMatrix to implement texture transformations. From Section 7.3.
- webgl/bumpmap.html — A mostly successful attempt to implement bumpmapping. From Section 7.3.
- webgl/skybox-and-env-map.html — Uses a cubemap texture to make a skybox and as an environment map. From Section 7.3.
- webgl/image-blur.html — Applies a blur filter to an image. A very simple demo of using blending for something other than transparency. Also a very simple example of a multi-pass algorithm. From Section 7.4.
- webgl/render-to-texture.html — Uses a WebGL framebuffer to draw an image directly into a texture. From Section 7.4.
- webgl/cube-camera.html — Shows a skybox and moving cubes reflected on the surface of an object. Uses a dynamic cubemap texture as an environment map on the reflective object. The six images for the cubemap texture are redrawn for each frame of an animation. From Section 7.4.
- webgl/anisotropic-filtering.html — Demonstrates the use of the WebGL anisotropic filtering extension. Shows a large textured rectangle extending into the distance and lets the user turn anisotropic filtering on and off. From Section 7.5.
- webgl/image-evolver.html — demonstrates use of the WEBGL_color_buffer_float WebGL extension. The application is a simple genetic algorithm that tries to approximate a given image. The floating point color buffer is used for finding the average of the color values in an image. From Section 7.5.
7. Live Demos
This book includes "live" or "interactive" demos. The demos are small programs written as web pages using JavaScript and either HTML canvas graphics or WebGL. Although they are designed to be run as small applications inside other web pages, they can also be run as independent web pages. In the web site download of this book, you can find the demos in the folder named demos, organized by chapter number. They can be run directly from that folder. Note that each of the demos requires certain other files that are contained in the demos folder; if you copy a demo to a different location, be sure to also copy all the files on which it depends.
The demos from Chapter 2 use the 2D canvas graphics API, which will work in almost all modern web browsers, including Internet Explorer 9 or later. Demos from the remaining chapters use WebGL, which will work with most modern desktop browsers, including Internet Explorer 11 or later, and many browsers on mobile devices. (However, WebGL might have problems in some of these browsers on some machines.)
The demos in Chapter 3 and Chapter 4 use glsim.js, a JavaScript library that I wrote to simulate a subset of OpenGL 1.1. Information about glsim can be found in glsim/glsim-doc.html.
For many of the demos, the reader is not expected to understand the program code for the demo at the point where the demo occurs in the book.
- c2/pixel-magnifier.html — from Section 2.1. Magnifies a small square of pixels in an image so that the user can see how text, lines and other shapes are made from pixels, including antialiasing.
- c2/rgb-hsv.html — from Section 2.1. Lets the user modify a color in the RGB and HSV color spaces by dragging sliders.
- c2/approximating-ovals.html — from Section 2.2. Shows how ovals can be approximated by a polygons with different numbers of sides.
- c2/cubic-bezier.html — from Section 2.2. Lets the user modify a cubic Bezier curve by dragging endpoints and control points.
- c2/quadratic-bezier.html — from Section 2.2. Lets the user modify a quadratic Bezier curve by dragging endpoints and control points.
- c2/transforms-2d.html — from Section 2.3. Lets the user apply a sequence of rotation, scaling, and translation transforms to a shape and see the results.
- c2/transform-equivalence-2d.html — from Section 2.4. attempts to demonstrate the equivalence between the modeling transform and the viewport transform in 2D.
- c2/cart-and-windmills.html — from Section 2.4. Shows a simple, animated 2D scene constructed using hierarchical modeling.
- c2/SimplePaintDemo.html — from Section 2.6. Lets the user draw on a canvas using some basic shapes. A "Smudge" tool illustrates pixel manipulation. This demo is pretty much the same as the sample program canvas2d/SimplePaintProgram.html.
- c2/image-filters.html — from Section 2.6. Lets the user apply a variety of "filters" to several images. A filter, as the term is used here, replaces the color of each pixel with a weighted average of the colors of that pixel and its eight neighbors.
- c3/first-triangle-demo.html — from Section 3.1. Shows the usual first example for OpenGL: A triangle with differently colored vertices. For this demo, you can change the colors of the vertices.
- c3/first-cube.html — from Section 3.1. Draws a cube with six different colors for the sides (with no lighting effects, and with the default orthographic projection). The user can turn the depth test on and off to see the effect. And the user can use a bigger cube, to see the effects of "clipping" when parts of the cube extend outside the visible range of z-values.
- c3/axes3D.html — from Section 3.2. Shows a set of coordinate axes in 3D. The user can drag the mouse to rotate the view.
- c3/rotation-axis.html — from Section 3.2. Illustrates rotation about an axis in 3D. A cube spins about an axis of rotation. The user can select the axis.
- c3/transform-equivalence-3d.html — from Section 3.3. attempts to demonstrate the equivalence between modeling and viewing in 3D. The user drags sliders to modify a transform, and sees that transform applied both to objects as a modeling transform and to the view volume as a viewing transform. The contents of the view volume and the image that is produced are the same in either interpretation.
- c3/ifs-polyhedron-viewer.html — from Section 3.4. Lets the user view a variety of polyhedra that are defined in the program as indexed face sets. The user can rotate the polyhedron and control some rendering options.
- c4/materials-demo.html — from Section 4.1. Lets the user change the diffuse, specular and shininess properties of an object and see the result.
- c4/smooth-vs-flat.html — from Section 4.1. Lets the user see the difference between using normal vectors to model a smooth surface versus modeling a flat-sided polyhedron.
- c4/four-lights-demo.html — from Section 4.2. Demonstrates the effect of multiple, differently colored, moving lights.
- c4/two-sided-demo.html — from Section 4.2. A little demo that illustrates two-sided lighting, with different front and back materials.
- c4/texture-transform.html — from Section 4.3. Shows textures on various objects, with texture transformations that the user can control using sliders.
- c4/texture-from-color-buffer.html — from Section 4.3. A simple demo of the copyTexImage2D() function; draws an animated 2D scene and uses it as a texture on a 3D object.
- c4/walkthrough.html — from Section 4.4. Lets the user move around in a 3D world by clicking buttons, demonstrating the idea of a moving viewer or camera.
- c5/point-cloud.html — from Section 5.1. A first example of using the three.js JavaScript 3D modeling API. It uses a PointCloud object to show an animated cloud of points.
- c5/mesh-objects.html — from Section 5.1. Lets the user view many of the basic three.js geometries, with a variety of materials.
- c5/vertex-and-color-animation.html — from Section 5.2. Uses per-face and per-vertex coloring to create a multicolored sphere. Both the colors and the position of the vertices can be animated.
- c5/textures.html — from Section 5.2. Demonstrates textures on a variety of three.js objects.
- c5/mesh-animation.html — from Section 5.2. Shows animated models of a horse and a stork, using models with "morph targets" and the class THREE.MorphAnimation. The models are from the three.js download.
- c5/raycaster-input.html — from Section 5.3. Lets the user edit a scene using the mouse. Uses an object of type THREE.Raycaster to get mouse input from the user.
- c5/shadows.html — from Section 5.3. Demonstrates support for shadows in three.js.
- c5/reflection-demo.html — from Section 5.3. Demonstrates environment mapping to simulate reflection of an environment. The environment in this case is a skybox. (The demo is very similar to the sample program threejs/reflection.html.)
- c6/shape-stamper-demo.html — from Section 6.2. A demo version of the sample WebGL program webgl/shape-stamper.html. The user clicks the canvas to stamp shapes onto the canvas, with properties determined by a set of popup menus. The demo has the same functionality as the sample program, but the shapes are drawn using a different technique.
- c6/moving-points-demo.html — from Section 6.2. A demo version of the sample WebGL program webgl/moving-points.html, with identical functionality. Uses a single gl.POINTS primitive to display a set of moving, colored disks.
- c6/webgl-limits.html — from Section 6.3. Displays a list of values for certain resource limits in WebGL, such as the number of attributes in a shader program or the size of the viewport. These values can be different on different devices and in different web browsers.
- c6/textured-points.html — from Section 6.4. shows texture images used on a primitive of type gl.POINTS. It is similar to moving-points-demo.html, except that the points are textured instead of colored.
- c6/multi-texture.html — from Section 6.4. Uses two textures on the same object, with two sampler variables in the shader program to represent the texture units that are used to apply the textures.
- c7/rotators.html — from Section 7.1. Demonstrates the difference between a SimpleRotator (webgl/simple-rotator.js) and a TrackballRotator (webgl/trackball-rotator.js) by letting the user rotate cubes using the two rotators.
- c7/per-pixel-vs-per-vertex.html — from Section 7.2. Lets the user compare per-pixel lighting to per-vertex lighting, by applying the two techniques to identical objects with identical lighting settings.
- c7/spotlight-demo.html — from Section 7.2. Three colored spotlights shine on a square, and the user controls the cutoff angle and spot exponent. A demo version of the sample program webgl/spotlights.html, with some added animation for fun.
- c7/generated-texcoords.html — from Section 7.3. Uses texture coordinates generated from object or eye coordinates, instead of providing the texture coordinates to the shader program as an attribute.
- c7/procedural-textures.html — from Section 7.3. Demonstrates several 2D and 3D procedural textures.
- c7/cube-camera-demo.html — from Section 7.4. Essentially a copy of the sample WebGL program webgl/cube-camera.html. Shows a skybox and moving cubes reflected on the surface of a teapot or other object. Uses a dynamic cubemap texture that is redrawn for every frame.