Hello Game Development SE!
I'm crawling my way through OpenGL with the hopes of creating a simple and very lightweight game engine. I view the project as a learning experience that might make a little money in the end, but will be fun either way.
So far I've used GLFW to gain some basic I/O, a window (with a oh so fancy F11 fullscreen key) and of course an OpenGL context. I've also used GLEW to expose the rest of the OpenGL extensions because I'm using Windows and I want to use all of OpenGL 3.0+.
Which brings me to the scene graph. In short, I'd like to roll my own. This decision came after looking at OSG and reading a few articles on how the concept of a scene graph has become twisted, bent and broken. One such article described how scene graphs have developed as...
Then we added in all this extra stuff, like hanging ornaments on a Christmas tree, except that some of the ornaments are nice juicy steaks and some are whole live cows.
Following the analogy, I'd like the steak, the meat of what a scene graph should be, without having to strap on piles of extra code, or any whole cows.
So with that in mind, I find myself wondering exactly what a scene graph should be and how a simple scene graph should be implemented? Here's what I have so far...
A one parent, n-children tree or DAG which...
- Should keep track of game object transformations (position, rotation, scale)
- Should hold render states for optimizations
- Should provide a means of culling objects not within the view frustum
With the following properties...
All nodes should be treated as renderable (even if they don't render) This means they...
- Should all have cull(), state() and draw() methods (return 0 if non-visible)
- cull() recursively calls cull() on all children, thus generating a complete cull mesh for the entire node, and all children. Another method, hasChanged() could allow so-called static meshes to not need to have their culling geometry computed each frame. This would work such that if any node in the sub-tree has changed then all geometry down to root is rebuilt.
Render states will be held in a simple enumeration, each node will select from this enumeration an OpenGL state set that it requires and that state will be setup before draw() is called on that node. This allows for batching, all nodes of a given state set will be rendered together, then the next state set is setup and so on.
No node should directly hold geometry/shader/texture data, instead nodes should point to shared objects (perhaps managed by some singleton object like a resource manager).
Scene graphs should be able to reference other scene graphs (maybe using a proxy node) to allow situations like this, thus allowing complex multi-mesh models/objects to be copied around the scene graph without adding a ton of data.
I'm hoping to get some valuable feedback on my current design. Is it missing functionality? Is there a vastly better way/design pattern? Am I missing some larger concept that will be necessary to include in this design for a somewhat simple 3D game? Etc.
Thanks, -Cody