GroveEngine/modules/BgfxRenderer/Resources/TextureLoader.cpp
StillHammer 2f8e78b247 feat(BgfxRenderer): Phase 6 - Texture loading with stb_image
- Add TextureLoader class using stb_image for PNG/JPG/etc loading
- Integrate TextureLoader with ResourceCache for cached texture loading
- Add SpritePass::setTexture() for binding textures to sprites
- Add "defaultTexture" config option to load texture at startup
- Create assets/textures folder structure
- Add 1f440.png (eyes emoji) test texture

Visual test confirms textured sprites render correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 19:44:13 +08:00

71 lines
2.0 KiB
C++

#include "TextureLoader.h"
#include "../RHI/RHIDevice.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
#include <fstream>
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<uint8_t> buffer(static_cast<size_t>(size));
if (!file.read(reinterpret_cast<char*>(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<int>(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<uint16_t>(width);
desc.height = static_cast<uint16_t>(height);
desc.format = rhi::TextureDesc::RGBA8;
desc.data = pixels;
desc.dataSize = static_cast<uint32_t>(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