The Fountain Simulation
Before you start
To understand the basics for this tutorial and to learn what you need to compile the source, please visit www.codecolony.de and read the first tutorials.
What can I learn in this tutorial?
This tutorial will show you
- some basics of physical simulation (simulation of a water drop)
- how to get antialiased points
- how to use blending
Some basic physics...
Simulation of physics is a very interesting topic. If you are planning a project where
you need lots of physics you should consider using a so called "physics engine". See
www.codecolony.de/Tokamak for an example.
What we want to do in this tutorial is much simpler: The target is to display a nice looking fountain, so we have to calculate the movement of the water. To make this easy, let's assume the following points:
- the water consists of discrete water drops
- each drop is considered to have a certain mass and a size of zero (we will use a size>0 for displaying, of course)
- the drops do not influence each other
- An object at rest tends to stay in rest and an object in motion tends to stay in motion in a straight line at constant speed unless acted upon by an outside force.
- The alteration of motion is proportional to the motive force impressed; and is made in the direction of the right line in which that force is impressed.
Knowing the acceleration and starting speed we can calculate the position at each point in time by using integration over time.
How can I render antialiased points?
When I wrote the example, I realized, that the foutain and its surrounding was drawn bigger or smaller, when I resized the window, but the drops' size remained the same. This didn't look too good, so I thought I could place a glPointSize() in my resize-function. But this command is only sensible, when you use antialiasing. This is only possible, when blending is enabled. Then the pixels next to the point's center do not get the point's color, but are blended with the color in the color buffer.
How can I use blending?
Blending means that a pixel's color isn't replaced by another color, but they are "mixed". Therefore you can use the alpha value of colors, it indicates how much of the color of the consisting pixel is used for the new color - for antialiasing of points, OpenGL computes this alpha value. After calling glEnable(GL_BLEND); you have to tell OpenGL how to use the alpha values. It isn't specified, that a higher alpha-value means more transparency or something like that. You can use them as you want. To tell OpenGL what you want, you must use glBlendFunc(). It takes two parameters, one for the source factor and the second for the destination factor. I used GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA as parameters. This combination is used quite often. Its effect is, that a higher alpha value means less transparency of the incoming fragment, i.e. the source.
The code contains several comments and further hints, so take a look at it:
ContactAny comments? Contact me!