#pragma once #include #include #include #include #include #include #include #include #include #include namespace frostbite2D { class RenderTexture; class Renderer { public: static Renderer& get(); bool init(); void shutdown(); void beginFrame(); void endFrame(); void flush(); bool beginRenderToTexture(RenderTexture& target, Camera* camera, const Color& clearColor = Color(0.0f, 0.0f, 0.0f, 0.0f), bool clear = true); bool endRenderToTexture(); void setViewport(int x, int y, int width, int height); void setWindowSize(int width, int height, float contentScaleX = 1.0f, float contentScaleY = 1.0f); void setVirtualResolutionEnabled(bool enabled); void setVirtualResolution(int width, int height); void setResolutionScaleMode(ResolutionScaleMode mode); void setSeparateUIVirtualResolutionEnabled(bool enabled); void setUIVirtualResolution(int width, int height); void setUIResolutionScaleMode(ResolutionScaleMode mode); void setClearColor(float r, float g, float b, float a = 1.0f); void setClearColor(const Color& color); void clear(uint32_t flags); /** * @brief 设置应用默认渲染风格预设 */ void setDefaultRenderStyleProfile(RenderStyleProfileId profile); /** * @brief 获取应用默认渲染风格预设 */ RenderStyleProfileId getDefaultRenderStyleProfile() const { return defaultRenderStyleProfile_; } /** * @brief 切换当前正在使用的渲染风格上下文 */ void setActiveRenderStyleProfile(RenderStyleProfileId profile, RenderStyleLayerRole role); /** * @brief 将指定风格作用到某个相机 */ void applyRenderStyleToCamera(Camera* camera, RenderStyleProfileId profile, RenderStyleLayerRole role) const; void setCamera(Camera* camera); Camera* getCamera() { return camera_; } int getVirtualWidth() const; int getVirtualHeight() const; int getUIVirtualWidth() const; int getUIVirtualHeight() const; Rect getViewportRect() const; Rect getUIViewportRect() const; const RenderResolutionState& getResolutionState() const { return resolutionState_; } const RenderResolutionState& getUIResolutionState() const { return uiResolutionState_; } bool isInitialized() const { return initialized_; } bool isFrameActive() const { return frameActive_; } bool isRenderingToTexture() const { return !renderTargetStack_.empty(); } void setCullingEnabled(bool enabled) { cullingEnabled_ = enabled; } bool isCullingEnabled() const { return cullingEnabled_; } void applyWorldViewport() const; void applyUIViewport() const; Vec2 screenToVirtual(const Vec2& screenPos) const; Vec2 screenToUIVirtual(const Vec2& screenPos) const; Vec2 virtualToScreen(const Vec2& virtualPos) const; void drawQuad(const Vec2& pos, const Size& size, float cr = 1.0f, float cg = 1.0f, float cb = 1.0f, float ca = 1.0f); void drawQuad(const Vec2& pos, const Size& size, Ptr texture); void drawQuad(const Rect& rect, const Color& color); void drawSprite(const Vec2& pos, const Size& size, Ptr texture); void drawSprite(const Vec2& pos, const Rect& srcRect, const Vec2& texSize, Ptr texture, const Color& color = Color(1, 1, 1, 1)); void setupBlendMode(BlendMode mode); /** * @brief 获取当前激活的层级风格设置 */ const RenderStyleLayerSettings& getActiveRenderStyle() const { return activeRenderStyle_; } /** * @brief 当前风格是否要求顶点像素对齐 */ bool shouldSnapVertices() const { return activeRenderStyle_.vertexPixelSnap; } /** * @brief 当前风格是否优先使用像素风采样 */ bool shouldUsePixelArtSampling() const { return activeRenderStyle_.pixelArtSampling; } /** * @brief 当前风格是否需要对子纹理 UV 做向内收缩 */ bool shouldShrinkSubTextureUVs() const { return activeRenderStyle_.shrinkSubTextureUVs; } ShaderManager& getShaderManager() { return shaderManager_; } Batch& getBatch() { return batch_; } private: Renderer(); void updateUniforms(); void recalculateResolutionState(); void recalculateSingleResolutionState(RenderResolutionState& state, bool useVirtualResolution, int virtualWidth, int virtualHeight, ResolutionScaleMode mode) const; void syncCameraViewport(); struct RenderTargetState { uint32 framebuffer = 0; int viewportX = 0; int viewportY = 0; int viewportWidth = 1; int viewportHeight = 1; float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; Camera* camera = nullptr; bool startedStandaloneBatch = false; bool cullingEnabled = true; }; ShaderManager shaderManager_; Batch batch_; Camera* camera_ = nullptr; RenderStyleProfileId defaultRenderStyleProfile_ = RenderStyleProfileId::Hybrid2D; RenderStyleProfileId activeRenderStyleProfile_ = RenderStyleProfileId::Hybrid2D; RenderStyleLayerRole activeRenderStyleRole_ = RenderStyleLayerRole::World; RenderStyleLayerSettings activeRenderStyle_; uint32_t clearColor_[4] = {0, 0, 0, 255}; bool useVirtualResolution_ = false; int virtualWidth_ = 1280; int virtualHeight_ = 720; ResolutionScaleMode resolutionMode_ = ResolutionScaleMode::Fit; bool useSeparateUIVirtualResolution_ = false; int uiVirtualWidth_ = 0; int uiVirtualHeight_ = 0; ResolutionScaleMode uiResolutionMode_ = ResolutionScaleMode::Fit; RenderResolutionState resolutionState_; RenderResolutionState uiResolutionState_; bool initialized_ = false; bool frameActive_ = false; bool cullingEnabled_ = true; std::vector renderTargetStack_; Renderer(const Renderer&) = delete; Renderer& operator=(const Renderer&) = delete; }; } // namespace frostbite2D