Hacker News new | ask | show | jobs
by zamalek 3699 days ago
I spent a lot of time making toy engines with XNA and carried much of its lessons to my toy engines in C++.

If your asset can be built, then your asset should be built. Content pipelines.

> Shaders are Strings

If you're using Vulkan, compile your shaders to SPIR-V alongside your project. If you're using OpenGL you're mostly out of luck - but there's still no reason to inline the shaders even with the most rudimentary content manager. Possibly do a syntax pass while building your project.

> Stringly Typed Binding Boilerplate

If you build your assets first then you can generate the boilerplate code with strong bindings (grabbing positions etc. in the ctor, publicly exposed getters/setters). I prototyped this in XNA but never really made a full solution.

Graphics APIs are zero-assumption APIs - they don't care how you retrieve assets. Either write a framework or use an opinionated off-the-shelf engine. Keeping it this abstract allows for any sort of imaginable scenario. For example: in my XNA prototype, the effects (shaders) were deeply aware of my camera system. In the presence of strong bindings I wouldn't have been able to do that.

Changing the way that the APIs work (to something not heterogeneous) would require Khronos, Microsoft and Apple to define the interaction interface for every single language that can currently use those APIs.

It's loosely defined like this for a reason - these are low-level APIs. It's up to you to make a stronger binding for your language.

2 comments

You can technically make shader binaries with OpenGL, the problem is Khronos never standardized a bytecode for it so you are basically shipping three binaries, one for each GPU vendors own intermediary (if they even have one, I only know AMD does):

https://www.opengl.org/sdk/docs/man/html/glShaderBinary.xhtm...

Noooo, please don't do that. That is not the intention of that API at all!

The API was built so that the cost of compilation by the driver would only be done once (likely at install, or at driver update time). So the idea is that when you are installing your PC game, it is compiling all the shaders against the current driver rev and hardware in your machine. Then when you play the game, it just loads the locally compiled binaries so your game doesn't hitch at random times when the driver compiler decides to kick off a compilation pass.

However, the binary is very sensitive to the driver version (as it owns the compiler), and the hardware itself. The binaries will differ across vendors, vendor architectures, and even sub-revisions inside of a single architecture.

Bonus: This API was provided as part of the GL_ARB_ES2_compatibility extension, in order to ease porting from OpenGL ES 2 to (big) OpenGL. OpenGL has a different API/extension, glProgramBinary, that is preferred for OpenGL. glShaderBinary might not even really work on any desktop implementation.

Probably the best source for this, though this information is relatively...obfuscated: https://community.amd.com/thread/160440

The Vulkan comment is particularly relevant, and the reason that technology exists is because of OpenGL's quirks.

This whole article is whinging against things that people have known for a while and have been working to fix. Sometimes it's not easy.