From 97c8847eb017111d82a962e8b3af59bb574eba73 Mon Sep 17 00:00:00 2001 From: BadQuanta Date: Sun, 26 Apr 2026 17:45:26 +0000 Subject: [PATCH] Added initial implementation of the SDL Pixels category. Co-authored-by: Copilot --- include/hdk/sdl.hpp | 6 +- include/hdk/sdl/pixels.hpp | 14 ++++ include/hdk/sdl/pixels/Palette.hpp | 39 ++++++++++ include/hdk/sdl/pixels/PixelFormat.hpp | 53 ++++++++++++++ include/hdk/sdl/pixels/PixelFormatDetails.hpp | 72 +++++++++++++++++++ include/hdk/sdl/render.hpp | 37 +++++++++- include/hdk/sdl/render/Renderer.hpp | 24 ++++--- include/hdk/sdl/render/Texture.hpp | 5 ++ 8 files changed, 239 insertions(+), 11 deletions(-) create mode 100644 include/hdk/sdl/pixels.hpp create mode 100644 include/hdk/sdl/pixels/Palette.hpp create mode 100644 include/hdk/sdl/pixels/PixelFormat.hpp create mode 100644 include/hdk/sdl/pixels/PixelFormatDetails.hpp diff --git a/include/hdk/sdl.hpp b/include/hdk/sdl.hpp index 06132ad..ded0e6c 100644 --- a/include/hdk/sdl.hpp +++ b/include/hdk/sdl.hpp @@ -5,5 +5,9 @@ **/ #include + +#include + +#include + #include -#include \ No newline at end of file diff --git a/include/hdk/sdl/pixels.hpp b/include/hdk/sdl/pixels.hpp new file mode 100644 index 0000000..6e9d60f --- /dev/null +++ b/include/hdk/sdl/pixels.hpp @@ -0,0 +1,14 @@ +#pragma once +/** @file pixels.hpp + * @brief glue together various pixel related wrappers that have circular dependencies + */ +#include "pixels/PixelFormat.hpp" +#include "pixels/PixelFormatDetails.hpp" +#include "pixels/Palette.hpp" + +/** Pixels are a complex subject. */ +namespace hdk::sdl { + /** @see https://wiki.libsdl.org/SDL3/SDL_GetPixelFormatDetails */ + PixelFormatDetails PixelFormat::GetDetails() const { return PixelFormatDetails::Get(*this); } + +} \ No newline at end of file diff --git a/include/hdk/sdl/pixels/Palette.hpp b/include/hdk/sdl/pixels/Palette.hpp new file mode 100644 index 0000000..921310c --- /dev/null +++ b/include/hdk/sdl/pixels/Palette.hpp @@ -0,0 +1,39 @@ +#pragma once +/** @file Palette.hpp + * @brief HDK sdl video header only wrapper for SDL_Palette struct & related functions + */ +#include +#include +namespace hdk::sdl { + /** + * @brief + * @note + */ + class Palette : public hdk::grid::SharedPtrWrapper { + public: + /** Inherit constructors from SharedPtrWrapper */ + using hdk::grid::SharedPtrWrapper::SharedPtrWrapper; + /** @see https://wiki.libsdl.org/SDL3/SDL_CreatePalette + * @brief Create a palette with a specified number of colors. + * @param ncolors The number of colors in the palette. + * @return Palette The created palette. If the creation fails, returns an invalid palette. + */ + static Palette Create(int ncolors) { + return Palette(get_or_cache(SDL_CreatePalette(ncolors), SDL_DestroyPalette)); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_DestroyPalette + * @brief Destroy a palette and free its associated memory. + */ + void Destroy() const { SDL_DestroyPalette(*this); } + /** @see https://wiki.libsdl.org/SDL3/SDL_SetPaletteColors + * @brief Set a range of colors in a palette. + * @param colors An array of SDL_Color structures representing the colors to set in the palette. + * @param firstcolor The index of the first color to set in the palette. + * @param ncolors The number of colors to set in the palette. + * @return bool True on success, false on failure. + */ + bool SetColors(const SDL_Color* colors, int firstcolor, int ncolors) const { + return SDL_SetPaletteColors(*this, colors, firstcolor, ncolors); + } + }; +} \ No newline at end of file diff --git a/include/hdk/sdl/pixels/PixelFormat.hpp b/include/hdk/sdl/pixels/PixelFormat.hpp new file mode 100644 index 0000000..1ac1b42 --- /dev/null +++ b/include/hdk/sdl/pixels/PixelFormat.hpp @@ -0,0 +1,53 @@ +#pragma once +/** @file PixelFormat.hpp + * @brief HDK sdl video header only wrapper for SDL_PixelFormat enum & related functions + */ +#include +#include +/** PixelFormat makes working with SDL_PixelFormat easier. */ +namespace hdk::sdl { + /// Forward declare to avoid circular dependency with PixelFormatDetails + class PixelFormatDetails; + /** + * @brief + * + */ + class PixelFormat : public hdk::grid::PrimitiveWrapper { + public: + /** Inherit constructors from PrimitiveWrapper */ + using hdk::grid::PrimitiveWrapper::PrimitiveWrapper; + /** @see https://wiki.libsdl.org/SDL3/SDL_GetMasksForPixelFormat + * @brief Get the pixel format masks for a given pixel format. + * @param bpp Pointer to int to be filled in with the number of bytes per pixel. + * @param Rmask Pointer to Uint32 to be filled in with the red mask for the pixel format. + * @param Gmask Pointer to Uint32 to be filled in with the green mask for the pixel format. + * @param Bmask Pointer to Uint32 to be filled in with the blue mask for the pixel format. + * @param Amask Pointer to Uint32 to be filled in with the alpha mask for the pixel format. + * @return bool True on success + */ + bool GetMasks(int* bpp, Uint32* Rmask, Uint32* Gmask, Uint32* Bmask, Uint32* Amask) const { + return SDL_GetMasksForPixelFormat(*this, bpp, Rmask, Gmask, Bmask, Amask); + } + // Implemented in `../pixels.hpp` to avoid circular dependency + PixelFormatDetails GetDetails() const; + + /** @see https://wiki.libsdl.org/SDL3/SDL_GetPixelFormatForMasks + * @brief Get the pixel format for a given set of pixel format masks. + * @param bpp The number of bytes per pixel for the pixel format. + * @param Rmask The red mask for the pixel format. + * @param Gmask The green mask for the pixel format. + * @param Bmask The blue mask for the pixel format. + * @param Amask The alpha mask for the pixel format. + * @return The pixel format corresponding to the given masks, or ::SDL_PIXELFORMAT_UNKNOWN + */ + static SDL_PixelFormat GetForMasks(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { + return SDL_GetPixelFormatForMasks(bpp, Rmask, Gmask, Bmask, Amask); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_GetPixelFormatName + * @brief Get the name of a pixel format. + * @return const char* The name of the pixel format, or "Unknown" if the pixel format is not recognized. + */ + const char* GetName() const { return SDL_GetPixelFormatName(*this); } + + }; +} \ No newline at end of file diff --git a/include/hdk/sdl/pixels/PixelFormatDetails.hpp b/include/hdk/sdl/pixels/PixelFormatDetails.hpp new file mode 100644 index 0000000..4af846c --- /dev/null +++ b/include/hdk/sdl/pixels/PixelFormatDetails.hpp @@ -0,0 +1,72 @@ +#pragma once +/** @file Palette.hpp + * @brief HDK sdl video header only wrapper pointers to const SDL_PixelFormatDetails & related functions + * @note Does note use smartpointers because these are SDL owned constant structs. + */ +#include +#include +/** PixelFormatDetails makes getting the details of a pixel format easier. */ +namespace hdk::sdl { + /** + * @brief + * + */ + class PixelFormatDetails : public hdk::grid::PrimitiveWrapper { + public: + /** Inherit constructors from PrimitiveWrapper */ + using hdk::grid::PrimitiveWrapper::PrimitiveWrapper; + /*** @see https://wiki.libsdl.org/SDL3/SDL_GetPixelFormatDetails + * @returns an PixelFormatDetails instance + */ + static PixelFormatDetails Get(SDL_PixelFormat format) { + return PixelFormatDetails(SDL_GetPixelFormatDetails(format)); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_GetRGB + * @brief Get the RGB values for a pixel value + * @param pixel The pixel value to query + * @param palette for indexed formats the palette to use, or NULL for non-indexed formats + * @param r pointer to Uint8 to store the red component + * @param g pointer to Uint8 to store the green component + * @param b pointer to Uint8 to store the blue component + * @param a pointer to Uint8 to store the alpha component + */ + void GetRGB(Uint32 pixel, SDL_Palette* palette, Uint8* r, Uint8* g, Uint8* b, Uint8* a) const { + SDL_GetRGB(pixel, *this, palette, r, g, b, a); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_GetRGBA + * @brief Get the RGBA values for a pixel value + * @param pixel The pixel value to query + * @param palette for indexed formats the palette to use, or NULL for non-indexed formats + * @param r pointer to Uint8 to store the red component + * @param g pointer to Uint8 to store the green component + * @param b pointer to Uint8 to store the blue component + * @param a pointer to Uint8 to store the alpha component + */ + void GetRGBA(Uint32 pixel, SDL_Palette* palette, Uint8* r, Uint8* g, Uint8* b, Uint8* a) const { + SDL_GetRGBA(pixel, *this, palette, r, g, b, a); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_MapRGB + * @brief Map RGB values to a pixel value for the pixel format + * @param palette for indexed formats the palette to use, or NULL for non-indexed formats + * @param r The red component of the color + * @param g The green component of the color + * @param b The blue component of the color + * @return The pixel value corresponding to the given RGB values for the pixel format + */ + Uint32 MapRGB(SDL_Palette* palette, Uint8 r, Uint8 g, Uint8 b) const { + return SDL_MapRGB(*this, palette, r, g, b); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_MapRGBA + * @brief Map RGBA values to a pixel value for the pixel format + * @param palette for indexed formats the palette to use, or NULL for non-indexed formats + * @param r The red component of the color + * @param g The green component of the color + * @param b The blue component of the color + * @param a The alpha component of the color + * @return The pixel value corresponding to the given RGBA values for the pixel format + */ + Uint32 MapRGBA(SDL_Palette* palette, Uint8 r, Uint8 g, Uint8 b, Uint8 a) const { + return SDL_MapRGBA(*this, palette, r, g, b, a); + } + }; +} \ No newline at end of file diff --git a/include/hdk/sdl/render.hpp b/include/hdk/sdl/render.hpp index 7d569fe..994b375 100644 --- a/include/hdk/sdl/render.hpp +++ b/include/hdk/sdl/render.hpp @@ -1,11 +1,44 @@ #pragma once /** - * @file Renderer_Texture.hpp + * @file render.hpp * @brief HDK sdl Renderer subsystem. Glues together Texture & Renderer which have circular dependencies */ #include #include namespace hdk::sdl { - + /** @see https://wiki.libsdl.org/SDL3/SDL_GetRendererFromTexture + * @return Renderer The renderer associated with the texture + */ + inline Renderer Texture::GetRenderer() const { + /** we may not have created the renderer we get back, if not we will not own it. */ + return Renderer(Renderer::get_or_view(SDL_GetRendererFromTexture(*this))); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_CreateTexture + * @brief Create a texture for a rendering context. + * @param format The pixel format of the texture + * @param access The access pattern for the texture + * @param w The width of the texture in pixels + * @param h The height of the texture in pixels + * @return Texture The created texture. If the creation fails, returns an invalid texture. + */ + inline Texture Renderer::CreateTexture(SDL_PixelFormat format, SDL_TextureAccess access, int w, int h) const { + return Texture(Texture::get_or_cache(SDL_CreateTexture(*this, format, access, w, h), SDL_DestroyTexture)); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_CreateTextureFromSurface + * @brief Create a texture from an existing surface. + * @param surface The surface to create the texture from. + * @return Texture The created texture. If the creation fails, returns an invalid texture. + */ + inline Texture Renderer::CreateTextureFromSurface(SDL_Surface* surface) const { + return Texture(Texture::get_or_cache(SDL_CreateTextureFromSurface(*this, surface), SDL_DestroyTexture)); + } + /** @see https://wiki.libsdl.org/SDL3/SDL_CreateTextureWithProperties + * @brief Create a texture for a rendering context with specific properties. + * @param properties The properties to create the texture with. + * @return Texture The created texture. If the creation fails, returns an invalid texture. + */ + inline Texture Renderer::CreateTextureWithProperties(SDL_PropertiesID properties) const { + return Texture(Texture::get_or_cache(SDL_CreateTextureWithProperties(*this, properties), SDL_DestroyTexture)); + } } \ No newline at end of file diff --git a/include/hdk/sdl/render/Renderer.hpp b/include/hdk/sdl/render/Renderer.hpp index 89a036e..6466f96 100644 --- a/include/hdk/sdl/render/Renderer.hpp +++ b/include/hdk/sdl/render/Renderer.hpp @@ -8,6 +8,7 @@ /** Renderers are used to render 2D graphics in SDL */ namespace hdk::sdl { class Window; + class Texture; /** * @brief Wraps the SDL_Renderer struct and related functions in a C++ class that uses shared_ptr for lifetime management. * @@ -16,6 +17,7 @@ namespace hdk::sdl { class Renderer : public hdk::grid::SharedPtrWrapper { public: friend class Window; + friend class Texture; friend std::pair CreateWindowAndRenderer( const char* title, int width, int height, SDL_WindowFlags window_flags); /** Inherit constructors from SharedPtrWrapper */ @@ -39,17 +41,23 @@ namespace hdk::sdl { static Renderer CreateSoftware(SDL_Surface* surface) { return Renderer(get_or_cache(SDL_CreateSoftwareRenderer(surface), SDL_DestroyRenderer)); } - // https://wiki.libsdl.org/SDL3/SDL_CreateWindowAndRenderer - // https://wiki.libsdl.org/SDL3/SDL_DestroyGPURenderState - // https://wiki.libsdl.org/SDL3/SDL_DestroyRenderer + /// @todo https://wiki.libsdl.org/SDL3/SDL_CreateWindowAndRenderer + /// @todo https://wiki.libsdl.org/SDL3/SDL_DestroyGPURenderState + /// @todo https://wiki.libsdl.org/SDL3/SDL_DestroyRenderer + /// Implemented in `../render.hpp` to avoid circular dependency with Texture + Texture CreateTexture(SDL_PixelFormat format, SDL_TextureAccess access, int w, int h) const; + /// Implemented in `../render.hpp` to avoid circular dependency with Texture + Texture CreateTextureFromSurface(SDL_Surface* surface) const; + /// Implemented in `../render.hpp` to avoid circular dependency with Texture + Texture CreateTextureWithProperties(SDL_PropertiesID properties) const; /** @see https://wiki.libsdl.org/SDL3/SDL_FlushRenderer * @brief Flush the current rendering commands to the screen. * @return bool True if the renderer was successfully flushed, false otherwise. */ bool Flush() const { return SDL_FlushRenderer(*this); } - // https://wiki.libsdl.org/SDL3/SDL_GDKResumeRenderer - // https://wiki.libsdl.org/SDL3/SDL_GDKSuspendRenderer - /** https://wiki.libsdl.org/SDL3/SDL_GetCurrentRenderOutputSize + /// @todo https://wiki.libsdl.org/SDL3/SDL_GDKResumeRenderer + /// @todo https://wiki.libsdl.org/SDL3/SDL_GDKSuspendRenderer + /** @see https://wiki.libsdl.org/SDL3/SDL_GetCurrentRenderOutputSize * @brief Get the output size in pixels of the current render target. * @param w A pointer to an int to be filled in with the width of the render output. If the renderer is invalid, * this will be set to 0. @@ -67,7 +75,7 @@ namespace hdk::sdl { bool GetDefaultTextureScaleMode(SDL_ScaleMode* scaleMode) const { return SDL_GetDefaultTextureScaleMode(*this, scaleMode); } - // https://wiki.libsdl.org/SDL3/SDL_GetGPURendererDevice + /// @todo https://wiki.libsdl.org/SDL3/SDL_GetGPURendererDevice // https://wiki.libsdl.org/SDL3/SDL_GetNumRenderDrivers /** @see https://wiki.libsdl.org/SDL3/SDL_GetRenderClipRect * @brief Get the clip rectangle for the current rendering target. @@ -131,7 +139,7 @@ namespace hdk::sdl { * @param window The window to query * @return Renderer The renderer associated with the window */ - static Renderer Get(SDL_Window* window) { + static Renderer GetFromWindow(SDL_Window* window) { /** we may not have created the renderer we get back, if not we will not own it. */ return Renderer(get_or_view(SDL_GetRenderer(window))); } diff --git a/include/hdk/sdl/render/Texture.hpp b/include/hdk/sdl/render/Texture.hpp index 2b18b6e..4dabbfc 100644 --- a/include/hdk/sdl/render/Texture.hpp +++ b/include/hdk/sdl/render/Texture.hpp @@ -7,9 +7,12 @@ #include /** Textures are used to store pixel data that can be rendered by a renderer. */ namespace hdk::sdl { + /// Forward declare to avoid circular dependency with Renderer + class Renderer; /** */ class Texture : public hdk::grid::SharedPtrWrapper { public: + friend class Renderer; /** Inherit constructors from SharedPtrWrapper */ using hdk::grid::SharedPtrWrapper::SharedPtrWrapper; @@ -99,6 +102,8 @@ namespace hdk::sdl { * @returns Properties associated with the texture. */ Properties GetProperties() const { return Properties(SDL_GetTextureProperties(*this)); } + /// Implemented in `../render.hpp` to avoid circular dependency with Renderer + Renderer GetRenderer() const; /** @see https://wiki.libsdl.org/SDL3/SDL_GetTextureScaleMode * @brief Get the scale mode for a texture. * @param scaleMode A pointer to an SDL_ScaleMode variable to be filled in