#include "Texture.hpp" #include "PodVector.hpp" #include #include #include #include #include #include #include #include #include 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 dataStorage; // uint8_t* dataPtr; // if (flipVertically) { // dataStorage = std::make_unique(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; }