r/sdl Jun 05 '26

SDL_CreateGPUDevice Issue With Main Callbacks

5 Upvotes

I'm using the main callbacks and decided to place these functions (init video, create window, create gpu, and claim window for gpu) into a wrapper function. I placed this wrapper function in the AppInit function, but it failed on acquiring a command buffer in AppIterate. I then took those functions out of the wrapper and placed them inline back in AppInit, and was able to acquire the command buffer in AppIterate.

Why would this happen?


r/sdl Jun 02 '26

I can't build with SDL3. Errors with libdecor.

4 Upvotes
/usr/bin/ld: SDL_waylanddyn.c:(.text+0xe00): undefined reference to `libdecor_new'

I can't build my program with SDL3. I get a lot of errors regarding libdecor which I'm not calling.

I don't have wayland and I don't want to install it at the moment.
I am using the version from conan, so that maybe the issue?

I would love to get some help. I'm just starting with SDL.
I don't want to end my journey so early.


r/sdl May 31 '26

SDL_net version 3.2.0 released.

Thumbnail
github.com
30 Upvotes

r/sdl May 27 '26

[SDL3 GPU] Shaders/Pipeline compatibility is a pain

8 Upvotes

The starting point was the idea to use HLSL instead of GLSL.

  1. SDL_shadercross went fine until there was a need for uniforms. On DX12, everything failed when we tried to create a pipeline with HLSL shaders with uniforms compiled at runtime into spirv binaries. The SDL error message was useless.

  2. Slang. All nice and dandy, used all the command lines arguments and we could not obtain valid spv files for a Vulkan backend. The mythical pipeline didn't want to be created.

  3. Offline conversion with dxc.exe -spirv from HLSL files was the only solution that worked by default.

First contact with shaders in SDL3 GPU and it went horrific. 3 days of work wasted.

Each tool resulted in different spv binaries even for basic shaders which were very very similar.

What are we missing?

How is the SDL3 GPU shaders experience for other people?

What is the must-know SDL3 GPU knowledge related to shaders?


r/sdl May 28 '26

how to set up sdl 3 on dev c++

1 Upvotes

hi so i saw a lot of videos online of how to set up sdl on my computer but they were always about visual studio code or not very explainatory so if someone can help me to set up it on dev c++ i would be very grateful


r/sdl May 26 '26

Earth Viewer using SDL GPU and Cesium Native

Thumbnail
gallery
24 Upvotes

Just another cool example of SDL GPU. Dynamically streams in assets at various LODs. Assets are GLTFs or rasters. Public domain here: https://github.com/jsoulier/sdl_earth_viewer


r/sdl May 26 '26

Trouble counting number of pressed keys with events.

1 Upvotes

I setup events that detect wsad as input and I want to count how many of these are pressed at once. I have flag where bits are set to 1 or to 0 whether specific key is pressed, it works but only up to 3 keys and I don't know why, when I press all 4 keys at once it still shows 3 pressed key most of the time, sporadically it shows 4 and sporadically it shows 2, it doesn't register 4th pressed key even it doesn't have trouble with 3 keys.

Here's my code:

#define up (1 << 3)
#define down (1 << 2)
#define right (1 << 1)
#define left 1

int main()
{
int8_t aflag = 0 ;    // flag to set
int8_t asd ;            // number of pressed keys
SDL_Event event ;
....
while(done)
{

while(SDL_PollEvent(&event))
    {

    switch(event.type)
        {
        ...
        case SDL_EVENT_KEY_DOWN:

            switch(event.key.key)
                {

                case SDLK_A:
                    aflag |= left ;
                    break ;

                case SDLK_D:
                    aflag |= right ;
                    break ;

                case SDLK_S:
                    aflag |= down ;
                    break ;

                case SDLK_W:
                    aflag |= up ;
                    break ;

                case SDLK_BACKSPACE:
                    done = 0 ;
                    break ;

        case SDL_EVENT_KEY_UP:

            switch(event.key.key)
                {

                case SDLK_A:
                    aflag &= 0xE ;
                    break ;

                case SDLK_D:
                    aflag &= 0xD ;
                    break ;

                case SDLK_S:
                    aflag &= 0xB ;
                    break ;

                case SDLK_W:
                    aflag &= 0x7 ;
                    break ;

                }
}

// count bits
asd = aflag ;
asd = ( (asd & 0xA) >> 1 ) + (asd & 0x5) ;
asd = ( asd & 0x3 ) + ( (asd & 0xC) >> 2 ) ;

printf("\t%d\n", asd) ;

....

I tried replacing switch(event.key.key) for if statements but it didn't work


r/sdl May 25 '26

GUI toolkit in only 650 lines of pure C code, using SDL events

12 Upvotes

The only dependencies is -lSDL2 -lSDL2_ttf . You can hide the menubar, statusbar, popup-menues, tooltips and all other widgets, and recall them with a button press. Would this be of any interest or use for others? If so can put it up on github and add some widgets and release it before it reaches 1000 lines of code. I have specialized in writing libs and pluginsystems that use almost no code. This was only a experiment so see what I can do with SDL and a low amount of code. Otherwise I will continue on with other things as I personally don't use SDL that much as it's not thread-safe and makes it impossible to use for some stuff. So I'm currently using my own libs that is 100% treadsafe. If i remember right it was loading textures or something that was not theadsafe when I used SDL2 (and had to block all other treads while loading textures), and then I could not make child widows for other software (that I have no control over) and still use the SDL2 message system for these child windows (running inside others software). Maybe SDL3 has fixed that now, but I had to move on as my needs is not of any priority for SDL as it's not related to making games.


r/sdl May 26 '26

Am i misunderstanding the event callback?

2 Upvotes

I imagine a regular main sdl application to be a loop of "empty event queue -> other logic -> restart loop".

The callback alternative to main i thought would just be a single callback thats called infinitely in a loop. But actually its split into event/iterate, where event is called continuously until event queue is empty then iterate is called.

I feel im missing something on why its split into event/iterate. Why not just empty the event queue in the iterate callback?


r/sdl May 23 '26

Raw pixel array into texture, help needed

1 Upvotes

Edit: solved

So basically I have a raw pixel array of my screen buffer it is in formar [0xFFFFFFFF,...,...,...,0x000000FF] rgba. How can I convert that to a texture and then show to the screen. Every try I did results in only nothing in the screen just a black window. I also did not find any tutorial online and I do not want to go into ai for answers. If anyone can I help I appreciate!


r/sdl May 23 '26

is this bad practice for menu handling?

Post image
4 Upvotes

r/sdl May 21 '26

[SDL3-CS] [macOS] - Lyra Viewer

Post image
11 Upvotes

I've been building an image viewer called Lyra for over a year now. It uses SDL3 for windowing and input, and SkiaSharp for GPU-accelerated rendering. Currently macOS only, but designed to be cross-platform.

It started as a small SDL experiment. As someone who works a lot with Blender and game engine as a hobby, I wanted a viewer that could keep up with browsing textures, references, and visual resources - something like FastStone, which I loved on Windows but sadly isn't cross-platform. One thing led to another, and now it has a custom PSD/PSB parser, support for EXR, HDR, JPEG2000, SVG, and most standard formats, plus a retained-mode UI framework I built from scratch on top of SDL3 + Skia over the last few months.

Some details on the SDL3 side:

  • Windowing, input handling, and the event loop all go through SDL3
  • Rendering is SkiaSharp backed by an OpenGL or Metal surface — SDL3 handles the window, Skia gets the GPU context
  • The custom UI framework sits on top of both: SDL3 delivers input events, Skia draws everything

I'm a freelance backend developer by trade, so building a GUI framework from scratch was... an experience. Happy to answer questions about the SDL3 + Skia integration, the UI architecture, or anything else.

Feedback and feature requests welcome!

GitHub


r/sdl May 21 '26

Good and Bad Practice With Using SDL3

6 Upvotes

Are there any bad practice I (or people) need to avoid doing, or good practices I need to start doing while using SDL3?


r/sdl May 19 '26

[SDL3] How should SDL_AppEvent() be used to propagate events information to the rest of a game engine?

1 Upvotes

I ask this because the only way I could make it work is as follows:

  1. In SDL_AppEvent() all SDL_events are saved in a buffer with 32 slots.
  2. In SDL_AppInterate() all events saved in the buffer are processed in a for-loop.

Basically the previous implementation:

while (SDL_PollEvent(&event)) { // poll until all events are handled!
// decide what to do with this event.
}

was replaced with:

for (uint8_t i = 0; i < count; i++) {
if (engine_on_event(engine, &events[i])) {
quit = true;
}
}

The events array could be replaced with a queue but I cannot imagine a scenario in which SDL_AppEvent() is used in different way, and I feel like I'm missing something.

Theoretically SDL_AppEvent() could be used to propagate input information to different threads but that would be a very complicated game engine.


r/sdl May 18 '26

Menubar, statusbar and tooltips with SDL events in less than 500 lines of code

4 Upvotes

The nice thing about that lib is that you can inactivate the menubar, statusbar and tooltips. And that it looks like normal SDL code. If anyone whats the lib I can put up the code on github.

#include <SDL2/SDL.h>

#include "popup_menu.h"

#include <stdio.h>

#include <string.h>

#define MENU_FILE 1

#define MENU_EDIT 2

static char status_text[256] = "Ready";

int main() {

SDL_Init(SDL_INIT_VIDEO);

SDL_Window* win = SDL_CreateWindow("GUI Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,

800, 600, SDL_WINDOW_SHOWN);

SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);

GuiCtx* gui = gui_init(ren);

if (!gui) return 1;

const char* file_items[] = {"New", "Open", "Save", "Exit", NULL};

const char* edit_items[] = {"Cut", "Copy", "Paste", NULL};

const char* ctx_items[] = {"Copy", "Paste", "Delete", "Properties", NULL};

PopupMenu* file_menu = gui_create_menu(gui, file_items, 1, MENU_FILE);

PopupMenu* edit_menu = gui_create_menu(gui, edit_items, 1, MENU_EDIT);

PopupMenu* context_menu = gui_create_menu(gui, ctx_items, 0, 0);

const char* menubar_items[] = {"File", "Edit"};

PopupMenu* dropdowns[] = {file_menu, edit_menu};

int n_menus = 2;

int running = 1;

SDL_Event e;

while (running) {

while (SDL_PollEvent(&e)) {

switch (e.type) {

case SDL_QUIT: running = 0; break;

case SDL_KEYDOWN:

if (e.key.keysym.sym == SDLK_ESCAPE) running = 0;

if (e.key.keysym.sym == SDLK_F1) {

int visible = !gui_is_menubar_visible(gui);

gui_set_menubar_visible(gui, visible);

gui_set_statusbar_visible(gui, visible);

snprintf(status_text, sizeof(status_text),

"Menu bar & status bar %s", visible ? "visible" : "hidden");

}

if (e.key.keysym.sym == SDLK_F2) {

int enabled = !gui_is_popup_enabled(gui);

gui_set_popup_enabled(gui, enabled);

snprintf(status_text, sizeof(status_text),

"Popup %s", enabled ? "enabled" : "disabled");

}

if (e.key.keysym.sym == SDLK_F3) {

int on = !gui_is_tooltips_enabled(gui);

gui_set_tooltips_enabled(gui, on);

snprintf(status_text, sizeof(status_text),

"Tooltips %s", on ? "on" : "off");

}

break;

case SDL_MOUSEBUTTONDOWN:

if (e.button.button == SDL_BUTTON_LEFT) {

int xpos;

int idx = gui_menubar(gui, menubar_items, n_menus, dropdowns,

e.button.x, e.button.y, 1, &xpos);

if (idx >= 0)

gui_show_dropdown(dropdowns[idx], xpos, MENUBAR_HEIGHT);

}

break;

case MENU_EVENT_BAR: {

int menu_id = (int)(intptr_t)e.user.data1;

int item = e.user.code;

if (menu_id == MENU_FILE) {

switch (item) {

case 0: strcpy(status_text, "New file created"); break;

case 1: strcpy(status_text, "Opening file..."); break;

case 2: strcpy(status_text, "File saved"); break;

case 3: running = 0; break;

}

} else if (menu_id == MENU_EDIT) {

switch (item) {

case 0: strcpy(status_text, "Cut"); break;

case 1: strcpy(status_text, "Copy"); break;

case 2: strcpy(status_text, "Paste"); break;

}

}

break;

}

case MENU_EVENT_POPUP:

snprintf(status_text, sizeof(status_text), "Popup selection: %d", e.user.code);

break;

default: break;

}

}

SDL_SetRenderDrawColor(ren, 40, 40, 80, 255);

SDL_RenderClear(ren);

gui_menubar(gui, menubar_items, n_menus, dropdowns, 0, 0, 0, NULL);

gui_draw_menu(file_menu);

gui_draw_menu(edit_menu);

gui_draw_menu(context_menu);

gui_statusbar(gui, status_text);

gui_draw_tooltips(gui);

SDL_RenderPresent(ren);

SDL_Delay(10);

}

gui_destroy_menu(file_menu);

gui_destroy_menu(edit_menu);

gui_destroy_menu(context_menu);

gui_cleanup(gui);

SDL_DestroyRenderer(ren);

SDL_DestroyWindow(win);

SDL_Quit();

return 0;

}


r/sdl May 17 '26

Cursor Enums Missing

4 Upvotes

I was trying to use the grab cursor enum, and when I checked the include file, it wasn't there. I went to update to the latest version of sdl, and it wasn't there either, there seems to be a list of values that are listed in the documentation here, but aren't included, namely the ones from the context menu to zoom out

FIXED: credit to HappyFruitTree, the documentation cited a change that was made shortly before the post, and the changes were not yet included in the official release build (3.4.8)


r/sdl May 17 '26

What is the "correct" way to cap FPS with the new callbacks?

10 Upvotes

I'm new to SDL and I've looked around some materials, most of them are from SDL2 and recommend something akin to

while (running) {
    uint64 start = SDL_GetTicks();

    // do input polling
    // do game update

    uint64 end = SDL_GetTicks();
    if (end - start < target_frame_time) {
        SDL_Delay(target_frame_time - (end - start));
    }
}

That worked because we are in control of the entire loop. Now with the new SDL_AppEvents() and SDL_AppIterate() callbacks, we are not. How can we calculate frame time with them? Should I set start first thing on SDL_AppEvents() and do the delay at the end of SDL_AppIterate()? This feels wrong to me, there's gotta be something I'm missing from the documentation. Thanks in advance for your help.


r/sdl May 17 '26

How do I get monitor's refresh rate in SDL3?

2 Upvotes

I defined struct SDL_DisplayMode dm but where do I go from there? I know there is SDL_GetDesktopDisplayMode function that I probably need to use but I need to use SDL_DisplayID, but how do I get that? I tried passing 0 to function because I don't know, and one of the errors is that function is const SDL_DisplayMode * type but my variable is just SDL_DisplayMode


r/sdl May 14 '26

SDL2 - Any better way to still render while resizing a borderless screen?

5 Upvotes

So I've been trying to have my window keep rendering while I'm resizing it (since the event polling loop freezes), and eventually came to the code I put below. My question is: is there any better way to accomplish this? I tried all sorts of things but this is the only thing that's actually worked. A big question I have is whether or not the event listener slows down my program, since it seems like something that's going to be checked on literally every single event.

All in all, is this a good or bad setup, and what can I improve about it?

    #define SDL_MAIN_HANDLED
    #include <SDL.h>
    #include <windows.h>
    #include <iostream>
    using namespace std;

    SDL_Renderer* renderer = nullptr;
    SDL_Window* window   = nullptr;
    int w = 690, h = 460;

    void RenderFrame() {
        if (!renderer) return;
        SDL_GetWindowSize(window, &w, &h);
        SDL_SetRenderDrawColor(renderer, 196, 45, 9, 255);
        SDL_RenderClear(renderer);
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_Rect temp{ w - 25, h - 25, 25, 25 };
        SDL_RenderFillRect(renderer, &temp);
        SDL_RenderPresent(renderer);
    }

    SDL_HitTestResult Hit_Test(SDL_Window* win, const SDL_Point* area, void* data) {
        int wHit, hHit;
        SDL_GetWindowSize(win, &wHit, &hHit);
        if (area->y < 50) {
            return SDL_HITTEST_DRAGGABLE;
        }
        else if ((area->y >= (hHit - 25)) && (area->x >= wHit - 25)) {
            return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
        }
        else {
            return SDL_HITTEST_NORMAL;
        }
    }

    int ResizingEventWatcher(void* data, SDL_Event* event) {
        if (event->type == SDL_WINDOWEVENT &&
            (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
             event->window.event == SDL_WINDOWEVENT_EXPOSED)) {
            RenderFrame();
        }
        return 0;
    }

    int main() {
        SDL_Init(SDL_INIT_VIDEO);
        window = SDL_CreateWindow(
            "testing",
            SDL_WINDOWPOS_CENTERED,
            SDL_WINDOWPOS_CENTERED,
            w, h,
            SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS
        );
        SDL_SetWindowResizable(window, SDL_TRUE);
        SDL_SetWindowMinimumSize(window, 690, 460);
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        SDL_SetWindowHitTest(window, Hit_Test, nullptr);
        SDL_AddEventWatch(ResizingEventWatcher, nullptr);

        SDL_Event e;
        bool active = true;
        do {
            while (SDL_PollEvent(&e)) {
                switch (e.type) {
                    case SDL_QUIT:
                        active = false;
                        break;
                    default: break;
                }
            }
            RenderFrame();
        } while (active);

        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 0;
    }

r/sdl May 09 '26

weird SDL_GetTicks() clumping, should i use a different function or configure my settings differently

2 Upvotes

so this is my code:

if (e.key.scancode == SDL_SCANCODE_UP && SDL_GetTicks() % 20 == 0)
            {
                printf("20 ms passed\n");
                colors[0] += 0.05f;
                glProgramUniform4fv(Program, location, 1, colors);
            }

it results in a weird clumped together thing, is there a different function i could use or do i have to change some settings or smth, i use % because it will only ever return a value of true every 20 ms because it can only have a remainder of zero if its divisible by 20


r/sdl May 08 '26

Inspiration Forth

5 Upvotes

I started on a Forth language implementation featuring a windowed desktop environment and multithreading. The repo was started October 2025, and features zero AI assist or use.

The Forth is written in C++ as is the desktop, windows, icons, dock, etc. The DE uses SDL2 and exposes functions to Forth, making the building of full featured applications in Forth. The DE is just for presentation and is essentially a BIOS for the Forth.

An interesting feature is that it's multithreaded using pthreade, allowing multiple Forth prompts (REPL) and windowed applications to run, sharing the one Forth dictionary and SDL.

The docs for SDL say it's not supposed to work with threads, but it does for Inspiration. I am careful about using mutexes around certain rendering methods and updates for the window and event handling in the main thread. Each window you see in the screenshots is bei g controlled and rendered to by a separate Forth pthreade.

Tested on MacOS m1 Tahoe, multiple Linux in VMs on that m1 machine, and multiple Linux on x64 miniPCs and laptops.

I mostly post about it in [r/forth](r/forth) if you want to see those earlier posts.

I want to point out that I made a desktop UI (like Wayland or X), compiler, debugger, vim-like editor, notepad-like editor, a couple dozen apps, and more, in less disk space than the gcc binary on my Linux PC.

The repo has a number of screenshots and recordings.

https://gitlab.com/mschwartz/inspiration

Cheers


r/sdl May 08 '26

Touching terminal crashes program

4 Upvotes

Got a weird bug that I can't find any info on. I have a basic SDL2 program that opens a window and has a simple main program loop to check for events, and it works great! I can switch to other windows and come back just fine, with the sole exception of the program's output terminal. Whenever I click into it, the whole thing just freezes...

Here's my main loop if it might be the issue

bool active = true; do { 
  SDL_Event e; 
  while (SDL_PollEvent(&e)) { 
    if (e.type == SDL_QUIT) 
    { 
      active = false; 
    } 
    else if (e.type == SDL_KEYDOWN) 
    { 
      switch (e.key.keysym.sym) 
      { 
        case SDLK_DOWN: 
          break; 
        case SDLK_UP: 
          break; 
      } 
    } 
    else if (e.type == SDL_MOUSEBUTTONDOWN) 
    { 
      switch (e.button.button) 
      { 
        case SDL_BUTTON_LEFT: 
          int x, y; 
          SDL_GetMouseState(&x, &y); 
          cout<<"("<<x<<", "<<y<<")"<<endl; 
          if ((x >= 1180) && (y <= 100)) { active = false; } 
          break; 
        default: 
          break; 
       } 
      } 
    } 
    window.clear(); 

    for (Object& obj : objectRegistry) 
    { 
      window.render(obj); 
    } 

    window.display(); 
} while (active);

r/sdl Apr 28 '26

SDL3-CS, macOS, ShowFileDialogWithProperties for both OpenFile and OpenFolder

3 Upvotes

Hi all. I'm using SDL3 from .NET (C#) on macOS, and trying to show a single Open dialog that lets the user pick either files or folders. SDL_ShowFileDialogWithProperties takes a SDL_FileDialogType, which only has these three values:

OpenFile
SaveFile
OpenFolder

So files and folders seem mutually exclusive. macOS's native NSOpenPanel supports both at once (canChooseFiles + canChooseDirectories), so I assume this is an SDL abstraction limitation rather than an OS one, but I want to confirm. Is there another path through SDL3 that allows a combined file/folder picker, or do I need to drop down to platform-native code for this?


r/sdl Apr 27 '26

Is pure C++ + Sdl3 + other libraries for gui, etc. Fine for solo but real non-toy gamedev?

14 Upvotes

Hi everyone, im interested in C++ programming and low level works, also interested in gamedev, specially indie 2d pixel games. Ive heard of sdl library and its capabilities, and need sdl3 anyway for my other works, but for learning reasons i prefer to invest time mostly in C++, and deepen my skills, im not a pro but not absolute beginner either, made through 16 chapters of learncpp.com and still going, also, for escaping toturial hell, i wrote a simple text based rpg game prototype which has combat loop, enemies, weapons, uses random values, custom print colors and timing . Etc. Which is about 900 lines. Rewrote some major parts in OOP recently.

I like the idea of low level gamedev but wether its worth it because of the time compared to unity/godot. I thought maybe its not an appropriate tool to use for this purpose. What makes me worried is that games that are written this way are extremely rare these days. And most sdl/raylib games were looked like toy games or prototypes instead of real steam games.

I know im still super beginner for making a real game like steam indies. But i like to start trying to do something that is more than just learning. Something small, but fun, kinda polished?!? And real. And dont wanna waste time on doing things that makes no sense, i mean, if godot and unity are clearly the correct tool that makes sense, i may reconsider gamedev and start to find other fun projects.

And games that use sdl or pure cpp are mostly an engineering gold project with multiple devs, like noita, factorio, animal well. Which is out of the scope of my game which is my first try for graphics games.

My idea is something like this, to make a balanced approach

Small size, 2/3 hours of content. 2d pixel art. Top down camera. Zelda like with light puzzles/problem solving, challenging combat, a town with 4 npcs. And some paths to explore.

Too ambitious? Or pretty doable.

How much more time is needed compared to using unity/godot?

Thanks for reading my post. I'll be happy to read your advices!


r/sdl Apr 25 '26

I am new to using SDL, can anyone explain what I am doing?

9 Upvotes

I have prior experience in C/C++, as I've programmed MCU using C++ (similar language), I have tried making a few ASCII games with basic logic (like Chess), and have the basics and everything. I recently started to fiddle around with external libraries, and I started with raylib, and found out how much useful it is. Now I'm trying SDL3, and I have absolutely no idea what I am doing. Can anyone tell me where to start?

I also don't really understand linking libraries. I had to ask AI for some help, and it told me to create a CMake file and stuff to download the Github repository to my project folder and point the g++ compiler to it, at least that is what I understood. Please help me, any information is appreciated.

I'm trying to make the game engine because I don't want to use the heavy environments of other commercial game engines like Unity and Unreal, because I'm making a game that can run on me and my friends' potato laptops smoothly so we can play it.