Task 087: Fireworks

The task is to implement a real-time simulation of fireworks in 3D. This involves a fireworks launcher, from which rockets are fired, which then explode in the air and dissolve into shining particles. Missiles and particles should move under the influence of a constant gravitational field (g = 9.81 m/s2). They should not interact with each other, though.

Fireworks Screenshot


The template application 087fireworks from the repository grcis serves as the basis of this project. This is a ready to use application that can render a 3D scene that can be viewed via the "trackball" control system. The actual fireworks are created by the function Fireworks.Simulate(). The simulation can be controlled via the buttons Start / stop, Reset sim a Update sim. You can provide an arbitrary string Param to pass arbitrary parameters to your simulation.


You have to implement a simple Euler simulation at discrete time intervals. This presumes a constant speed of all the components of the simulation during the time step interval simulated. The moving objects (Particle) are influenced by at least two independent forces:

  • gravitational force - a constant downward force with acceleration g = 9.81 m/s2
  • aerodynamic resistance - resistance caused by air resistance, we recommend a model with linear and quadratic components: |a| = K1 |v| + K2 |v|2, see e.g. this page

Technical details

You must implement the functionality of the following components:

  • Launcher - launch pad of the rockets
  • Particle - primary (rocket explosions), or secondary particles (glowing remnants of an explosion). Is it possible to implement multi-phase explosions, colour changes, etc. The only condition is that the particles obey at least some degree of physical plausibility.

The simulation is re-calculated at discrete time intervals: once every display cycle. All simulated objects (Fireworks, Launcher and Particle) have a function Simulate ( double time ) for this purpose. Objects must be able to recalculate their appearance and position so that they match the desired state at a given time (specified in seconds from simulation start).


The universal system (interface IRenderObject) is used to render all components of the simulated world. Individual objects have to define points (GL_POINTS), lines (GL_LINES) and/or triangles (GL_TRIANGLES), that are to be used to display them (the actual combination of primitives is up to you). Rendering takes place separately for each of these three graphics primitives, and is implemented as a two-stage process:
1. first the methods TriangleVertices() (TriangleIndices(), LineVertices(), LineIndices() or PointVertices()) are called without a data pointer, just to compute the size needed for the vertex buffer
2. and only in a second step, the buffers are actually filled, and transferred to the graphics card via GL.MapBuffer()

The global simulation object Fireworks implements drawing in three phases, first triangles (FillTriangleData()), then lines (FillLineData()) and finally points ("point-sprites" .. FillPointData()). If you just use primitives for your scene, it is sufficient if your objects implement interface IRenderObject, and you do not have to worry about rendering beyond that point. Of course, if you use advanced effects like shaders (see Form1.InitShaderRepository()), you have to modify the actual rendering code.

In the fireworks simulation, there are two types of object that can generate output: launch sites (Launcher) a rockets / particles (Particle). The global simulation object Fireworks contains a list of all launch sites and rockets at any given time, which are rendered via the RenderScene() method. The system is designed to be used with shaders and VBO buffers, and does not work without them (VAO objects are excluded, so that the code will work on older graphics cards).

For your solution, take inspirations from the pilot implementations of Launcher and Particle, which are both descendants of DefaultRenderObject. This is convenient for you, as you only have to implement certain functions - depending on whether you want to draw the object via points, lines OR triangles (although nothing will prevent you from using all of them together when rendering a single object).

Pay attention to the vertex attributes that are sent to the GPU. Modifying the colour makes sense for all types, but e.g. setting the point size (gl_PointSize) only makes sense for point objects. The form contains several switches with obvious meanings, and their settings can easily changed via the method Form1.InitParams(). The rendering system is based on two simple shaders (vertex.glsl a fragment.glsl), which access these option values via the "uniform" variables. For inspiration with regard to textures, see the texture display code in Form1.GenerateTexture(). If needed, you can easily add other textures, though it probably will not be necessary for this assignment.


Hand in until: 28. 02. 2022


Basis: 8 points for a simple but functional simulation, bonus up to 12 points for interesting effects.


Visual Studio project: 087fireworks.

Source file

Modify and hand in the source file: Fireworks.cs, as well as any shader files that are part of the project.
As a comment in the first line, please include your name!

Copyright (C) 2010-2022 J. Pelikán & V. Tázlar, last change: 2022-02-02 01:03:41 +0100 (Wed, 02 Feb 2022)