For this MP, you will be implementing a Fractal Mountain by using a Random Midpoint-Displacement Method, in combination with a conic Control Surface. Your program will take input from the mouse to rotate the mountain in three-dimensions and input from the keyboard to designate the level of subdivision.
This MP also introduces the concept of Shading of objects in OpenGL, rather than coloring them. You will need to consult the OpenGL Programming Guide (or the online documentation) to learn more about how to specify lighting and surfaces to colorize the fractal mountain.
Upon completion of this MP, you should be able to do the following things:
Read Chapter 10, sections 18, in the required text for this class - ``Computer Graphics, C Version, 2nd Edition'' by Hearn & Baker. It discusses various fractals, including the Random Midpoint-Displacement Method you will need for this MP. You should pay close attention to the concept of fractal dimension and how it relates to the surface of the mountain. Such material may appear on the exam.
For this MP, you will be required to write a mouse input function that will allow you to view the objects on the screen from any angle. Basically, you will need to write code which will allow you to move the camera along the surface of a sphere surrounding the fractal mountain. The demonstration program for this MP shows one way of using the mouse to manipulate the view. It is a very basic method which operates on the camera rather than the objects. You should look in the ``Red Book'' for some possible camera manipulation routines.
You will also need to get input from the keyboard to set the level of subdivision and surface roughness of the fractal mountain. You can use code from previous MPs if you like.
In order to view the fractal mountain in three-dimensions properly, you need to turn on OpenGL lighting. In previous MPs, you simply drew to the screen using glColor to set the color of the various elements. If you try to use a similar convention to draw the fractal mountain, you will find that all of the surfaces have the same color. Instead, we want the fractal mountain to be shaded based not only on color, but also on each surface's orientation with respect to the light source. Therefore, we need to turn on lighting, and ``color'' the surfaces using glMaterial. You should look at the ``Red Book'' for more information on using lighting in OpenGL.
You are to write a program that generates a fractal mountain using the random midpoint-displacement method. You will do this by first generating a fractal landscape by applying the random midpoint-displacement method to a square ground plane, and then constraining this landscape to a mountain by using a conic control surface.
Some examples of mountains generated using this method are shown below. The examples are shown at various levels of subdivision.
![]() |
![]() |
![]() |
2 Subdivisions | 3 Subdivisions | 4 Subdivisions |
In order to view all sides of the fractal mountain, you have to figure out mouse input routines that will allow you to view the mountain from any angle. There are two approaches you can take. You can imagine the camera to be at a fixed location in space and use the mouse to rotate the fractal to any position OR you can imagine the fractal to be fixed in space and use the mouse to move the camera along the surface of a sphere surrounding the mountain.
The demonstration program takes the second approach, and is MUCH easier to implement. There is some code in the ``Red Book'' which may be useful to you. Chapter 3 talks about three-dimensional viewing. On page 119, you will find code for having a camera rotate about a fixes object. Three values are involved: azimuth, elevation, and twist.
Note that these are just suggestions. You can come up with a different scheme if you prefer. Whatever you come up with, be sure to document how to use the mouse to view the fractal. It would also be helpful to print out a USAGE message when the program first starts to let the user know the inputs to your program.
When the user types a number from ``1'' to ``6'', you must redraw the mountain with that many subdivisions. Your program will start off with displaying a mountain with 1 level of subdivision. This means that you will have your original square ground plane subdivided once, to obtain a 2x2 grid of 4 squares total. An input of ``6'' would divide your original square ground plane 6 times in order to obtain a 64x64 grid of 4096 squares total. (Notice: if we let S be the number of subdivisions, then the number of squares in the grid is 2S * 2S).
Note: if the user types a number and you are already displaying a mountain with that many subdivisions, then you do not need to recalculate the mountain. Recalculate the mountain only if the user types in a number different from the current level of subdivision.
When the user types the letter ``q'' or ``Q'', the program should exit.
Follow these implementation details when implementing your fractal mountain program.
/***********************************************************************/ /* RandomGaussian returns a random number from a Gaussian */ /* distribution with the given "mean" and "stddev". This algorithm */ /* was adapted from "Numerical Recipies in C" in the section on */ /* "Normal Deviates". Include <stdlib.h> for RAND_MAX. */ /***********************************************************************/ float RandomGaussian(float mean, float stddev) { float factor; float radiussq; float value1, value2; do { value1 = 2.0 * (float)rand() / RAND_MAX - 1.0; value2 = 2.0 * (float)rand() / RAND_MAX - 1.0; radiussq = value1 * value1 + value2 * value2; } while ((radiussq >= 1.0) || ((radiussq - 0.000001) < 0.0)); factor = sqrt(-2.0 * log(radiussq) / radiussq); return value1 * factor * stddev + mean; }
glScaled(...); glRotated(...); glTranslated(...);
This will be one of your biggest problems when dealing with OpenGL transformations. (Of course, if you want, you can use your own tranformation routines from MP2.)
GLdouble OldMatrix[16]; /* To save the current "invisible" matrix */ glGetDoublev(GL_MODELVIEW_MATRIX,OldMatrix); /* Save the matrix */ glLoadIdentity(); /* Clear the matrix */ glScaled(...); /* Apply our transformation sequence */ glRotated(...); /* Note again the "reversed" order! */ glTranslated(...); glMultMatrixd(OldMatrix); /* Multiply the saved matrix */
Here is the explanation. Let's say that the transformation matrix already on the matrix stack is called M. What we are trying to do is S * R * T * M (assuming points are represented as column vectors), but to accomplish this in OpenGL, we have to do the ``backwards'' multiplication shown in the sample code above.
Those graduate students enrolled for 1 unit of credit, and undergrad students registered for honors credit, must also implement the following additional functionality.
When the user types the letter ``c'' or ``C'', the mountain will become multicolored with ``dirt'' and ``snow''. To do this, color the bottom 1/4th of the mountain BROWN, the top 1/4th of the mountain WHITE, and the middle of the mountain GREEN.
The user can toggle this multicolored state on and off. By repeatedly typing ``c'' or ``C'', you change the mountain from all GREEN to BROWN/GREEN/WHITE and back. The initial state is all GREEN.
When the user types the letter ``m'' or ``M'', the mountain changes from a fractal mountain to a fractal landscape. If you want to display just a fractal landscape, then you don't constrain your grid to the cone.
When you are displaying the fractal landscape, draw the outline of the grid in BLACK so that you can better see the squares that make up the landscape. Do not draw this grid outline when drawing the fractal mountain. Note that when you draw this grid, you are not drawing polygons, and therefore you do not need to draw the grid outline as triangles.
The user can toggle the Mountain State on and off. By repeatedly typing ``m'' or ``M'', you can change the mountain into a landscape and back. The initial state is a fractal mountain.
When the user types the Up Arrow and Down Arrow keys, the H value is increased and decreased, respectively. As described in the textbook, H = 3 - D, where D > 2 is the fractal dimension for the surface. By increasing the H value, the fractal landscape becomes smoother. By decreasing the H value, the fractal landscape becomes more jagged.
For this MP, let the H value range from 0.2 to 1.8, in increments of 0.2. In other words, valid values for H are 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, and 1.8. Give H an initial value somewhere in the middle.
For this and future MPs, we will be using the electronic handin program. Once you have completed your program, logon or telnet to one of the Sun Sparc machines (``handin'' does not work on the WindowsNT machines) and hand in your source code by typing ``handin cs318 mp5 mp5.c''. (For more information on handing in your code, consult the class web page at http://www-courses.cs.uiuc.edu/~cs318/handin.html.) This will send your program to the class directory for grading.
Do not submit your executable program. Also, put all your source code in one file. You must hand in your source code file before 10:00am of the due date, as handin will not accept late assignments. Make sure your name, login, MP#, and date appear at the top of your code listing. See the class web page for a sample file header.
If your program does not run as required, you will be given at most 50% of the total points for the MP. You are responsible for making sure your program compiles on the WindowsNT machines using the makewin batch file.
Late assignments will not be accepted. If you are having problems beyond your control, you must let a TA know at least 24 hours before the due date to arrange for a possible extension. There will be no exceptions!