From 96a92ec0e298e1c02b5632a96c12a5d244a31f4a Mon Sep 17 00:00:00 2001 From: Mars Date: Sat, 12 Oct 2024 00:07:13 -0400 Subject: [PATCH] make helper class for image stuff --- src/main.cpp | 19 ++++++------ src/util/unique_image.h | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 src/util/unique_image.h diff --git a/src/main.cpp b/src/main.cpp index 5de407b..f405818 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,9 +10,6 @@ #include #include -#define STB_IMAGE_IMPLEMENTATION -#include - #define TINYOBJLOADER_IMPLEMENTATION #include @@ -24,6 +21,7 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE #include "util/types.h" +#include "util/unique_image.h" #define VKFW_NO_STD_FUNCTION_CALLBACKS #include "vkfw.hpp" @@ -61,10 +59,12 @@ struct Vertex { } static fn getAttributeDescriptions() -> std::array { + using namespace vk; + return { - vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, pos)), - vk::VertexInputAttributeDescription(1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color)), - vk::VertexInputAttributeDescription(2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord)) + VertexInputAttributeDescription { 0, 0, Format::eR32G32B32Sfloat, offsetof(Vertex, pos) }, + VertexInputAttributeDescription { 1, 0, Format::eR32G32B32Sfloat, offsetof(Vertex, color) }, + VertexInputAttributeDescription { 2, 0, Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } }; } @@ -745,9 +745,10 @@ class VulkanApp { } fn createTextureImage() -> void { - i32 texWidth = 0, texHeight = 0, texChannels = 0; + stb::UniqueImage image(TEXTURE_PATH); - u8* pixels = stbi_load(TEXTURE_PATH, &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); + u8* pixels = image.getData(); + i32 texWidth = image.getWidth(), texHeight = image.getHeight(); vk::DeviceSize imageSize = static_cast(texWidth) * static_cast(texHeight) * 4; @@ -770,8 +771,6 @@ class VulkanApp { copyData(stagingBufferMemory.get(), imageSize, pixels); - stbi_image_free(pixels); - createImage( static_cast(texWidth), static_cast(texHeight), diff --git a/src/util/unique_image.h b/src/util/unique_image.h new file mode 100644 index 0000000..d3f2a5d --- /dev/null +++ b/src/util/unique_image.h @@ -0,0 +1,67 @@ +#define STB_IMAGE_IMPLEMENTATION +#include + +#include "types.h" + +namespace stb { + class UniqueImage { + public: + // Constructor + UniqueImage(const char* filename) { load(filename); } + + // Deleted copy constructor and assignment operator + UniqueImage(const UniqueImage&) = delete; + fn operator=(const UniqueImage&)->UniqueImage& = delete; + + // Move constructor and assignment operator + UniqueImage(UniqueImage&& other) noexcept + : mData(other.mData), mWidth(other.mWidth), mHeight(other.mHeight), mChannels(other.mChannels) { + other.mData = nullptr; // Set the other's data to nullptr + } + + fn operator=(UniqueImage&& other) noexcept -> UniqueImage& { + if (this != &other) { + // Free existing resource + if (mData) + stbi_image_free(mData); + + // Move the resource + mData = other.mData; + mWidth = other.mWidth; + mHeight = other.mHeight; + mChannels = other.mChannels; + other.mData = nullptr; // Set the other's data to nullptr + } + return *this; + } + + // Destructor + ~UniqueImage() { + if (mData) + stbi_image_free(mData); + } + + // Accessors for image data and dimensions + [[nodiscard]] fn getData() const -> unsigned char* { return mData; } + + [[nodiscard]] fn getWidth() const -> int { return mWidth; } + + [[nodiscard]] fn getHeight() const -> int { return mHeight; } + + [[nodiscard]] fn getChannels() const -> int { return mChannels; } + + private: + unsigned char* mData = nullptr; + int mWidth = 0; + int mHeight = 0; + int mChannels = 0; + + // Load function + void load(const char* filename) { + mData = stbi_load(filename, &mWidth, &mHeight, &mChannels, STBI_rgb_alpha); + + if (!mData) + throw std::runtime_error("Failed to load image: " + std::string(stbi_failure_reason())); + } + }; +}