#pragma once #include #include #include #include #include namespace extra2d { // ============================================================================ // 渲染目标配置 // ============================================================================ struct RenderTargetConfig { int width = 800; // 宽度 int height = 600; // 高度 PixelFormat colorFormat = PixelFormat::RGBA8; // 颜色格式 bool hasDepth = true; // 是否包含深度缓冲 bool hasDepthBuffer = true; // 兼容旧API的别名 (同hasDepth) bool hasStencil = false; // 是否包含模板缓冲 int samples = 1; // 多重采样数 (1 = 无MSAA) bool autoResize = true; // 是否自动调整大小 }; // ============================================================================ // 渲染目标 - 基于FBO的离屏渲染 // ============================================================================ class RenderTarget { public: RenderTarget(); ~RenderTarget(); // 禁止拷贝 RenderTarget(const RenderTarget &) = delete; RenderTarget &operator=(const RenderTarget &) = delete; // 允许移动 RenderTarget(RenderTarget &&other) noexcept; RenderTarget &operator=(RenderTarget &&other) noexcept; // ------------------------------------------------------------------------ // 创建和销毁 // ------------------------------------------------------------------------ /** * @brief 创建渲染目标 */ bool create(const RenderTargetConfig &config); /** * @brief 初始化渲染目标(create的别名,兼容旧API) */ bool init(const RenderTargetConfig &config) { return create(config); } /** * @brief 从现有纹理创建渲染目标 */ bool createFromTexture(Ptr texture, bool hasDepth = false); /** * @brief 销毁渲染目标 */ void destroy(); /** * @brief 关闭渲染目标(destroy的别名,兼容旧API) */ void shutdown() { destroy(); } /** * @brief 检查是否有效 */ bool isValid() const { return fbo_ != 0; } // ------------------------------------------------------------------------ // 尺寸和格式 // ------------------------------------------------------------------------ int width() const { return width_; } int height() const { return height_; } Vec2 size() const { return Vec2(static_cast(width_), static_cast(height_)); } PixelFormat getColorFormat() const { return colorFormat_; } // ------------------------------------------------------------------------ // 绑定和解绑 // ------------------------------------------------------------------------ /** * @brief 绑定为当前渲染目标 */ void bind(); /** * @brief 解绑(恢复默认渲染目标) */ void unbind(); /** * @brief 清除渲染目标 */ void clear(const Color &color = Colors::Transparent); // ------------------------------------------------------------------------ // 纹理访问 // ------------------------------------------------------------------------ /** * @brief 获取颜色纹理 */ Ptr getColorTexture() const { return colorTexture_; } /** * @brief 获取深度纹理(如果有) */ Ptr getDepthTexture() const { return depthTexture_; } // ------------------------------------------------------------------------ // 视口和裁剪 // ------------------------------------------------------------------------ /** * @brief 设置视口(相对于渲染目标) */ void setViewport(int x, int y, int width, int height); /** * @brief 获取完整视口 */ void getFullViewport(int &x, int &y, int &width, int &height) const; // ------------------------------------------------------------------------ // 工具方法 // ------------------------------------------------------------------------ /** * @brief 调整大小(会销毁并重新创建) */ bool resize(int width, int height); /** * @brief 复制到另一个渲染目标 */ void copyTo(RenderTarget &target); /** * @brief 复制到另一个渲染目标(blitTo的别名,兼容旧API) * @param target 目标渲染目标 * @param color 是否复制颜色缓冲 * @param depth 是否复制深度缓冲 */ void blitTo(RenderTarget &target, bool color = true, bool depth = false); /** * @brief 复制到屏幕 */ void copyToScreen(int screenWidth, int screenHeight); /** * @brief 保存为图像文件 */ bool saveToFile(const std::string &filepath); // ------------------------------------------------------------------------ // 静态方法 // ------------------------------------------------------------------------ /** * @brief 创建渲染目标的静态工厂方法 */ static Ptr createFromConfig(const RenderTargetConfig &config); /** * @brief 获取当前绑定的渲染目标ID */ static GLuint getCurrentFBO(); /** * @brief 绑定默认渲染目标(屏幕) */ static void bindDefault(); /** * @brief 获取FBO ID(供内部使用) */ GLuint getFBO() const { return fbo_; } protected: GLuint fbo_ = 0; // 帧缓冲对象 GLuint rbo_ = 0; // 渲染缓冲对象(深度/模板) Ptr colorTexture_; // 颜色纹理 Ptr depthTexture_; // 深度纹理(可选) int width_ = 0; int height_ = 0; PixelFormat colorFormat_ = PixelFormat::RGBA8; bool hasDepth_ = false; bool hasStencil_ = false; int samples_ = 1; bool createFBO(); void deleteFBO(); }; // ============================================================================ // 多重采样渲染目标(用于MSAA) // ============================================================================ class MultisampleRenderTarget : public RenderTarget { public: /** * @brief 创建多重采样渲染目标 */ bool create(int width, int height, int samples = 4); /** * @brief 解析到普通渲染目标(用于显示) */ void resolveTo(RenderTarget &target); /** * @brief 销毁渲染目标 */ void destroy(); private: GLuint colorRBO_ = 0; // 多重采样颜色渲染缓冲 }; // ============================================================================ // 渲染目标栈(用于嵌套渲染) // ============================================================================ class RenderTargetStack { public: static RenderTargetStack &getInstance(); /** * @brief 压入渲染目标 */ void push(RenderTarget *target); /** * @brief 弹出渲染目标 */ void pop(); /** * @brief 获取当前渲染目标 */ RenderTarget *getCurrent() const; /** * @brief 获取栈大小 */ size_t size() const; /** * @brief 清空栈 */ void clear(); private: RenderTargetStack() = default; ~RenderTargetStack() = default; std::vector stack_; mutable std::mutex mutex_; }; // ============================================================================ // 渲染目标管理器 - 全局渲染目标管理 // ============================================================================ class RenderTargetManager { public: /** * @brief 获取单例实例 */ static RenderTargetManager &getInstance(); /** * @brief 初始化渲染目标管理器 * @param width 默认宽度 * @param height 默认高度 */ bool init(int width, int height); /** * @brief 关闭渲染目标管理器 */ void shutdown(); /** * @brief 创建新的渲染目标 */ Ptr createRenderTarget(const RenderTargetConfig &config); /** * @brief 获取默认渲染目标 */ RenderTarget *getDefaultRenderTarget() const { return defaultRenderTarget_.get(); } /** * @brief 调整所有受管渲染目标的大小 */ void resize(int width, int height); /** * @brief 检查是否已初始化 */ bool isInitialized() const { return initialized_; } private: RenderTargetManager() = default; ~RenderTargetManager() = default; RenderTargetManager(const RenderTargetManager &) = delete; RenderTargetManager &operator=(const RenderTargetManager &) = delete; Ptr defaultRenderTarget_; std::vector> renderTargets_; bool initialized_ = false; }; // ============================================================================ // 便捷宏 // ============================================================================ #define E2D_RENDER_TARGET_STACK() ::extra2d::RenderTargetStack::getInstance() #define E2D_RENDER_TARGET_MANAGER() \ ::extra2d::RenderTargetManager::getInstance() } // namespace extra2d