Files
hdk-sdl/examples/HelloRenderer2D.cpp
T
2026-05-13 19:48:22 +00:00

120 lines
5.0 KiB
C++

#include <hdk/sdl.hpp> // Hollow Wrapper to SDL
#include <hdk/sdl/main.hpp> // Hollow Wrapper to SDL main boilerplate via hdk::sdl::ApplicationInterface & the macro HDK_SDL_MAIN_CLASS
#include <filesystem>
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