Using SDL for Window Management π‘ΒΆ
Resulting code: step030-sdl
Resulting code: step030-sdl-vanilla
The main part of this guide uses GLFW for window management because it is very lightweight. However, another popular choice is to use the SDL (Simple DirectMedia Layer).
The SDL has support for Android and iOS and brings other nice capabilities for writing video games, like sound manipulation for instance.
This appendix shows how to replace GLFW with SDL2 on the simple example of the Hello Triangle chapter.
DependenciesΒΆ
Start by removing the glfw
and glfw3webgpu
directories. We replace them with their SDL equivalent:
Download the source code of the latest release of SDL (tested with 2.28.5), unzip it so that you have a file
SDL2/README-SDL.txt
.Download the equivalent of
glfw3webgpu
for SDL2, namelysdl2webgpu
. Unzip it so that you have a filesdl2webgpu/CMakeLists.txt
.
In the main CMakeLists.txt
, replace GLFW with SDL2:
- add_subdirectory(glfw)
+ add_subdirectory(SDL2)
add_subdirectory(webgpu)
- add_subdirectory(glfw3webgpu)
+ add_subdirectory(sdl2webgpu)
add_executable(App
main.cpp
)
- target_link_libraries(App PRIVATE glfw webgpu glfw3webgpu)
+ target_link_libraries(App PRIVATE SDL2::SDL2 webgpu sdl2webgpu)
CodeΒΆ
At the beginning of main.cpp
, replace the inclusion of GLFW
and glfw3webgpu
:
#include <glfw3webgpu.h>
#include <GLFW/glfw3.h>
becomes:
#define SDL_MAIN_HANDLED
#include <sdl2webgpu.h>
#include <SDL2/SDL.h>
Note
Defining SDL_MAIN_HANDLED
prevents SDL from creating its own main
function, which would conflict with yours.
In the main
function, replace call to glfwInit()
:
// Remove
if (!glfwInit()) {
std::cerr << "Could not initialize GLFW!" << std::endl;
return 1;
}
becomes:
// Add
SDL_SetMainReady();
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "Could not initialize SDL! Error: " << SDL_GetError() << std::endl;
return 1;
}
Note
Calling SDL_SetMainReady()
is needed when using SDL_MAIN_HANDLED
instead of letting SDL automatically manage the main function.
Change the creation of the window:
// Remove
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(640, 480, "Learn WebGPU", NULL, NULL);
becomes:
// Add
int windowFlags = 0;
SDL_Window *window = SDL_CreateWindow("Learn WebGPU", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, windowFlags);
Change the name of the function to get a surface:
// Remove
Surface surface = glfwGetWGPUSurface(instance, window);
becomes:
// Add
Surface surface = SDL_GetWGPUSurface(instance, window);
The main loop also changes:
// Remove
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// [...]
}
becomes:
// Add
bool shouldClose = false;
while (!shouldClose) {
// Poll events and handle them.
// (contrary to GLFW, close event is not automatically managed, and there
// is no callback mechanism by default.)
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
shouldClose = true;
break;
default:
break;
}
}
// [...]
}
Finally, clean up is done this way:
// Remove
glfwDestroyWindow(window);
glfwTerminate();
becomes:
// Add
SDL_DestroyWindow(window);
SDL_Quit();
ConclusionΒΆ
You now have a good base to work with SDL. If you want to port a more advanced chapter, you may need to adapt the event handling to have SDL event trigger the callback we used to pass to GLFW (like window resize, mouse move, click, keyboard, etc.).
Important
Let me know if sdl2webgpu does not work on your platform as I did not intensively check yet. I also did not adapt it to Android and iOS yet.
Resulting code: step030-sdl
Resulting code: step030-sdl-vanilla