3D in SDL

I don’t know much about 3D, maybe it’s time to do it…
What to use? The SDL documentation seems to be fading away, but there is some support for OpenGl and Vulkan… Or maybe something else? What are the differences ? Ease of use/learning is important to me. How does it work on Android (including older versions like 5.0)? How to start learning?

SDL doesn’t (currently) have any functionality for 3D beyond creating a window and surface/layer to draw into. For OpenGL it can also create an OpenGL context for you, but that’s the only API it does that for.

At some point this is going to change, whenever SDL_GPU gets merged in. Then it’ll have its own 3D API abstraction that sits on top of Metal/Vulkan/DirectX12.

OpenGL is the easiest to learn, and available on Windows, Linux, and Macs, but it’s been abandoned; there aren’t any new versions being worked on. GPU vendors apparently aren’t updating their OpenGL drivers on Windows anymore. It’s officially deprecated in Apple land; on M-series Macs and all iDevices, OpenGL is actually implemented on top of Metal.

Vulkan is the hardest to learn. The only place Vulkan seems popular for game dev is Linux (incl. Android), where it’s the only low-level 3D API.

Metal is between OpenGL and Vulkan in terms of difficulty to learn. It’s Apple-only.

DirectX 11 seems a tad harder than OpenGL to learn. It’s Windows-only (IDK if you can still ship Xbox games that use DX11).

DirectX 12 is on-par with Vulkan in difficulty to learn. It’s only available on Windows and Xbox.

Maybe not quite 3d in SDL per se, but I have recently discovered https://www.scratchapixel.com/ which is a great website for learning 3d concepts. The website is designed for folks who are interested in writing software rendering from scratch. Just by following the first few tutorials I was able to create a 3d rotating cube using what I learned from the site and also some basic SDL skills like opening a window, drawing a line and creating a simple loop.

Really just this lesson is all it took to start: https://www.scratchapixel.com/lessons/3d-basic-rendering/get-started/gentle-introduction-to-computer-graphics-programming.html.

And also a few of the starting chapters of the geometry section: https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/points-vectors-and-normals.html

Here is the result that I created: https://www.youtube.com/watch?v=ISxYqYdubPc

I felt inclined to learn some of the basics before jumping into a 3d lib. I plan to learn Vulkan later as it seems that will be the defacto moving forward.

Hope this helps,

Electrosys

This sounds quite exciting. Will this come with SDL3 or do we have to wait for SDL4?

OpenGL is the easiest to learn, and available on Windows, Linux, and Macs, but it’s been abandoned; there aren’t any new versions being worked on. GPU vendors apparently aren’t updating their OpenGL drivers on Windows anymore. It’s officially deprecated in Apple land; on M-series Macs and all iDevices, OpenGL is actually implemented on top of Metal.

I think that’s a real shame, but OpenGL is the perfect thing that’s available on all platforms. Vulcan is way too complicated.
Do you know a reason why it isn’t being developed further?

The last official word that I have heard was that it would be released in SDL3’s next major release.
(Edit: The title is “The GPU API” → 3.x Milestone · GitHub : Looks like it might have been pushed back again.)

There are two different versions of the GPU library that are in contention at the moment.
Here’s a quote from the Q&A session that the developers hosted a couple of months ago:

In the same Q&A there was this that indicated that implementing shaders was being added to the works:

Does this mean that SDL will ble able to do some sort of 3D rendering, without using the Open GL API , but will it still rely on OpenGL?

I mean just having some sort of api like SDL_RenderGeometry?

This would be great!

You can find the versions of the SDL GPU API online if you want to study it, but please don’t use it in production code for obvious reasons.

Here’s a quote from the Icculus version that hopefully answers some questions:


/* !!! FIXME: this all needs formal (and significantly more robust) documentation. */

/*
 * The basic sizzle reel:
 *
 *  - You work in terms of modern GPU APIs without having to bog down
 *    in their specific minutiae.
 *  - It works on several APIs behind the scenes.
 *  - It's about _removing existing limitations_ without giving up
 *    most comfort, portability, or performance.
 *  - You write shaders in a simple language once, and either ship
 *    shader source code or bytecode. At runtime, we figure out how to
 *    make it work.
 *  - You work in one coordinate system and we deal with the
 *    differences for you.
 *
 *  !!! FIXME: explain shader policy (it's all a simple C-like thing,
 *  !!! FIXME: meant to be easy-ish to parse and write in. It is not
 *  !!! FIXME: GLSL or HLSL or MSL, because while being able to reuse
 *  !!! FIXME: shaders would be nice, the language specs are huge and
 *  !!! FIXME: carry various API-specific quirks, making them bad fits
 *  !!! FIXME: for SDL. It's quite possible to build external tools
 *  !!! FIXME: that will convert from existing shader languages to
 *  !!! FIXME: SDL_gpu. The same ideas apply to shader bytecode.)
 *
 *  !!! FIXME: document coordinate systems (it's the same as Direct3D 12
 *  !!! FIXME:  and Metal, which is what WebGPU landed on, too. We'll
 *  !!! FIXME:  convert behind the scenes for OpenGL and Vulkan where
 *  !!! FIXME:  appropriate).
 *
 *  Some rules and limitations:
 *  - There is no software renderer, and this API will not make heroic
 *    efforts to work on ancient GPUs and APIs.
 *  - This doesn't expose all of Metal/Vulkan/DX12. We are trying to
 *    drastically improve on SDL's render API functionality while
 *    keeping it simple-ish. Modern APIs put most of the heavy lifting
 *    into shaders, command queues, and precooked state objects, and
 *    we are exposing that specific set, which is powerful enough for
 *    almost anything you want to build outside of the highest of
 *    high end triple-AAA titles.
 *  - This exposes a feature set that the underlying API probably can't
 *    entirely lift before OpenGL 4 or Direct3D 11. For example, it allows
 *    vertex shaders to use samplers, which wasn't available in
 *    Direct3D 10. D3D11 was available in the retail release of
 *    Windows 7, though--and backported to Vista!--which is probably
 *    reasonable. It also means ancient, now-garbage GPUs are not and
 *    will not be supported. Hypothetically we could make _most_ of this
 *    work on OpenGL 2 and Direct3D 9, but why bother in modern times?
 *    (then again: maybe we can support enough of this to make many
 *    reasonable apps run on older GL/D3D, and just fail in
 *    SDL_GpuCreateShader on unsupported stuff).
 *  - Modern GPUs expect you to draw triangles, lines, or points.
 *    There are no quads or complex polygons. You can build them out of
 *    triangles yourself when you need them.
 *  - Modern APIs expose an enormous amount of fine-grained resource
 *    management, but I've opted for something simpler: there are GPU
 *    buffers and CPU buffers, and you have to queue a blit command to
 *    transfer between them. All the other stuff about what type of
 *    memory a buffer should be in, or CPU cache modes, etc, is mostly
 *    hidden here. GPU does fast things with GPU buffers, CPU does fast
 *    things with CPU buffers, transferring between them is slow, done.
 *  - You are NOT allowed to call into the underlying API directly.
 *    You can not force this to use OpenGL so you can intermingle
 *    your own OpenGL calls, etc. There is no compatibility functions
 *    to pull lowlevel API handles out of this to use in your own app.
 *    If you want to do this: just copy the source code out of here
 *    into your app, do what you like with it, and don't file a bug report.
 *    (!!! FIXME: it's been pointed out to me that there's a value in
 *    getting the lowlevel handles so you can plug them into OpenXR for
 *    rendering in a VR headset, and this seems worthwhile.)
 *  - The shader compiler is meant to be fast and lightweight. It does
 *    not do heavy optimizations of your code. It's meant to let you
 *    deal with source code at runtime, if you need to generate it on
 *    the fly for various reasons.
 *  - The shader bytecode is also meant to be fast and lightweight. Its
 *    primary goal is to convert quickly to whatever the underlying API
 *    needs. It's possible the underlying API might do an optimization
 *    pass, though.
 *  - There's no reason an offline compiler can't optimize the bytecode
 *    passed in here, but this doesn't currently exist and will not
 *    be implemented as a standard piece of the runtime.
 *
 *
 *  some things that modern GPU APIs offer that we aren't exposing
 *  (but that does not mean we will _never_ expose)...
 * 
 *  - compute
 *  - geometry shaders
 *  - tesselation
 *  - ray tracing
 *  - device enumeration/selection
 *  - multiple command queues (you can encode multiple command buffers, from multiple threads, though)
 *  - Most of the wild list of uncompressed texture formats.
 *  - texture slices (with the exception of cubemap faces)
 *
 *  some things I said no to originally that I was later convinced to support:
 *
 *  - multisample
 *  - texture arrays
 *  - compressed texture formats
 *  - instancing
 */

The version by thatCausmonaut looks like the most recently updated version… Hopefully more documentation is on the way there.

It looks like the default behavior is to use the native libraries when available (metal or d3d11) otherwise it will use vulkan as the backup. So basically it’s going to be a unifying, cross-platform API that focuses on speed which is what SDL is well known for.

The 2nd version looks a lot more current, the last change was an hour ago, the first version was 7 months ago!

It’s possible, but definitely won’t be hitting 60 FPS doing raytracing or anything modern. Think of SNES fake-3D methods perhaps until SDL_GPU is released.

The 2nd, competing version is being developed by multiple people, as an existing project that some people are trying to retrofit onto SDL, so there’s lots of GitHub activity. The first version is being developed by @icculus specifically for SDL, on his own (for now) so less GitHub activity.

That Ryan hasn’t pushed any changes of his version of SDL GPU to GitHub in a while doesn’t mean he hasn’t worked on it since then.

From what I see, things are now getting serious with the SDL_GPU?

Quite serious. :slight_smile:

We have merged the other PR; the team took my vision and ran with it, and added a ton of good stuff to it.

We still have more to do, but this is shipping on day one for SDL3!

1 Like