diff options
Diffstat (limited to 'source/Texture.cpp')
-rw-r--r-- | source/Texture.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/source/Texture.cpp b/source/Texture.cpp new file mode 100644 index 0000000..968c4bc --- /dev/null +++ b/source/Texture.cpp @@ -0,0 +1,99 @@ +#include "Texture.hpp" + +#include "PodVector.hpp" + +#include <stb_image.h> +#include <stb_rect_pack.h> +#include <cstdint> +#include <cstring> +#include <deque> +#include <filesystem> +#include <fstream> +#include <stdexcept> +#include <utility> + +Texture::~Texture() { + glDeleteTextures(1, &mHandle); +} + +static GLenum MapTextureFilteringToGL(Texture::Filtering option) { + switch (option) { + case Texture::LinearFilter: return GL_LINEAR; + case Texture::NearestFilter: return GL_NEAREST; + } + return 0; +} + +bool Texture::InitFromFile(const char* filePath, const TextureProperties& props, bool flipVertically) { + int width, height; + int channels; + + stbi_set_flip_vertically_on_load(flipVertically); + auto result = (uint8_t*)stbi_load(filePath, &width, &height, &channels, 4); + if (!result) { + return false; + } + + glDeleteTextures(1, &mHandle); // In case the caller gave us + glGenTextures(1, &mHandle); + glBindTexture(GL_TEXTURE_2D, mHandle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter)); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result); + + mInfo.size = { width, height }; + mInfo.isAtlas = false; + return true; +} + +// bool Texture::InitFromImage(const Image& image, const TextureProperties& props, bool flipVertically) { +// GLenum sourceFormat; +// switch (image.GetChannels()) { +// case 1: sourceFormat = GL_RED; break; +// case 2: sourceFormat = GL_RG; break; +// case 3: sourceFormat = GL_RGB; break; +// case 4: sourceFormat = GL_RGBA; break; +// default: return false; +// } + +// auto size = image.GetSize(); + +// std::unique_ptr<uint8_t[]> dataStorage; +// uint8_t* dataPtr; +// if (flipVertically) { +// dataStorage = std::make_unique<uint8_t[]>(image.GetDataLength()); +// dataPtr = dataStorage.get(); + +// size_t rowStride = size.width * image.GetChannels() * sizeof(uint8_t); +// for (size_t y = 0; y < size.height; ++y) { +// size_t invY = (size.height - 1) - y; +// std::memcpy(dataPtr + invY * rowStride, image.GetDataPtr() + y * rowStride, rowStride); +// } +// } else { +// // dataStorage is unused, we read pixels directly from `image` +// dataPtr = image.GetDataPtr(); +// } + +// glDeleteTextures(1, &mHandle); +// glGenTextures(1, &mHandle); +// glBindTexture(GL_TEXTURE_2D, mHandle); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ::MapTextureFilteringToGL(props.minifyingFilter)); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ::MapTextureFilteringToGL(props.magnifyingFilter)); +// glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, size.width, size.height, 0, sourceFormat, GL_UNSIGNED_BYTE, dataPtr); + +// mInfo.size = size; +// mInfo.isAtlas = false; +// return true; +// } + +const TextureInfo& Texture::GetInfo() const { + return mInfo; +} + +GLuint Texture::GetHandle() const { + return mHandle; +} + +bool Texture::IsValid() const { + return mHandle != 0; +} |