HDK-SDL wrapper
HDK-SDL uses the grid SharedPtrWrapper to create relatively light-weight reference wrappers around pointers to SDL3 primitives.
Use classes without declaring pointers to them, knowing that copying or referencing is relatively cheap and that the underlying SDL3 primitive will be properly managed and cleaned up when no longer needed.
Dependencies
Building
To build the hdk-sdl, checkout the source, change into the source directory, make a build directory & run the following commands in the root of the repository:
git clone https://git.ufp.institute/ufp/hdk-sdl.git
mkdir build-hdk-sdl
cd build-hdk-sdl
cmake ../hdk-sdl
cmake --build .
This may require the building of SDL if your system does not have the required version installed. See SDL3 Build Dependencies if SDL fails to build on your machine.
Naming Conventions
API that is 1 to 1 with SDL with otherwise minimal wrapping will be as close to the original SDL function call as possible: for example, SDL_CreateWindow will be wrapped by hd::sdl::Window::Create.
To update a surface, the original SDL function is SDL_UpdateWindowSurface(SDL_Window* window), and the wrapper will be window.UpdateSurface().
So on and so forth. But there are some exceptions and edge cases.
For example when Bliting a surface, the original SDL function is SDL_BlitSurface, but the wrapper will expose two alternatives: BlitTo and BlitFrom, each implying that this* is the source or destination of the blit, respectively. In this case not only is the function name changed, but the parameters are also rearranged to be more intuitive and consistent with the implied source/destination of the blit.
Default values
While done sparingly, some wrapper methods may provide default values for parameters that are commonly used with a specific value. For example when the last parameter of a function is an optional pointer it may be defaulted to nullptr in the wrapper method, so that the caller can omit it when they don't need it. Sensible defaults may also be provided elsewhere.
Headers
Within include/hdk/sdl there are folders for each SDL3 header files, and within each files for corresponding wrappers of SDL3 primitive types. Basically if SDL3 lets you "create" a primitive, use that primitive with some functions, and then "destroy" that primitive, there should be a wrapper for that primitive in the corresponding header file. The prime example is include/hd/sdl/video/Window.hpp which contains the hd::sdl::video::Window wrapper for SDL_Window
With this entirely header-only and inline design, there is no need for a corresponding .cpp and the resulting compiled code should be as efficient as if you were using the raw SDL3 API directly, while still benefiting from the safety and convenience of C++ RAII and wrapper classes.
Dependency Resolution
hdk-sdl resolves SDL3 with a system-first policy by default:
- Try
find_package(SDL3 <minimum>). - If unavailable or too old, fall back to
FetchContent.
Relevant CMake options:
HDK_SDL_SYSTEM_SDL3HDK_SDL_FETCH_SDL3_FALLBACKHDK_SDL_MIN_SDL3_VERSION
Example Assets
When building examples, hdk-sdl resolves shared assets in this order:
- Repository checkout assets (when building inside the HDK monorepo)
- Installed
hdk-assetspackage with minimum version FetchContentfallback fromHDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORY
Relevant CMake options:
HDK_SDL_EXAMPLES_FETCH_ASSETSHDK_SDL_EXAMPLES_ASSETS_MIN_VERSIONHDK_SDL_EXAMPLES_ASSETS_GIT_REPOSITORYHDK_SDL_EXAMPLES_ASSETS_GIT_TAG
Installation Layout
Installed examples and assets are organized under one prefix using GNU install dirs.
- Example binaries:
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} - Shared assets:
${CMAKE_INSTALL_PREFIX}/${HDK_SDL_EXAMPLES_INSTALL_ASSETSDIR}
The default shared assets directory is assets, giving ${CMAKE_INSTALL_PREFIX}/assets.