In this tutorial, we will see how to add fog in the scene of the Tutorial 7.
Another usefull thing is time based movements. In previous tutorials, the
objects was updated for each frame at a fixed step, without taking into
account the time for rendering. Due to the performance of computers are
highly variable, frames rate (speed of rendering) is also highly variable from
computer to computer.
Time based movement is based on calculating the time passed for rendering a
frame. Then, depending on the object speed, we can calculate the object
movement between the last and the current frames. With this, the objects will
move at the same speed, independently to the frame rate and to the computer
used. The difference between a low or high performance computer, is the number
of frames rendered to display the same animation. On a performant computer,
the animation will be smooth, on an old computer the animation will be jerky.
Time based movement are necessary for realtime applications.
In the Lesson 4, you can lear how OpenGl computes fog and understand the effect of the differents properties of the fog.
The following code will show you how to set-up the fog. Please notice that
GL_FOG_DENSITY is only used by the modes
GL_EXP, GL_EXP2.
Similarly, GL_FOG_START and
GL_FOG_END are only used with
GL_LINEAR.
When using fog, to have a realistic effect, set the clearing (ie background) color to the fog color.
Initialization of the fog |
//Color of the fog : grey fog |
In the display loop, we will add a counter to know how many time was taken to
render our frames. This time will be used to update our animation to run at a
constant speed.
This counter will keep track of the time. By a subtraction between the current
time (currentTimeMillis) with last time keeped (lastTime), we
deduce the time passed to render the last frame and we store this value int
timePassed.
Time based movement (TimeFPSCounter) |
/* Enable the counter */ |
FPS for 'frame per second' is the speed of rendering.
This quantity is calculated with :
fps = 'number of frames render' / 'time to render the
frames'
Previously, we have have calculated timePassed
which is the time for rendering a
frame (in milliseconds). To calculate the FPS, at each frame, the formula
becomes :
fps = 1 / (timePassed/1000.0f)
In the TimeFPSCounter counter, the FPS is not updated each frame. It is updated
when a certain laps of time is passed, like this we calculate an average FPS.
This method should be called at each rendering :
Using updateTime |
public void display(GLDrawable glDrawable) |
Now, we have access in the display method of the time passed to draw the previous frame.
After the animation has been stopped and restart, we need to reset the time counter.
In Jogl/JSR231, after animator.start() we need to call lastTime = -1.
In Gl4java, to unpause the animation we call setSuspended(false).
The method ReInit can be overwritten in the GLAnimCanvas class. This method is called after
setSuspended(false)
was called.
So I've modify the calls in the container to put setSuspended(false, true) instead of setSuspended(false).
Unpause animation |
In Jogl
/ JSR-231: In Gl4java : |
Now, we know the last frame time and we want our objects moves at a constant
speed.
A speed have the dimension of a distance (or a rotation) over a time. To obtain
the movement distance/rotation, we simply multiply those two values like this :
speed*getTimePassed()
For a translation, the speed is the distance to be covered in a millisecond :
translationSpeed = ...;
//In units by milli-seconds
translationSpeed * getTimePassed()
For a rotation, the speed is the angle to be covered in a millisecond :
rotationSpeed = ...;
//In angles by milli-seconds
rotationSpeed * getTimePassed()
Increase Movements |
/** |
The screen refresh frequency tell the number of times per second the screen
is refresh. A screen at 75Hz, will render 75 images per seconds.
If your application is running at a fps speed considerably higher, for example
500fps, lot of frame will be computed but not used at all (ie not rendered to
the screen). This involve an important usage of the cpu and gpu for nothing.
In this case, the best way will be the rendered the maximum number of frames
handled by the screen. This can be easily done by synchronizing the application
with the screen refresh frequency, generally called V-Sync (vertical
synchronization) :
Enable/Disable V-Sync |
//JOGL |
In the contrary, if you want to render the maximum frame possible just disable
the V-Sync.
In some other cases, you may want to run at a different frame
rate (different to screen refresh freq.).
A typical case for that is an application which a huge amount of datas to be
computed or displayed. In that case, the fps can goes does lower than screen
refresh rate.
Suppose the case you want to set frame constant to 30fps. The maximum time to
prepare a frame will be maxFrameDuration = 1000ms / 30fps = 33.33ms. For
each frame rendered, track the duration: frameDuration.
When a fast frame occures (faster than 33.33ms), you will need to wait before
rendering the next one: waitTime = (maxFrameDuration - frameDuration).
Here is a simple example:
Constant frame-rate pseudo code |
final float constantFps = 30.0f; |
In addition to that, you can take into account too slow frames to wait less time
when faster frames will be rendered. I've just wanted to show you here the basic
idea.
1-3 : select a fog mode
F : enable/disable fog
P : pause/unpause z deplacement
+ - : increase/decrease fog density (has an effect for the mode 1 & 2)
Remember to download the GraphicEngine-1.1.2 to run this tutorial !
Tutorial 10 src ( 9 ko) //Port to Jogl JSR-231 initially done by Magarrett Dias
If you've got any remarks on this tutorial, please let
me know to improve
it.
Thanks for your feedback.
Copyright © 2004-2012 Jérôme Jouvie - All rights reserved. | http://jerome.jouvie.free.fr/ |