Height fields may be found in many applications of computer graphics. They are used to represent terrain in video games and simulations, and also often utilized to represent data in three dimensions. This assignment asks you to create a height field based on the data from an image which the user specifies at the command line, and to allow the user to manipulate the height field in three dimensions by rotating, translating, or scaling it. After the completion of your program, you will use it to create an animation. You will program the assignment using OpenGL's core profile.
This assignment is intended as a hands-on introduction to OpenGL and programming in three dimensions. It teaches the OpenGL's core profile and shader-based programming. The starter code we provide is minimal, giving only the functionality to initialize GLUT, read and write a JPEG image and handle mouse and keyboard input. You must write the code to handle camera transformations, transform the landscape (translate/rotate/scale), perform rendering, and handle any other functionality you may desire. Please see the OpenGL Programming Guide for information, or, OpenGL.org.
A height field is a visual representation of a function which takes as input a two-dimensional point and returns a scalar value ("height") as output. In other words, a function f takes x and y coordinates and returns a z coordinate.
Rendering a height field over arbitrary coordinates is somewhat tricky--we will simplify the problem by making our function piece-wise. Visually, the domain of our function is a two-dimensional grid of points, and a height value is defined at each point. We can render this data using only a point at each defined value, or use it to approximate a surface by connecting the points with triangles in 3D.
You will be using image data from a grayscale JPEG file to create your height field, such that the two dimensions of the grid correspond to the two dimensions of the image and the height value is a function of the image grayscale level. Since you will be working with grayscale image, the bytes per pixel (i.e., ImageIO::getBytesPerPixel) is always 1 and you don't have to worry about the case where the bytes per pixel is 3 (i.e., RGB images).
Starter code:
For the Windows platform, we provide the Visual Studio 2013 and 2015 solution/project files in ./hw1-starterCode. Additionally, the precompiled libraries (glew, freeglut and lib) for VS2013/2015 Win32 Debug/Release environment are included in the starter code package. Students who use Windows should be able to build the VS 2013 and VS 2015 projects directly.
On Linux, you need the libjpeg library, which can be obtained by
"sudo apt-get install libjpeg62-dev".
For Windows and Mac OS X, the starter code contains a precompiled jpeg library.
For Mac OS X, before you do any coding, you must install command-line utilities (make, gcc, etc.).
On Mac OS X Lion or newer, install XCode from the Mac app store,
then go to XCode, and use "Preferences/Download" to install the command line tools.
In Mac OS X Snow Leopard or older, you must install Mac OS X Developer Tools from the Mac OS X DVD.
Here is a sample sequence of Ubuntu or Mac Terminal Shell commands that get everything compiled:
> unzip assign1_coreOpenGL_starterCode_MSVS2013_linux_mac.zip
> cd hw1-starterCode
> make
> ./hw1 heightmap/spiral.jpg
If your OpenGL version is too low, try updating your graphics card driver to a more recent version. Nvidia drivers have been supporting OpenGL 3.2 since 2009. On the Mac, OpenGL core profile 3.2 is supported since Mac OS X 10.7.5.
Please email the TA if you have trouble compiling the starter code.
After finishing your program, you are required to submit a series of JPEG images which are screenshots from your program. Functionality to output a screenshot is included in the starter code, and assumes you are using a window size of 1280x720 -- your JPEG images must be this size. Please name your JPEG frames 000.jpg, 001.jpg, and so on, where 000.jpg is the first frame of your animation, and please do not exceed 300 frames. Expect a framerate of 15 frames per second, which corresponds to 20 seconds of animation running time maximum.
There is a large amount of room for creavitiy in terms of how you choose to show your results in the animation. You can use our provided input images, or modify them with any software you wish, or use your own input images. You may also use your animation to show off any extra features you choose to implement. Your animation will receive credit based on its artistic content, whether pretty, funny, or just interesting in some manner.
We will compile a video of all student submissions and show it in class. Optional: If you would like to convert your frames to a video by yourself, you can use Adobe Premiere, ffmpeg, QuickTime Pro, or Windows Movie Maker.
Please zip your code and JPEG images into a single file and submit it to Blackboard. After submission, please verify that your zip file has been successfully uploaded. You may submit as many times as you like. If you submit the assignment multiple times, we will grade your LAST submission only. Your submission time is the time of your LAST submission; if this time is after the deadline, late policy will apply to it.
By the milestone deadline, you must be able to render a single triangle on the screen. The triangle vertices are: (0,0,-1) (red color), (1,0,-1) (green color), (0,1,-1) (blue color). The triangles must be viewed with a camera positioned at (0, 0, zStudent), where zStudent = 3 + [10-digit USC student ID] / 10,000,000,000. Example: if your student ID is 4483471708, then zStudent=3.4483471708. The camera must be pointing in the negative-z direction, and use the perspective view: aspect ratio=1280:720, field of view = 45 degrees. Please upload a screenshot image (1280x720) of your result to the blackboard, to "Assignment 1 Milestone". No code submission is needed. The screenshot image should show the following: your first and last name, and your zStudent value. You can add this text using GIMP or Photoshop.
Milestone grading: we will deduct 10 points (from the final hw1 score) for a missing or late milestone submission. Incomplete or incorrect submissions will receive a deduction of 0-10 points. There are no late days for the milestone.
matrix->Perspective(fovy, aspect, 0.01, 1000.0);A bad call would be:
matrix->Perspective(fovy, aspect, 0.0001, 100000.0);or even worse:
matrix->Perspective(fovy, aspect, 0.0, 100000.0);In the last two examples, the problem is that the ratio between the distance of the far clipping plane (=last parameter to Perspective), and the distance of the near clipping plane (=third parameter to Perspective) is way too large. Since the z-buffer has only finite precision (only a finite number of bits to store the z-value), it cannot represent such a large range. OpenGL will not warn you of this. Instead, you will get all sorts of strange artifacts on the screen and your scene will look nothing like what you intended it to be.
You may choose to implement any combination of the following for extra credit.
Please note that the amount of extra credit awarded will not exceed 10% of the assignment's total value.
Input (Source Image) |
Output (Height Field) |
![]() |
![]() |
More inputs (real-world data): |
|||||
|