From f72bd8c44f9c5c96cc9ea8c9a6d48cb76949163e Mon Sep 17 00:00:00 2001 From: homeburger Date: Sat, 9 May 2026 15:36:53 -0500 Subject: [PATCH] create SDL window --- CMakeLists.txt | 18 +++++++++++++++++ src/App.cpp | 51 ++++++++++++++++++++++++++++++++++++++---------- src/App.hpp | 14 ++++++++----- src/Window.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++ src/Window.hpp | 34 ++++++++++++++++++++++++++++++++ src/main.cpp | 2 ++ test/TestApp.cpp | 15 ++------------ 7 files changed, 151 insertions(+), 28 deletions(-) create mode 100644 src/Window.cpp create mode 100644 src/Window.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e177d05..6f2a14c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,28 +17,45 @@ FetchContent_Declare( ) FetchContent_MakeAvailable(googletest) +# sdl3 +FetchContent_Declare( + sdl3 + GIT_REPOSITORY https://github.com/libsdl-org/SDL.git + GIT_TAG release-3.4.x +) +FetchContent_MakeAvailable(sdl3) + # add_subdirectory() to nest CMakeLists add_executable(maiden src/App.cpp + src/Window.cpp src/main.cpp # include extra source files here ) add_executable(maiden_test src/App.cpp + src/Window.cpp test/TestApp.cpp ) +# i think the strat is to build all of the core app components into a single library +# and then you link that to the two different executables (real main and test main) target_include_directories(maiden PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src" # add additional include directories here ) +target_link_libraries(maiden PRIVATE + SDL3::SDL3 +) + target_include_directories(maiden_test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src" ) +# test only stuff down here VVV target_compile_options(maiden_test PRIVATE --coverage) target_link_options(maiden_test PRIVATE --coverage) @@ -46,6 +63,7 @@ target_link_options(maiden_test PRIVATE --coverage) target_link_libraries(maiden_test PRIVATE GTest::gmock GTest::gmock_main + SDL3::SDL3 ) include(CTest) diff --git a/src/App.cpp b/src/App.cpp index 0026493..d6845cc 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -1,18 +1,49 @@ #include "App.hpp" -void App::run() { - - std::cout << "im an app and im running !!" << std::endl; - - (void)foo(); - - return; +#include +#include +#include +App::App(): window_(new Window()) { + // smart pointers might be a good idea + // since app will be the top level owner we can use unique ptrs for almost everything } -int32_t App::foo() { +int32_t App::run() { - return 12; + SDL_Event event; + while (window_->open()) { + // app loop for as long as the window is open -} + // pass events to the window + while(SDL_PollEvent(&event) != 0) { + window_->handleEvent(event); + } + + // pass vulkan handling to engine + // call engine.render() or something + // engine will have a pointer to window so can handle pushing to the screen + + if(window_->rendering()) { + // engine.draw(); + + // TODO: performance profiling :3 + // static int counter = 0; + // if(counter > 100) { + // std::cout << "out" << std::endl; + // counter = 0; + // } + // counter++; + + } else { + // throttle while the window isn't active + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + // SDL teardown handled in window destructor + + return 0; // maybe want to have an error codes enum for better clarity + +} \ No newline at end of file diff --git a/src/App.hpp b/src/App.hpp index 500db8c..c94bb56 100644 --- a/src/App.hpp +++ b/src/App.hpp @@ -4,16 +4,20 @@ #include #include +#include "Window.hpp" + class App { - public: - App() = default; +public: + App(); ~App() = default; - void run(); + int32_t run(); - private: +private: - int32_t foo(); + Window* window_; + + bool rendering_ = true; }; diff --git a/src/Window.cpp b/src/Window.cpp new file mode 100644 index 0000000..2d12611 --- /dev/null +++ b/src/Window.cpp @@ -0,0 +1,45 @@ + +#include "Window.hpp" + +#include + +Window::Window() { + + (void)init(); + +} + +Window::~Window() { + + SDL_DestroyWindow(sdlWindow_); + SDL_Quit(); + +} + +int Window::init() { + + // TODO: config service for controlling window parameters + sdlWindow_ = SDL_CreateWindow("Ouros: Vulkan", 1280u, 720u, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); + + if(sdlWindow_ != nullptr) { + rendering_ = true; + open_ = true; + return 0; + } else { + return -1; + } + +} + +void Window::handleEvent(SDL_Event& event) { + + if(event.type == SDL_EVENT_QUIT ) { + open_ = false; + } + + if(event.type == SDL_EVENT_WINDOW_MINIMIZED) { + rendering_ = false; + } else if(event.type == SDL_EVENT_WINDOW_RESTORED) { + rendering_ = true; + } +} diff --git a/src/Window.hpp b/src/Window.hpp new file mode 100644 index 0000000..a8889e8 --- /dev/null +++ b/src/Window.hpp @@ -0,0 +1,34 @@ + +#pragma once + +#include "SDL3/SDL.h" +#include "SDL3/SDL_vulkan.h" + +// reference: https://wiki.libsdl.org/SDL3/SDL_CreateWindow +class Window { + +public: + + Window(); + ~Window(); + + // for SDL3 event polling, runs once per app iteration in its while(running) loop + void handleEvent(SDL_Event& event); + + bool rendering() { return rendering_; } + bool open() { return open_; } + +private: + + // launches window, runs at app startup + int init(); + + // this window class will eventually hold mouse, keyboard, audio, etc. interfaces, like an SDL3 hub + // app will be able to attach callbacks for mouse and keyboard events + + SDL_Window* sdlWindow_; + + bool rendering_ = false; + bool open_ = false; + +}; diff --git a/src/main.cpp b/src/main.cpp index 80dab38..ff0f4f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,8 +7,10 @@ int main(int argc, char** argv) { std::cout << "hi mom !" << std::endl; + // create app and run App app; app.run(); + // no freaking way return 0; } diff --git a/test/TestApp.cpp b/test/TestApp.cpp index 65159fa..ae61cb2 100644 --- a/test/TestApp.cpp +++ b/test/TestApp.cpp @@ -2,9 +2,7 @@ #include #include -#define private public -#include -#undef private +#include "App.hpp" class TestApp : public testing::Test { @@ -21,16 +19,7 @@ class TestApp : public testing::Test { TEST_F(TestApp, TestApp_run_nominal) { createUut(); - uut_->run(); - // no expect here + //EXPECT_EQ(uut_->run(), 0l); } - -TEST_F(TestApp, TestApp_foo_nominal) { - - createUut(); - - EXPECT_EQ(uut_->foo(), 12); - -}