The biggest, step apart from the first, was putting my money where my mouth is.
Actually proving that GR Graphics design was Api - Agnostic.
That I could expose the same classes to use DirectX or OpenGl, even though I had not finished templatizing everything yet.
When the library is actually finished, switching from one to the other should be a single parameter on startup. For now, I have allowed the shader configurations to be different between the two (spoiler - OpenGl is still using attribute names, while DirectX is using register numbers. Spoiler 2: I have only used interleaved buffers for directx and non-interleaved buffers for OpenGl. The endgame is a bit of both - changeable buffers containing positions and normals, static buffers containing texture coords et.c.).
I had a blast.
It was difficult - I was determined to fully understand the graphics hardware setup, even concepts that I couldn't find in the textbooks, by studying how to implement the exact same thing in DirectX 11 as with OpenGl 4.2.
Let me explain.
As most people that concern themselves with graphics already know, DirectX and OpenGl are actually hardware - driven. The cards drive the APIs, and not the other way around. That means, that when you see a new feature in the API, you know that 90% it is a new hardware capability.
OpenGl is a state machine, as barebones as possible, with as little overhead as possible: a free-functions only, bind/change,bind/set, bind/do kind of thing. There is direct state access (i.e. ChangeFeature(feature, option) but mostly it is just an extension yet. In fact, to the outside world, any object is just a GLuint "name". Then there are functions to bind names, and functions to manipulate the bound object. That's it. Objects are an unknown word, much less a pattern.
DirectX is COM. As in Component Object Model. A more unfair, asymmetric comparison could not be made. COM is textbook OOP, interface-driven, with all objects created from factories and never actually instantiated, all communication through smart pointers to interfaces, everything virtual-ed to the death. Yet DirectX has some state-machining as well.
For example we can learn that, philosophically, the Graphics Pipeline IS a state machine, up to a point, with active state for the input, shader and output stages, by studying how both API's treats them thus...
For another example, buffers, samplers and textures are probably not state - not by a longshot. They are bona-fide objects, and even OpenGL provides direct state access to them sometimes. They are far too easy to throw and move around to represent any kind of state.
On the other hand, their binding points, ARE state, and very much so... And so on.
I really had a blast :)
No comments:
Post a Comment