Search code examples
openglfreeglut

opengl: How to display a comet and path traced by it?


I am trying to do some opengl programming using freeglut. Suppose an object(comet/aeroplane) which moves in 3D space and I want render the path traced by it as a point cloud (which represents white trail left behind by aeroplane).

My problem is, I need to clear the screen using glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) every time glutDispFunc is called in-order to give movement to the aeroplane(I am using a keyboardfunction to change the position of the plane). However I also need to display a huge number of points which go on accumulating as the plane moves.I have tried with clear screen using

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

which results in severe performance degradation as the number of points increase but can display the moving plane as well as the cloud of points. Anyone knows how to handle such scenarios?


Solution

  • Yes, you clear screen and redraw everything every time. That's how many game engines work.

    However I also need to display a huge number of points which go on accumulating as the plane moves.I have tried with clear screen using

    You're probably trying to draw too many particles. 100 particles (or a few hundreds, but less than a thousand) should be enough to draw comets trail. With just 200 (BIG) particles, you can create very convincing cloud.

    Also, you don't need points to draw comet trail. Using alpha-blending you can draw semi-transparent light-saber-like lines easily using triangles.

    Light-saber-like, plasma-like, flame-like should use any color with small tint of white (rgb 255, 10, 10, for example), and are traditionally drawn using glBlendFunc(GL_SRC_ALPHA, GL_ONE)

    Here are few examples. Examples show triangular mesh you should use. Numbers indicate alpha. 0 - fully transparent, 1 - fully opaque. slashes indicate triangulation, when necessary. "|" and "-" indicate face edges:

    glowing line

     0--0--0--0
     | \|  | /|
     0--1--1--0
     | /|  | \|
     0--0--0--0
    
     repeat
     0--0
     |  |
     1--1
     |  |
     0--0
     to add more segments
    

    thick glowing line

     0--0--0--0
     | \|  | /|
     0--1--1--0
     |  |  |  |
     0--1--1--0
     | /|  | \|
     0--0--0--0
    repeat
     0--0
     |  |
     1--1
     |  |
     1--1
     |  |
     0--0
    to add more segments.
    

    You can use something like that for comet trail. And add few small particles for sparks or something. Also don't forget about textures. Using textures you can easily add more details than if you were trying to draw everything using untextured geometry.

    --edit--

    aeroplane's white trail

    To implement smoke of any kind...

    1. you need to use very BIG textured particles with "smoky"/"cloudy" texture. If you google "smoke particle texture" on google images, you'll see what I'm talking about.
    2. Those "big" particles cannot be normally drawn using point sprites (because it can be bigger than screen at close distance) and require "billboards". Billboard is a square that always faces camera.
    3. Ideally color channel of smoke texture should be completely white (so you can color individual particles using vertex color), and "smoke" should be painted on alpha.
    4. Smoke particles should be sorted by depth when you draw them and should be rendered from farthest to nearest (from camera). Insertion sort algorithm works well with "partially sorted" data.
    5. Smoke particles should be rendered with depth write disabled (glDepthMask(0), if I remember correctly)
    6. Smoke particles should use glBlendFunc(GL_SRC_ALPHA, GL_INV_SRC_ALPHA) blending.
    7. However, if there's flame within smoke, flame should use glBlendFunc(GL_SRC_ALPHA, GL_ONE). Flame particles should be either intermixed with (i.e. sorted by depth along with them), or drawn after the smoke (if it uses separate particle system).
    8. To make smoke realistic, assign small initial velocity to all particles, slowly increase their size with time, and make them become more transparent. When particles become completely transparent, remove them from particle system.
    9. When drawing semi-transparent alpha blended surface, enable alpha-test and cut off pixels with alpha==0. This will speed up rendering. (Important, because you can kill framerate with too many smoke particles even on decent hardware)
    10. using many billboard smoke particles can be expensive especially if they're very close, so if you want to fill large area with this smoke and particles are going to be large and float at eye level, covering entire screen area with semi-transparent surfaces multiple times, you might want to research some other volumetric fog technology.
    11. Do not move individual particles using matrices. Do not draw one particle per call. Draw them all in one go, this will be much faster.