Wow, very nice ;)

OpenGL was a very nice API and even despite its shortcomings, it is quite telling that VK didn't fully replace it 10 years later.

Cross-vendor mesh shader support is great - we had NV_mesh_shader for quite a while but it's great that it's also supported on AMD now. It's good for voxel games like this - the shape of the vertex data is fairly fixed and very compressible, mesh shaders can really cut down on the VRAM usage and help reduce overhead.

Most minecraft optimisation mods generally try to reduce drawcalls by batching chunks (16x16x16) into bigger regions and use more modern OpenGL to reduce API overhead.

This mod does GPU-driven culling for invisible chunk sections (so the hidden chunks aren't rendered but without a roundtrip to the CPU) and also generates the triangles themselves with a mesh shader from the terrain data, which cuts down on the vertex size a lot. (EDIT: I reworded this section because the mod does only a few drawcalls in total so my wording was inaccurate. Sorry!)

Sadly, optimising the game is a bit tricky due to several reasons - the first big one is translucency sorting, because there are translucent blocks in the game like stained glass, which have to be properly sorted for the blending to work. (the base game doesn't sort correctly either by default....)

The second is that it's quite overengineered, so improving it while also not breaking other mods and accidentally fixing vanilla bugs is quite hard.

There are further improvements possible but honestly, this is day and night compared to the vanilla renderer :)

For us mere mortals (not working at Unity or Unreal), the complexity is just too much. Vulkan tries to abstract desktop and mobile together, but if you're making an indie game, there's no value for you in that. The GL/GLES split was better because each could evolve to its strengths instead of being chained to a fundamentally different design.

The global state in OpenGL is certainly an annoyance, but I do not think that replacing it with fixed pipelines is an improvement, especially considering that most of that state is just a register write in desktop GPUs. Luckily, they eased up on that, but the API is still confusing, the defaults are not sane, and you need vendor-specific advice to know what's usable and what isn't. Ironically, writing Vulkan makes you more vendor-dependent in a sense, because you don't have OpenGL extension hell - you have Vulkan extension hell AND a bunch of incidental complexity around the used formats and layouts and whatnot.

On a more positive note, I seriously hope that OpenGL won't be entirely abandoned in the future, it has been a great API so far and it only really has small issues and driver problems but nothing really unfixable.

> OpenGL was a very nice API

I think this is an extremely subjective take :) If you haven't been closely following OpenGL development since the late 1990s it is a very confusing API, since it simply stacks new concepts on top of old concepts all the way back to GL 2.0. E.g. if anything good can be said about Vulkan it's that at least it isn't such a hot mess of an API (yet) like OpenGL has become in the last 25 years ;)

Just look at glVertexAttribPointer()... it's an absolute mess of hidden footguns. A call to glVertexAttribPointer() 'captures' the current global vertex buffer binding for that attribute (very common source of bugs when working with vertex-input from different buffers), and the 'pointer' argument isn't a pointer at all, but a byte-offset into a vertex buffer. The entire API is full of such weird "sediment layers", and yes there are more recent vertex specification functions which are cleaner, but the old functions are still part of the new GL versions and just contribute to the confusion for new people trying to understand the API.

>I think this take is an extremely subjective take.

Okay fair but that's all takes on this site :)

Yes, vertexAttribPointer is a footgun (in my project I wrote an analyser to generate a compiler error when you write it down...) but luckily in modern OpenGL it doesn't matter because you have separated vertex format. The names are confusing because it's legacy shit but the functionality is there. It's very much not as clean as other APIs but it gets the job done.

If you stick to the modern versions (so bindVertexBuffer / vertexAttribFormat / VertexAttribBinding) and do one VAO per vertex format, it's quite nice. And just forbid using the old ones. ;)

More broadly, I admit it's a subjective thing but I find these issues much smaller than like, broader conceptual issues. You mix the function names up a few times then you learn not to do it. But when an API is just fundamentally unergonomic and inflexible, you can't really get past that. Maybe you get used to it after a while but the pain will always be there....