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.
This tutorial will show you
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:
Knowing the acceleration and starting speed we can calculate the position at each point in time by using integration over time.
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.
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: