OpenGL version: Optimization for real time rendering
Similarities between 2 Renderers
Portable: Use ANSI C++, Tcl/TK, and OpenGL
Optimization
Differ mainly in rendering pass only
C++ class hierarchy
Nodes hierarchy
Vector Package
C++ Utility Libraries
Datalib: lists and hash tables
4D Vector and Matrix Package
Tcl/TK
System independent Windowing API
Scripting Language of SLIDE
Interpreter
OpenGL
Rendering API
Software: Only uses 2D version
OpenGL: Uses full API including optimization mechanisms
Display Lists and Texture Objects
Outline of Execution of a Scene
Initialization
Parser
World Preprocess
World Preprocess Graph
World Create Dynamics List
World Create All Windows
Window Prerender Display Lists and Texture Objects
World Create Timer Event to start dynamics
World Update
World Update
World Update Graph
World Post Redisplay All Windows
World Create Timer Event for next frame
Window Render
Static Scene Graph abstraction
Run rendering traversal
Example for Discussion
Parsing
Built with Flex and Bison (GNU versions of Lex and Yacc)
Will not resource a file which has already been read, checks for circular file inclusion
ID hash table in scanner, so that ID comparisons can be pointer comparisons instead of strcmp's
Structure of a SLIDE file is rather flat which makes it easy to parse
A SLIDE scene describes a single World, World has bins for
tclinit blocks
tclupdate blocks
surfaces
points
faces
transforms
instances
nodes
viewports
windows
render statements
fog?
All nodes share the same name space
tclinit done which can produce more geometry
Check Semantics
Objectives
Resolve all references
Execution
After tclinit blocks, all geometry has been created
World calls Check Semantics and dereferences all ID's linking up the structure
Preprocess
Objectives
Initialize all Tcl controlled values
Mark dynamic entities
Initialize nodes in preparation for the Preprocess Graph traversal
Execution
World calls Preprocess on all entities and Tcl controlled values are initialized
Entities with dynamic components are marked dynamic
Nodes are marked unvisited (bounding boxes invalidated) in preparation for the depth first graph traversal of PreprocessGraph
Diagram of World's forest after Preprocess
Preprocess Graph
Objectives
Compute the bounding boxes for all nodes
Mark nodes who's bounding boxes could possibly change as having a dynamic bounding box
Make a list of the changing nodes and store that for fast updates
Execution
World calls PreprocessGraph on each of the render statements (any nodes which are not descended from any render statement can never be viewed)
Each render statement begins a depth first traversal of the scene graph DAG which begin at its geometry root
In this depth first traversal, bounding boxes are computed hierarchically and all nodes which will need to be updated as the scene runs are marked as being in some way dynamic
Bounding boxes computed by:
Nodes are classified as dynamic (bound vs. surface properties)
Difference between software and OpenGL versions
Create Dynamics List
Objectives
World stores a list of the changing nodes and store that for fast updates
Execution
World runs through its lists of surfaces, points, faces, transforms, instances, nodes, viewports, and renders in this order.
If any of these have anything dynamic about they are added to the dynamics list.
Saves on searching through all nodes to find the dynamic ones on each update.
Preprocess Windows
Objectives
Window objects are created and initialized (Togl Area and Frame)
In OpenGL version, Static geometry and texture maps are registered with OpenGL for faster rendering
Execution
Windows created
In OpenGL version, each window calls prerender on all of its viewports' render nodes
Prerender is for completely static branches of the scene graph and texture maps
For these static objects it is the only time there geometry will need to passed to OpenGL
Once all of the windows have been created, the World set a timer event (the heart beat) and goes to sleep)
Update
Objectives
For all entities on Dynamics list, update all Tcl controlled values
Mark any nodes on the list as unvisited (bounding box invalid)
Execution
World wakes up from timer event
World records current system time
World updates SLF_TIME and SLF_FRAME
World calls tclupdate blocks
World traverses Dynamics list calling update on each entity
Update any Tcl controlled values
Instances smash matrices
Nodes marked as unvisited (bounding boxes invalidated)
Update Graph
Objectives
Update the hierarchical bounding boxes
Execution
World calls UpdateGraph on all render nodes
If render LOD == OFF return
Call recursive UpdateGraph on root node
Per Node: if LOD == OFF or bound valid (visited) return
call UpdateGraph on all children
Calculate bounding box from children
Set bound valid (visited)
Send all windows redraw events
World Records update ending time
World Creates timer event for 1/30 second - update elapsed time (tries to maintain a constant 30 frames a second) and goes to sleep
Rendering
Objectives
Render the current state of the scene graph into the 2D window
Differences between Software and OpenGL renderers
OpenGL is a state machine which you alter at the right times
Software renderer passes in formation down the C call stack and everything resolved finally at the faces
I will describe the software renderer and I will make notes of how similar tasks are achieved using OpenGL
Passes down transform matrices and their inverses for transforming normals
Execution
Window
Window receives a redraw event
Window activates its OpenGL drawing context
Window resets the OpenGL to default values
Window calls Render on viewports passing its current pixel dimensions
Viewport
Modifies pixel dimensions to be the size of subwindow
OpenGL: calls glViewport
Calls Render on each of its renders passing in modified pixel window
Render
If LOD == OFF returns
Gets camera from camera path
Software: Uses pixel window and camera frustum to create a normalized Half Cube to viewport mapping matrix
Gets the Projection matrix from the camera (OpenGL: Multiplies it onto the GL Projection Matrix Stack )
Initializes the modeling matrix with the inverse of the camera path matrix
Sets up the lights
Software: creates VRC->light matrix and stores it in the light path
Passes Obj->VRC, VRC->CUBE, CUBE->VP and all of the light paths with their VRC->LIGHTi matrices recursively down the scene graph starting at the root
Group
LOD == OFF return
Bounding box cull against canonical half cube
OpenGL: Static => call Display List
Save on stack then Modify LOD flag, Shading flag, and surface pointer (OpenGL: glPushAttrib)
Modify LOD flag, Shading flag, and surface pointer
Call on all instances passing current state
OpenGL: glPopAttrib on way back up
Instance
LOD == OFF return
Save on stack then Modify LOD flag, Shading flag, and surface pointer (OpenGL: glPushAttrib)
Modify LOD flag, Shading flag, and surface pointer
Save current Obj->VRC transform on stack (OpenGL: glPushMatirx)