Hacker News new | ask | show | jobs
by AldousHaxley 3344 days ago
D3D9 is my all-time favorite 3D API. It was at that sweet spot of being powerful enough that you could do stunning things with it (the Xbox 360 generation is effectively D3D9-level hardware), and it was simple enough that amateurs and hobbyists (and high school kids, as I was at the time) could dive in and get stuff on the screen relatively quickly. D3DX had some handy helper libraries for loading models, doing transforms, and loading textures. I get the benefits afforded by subsequent iterations, and nowadays Vulkan and D3D12, but their interfaces are so optimized toward specialists, and it would be nice if more was in place to cover that middle ground use case between "I don't need a full-on 3D game engine, but I don't need to worry about low level GPU stuff either." Of the new APIs out there, I feel like Metal is the only one approaching layperson usability, and it's trapped in the world of Mac and iOS. Of course you can stitch together something that looks like an open source equivalent of the old D3D9 SDK yourself from things like glm and AssImp, but it's nice to have all that in one package.
7 comments

Same here, but replace D3D9 with OpenGL 2.x or "compatibility profile" as kids call it these days. Basically the entire OpenGL instead of the crippled "core profile" that was originally made to give a chance to troubled implementors (coughATIcough) make something that works (and failed, while we still ended up with the schism).

Fortunately this is still supported in its entirety by all sane desktop implementations and at least Nvidia has said that they will always continue supporting it. The only sad marks are Apple and Mesa, but Apple seems to have abandoned the OpenGL ship and Mesa (or a fork) will hopefully implement it at some point. And in the meanwhile there is Regal, although i'm not sure how complete that is.

I find that OpenGL ES 3.0 hits the GL 2.x sweet spot for me. Main reason I prefer it over desktop 3.0 is that it doesn't require the use of vbos, which always seem to complicate simple programs (even though I keep being told that I can just set one up and bind it, then forget about it).

I especially like that it's hands-off wrt a lot of things like matrix manipulation and geometry optimization. It gives you an opportunity to think about these things clearly and get an optimal solution without having to port all of your matrix code out of somebody else's library.

Sure, ATI/AMD (and Windows Intel) lagged behind NV in the full OpenGL implementation. But the "compatability" profile is full of a lot of cruft that had nothing to do with modern GPUs, and whose primary value was to passing workstation test suites, not actual modern GPU programming.

I know we have the "but mah immediate mode" crowd, but those folks have to just get off it. Write your own immediate mode recorder if you're so desperate. I'm also looking at you, matrix stack abusers. Your programs are bad, and you should feel bad.

> I know we have the "but mah immediate mode" crowd

I'm in the "but mah immediate mode" crowd, so thanks for the condescending tone. I like immediate mode and matrix stacks and all the nice stuff compatibility mode provides because they are convenient even if they aren't fast. Quite often what you want is convenience, not performance and adding a usually badly documented 3rd party library that might be dropped next year (or whatever) or break its API is not a desirable solution. Especially when the entire point is moot since OpenGL 1.x/2.x and 3.x/4.x compatibility isn't going anywhere any time the next couple of decades - at least.

Besides the parent post is about what someone's favorite API was so i also added what my favorite API is. D3D9 isn't any more deserving to be someone's favorite API than OpenGL.

I would actually argue that it is _bad_ for graphics. The GPU abstraction that OpenGL represents is now 30+ years old, and not at all representative of how modern GPUs (desktop or mobile) work. I'd even argue that OGL obfuscate the GPU machinery to all the budding graphics programmers who use OGL. OGL was never meant to be a graphics toolkit/middleware, but that's what it's become (at least the compat profile).

As far as the value to you, to be perfectly frank, you would not have compatibility profile if it wasn't for workstation ISVs demanding OpenGL 1.1 still be supported for their legacy applications (and shelling out the big bucks to maintain that support). There isn't a singly IHV who is keeping these legacy features on for any hobbyist or learning programmer. Not one. The IHVs know it's bad, but there's a lot of money in keeping it around.

I don't even know if there's value in mentioning this, but I used to be an OpenGL driver engineer, and then when I worked on it, I realized "Hey, wtf, this has nothing to do with how the GPU works!" I'm still happy/proud about the work I did, but I don't think it advanced the graphics state-of-the-art (for the most part, there are some cool things that showed up first in OpenGL). And then as far as the cruft I mentioned...it's just a psychotic maintenance nightmare.

That is all nice but i don't see what is the point of trying to convince me that i shouldn't like something i like :-P. Regardless of how good OpenGL is in representing how GPUs work or why it is still around, it doesn't change the fact that it is still around and i like using it.
If you are talking about OpenGL compat profile, Mesa will not go beyond 3.0. You might or might not be able to convince the project to change that with patches, I am not sure what's the attitude on that.

If you are talking about D3D9, for Gallium driver (relevant ones are r600, radeonsi, nouveau), there is Gallium Nine: https://wiki.ixit.cz/d3d9

Yeah i am considering at some point to try and see what would take to add support for the compatibility profile. I do not see a reason to not have it considering that the functionality is mostly there (and AFAIK there is even an environment variable that sort-of allows the creation of compatibility profiles, it just doesn't fully work). If nothing else, not having it makes the Mesa implementation inferior to the proprietary ones.
D3D has always been a low-level API and D3D9 is no exception. The D3D9 just supported really simple hardware where pixels were pushed through a rigid pipeline one primitive at a time.

Interestingly, Xbox 360 was already beyond DX9, it had real shader units and shader stages (i.e. the same unit could execute both pixel and vertex shader instructions) and even ability to write data back from a shader (if you wanted to use shader to process non-pixel data on the DX9-level hardware you still had to write the output as pixels because the color/depth buffer was the only output of a shader). So X360's graphics library extended DX9 a lot to support that hardware.

Vulcan blows open the doors for anyone to create a library with the power and ease-of-use of DX9, rather than it being tied to OS vendors.
Why not OpenGL 3.2+? It is capable of modern effects and pretty easy to use.
Console developers don't get much choice: You pretty much must use D3D9, D3D11, GNM(X), etc.

Mobile's not much better: OpenGL ES for Android (which is a far cry from real desktop OpenGL - to the point that I consider it a completely different graphics API that just happens to confusingly reuse the names of some functions.) Maybe Metal for iOS.

Real desktop OpenGL is one of the few graphics APIs I've never been forced to use - so why spend even a single dev-month porting to it? Even games with OpenGL render paths may work better using their Direct3D renderers on Linux via Wine!

Even counting Linux/OS X, at this point I'm not even convinced OpenGL is actually the more portable API...

I've written an iOS app and the OpenGL code was (except very few ifdefs) identical to the desktop code. So I wouldn't say that ES is a completely different API, you can certainly reuse a lot.
Not even our shaders went unscathed - no rectangular matrix support (mat4x3? nope!), mandatory precision specifiers (lowp-highp), no Uniform Buffer Objects. Can't even call glTexImage2D on ES 2 without perfectly fine OpenGL code failing - because format !== internalFormat is forbidden (read: documented "must be the same"), and you were a good explicit OpenGL citizen and asked for something as horrifically complicated as format=GL_RGBA and internalFormat==GL_RGBA8. Multiple render targets? Are you out of your mind? We can't have that - goodbye deferred rendering, hello old school forward rendering!

Even your bread and butter - functions like glUniformMatrix3fv do things like just outright ignore the transpose parameter. This is extremely well documented: "Specifies whether to transpose the matrix as the values are loaded into the uniform variable. Must be GL_FALSE." ( https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml... )

I swear I've reused more code between D3D11 and PS4 codepaths than between OpenGL ES and OpenGL codepaths, and the d3d11 and ps4 APIs don't share a single common function name betwixt them!

I must assume going from OpenGL ES 2 to real OpenGL a bit easier - even if you're probably giving all the fast paths in the latter a wide berth in doing so. Or maybe OpenGL ES 3 is a bit closer to real OpenGL. But OpenGL ES 2 vs desktop OpenGL? They both render triangles, but beyond that, it's a crap-shot, and a lot of #ifdefs in my experience. Separate files, even. Not just a few.

EDIT: s/codepaths/apis/, finish summarizing my thoughts.

Yes, calling OpenGL ES "OpenGL" compatible is only true to the ears of those that never had the "fun" to write portable code across multiple GPUs.

At the end of the day, the code paths, extension support and driver workarounds are so many that one could just be coding against multiple APIs anyway.

I guess you're right, as I was only using rather basic stuff (e.g. no lightning, no shaders), just framebuffers, VBOs, etc.

(replied to my own comment by accident first)

I guess you're right, as I was only using rather basic stuff (e.g. no lightning, no shaders), just framebuffers, VBOs, etc.
Because for fonts, textures, windowing, effects, materials, requires the use of third party libraries outside the spec.

Also it is stuck in a C world API, with each binding being a third party library with different degrees of coverage.

All of that is outside of the spec. That has nothing to do with 3D graphics. MS just lumped it all together and called it DX.
I think that is kind of the point.
Well, it's a counter point really, since all of that is unportable (without such kind of translation).

As developers put it here[1]: "Don't make a game that depends on Direct3D. All the hard hard work is getting the thing to run with OpenGL".

1. https://www.gamingonlinux.com/articles/about-linux-games-bei...

That's stupid. Competent 3d on Windows is DirectX. Competent 3d on Mac/ios is Metal. Competent 3d on consoles uses their propriatary API. So, what is the point of OpenGL portability? Between Linux and Android? You _will_ have to switch API if you are making anything worthy.
Also on Windows, Direct3D is better supported.

If you write an app based on Direct3D 9 or 11, it usually just works on any supported version of Windows.

I once wrote an app that uses OpenGL 4.0 (this one: https://github.com/Const-me/GL3Windows), and it only worked on half of my PCs. To make it work everywhere, I had to downgrade to OpenGL 3.0, and also implement S3 texture decompression on the CPU.

GL 3.x is my current go to for the case of needing simple immediate mode 3D rendering. But it's still Bring Your Own Matrices/Texture Loading/Text Rendering/Model Loading, and D3D9 + D3DX had that all in a nice package. Like I said, stitching this stuff together isn't the hardest thing ever, but it's nice to have a basic set of boilerplate that's idiomatically consistent and works out of the box.
Because OpenGL is a dumpster fire of conflicting information for a beginner. I've been looking for a decent opengl book for years, in vain. DirectX 9 was sort of the sweet spot, where the technology stabilized for a few years at something decent. Nonetheless, aside from dumping the useful parts of d3dx, DirectX 11 is a lot friendlier to work with.
Doesn't a 3D graphics (not game) engine like OGRE or Irrlicht fill this void? I don't know if either one supports DX12/Vulkan yet, but I imagine they will in the not too distant future.
I'm thinking more like bgfx, which is a cross platform API to access vertex and index buffers, textures, rendertargets, shaders and render states. Primitives like models, sprites, fonts, etc are up to you but the repo contains examples with extra utilities for those things.
bgfx looks really cool, thanks for letting me know about it!
Those are higher level scene graphs. D3D9 was an immediate mode API with some helper libraries, so you still were in control of your app's rendering architecture.
The original Xbox also ran D3D9. After getting my hands on the XDK for that box I had a lot of fun with it, I see your point regarding the sweet spot.