How to fix `sdl3webgpu` to run a simple example

I have found a temporary solution in my issue: How to fix `sdl3webgpu` to run a simple example in January 2026 · Issue #7 · eliemichel/sdl3webgpu · GitHub This is a copy of the solution below from the issue.

Maybe it will be useful for someone who want to start to practice with WebGPU using SDL3 to create apps in C or C++ for Windows and Web (using Emscripten and WebAssembly). You need to copy two files in your project: sdl3webgpu.h and sdl3webgpu.c. Maybe someone will write how to improve something.

I use this version of the sdl3webgpu: GitHub - eliemichel/sdl3webgpu at 4fa9d70935e41c075f664b231ee10a64262a8ac7 That commit was created 9 month ago. It is the last commit at this moment.

At first time it did not work but Gemini 3 helped to fix it:

Before:

sdl3webgpu.h

WGPUSurface SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window* window);

After:

WGPUSurface wgpuSurfaceCreateFromSDLWindow(WGPUInstance instance, SDL_Window *window);

Before:

sdl3webgpu.c

SDL_GetWGPUSurface(WGPUInstance instance, SDL_Window *window)

After:

WGPUSurface wgpuSurfaceCreateFromSDLWindow(WGPUInstance instance, SDL_Window *window)

Before:

sdl3webgpu.c

#elif defined(__EMSCRIPTEN__)
    {
#ifdef WEBGPU_BACKEND_EMDAWNWEBGPU
        WGPUEmscriptenSurfaceSourceCanvasHTMLSelector fromCanvasHTMLSelector;
        fromCanvasHTMLSelector.chain.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector;
#else
        WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
        fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
#endif
        fromCanvasHTMLSelector.chain.next = NULL;
        fromCanvasHTMLSelector.selector = "canvas";

        WGPUSurfaceDescriptor surfaceDescriptor;
        surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
        surfaceDescriptor.label = NULL;

        return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
    }

After:

#elif defined(__EMSCRIPTEN__)
    {
        // Emscripten/Dawn naming convention
        WGPUSurfaceDescriptorFromCanvasHTMLSelector fromCanvasHTMLSelector;
        fromCanvasHTMLSelector.chain.sType = WGPUSType_SurfaceDescriptorFromCanvasHTMLSelector;
        fromCanvasHTMLSelector.chain.next = NULL;
        fromCanvasHTMLSelector.selector = "canvas";

        WGPUSurfaceDescriptor surfaceDescriptor;
        surfaceDescriptor.nextInChain = &fromCanvasHTMLSelector.chain;
        surfaceDescriptor.label = NULL; // On Web this is usually just a char*

        return wgpuInstanceCreateSurface(instance, &surfaceDescriptor);
    }

Source code of the simple example: webgpu-sdl3-c.zip (9.2 KB). This example simply changes the background color over time.

Now I can compile and run this simple example with SDL3 for Windows and Web. I use these commands on Windows:

config-exe
build-exe
run-exe

These are batch files - see my archive with a source code above.

So, it is my first window in WebGPU for Windows: webgpu-sdl3-c-exe.zip (zip: 5.43 MB, unzipped: 15.9 MB)

I can build my example with Emscripten/WebAssembly and upload to Vercel: https://webgpu-sdl3-c.vercel.app/

vercel login
vercel

Run vercel --prod to overwrite later.

Libs for Windows and WASM that my example uses:

I use CMake and absolute paths for libs:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(webgpu-sdl3-c)
add_executable(app)

# 1. Set the path to where you unzipped wgpu-native
set(WGPU_PATH "H:/libs/wgpu-windows-x86_64-gnu-release-27.0.4.0")

target_sources(app PRIVATE
    src/main.c
    src/sdl3webgpu.h
    src/sdl3webgpu.c
)

if (EMSCRIPTEN)
    # This prevents the "linker setting ignored during compilation" warning
    target_link_options(app PRIVATE "-sUSE_WEBGPU=1")
    
    # This tells Emscripten to link the WebGPU library
    target_link_libraries(app PRIVATE "webgpu")

    set(SDL3_DIR "H:/libs/SDL3-devel-3.4.0-wasm/lib/cmake/SDL3")
elseif (WIN32)
    list(APPEND CMAKE_PREFIX_PATH "H:/libs/SDL3-devel-3.4.0-mingw")

    target_link_libraries(app PRIVATE "${WGPU_PATH}/lib/libwgpu_native.dll.a")
else()
    message(WARNING "Unknown platform!")
endif()

find_package(SDL3 REQUIRED)

# Only include the Windows WGPU path if we are NOT on Emscripten
if (NOT EMSCRIPTEN)
    target_include_directories(app PRIVATE ${WGPU_PATH}/include)
endif()

target_link_libraries(app PRIVATE SDL3::SDL3)

# Copy the DLL to the folder where your .exe is
add_custom_command(TARGET app POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    "${WGPU_PATH}/bin/wgpu_native.dll" $<TARGET_FILE_DIR:app>
)

This is a very simple particle system in C and WebGPU-Native with Instancing but without of using of Compute Shader

View in the browser on Vercel

Download EXE: instancing-simple-particles-webgpu-sdl3-c-exe.zip (5.4 MB)

Source code: instancing-simple-particles-webgpu-sdl3-c.zip (12.9 KB)

instancing-simple-particles-webgpu-sdl3-c