From d43508ba4843801cbbf1f42a27af260d4eef5701 Mon Sep 17 00:00:00 2001 From: hnOsmium0001 Date: Sun, 17 Apr 2022 20:08:57 -0700 Subject: Initial work on sprites and texture system --- source/Image.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 source/Image.cpp (limited to 'source/Image.cpp') diff --git a/source/Image.cpp b/source/Image.cpp new file mode 100644 index 0000000..3673acc --- /dev/null +++ b/source/Image.cpp @@ -0,0 +1,101 @@ +#include "Image.hpp" + +#include +#include +#include + +Image::Image() + : mSize{} + , mChannels{ 0 } { +} + +bool Image::InitFromImageFile(const char* filePath, int desiredChannels) { + // Dimensions of the image in + int width, height; + // Number of channels that the image has, we'll get `desiredChannels` channels in our output (if it's non-0, which is the default argument) + int channels; + + // NOTE: don't free, the data is passed to std::unique_ptr + auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, desiredChannels); + if (!result) { + return false; + } + + mData.reset(result); + mSize = { width, height }; + mChannels = desiredChannels == 0 ? channels : desiredChannels; + return true; +} + +bool Image::InitFromImageData(std::span data, int desiredChannels) { + int width, height; + int channels; + + // NOTE: don't free, the data is passed to std::unique_ptr + auto result = (uint8_t*)stbi_load_from_memory(data.data(), data.size(), &width, &height, &channels, desiredChannels); + if (!result) { + return false; + } + + mData.reset(result); + mSize = { width, height }; + mChannels = desiredChannels == 0 ? channels : desiredChannels; + return true; +} + +bool Image::InitFromPixels(std::span pixels, glm::ivec2 dimensions, int channels) { + mData = std::make_unique(pixels.size()); + std::memcpy(mData.get(), pixels.data(), pixels.size()); + mSize = dimensions; + mChannels = channels; + return true; +} + +bool Image::InitFromPixels(std::unique_ptr pixels, glm::ivec2 dimensions, int channels) { + mData = std::move(pixels); + mSize = dimensions; + mChannels = channels; + return true; +} + +RgbaColor Image::GetPixel(int x, int y) const { + size_t offset = (y * mSize.x + x) * mChannels; + RgbaColor color; + color.r = mData.get()[offset + 0]; + color.g = mData.get()[offset + 1]; + color.b = mData.get()[offset + 2]; + color.a = mData.get()[offset + 3]; + return color; +} + +void Image::SetPixel(int x, int y, RgbaColor color) { + size_t offset = (y * mSize.x + x) * mChannels; + mData.get()[offset + 0] = color.r; + mData.get()[offset + 1] = color.g; + mData.get()[offset + 2] = color.b; + mData.get()[offset + 3] = color.a; +} + +uint8_t* Image::GetDataPtr() const { + return mData.get(); +} + +size_t Image::GetDataLength() const { + return mSize.x * mSize.y * mChannels * sizeof(uint8_t); +} + +std::span Image::GetData() const { + return { mData.get(), GetDataLength() }; +} + +glm::ivec2 Image::GetSize() const { + return mSize; +} + +int Image::GetChannels() const { + return mChannels; +} + +bool Image::IsEmpty() const { + return mSize.x == 0 || mSize.y == 0; +} -- cgit v1.2.3-70-g09d2