#pragma once #include #include #include #include #include #include #include namespace extra2d { /** * @brief 实例数据 * * 单个实例的属性数据,用于实例化渲染 * 布局遵循 std140 对齐规则 */ struct InstanceData { // 第一组 16 字节 Vec2 position; // 位置偏移 (8 bytes) float rotation; // 旋转角度 (4 bytes) float padding0; // 填充到 16 字节对齐 (4 bytes) // 第二组 16 字节 Vec2 scale; // 缩放 (8 bytes) float padding1[2]; // 填充到 16 字节对齐 (8 bytes) // 第三组 16 字节 Color color; // 颜色 (16 bytes) - r, g, b, a // 第四组 16 字节 float uvX; // UV 起始 X (4 bytes) float uvY; // UV 起始 Y (4 bytes) float uvWidth; // UV 宽度 (4 bytes) float uvHeight; // UV 高度 (4 bytes) InstanceData() : position(0.0f, 0.0f) , rotation(0.0f) , padding0(0.0f) , scale(1.0f, 1.0f) , padding1{0.0f, 0.0f} , color(Color::White) , uvX(0.0f) , uvY(0.0f) , uvWidth(1.0f) , uvHeight(1.0f) {} }; static_assert(sizeof(InstanceData) == 64, "InstanceData size should be 64 bytes for std140 alignment"); /** * @brief 实例缓冲区 * * 管理实例化渲染的实例数据缓冲区 * 支持动态更新和双缓冲 */ class InstanceBuffer { public: /** * @brief 默认构造函数 */ InstanceBuffer(); /** * @brief 析构函数 */ ~InstanceBuffer(); // 禁止拷贝 InstanceBuffer(const InstanceBuffer&) = delete; InstanceBuffer& operator=(const InstanceBuffer&) = delete; // 允许移动 InstanceBuffer(InstanceBuffer&& other) noexcept; InstanceBuffer& operator=(InstanceBuffer&& other) noexcept; /** * @brief 初始化实例缓冲区 * @param maxInstances 最大实例数量 * @return 初始化是否成功 */ bool initialize(uint32_t maxInstances); /** * @brief 关闭缓冲区 */ void shutdown(); /** * @brief 更新实例数据 * @param instances 实例数据数组 * @param count 实例数量 * @return 更新是否成功 */ bool updateInstances(const InstanceData* instances, uint32_t count); /** * @brief 添加单个实例 * @param instance 实例数据 * @return 实例索引 */ uint32_t addInstance(const InstanceData& instance); /** * @brief 清除所有实例 */ void clear(); /** * @brief 获取当前实例数量 * @return 实例数量 */ uint32_t getInstanceCount() const { return instanceCount_; } /** * @brief 获取最大实例数量 * @return 最大实例数量 */ uint32_t getMaxInstances() const { return maxInstances_; } /** * @brief 获取 RHI 缓冲区句柄 * @return 缓冲区句柄 */ BufferHandle getBufferHandle() const { return bufferHandle_; } /** * @brief 获取 RHI 缓冲区指针 * @return 缓冲区指针 */ RHIBuffer* getRHIBuffer() const { return bufferHandle_.get(); } /** * @brief 检查是否有效 * @return 是否有效 */ bool isValid() const { return bufferHandle_.isValid(); } private: BufferHandle bufferHandle_; // RHI 缓冲区句柄 uint32_t maxInstances_ = 0; // 最大实例数量 uint32_t instanceCount_ = 0; // 当前实例数量 std::vector cpuBuffer_; // CPU 端缓冲区 }; /** * @brief 实例缓冲区管理器 * * 管理多个实例缓冲区的分配和回收 */ class InstanceBufferManager { public: /** * @brief 默认构造函数 */ InstanceBufferManager(); /** * @brief 析构函数 */ ~InstanceBufferManager(); // 禁止拷贝 InstanceBufferManager(const InstanceBufferManager&) = delete; InstanceBufferManager& operator=(const InstanceBufferManager&) = delete; // 允许移动 InstanceBufferManager(InstanceBufferManager&& other) noexcept; InstanceBufferManager& operator=(InstanceBufferManager&& other) noexcept; /** * @brief 初始化管理器 * @return 初始化是否成功 */ bool initialize(); /** * @brief 关闭管理器 */ void shutdown(); /** * @brief 获取或创建实例缓冲区 * @param minSize 最小容量(实例数量) * @return 实例缓冲区指针 */ InstanceBuffer* acquireBuffer(uint32_t minSize); /** * @brief 回收实例缓冲区 * @param buffer 缓冲区指针 */ void releaseBuffer(InstanceBuffer* buffer); /** * @brief 重置所有缓冲区 */ void reset(); private: std::vector> bufferPool_; uint32_t currentBufferIndex_ = 0; static constexpr uint32_t DEFAULT_BUFFER_SIZE = 1024; }; } // namespace extra2d