
Originally Posted by
elanthis
DX10/11 is an entirely different beast than DX9 and earlier.
A lot of programmers also really hate the extension system of OpenGL. Sure, it's more flexible, but many devs don't give a shit. They just want to say "we're using DX9" and know exactly what features are going to be there, without needing to write every other bit of the graphics engine as "if GLEW says extension Foo exists then UseFoo else UseShittyWorkaround". Most of my OpenGL work just checks for some specific version of OpenGL, bails if that version isn't available, and only uses the core functionality of that version -- makes the code smaller, cleaner, saner, easier, and (IMO) better.
There's also the matter of DX being a C++ OOP API, which more and more programmers are preferring over the procedural state machine API of GL.
Plus, the DX API is inherently faster than OpenGL in some ways on account of not being a state tracker, because there are less built-in state transition points. For instance, an object in DX is configured once, while an object in GL can be reconfigured at almost any time. This in turn means the GL driver must be complicated and contain more tests (and hence more branches, and more overall code to try to fit in the CPU's code cache, both of which hurt performance quite badly on modern CPUs).
Then there's the multi-threaded programming D3D allows that OpenGL currently does not. This is really important on modern hardware. With OpenGL, you can only do the client application processing of graphics data in multiple threads. You will then need to serialize the computed data through the main thread for submission to the driver. The driver, before it submits the data to the GPU, first does a series of validation checks as well as potential data conversion steps. D3D lets this validation and conversion happen in the individual threads, and only the actual dispatch of the command buffers has to happen in the main thread. D3D is hence inherently able to squeeze out better performance in multi-threaded rendering engines, which exist and are used in commercial titles today. Even the sophomore students' game engines at my school (all game titles are required to be written from scratch, ground up) are being written with multi-threaded physics and graphics components more and more often.
You can also look at Carmack's old GL vs DX post from years ago, and see how yesterday's "better" is today's "worse." It's actually very amusing to note how he thought that the now deprecated (and literally removed in OpenGL ES and OpenGL 3.1+ Core Mode) glBegin/glVertex/glEnd sequence is better than vertex buffers at all. Quite simply, for modern hardware and modern drivers, the old GL method is just incredibly slow and stupid. It can and does result in _massive_ performance degradation from the overhead of making multiple indirect function calls for every vertex attribute. His argument that the old GL 1.x API was easier isn't even that accurate; his code sample of using a vertex buffer looked ugly because he made it look ugly, not because using them is actually difficult or even remotely that bad looking. Modern engines are keeping buffers of vertex data around anyway for CPU-side culling and effects, and it's actually even easier to use DX/GL vertex buffers than it is to use the old GL 1.x API.
I still think it would be neat for someone to define a new, Open API that gives us what Longs Peak was supposed to be: modern OO stateless 3D API targeted at modern hardware. Essentially, in a way, implement D3D 11 with different names/identifiers, and use GLSL 4.10 as the shading language (including support for pre-compiled shaders). Try to get D3D 11's multi-threaded rendering support in, too, that's pretty important these days. (It's possible to implement a much slower version of that in GL, but it's impossible to do it as efficiently in GL due to the nature of the API.) Add an extension framework if you really want, but for the love of God keep the library versioned and based on hardware generations, so if a developer wants to keep his sanity and just use library v.X, he can, and knows exactly what he's getting, and users can easily know if their hardware is or is not v.X compatible. That's incredibly more useful and important than being able to use extensions.