#include // Hollow Wrapper to SDL #include // Hollow Wrapper to SDL main boilerplate via hdk::sdl::ApplicationInterface & the macro HDK_SDL_MAIN_CLASS #include namespace hello_renderer_2d { using namespace hdk; namespace fs = std::filesystem; fs::path GetAssetsRoot() { const char* base = SDL_GetBasePath(); if (!base || *base == '\0') { return fs::path("assets"); } fs::path exe_dir(base); return exe_dir / ".." / "assets"; } fs::path AssetPath(const fs::path& category, const fs::path& relative_path) { return GetAssetsRoot() / category / relative_path; } class HelloRenderer2D : public sdl::PublicApp { public: const sdl::Log& AppLog { sdl::Log::Application }; grid::eps::TapScope taps, loud; sdl::evt::AllTypes events; const sdl::evt::EventConduit::Callback_t LOG_EVENT = [&](SDL_Event* event) { auto description = sdl::Event::GetDescription<1024>(event); AppLog.Debug("Event received: %s", description.c_str()); }; virtual SDL_AppResult Event(SDL_Event* event) override { // Get a description of the event for logging, you can adjust the buffer size as needed, defaults to 512 events.Trigger(event); return AppStatus; } sdl::Window window { nullptr }; sdl::Renderer renderer { nullptr }; sdl::Surface surface { nullptr }; sdl::Texture texture { nullptr }; virtual SDL_AppResult Init(int argc, char* argv[]) override { SDL_SetAppMetadata("Hello Renderer 2D", "0.0.1", "institute.ufp.hdk.sdl.examples.hello_renderer_2d"); sdl::Log::SetPriorities(SDL_LOG_PRIORITY_DEBUG); auto [w, r] = sdl::CreateWindowAndRenderer("Hello World", 800, 600, 0); window = w; renderer = r; if (!window || !renderer) { SDL_Log("Failed to create window or renderer: %s", SDL_GetError()); return AppStatus = SDL_APP_FAILURE; } AppLog.Info("Assets root: %s", GetAssetsRoot().lexically_normal().string().c_str()); fs::path matStoneGray01Path = AssetPath( "textures", "sbs_-_base_materials_pack_128x128/Base Materials 128x128/Stone/Mat_Stone_Gray_01-128x128.png"); AppLog.Info("Example texture path: %s", matStoneGray01Path.lexically_normal().string().c_str()); surface = sdl::Surface::LoadSurface(matStoneGray01Path.string().c_str()); if (!surface) { AppLog.Error("Failed to load surface: %s", SDL_GetError()); return AppStatus = SDL_APP_FAILURE; } texture = renderer.CreateTextureFromSurface(surface); if (!texture) { AppLog.Error("Failed to create texture from surface: %s", SDL_GetError()); return AppStatus = SDL_APP_FAILURE; } taps << events.Quit.Attach([&](SDL_Event* event) { AppStatus = SDL_APP_SUCCESS; printf("Quit event received, exiting...\n"); }); //loud << events.Attach(LOG_EVENT); SDL_WindowID window_id = window.GetID(); taps << events.Window[window_id].MouseLeave.Attach([&](SDL_Event* event) { AppLog.Info("Mouse left the window!"); loud.PauseAll(); }); taps << events.Window[window_id].MouseEnter.Attach([&](SDL_Event* event) { AppLog.Info("Mouse entered the window!"); loud.ResumeAll(); }); taps << events.Window[window_id].Moved % [&](SDL_Event* event) { AppLog.Info("Window moved to (%d, %d)", event->window.data1, event->window.data2); }; renderer.SetLogicalPresentation(800, 600, SDL_LOGICAL_PRESENTATION_LETTERBOX); renderer.SetDrawColor(255, 0, 0, 0); renderer.FillRect(nullptr); renderer.Present(); return AppStatus; } virtual SDL_AppResult Iterate() override { renderer.SetViewport({0, 0, 800, 600}); renderer.SetDrawColor(0, 0, 0, 0); renderer.FillRect(nullptr); renderer.RenderTextureTiled(texture, nullptr, 2.0f, nullptr, 1.0f); renderer.SetDrawColor(255, 255, 255, 255); auto displays = sdl::Display::GetDisplays(); renderer.DebugTextFormat(0, 0, "Displays: %d", displays.size()); renderer.DebugTextFormat(0, 20, "Render Drivers: %d", sdl::Renderer::GetNumRenderDrivers()); renderer.SetViewport({10, 300, 800, 300}); for(auto & display : displays) { sdl::FRect fbounds = display.GetBounds(); fbounds *= 0.15f; // scale down for better visibility renderer.SetDrawColor(255, 255, 255, 255); renderer.RenderRect(&fbounds); renderer.DebugTextFormat(fbounds.x+2, fbounds.y+2, " %s ", display.GetName()); } renderer.Present(); return AppStatus; } }; } // We tell the HDK_SDL_MAIN_CLASS macro to use our HelloRenderer2D class HDK_SDL_MAIN_CLASS(hello_renderer_2d::HelloRenderer2D) // this builds all the SDL main boilerplate and connects it to our HelloRenderer2D class