Wednesday 29 June 2016

PVS - John Carmack's infamous potentially-visible set



So, I have been working hard on realtime game editor stuff - being able to check and edit the state of the game engine, and things like that.
One major recent component to the game editor stuff is called Constructive Solid Geometry.
Realtime CSG editing is not completely new, but relatively unpopular, mostly due to John Carmack creating a visual game editor based on BSP-CSG.

John and I have some things in common, but there are things we disagree on.
I believe in realtime csg editing, but I think that BSP is not the only spatial partitioning system that can support CSG operations.
In fact, I might even publish my editor at some point, just to stick it to the man, JC, you might be, but your stolen tech from the 1968 paper is not even relevant now, and neither are you.

I would further extend this sentiment to a somewhat more interesting person, did you guess who?
The games I make have no god complex, that should be all the clues needed, who holds the can?

Seriously though, I do have some things to say about PVS, and I promise to do so in the next post, it's interesting stuff, real philosophers would shit their pants.


Friday 17 June 2016

Material Instancing on the GPU


It seems like a lifetime ago that I learned how to perform 'gpu instancing' by sending to the GPU a special VertexBuffer containing an array of ModelToWorld transforms, and telling the underlying renderer (OpenGL) that this buffer's content is not per vertex, its per mesh instance (so all vertices).
We can issue one single draw call, but draw the current mesh subset multiple times, at different positions and orientations. I noted at the time, this meant we could render all instances of a mesh with as few as ONE DRAW CALL PER SUBSET, based on the premise that a mesh is divided into per-material subsets of faces (or triangles), and that we at least need to change Materials inbetween draw calls.

More recently, I expounded that I believed it to be quite possible to further reduce draw calls, by supplying a second 'Per Instance VertexBuffer' containing an array of Material data, and by tagging individual Triangles with a local material index.

Today, I'm adding a 'Tumbler' 3D Widget to the Editor interface - it will display the current camera view's orientation, and also act as a tool to select from multiple fixed views (top, front, etc.)
I've created a special mesh for this widget, which has SEVEN materials, identifying the (signed) major axes plus one extra 'arbitrary' perspective view.

Note that I only have one instance of this guy, but it contains seven materials - this implies that using the render technology described thus far, I would need seven draw calls to draw this ONE instance of this multi-material mesh.

This seems like a good time to experiment with the concept that we can use 'gpu instance buffers' to send *anything* that we need per instance, not just the Model transform, but ANYTHING.

Anyone done this already, or know of any references?

Tuesday 7 June 2016

Immediate-Mode as a Programming Paradigm?


So, I needed to implement some sort of GUI (graphical user interface) in the FireStorm (v2) engine framework, and my previous effort had been to cobble together a custom solution, which was basically a classic Retained-Mode Gui, where we create a bunch of 'widget objects' upfront, that might be visible, and might not be, and often holds lots of redundant state.

I was recently re-introduced to 'Dear ImGui', an immediate-mode gui library, which does things very differently - basically, under the immediate-mode paradigm, the items we work with never 'exist as objects', unless they are actually being referenced... conceptually, if we choose not to draw something, it does not exist, and contains no state either way.
Updating the logic for gui widgets under a retained-mode system is not the responsibility of each widget, since they don't exist, but the responsibility of the system framework... when we 'draw' each widget, we can update its logic at the same time, and depending on the result, choose to do (whatever), including actually displaying it. The gui code becomes highly 'lexically-scoped', and is a really good fit with most modern scripting languages.
In fact, I found myself able to edit my gui script with itself, within minutes of working with a well-designed immediate-mode GUI.

Which brings me to my point.

Classical GUI are typically hierarchical, tree-structured things, which got me thinking, if the immediate-mode works so well with GUI, and allows us to break the shackles of the traditional model of retained-mode object hierarchies, what ELSE can we use it for?



Saturday 4 June 2016

'Truly global' variables pay off


In order to facilitate Rapid Application Development, the FireStorm game engine implements the Lua scripting engine, and also the Dear ImGui immediate-mode gui library.

One of the 'problems' when interfacing C and Lua code is that Lua likes to 'own everything', and does not easily share its data with other languages (like C, the language in which it was written). Allowing Lua to own all our application's runtime variables is the easy option, but it has a terrible price, and furthermore, Lua is not designed with hardware multithreading in mind - sharing data between one Lua state and the engine is one thing, but multiple Lua states means that letting Lua own anything is just a really bad idea - Lua is not the center of the Universe.

To be clear, I found that I had two concepts of 'global data' - the Lua global variables stored in (each) Lua State, and the C 'global data', but rather than choose one, I created a third - the C 'blackboard' whose sole purpose is to share data across all interested parties regardless of language or thread.

I chose to keep all my data on the C (engine) side, as the engine is my hub, my nexus, no matter how many threads are independently running Lua engine instances.
This turned out to be a good idea, with respect to ImGui.

You see, the immediate-mode GUI requires that we provide Pointers to Typed Data, which it can use to display variable contents, and also to allow their live editing.
But values in Lua don't have pointers, and we can't create them, so Lua variables are pretty much useless with respect to interfacing with the ImGui library.
Luckily, it's no problem to get raw pointers to the data held by the engine's 'truly global' shared data.

As a result, I'm able to smash out quite complex Application GUIs  with a fairly small amount of Lua Scripting, and to illustrate how handy that is, I can use the GUI to edit its own script, and reload the edited script into the Engine, without blinking an eye;)