diff --git a/.gitmodules b/.gitmodules index 35ec1c6..91d3e6e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = extern/dawn url = https://github.com/google/dawn.git shallow = true +[submodule "extern/sdl3webgpu"] + path = extern/sdl3webgpu + url = https://github.com/eliemichel/sdl3webgpu.git diff --git a/CMakeLists.txt b/CMakeLists.txt index be64417..9a75867 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.22) -project(webgpu) +project(webgpu-engine) set(CMAKE_CXX_STANDARD 20) # Compile commands for dev @@ -9,40 +9,77 @@ if(CMAKE_EXPORT_COMPILE_COMMANDS) ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}) endif() -# Binaries -add_executable( ${PROJECT_NAME} ) -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ -) -file(GLOB_RECURSE SOURCE_FILES - ${CMAKE_SOURCE_DIR}/src/*.cpp) -target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_FILES}) +add_executable(${PROJECT_NAME}) # Error on memory address issues in debug mode if(CMAKE_BUILD_TYPE MATCHES "Debug") - set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -Werror -fsanitize=undefined -fsanitize=address" + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Werror -fsanitize=undefined -fsanitize=address" ) target_link_options(${PROJECT_NAME} BEFORE PUBLIC -fsanitize=undefined PUBLIC -fsanitize=address ) endif() -# Dawn library set up -# If we're in debug mode fast linking is the priority over easy distribution. -if(CMAKE_BUILD_TYPE MATCHES "Debug") - set(DAWN_BUILD_MONOLITHIC_LIBRARY "SHARED") -endif() -set(DAWN_FETCH_DEPENDENCIES ON) -add_subdirectory("extern/dawn" EXCLUDE_FROM_ALL) +# Dawn library setup +find_package(Threads REQUIRED) +find_package(Dawn) +if (NOT Dawn_FOUND) + if(CMAKE_BUILD_TYPE MATCHES "Debug") + set(DAWN_BUILD_MONOLITHIC_LIBRARY "SHARED") + endif() + set(DAWN_FETCH_DEPENDENCIES ON CACHE BOOL "" FORCE) + + # Prevent Dawn from building excessive tools/samples to save compile time + set(DAWN_BUILD_SAMPLES OFF CACHE BOOL "" FORCE) + set(DAWN_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) + + add_subdirectory("extern/dawn" EXCLUDE_FROM_ALL) -# Linking -if(EMSCRIPTEN) - set_target_properties(app PROPERTIES SUFFIX ".html") - target_link_libraries(app PRIVATE emdawnwebgpu_cpp webgpu_glfw) - target_link_options(app PRIVATE "-sASYNCIFY=1" "-sUSE_GLFW=3") + set(DAWN_LINK_TARGET webgpu_dawn) else() - target_link_libraries(${PROJECT_NAME} PRIVATE webgpu_dawn webgpu_glfw glfw) + set(DAWN_LINK_TARGET dawn::webgpu_dawn) +endif() + + + +# Find SDL3 Packages +find_package(SDL3 REQUIRED) +find_package(SDL3_image REQUIRED) +set(SDL3_image_LIBRARIES SDL3_image::SDL3_image) + +# Force the 'webgpu' dependency expected by sdl3webgpu to point to Dawn instead +if(NOT TARGET webgpu) + add_library(webgpu ALIAS ${DAWN_LINK_TARGET}) +endif() + +# Configure and include sdl3webgpu +add_subdirectory(extern/sdl3webgpu) + +# Include directories +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + ${SDL3_INCLUDE_DIRS} + ${SDL3_image_INCLUDE_DIRS} +) + +file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/src/*.cpp) +target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_FILES}) + + +# Linking Layer +if(EMSCRIPTEN) + # Note: your target is ${PROJECT_NAME}, updated 'app' references to match + set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") + target_link_libraries(${PROJECT_NAME} PRIVATE emdawnwebgpu_cpp webgpu_glfw) + target_link_options(${PROJECT_NAME} PRIVATE "-sASYNCIFY=1" "-sUSE_GLFW=3") +else() + target_link_libraries(${PROJECT_NAME} PRIVATE + ${DAWN_LINK_TARGET} + sdl3webgpu + SDL3::SDL3 + ${SDL3_image_LIBRARIES} + ) endif() diff --git a/README.md b/README.md index 2747f65..de60d30 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,14 @@ My build command ```bash CXX=clang++ CC=clang cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -GNinja -B build . && cmake --build build -j16 ``` + +## Development +This project relies on a webgpu native implementation called dawn. If you plan +on doing any development in this project you should install it systemwide to +reduce the chances of having to re-install it while working on the project. +I like to use this command to generate the build project so it has debug headers +and is a shared library for faster linking `cmake -S . -B out/Debug -G Ninja +-DDAWN_FETCH_DEPENDENCIES=ON -DDAWN_ENABLE_INSTALL=ON -DGLFW_INSTALL=ON +-DCMAKE_BUILD_TYPE=Debug -DDAWN_BUILD_MONOLITHIC_LIBRARY=SHARED +-DDAWN_BUILD_SAMPLES=OFF` and use the rest of the instructions +[here](https://dawn.googlesource.com/dawn.git/+/HEAD/docs/quickstart-cmake.md). diff --git a/extern/dawn b/extern/dawn index 98747c7..92c4ae4 160000 --- a/extern/dawn +++ b/extern/dawn @@ -1 +1 @@ -Subproject commit 98747c789b4be3793d8676413bb1ab163b8e08a9 +Subproject commit 92c4ae4cfeb209d513ef619014084b79fd6f1af1 diff --git a/extern/sdl3webgpu b/extern/sdl3webgpu new file mode 160000 index 0000000..4fa9d70 --- /dev/null +++ b/extern/sdl3webgpu @@ -0,0 +1 @@ +Subproject commit 4fa9d70935e41c075f664b231ee10a64262a8ac7 diff --git a/include/wne/window.hpp b/include/wne/window.hpp index 50bc16d..63eb48f 100644 --- a/include/wne/window.hpp +++ b/include/wne/window.hpp @@ -3,12 +3,12 @@ #include #include +#include #if defined(__EMSCRIPTEN__) #include #endif #include #include -#include namespace wne { // TODO: load me in a better way diff --git a/src/window.cpp b/src/window.cpp index 686fb76..c580e11 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,5 +1,10 @@ #include "wne/window.hpp" +#include +#include +#include +#include + namespace wne { void window::ConfigureSurface() { @@ -91,26 +96,42 @@ window::window() { instance.WaitAny(f2, UINT64_MAX); } void window::Start() { - if (!glfwInit()) { + if (!SDL_Init(SDL_INIT_VIDEO)) { return; } - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow *window = - glfwCreateWindow(kWidth, kHeight, "WebGPU window", nullptr, nullptr); - surface = wgpu::glfw::CreateSurfaceForWindow(instance, window); + SDL_Window *window = SDL_CreateWindow("Hello World!", kWidth, kHeight, 0); + + // surface = wgpu::glfw::CreateSurfaceForWindow(instance, window); + WGPUSurface c_surface = SDL_GetWGPUSurface(instance.Get(), window); + surface = wgpu::Surface::Acquire(c_surface); InitGraphics(); #if defined(__EMSCRIPTEN__) emscripten_set_main_loop(Render, 0, false); #else - while (!glfwWindowShouldClose(window)) { - glfwPollEvents(); + bool wants_running = true; + while (wants_running) { + // TODO: Create event handler files + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_EVENT_QUIT: + wants_running = false; + break; + case SDL_EVENT_KEY_DOWN: + if (event.key.key == SDLK_ESCAPE) { + wants_running = false; + } + break; + } + } Render(); surface.Present(); instance.ProcessEvents(); } #endif + SDL_Quit(); } } // namespace wne