This assignment is intended to introduce students to graphics performance, measurement, benchmarking and optimisation, primarily through the use of more modern, performant approaches, in particular vertex buffer objects (VBOs) along with associated APIs. It is also intended to introduce SDL for UI and event handling instead of GLUT, although not for performance reasons, but to use an industry strength cross platform library and to see the details of a main interative loop such as provided by glutMainLoop.
The assignment may be undertaken in pairs or individually. By undertaking the assignment in pairs students can gain deeper understanding by discussing performance results they observe.
In computer graphics - real-time applications in particular - performance is always of interest, or, more accurately, image quality and performance tradeoffs: better images take longer - but how much better for how much longer. In this assignment techniques for improved rendering performance using buffers are used and measured.
In the I3D assignments procedural generation was used for shapes and surfaces, possibly a water surface or terrain or other objects in the scene. For investigating graphics performance, this assignment also uses procedurally generated objects, specifically a 3D sine wave, or sum of sine waves, similar to that used in the ‘Frogger’ assignment in Interactive 3D Graphics semester 1.
There are three components to the assignment:
- Modifying and extending the supplied sine wave code sinewave3D-fw.c which uses GLUT and immediate mode rendering to use SDL for event handling and a series of techniques up to using vertex buffer objects (VBOs) along with various interactive controls.
There are suggested placeholder functions for implementing the other rendering modes including stored arrays (SAs), VAs and VBOs. To implement VBOs a step wise approach where first stored arrays are used, then vertex arrays then finally vertex buffer objects.
- Conducting performance experiments, including benchmarks.
- Plotting performance graphs and answering questions.
All performance measurements are to be done in the Sutherland Lab locally - so that results can be compared - and the aim is that much of it can be done in tutorial time.
The assignment requires you compare peformance of immediate mode (IM) using complete recomputation (CR), as was done in Interactive 3D Graphics, with several techniques up to using modern vertex buffer objects (VBOs) for both static and animated geometry. Use triangle strips for rendering. Use one strip per column, and not one strip for an entire object. For VBOs use glDrawElements, and optionally glMultiDrawElements.
Your program should have a performance meter or ‘perfmeter’ as an on screen display (OSD) showing frame-rate, frame-time, tesselation and triangle-rate (triangles/second). The OSD can be implemented using GLUT.
The program should implement the following controls:
- Tesselation increase/decrease (‘+/-‘ keys), using doubling/halving from a min of 8X8 and a max of 1024x124 (two million polygons - with polygons about 1 pixel in size for 1920x1080 HD resolution). To begin with use fixed size static arrays (use largest size needed). However, a better approach is to use dynamic allocation, and reallocate whenever the tesselation changes.
- Wireframe or filled rendering can be selected
- Use of immediate mode or vertex buffer objects can be selected.
- Animation of the wave can be turned on/off.
- Lighting can be enabled and number of lights increased/decreased up to 9. Use a default [0, 0, 1] directional light for the first light, and then directional lights from the corners of a unit cube, e.g. [1, 1, 1], [-1, 1, 1] etc.
- Four way split screen can be enabled/disabled
- Option to have the perfmeter print to the console instead of using an OSD (which can affect performance in itself).
Measure performance and other impacts of:
- Increasing tesselation.
- Using stored arrays versus complete recalculation every frame.
- Using immediate mode and vertex buffer objects.
- Changing rendering mode from wireframe to filled
- Turning lighting on and off, and specifying or not specifying normals accordingly (they are not needed if lighting is disabled).
- Increasing the number of lights, up to a maximum of 9.
- Animating the wave, where all data needs to be regenerated every frame.
- Using split screen, and rendering the wave with front, top, left and general views.
Use 1920x1080 (HD) resolution with the OSD turned off - print to the console instead.
As part of the investigation you are specifically required to find how many lit shaded triangles (polygons) can be drawn at a ‘real-time frame rate’ of around 30 fps, i.e. in 1/30th of a second using the fastest rendering approach.
You are also to specifically find how long a wave shape with 1-2 million polygons (triangles) takes to render.
An optional aspect, for higher credit, is to modify the program so that a steady frame rate of around 30 fps is drawn whilst varying rendering mode and parameters. Use a main loop with an idle function as discussed in the SDL lecture. In the ‘idle’ routine game logic would normally be peformed including game logic, AI, physics, etc but for this assignment idle() should just sleep (use nanosleep()).
Another optional aspect is to use just one strip per object, including the use of dummy vertices. Check the rendering in wireframe mode.
- Plot a graph showing performance for static geometry using the techniques you have implemented: complete recalculation (CR), stored arrays (SAs), vertex arrays (VAs) and vertex buffer objects (VBOs). Use time per frame versus number of polygons. Make sure you use a linear scale.
- What is the scaling relationship evident from your graph?
- What performance factor improvement i.e. speedup is there between each technique you have implemented and stored arrays?
- Repeat 1-3 but for animated geometry.
- What is the maximum speedup for static geometry compared to maximum speedup for animated geometry? Use the fastest technique you have implemented.
- What is the performance effect of increasing the number of lights? Explain why, with reference to the GPU architecture.
- What is the performance difference between wireframe and filled using one light? Again explain with reference to GPU architecture.
- How many polygons/triangles can be rendered in 1 second? How long does it take to render 1 million polygons?
For each question an answer 1-2 paragraphs, in some cases just a sentence.
You are encouraged to ask for help if you have any problems, especially in tutorials, but also including using the online channel. Good luck.
Before you submit anything, read through the assignment specifications again carefully and check that you have followed all instructions. Your code must be written in either C or C++ use SDL and compile and run on the Sutherland machines using either gcc/g++ or clang/clang++.
You must submit all source code, as well as a readme file and performance investigation as a tar or zip archive. If you have worked in pairs only submit one assignment but specify both group members in your readme file.
Submit via Canvas.
- PA: SDL. Rendering controls: tesselation, lighting and lights, wireframe/filled, animation, perfmeter, multiview/split screen. Performance investigation using CR.
- CR: SAs (using vertices and indices). Performance investigation using SAs and CR.
- DI: VAs Performance investigation using VAs, SAs and CR.
- HD: VBOs. Steady 30 fps modification. Single strip using dummy vertices. Performance investigation using VBOs, VAs, SAs and CR.
Note: subject to (minor) change