GroveEngine/modules/BgfxRenderer/Shaders/ShaderManager.h
StillHammer 262eef377e feat(BgfxRenderer): Phase 5.5 - Sprite shader with instancing and texture support
- Create proper sprite shader (vs_sprite.sc, fs_sprite.sc) with GPU instancing
- SpriteInstance struct now 80 bytes (5 x vec4) for GPU layout compatibility
- Add BufferDesc::Layout enum (Raw, PosColor, InstanceData) for proper vertex layouts
- BgfxDevice creates correct VertexLayout based on buffer type
- SpritePass uses PosColor layout for quad vertices (Position + Color0)
- Instance buffer uses 5 x vec4 layout (TexCoord7-3) for i_data0-4
- Add texture support with v_texcoord0 interpolation from instance UVs
- Create default white 1x1 texture fallback
- Compile shaders for SPIRV (Vulkan), GLSL (OpenGL), and Metal

Visual test confirms sprites render correctly at ~545 FPS.

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

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

67 lines
1.9 KiB
C++

#pragma once
#include "../RHI/RHITypes.h"
#include <string>
#include <unordered_map>
namespace grove {
namespace rhi { class IRHIDevice; }
/**
* @brief Manages shader loading and caching for BgfxRenderer
*
* Loads embedded pre-compiled shaders based on the current renderer type.
* Supports: OpenGL, OpenGL ES, Vulkan, DirectX 11/12, Metal
*
* Uses the RHI abstraction - no bgfx types exposed.
*/
class ShaderManager {
public:
ShaderManager() = default;
~ShaderManager();
// Non-copyable
ShaderManager(const ShaderManager&) = delete;
ShaderManager& operator=(const ShaderManager&) = delete;
/**
* @brief Initialize with RHI device and renderer name
* @param device The RHI device for shader creation
* @param rendererName Renderer name from device caps (e.g., "Vulkan", "OpenGL")
*/
void init(rhi::IRHIDevice& device, const std::string& rendererName);
/**
* @brief Shutdown and destroy all shaders
* @param device The RHI device for shader destruction
*/
void shutdown(rhi::IRHIDevice& device);
/**
* @brief Get a shader program by name
* @param name Program name (e.g., "color", "sprite", "debug")
* @return Valid shader handle or invalid handle if not found
*/
rhi::ShaderHandle getProgram(const std::string& name) const;
/**
* @brief Check if a program exists
*/
bool hasProgram(const std::string& name) const;
/**
* @brief Get number of loaded programs
*/
size_t getProgramCount() const { return m_programs.size(); }
private:
void loadBuiltinShaders(rhi::IRHIDevice& device, const std::string& rendererName);
void loadSpriteShader(rhi::IRHIDevice& device, const std::string& rendererName);
std::unordered_map<std::string, rhi::ShaderHandle> m_programs;
bool m_initialized = false;
};
} // namespace grove