#pragma once #include #include #include #include #include #include #include #include #include #include namespace extra2d { // 前向声明 class Material; class Texture; /** * @brief 材质参数信息 */ struct MaterialParamInfo { MaterialParamType type; uint32_t offset; uint32_t size; }; /** * @brief 纹理槽位信息 */ struct TextureSlot { Handle handle; uint32_t slot; std::string uniformName; }; /** * @brief 材质布局类 * * 定义材质参数的布局,可被多个材质共享 */ class MaterialLayout : public RefCounted { public: /** * @brief 默认构造函数 */ MaterialLayout(); /** * @brief 添加参数 * @param name 参数名称 * @param type 参数类型 */ void addParam(const std::string& name, MaterialParamType type); /** * @brief 完成布局定义,计算偏移和总大小 */ void finalize(); /** * @brief 获取参数信息 * @param name 参数名称 * @return 参数信息指针,不存在返回 nullptr */ const MaterialParamInfo* getParam(const std::string& name) const; /** * @brief 获取缓冲区大小 * @return 缓冲区大小 */ uint32_t getBufferSize() const { return bufferSize_; } /** * @brief 检查是否已最终化 * @return 是否已最终化 */ bool isFinalized() const { return finalized_; } private: std::unordered_map params_; uint32_t bufferSize_ = 0; bool finalized_ = false; }; /** * @brief 材质类 * * 作为着色器和纹理的中间层,管理: * - 着色器程序 * - 材质参数(通过 UBO 上传) * - 纹理绑定 * * 使用示例: * @code * // 创建自定义着色器 * auto shader = makePtr(); * shader->loadFromFile("custom.vert", "custom.frag"); * * // 创建材质布局 * auto layout = makePtr(); * layout->addParam("uTintColor", MaterialParamType::Color); * layout->addParam("uOpacity", MaterialParamType::Float); * layout->finalize(); * * // 创建材质 * auto material = makePtr(); * material->setShader(shader); * material->setLayout(layout); * material->setColor("uTintColor", Color::White); * material->setFloat("uOpacity", 1.0f); * * // 设置纹理 * material->setTexture("uTexture", textureHandle, 0); * * // 注册到渲染器 * MaterialHandle handle = renderer->registerMaterial(material); * @endcode */ class Material : public RefCounted { public: /** * @brief 默认构造函数 */ Material(); // ======================================== // 着色器和布局设置 // ======================================== /** * @brief 设置材质布局 * @param layout 材质布局 */ void setLayout(Ptr layout); /** * @brief 设置着色器 * @param shader 着色器 */ void setShader(Ptr shader); /** * @brief 获取着色器 * @return 着色器 */ Ptr getShader() const { return shader_; } // ======================================== // 参数设置 // ======================================== /** * @brief 设置 float 参数 * @param name 参数名称 * @param value 值 */ void setFloat(const std::string& name, float value); /** * @brief 设置 vec2 参数 * @param name 参数名称 * @param value 值 */ void setVec2(const std::string& name, const Vec2& value); /** * @brief 设置 vec4 参数 * @param name 参数名称 * @param value 值 */ void setVec4(const std::string& name, float x, float y, float z, float w); /** * @brief 设置颜色参数 * @param name 参数名称 * @param value 颜色值 */ void setColor(const std::string& name, const Color& value); /** * @brief 设置 mat4 参数 * @param name 参数名称 * @param value 矩阵数据指针 */ void setMat4(const std::string& name, const float* value); // ======================================== // 纹理管理 // ======================================== /** * @brief 设置纹理 * @param uniformName 着色器中的采样器 uniform 名称 * @param texture 纹理句柄 * @param slot 纹理槽位(0-15) */ void setTexture(const std::string& uniformName, Handle texture, uint32_t slot); /** * @brief 获取所有纹理槽位 * @return 纹理槽位列表 */ const std::vector& getTextures() const { return textures_; } /** * @brief 清除所有纹理 */ void clearTextures(); // ======================================== // 数据访问 // ======================================== /** * @brief 获取材质数据指针 * @return 数据指针 */ const void* getData() const { return data_.data(); } /** * @brief 获取材质数据大小 * @return 数据大小 */ uint32_t getDataSize() const { return static_cast(data_.size()); } // ======================================== // 应用材质(渲染时调用) // ======================================== /** * @brief 应用材质 * * 绑定着色器、上传 UBO 数据 * @param uboManager UBO 管理器 */ void apply(UniformBufferManager& uboManager); private: Ptr layout_; // 材质布局 Ptr shader_; // 着色器 std::vector data_; // 材质数据(UBO 缓冲) std::vector textures_; // 纹理槽位列表 }; } // namespace extra2d