#include "TextureLoader.h" #include "../RHI/RHIDevice.h" #define STB_IMAGE_IMPLEMENTATION #include #include namespace grove { TextureLoader::LoadResult TextureLoader::loadFromFile(rhi::IRHIDevice& device, const std::string& path) { LoadResult result; // Read file into memory std::ifstream file(path, std::ios::binary | std::ios::ate); if (!file.is_open()) { result.error = "Failed to open file: " + path; return result; } std::streamsize size = file.tellg(); file.seekg(0, std::ios::beg); std::vector buffer(static_cast(size)); if (!file.read(reinterpret_cast(buffer.data()), size)) { result.error = "Failed to read file: " + path; return result; } return loadFromMemory(device, buffer.data(), buffer.size()); } TextureLoader::LoadResult TextureLoader::loadFromMemory(rhi::IRHIDevice& device, const uint8_t* data, size_t size) { LoadResult result; // Decode image with stb_image int width, height, channels; // Force RGBA output (4 channels) stbi_uc* pixels = stbi_load_from_memory(data, static_cast(size), &width, &height, &channels, 4); if (!pixels) { result.error = "stb_image failed: "; result.error += stbi_failure_reason(); return result; } // Create texture via RHI rhi::TextureDesc desc; desc.width = static_cast(width); desc.height = static_cast(height); desc.format = rhi::TextureDesc::RGBA8; desc.data = pixels; desc.dataSize = static_cast(width * height * 4); result.handle = device.createTexture(desc); result.width = desc.width; result.height = desc.height; result.success = result.handle.isValid(); if (!result.success) { result.error = "Failed to create GPU texture"; } // Free stb_image memory stbi_image_free(pixels); return result; } } // namespace grove