1181 words
6 minutes
EchoEngine开发笔记-Render Architecture

近期开发进度#

在最近的开发中,EchoEngine相关基础模块不断完善,如:主窗口(MainWindow)、事件系统(Event System)、层(Layer)。因此,在此先简要回顾一下之前关键模块的设计思想,并为接下来的渲染模块开发提供重要基础。

主窗口(MainWindow)#

在EchoEngine的开发中,主窗口作为渲染现实喝用户交互的核心组件,并且为了实现跨平台支持以及灵活的窗口管理,我采用了抽象接口和平台相关实现相结合的设计模式。

  • 定义了一个窗口属性结构体sWindowProp,用于描述窗口的基本属性
/// @brief 窗口属性
typedef struct sWindowProp 
{
    uint32_t m_iWidth;  //窗口宽
    uint32_t m_iHeight;  //窗口高
    std::string m_sTitle; //窗口标题

    sWindowProp(const std::string& sTitle = "Echo Engine", uint32_t iWidth = 1600, uint32_t iHeight = 900)
        : m_iWidth(iWidth), m_iHeight(iHeight), m_sTitle(sTitle)
    {}

}sWindowProp;
  • 设计了抽象类MainWindow,定义统一的窗口接口,包括窗口更新、获取窗口尺寸与标题、设置垂直同步(VSync)、以及事件回调等功能
/// @brief 主窗口类,此类为抽象类,需要继承并实现其纯虚函数
class MainWindow 
{
public:
    /// @brief 事件回调函数
    using EventCallBackFun = std::function<void(Event&)>;

    virtual ~MainWindow() {}

    /// @brief 创建主窗口
    /// @param prop 窗口属性
    /// @return 
    static Scope<MainWindow> CreateMainWindow(const sWindowProp& prop = sWindowProp());

public:
    /// @brief 窗口更新
    virtual void OnUpdate() = 0;

    /// @brief 获取窗口宽度
    virtual uint32_t GetWidth() const = 0;
    /// @brief 获取窗口高度
    virtual uint32_t GetHeight() const = 0;
    /// @brief 获取窗口标题
    virtual const std::string& GetTitle() const = 0;

    /// @brief 设置垂直同步
    /// @param bEnable true-开启,false-关闭
    virtual void SetVSync(bool bEnable) = 0;
    /// @brief 获取垂直同步状态
    /// @return true-开启,false-关闭
    virtual bool IsVSync() const = 0;

    /// @brief 获取当前活动窗口
    /// @return 当前活动窗口指针
    virtual void* GetNativeWindow() const = 0;

    /// @brief 设置事件回调函数
    /// @param callback 
    virtual void SetEventCallBack(const EventCallBackFun& callback) = 0;
};

Scope<MainWindow> MainWindow::CreateMainWindow(const sWindowProp& prop)
{
#ifdef ECHO_PLATFORM_WINDOWS
    return CreateScope<MainWindow_Windows>(prop);
#else
    ECHO_CORE_ASSERT(false, "Unknown platform!");
    return nullptr;
#endif // ECHO_PLATFORM_WINDOWS
}

事件系统(Event System)#

事件系统是EchoEngine实现响应用户输入和内部通信的关键模块。在EchoEngine中,我设计了三类事件类型:

  • 应用程序事件:用于处理应用程序相关的事件,如窗口大小变化、窗口关闭、App渲染、App更新等。
  • 键盘事件:用于处理键盘输入事件,如按键按下、按键松开等。
  • 鼠标事件:用于处理鼠标输入事件,如鼠标移动、鼠标点击等。

层(Layer)#

层(Layer)的概念在EchoEngine中用于组织和管理渲染顺序,使得场景渲染更加高效。每个Layer作为独立的渲染单元,具有自己的渲染状态和资源管理策略。设计Layer系统的主要优势包括:

  • 渲染顺序控制:通过将不同的渲染元素分配到不同的层次,能够灵活控制绘制顺序和混合模式。
  • 性能优化:每个Layer可以单独优化渲染流程,提升整体性能,尤其在复杂场景中表现更为明显。
  • 资源管理:层与层之间相互独立,有助于更好地管理资源加载和释放,减少内存占用和重复绘制。

Render Architecture-渲染架构#

渲染是什么?#

在开始渲染模块设计之前,先回答一个最基础的问题:渲染是什么的? 在我看来,渲染即是在屏幕上绘制出图像,并根据外部交互进行相应的渲染调整。

渲染架构设计#

Render Architecture

  • 整个渲染架构分为两部分:渲染器(Renderer)和渲染API(Render API)
    • 渲染器(Renderer):与操作系统和图形API无关
    • 渲染API(Render API):与操作系统和图形API相关

渲染器(Renderer)#

在渲染器中,包含以下内容:

  • 渲染器:2D渲染器、3D渲染器(用于实现前向渲染、延迟渲染等)
  • 渲染管理
    • ⭐场景图:管理渲染场景中的所有渲染元素,如:模型、灯光、相机等
    • ⭐排序:基于Layer进行渲染元素的排序
    • 剔除:剔除掉不需要渲染的元素,减少绘制次数
  • 材质
  • LOD
  • 动画
  • ⭐相机系统
  • 视觉系统:粒子系统、后期效果、反射等

渲染API(Render API)#

在渲染API中,包含以下内容:

  • ⭐图形上下文(Graphics Context):用于管理渲染相关的状态、资源和配置等信息
  • 交换链:交换缓冲(Swap Buffer)
  • ⭐缓冲对象:根据不同图形API封装顶点缓冲(VAO)、索引缓冲(IBO)、帧缓冲(FBO)
  • 纹理和着色器:根据不同图形API封装纹理和着色器API
  • 渲染状态管理
  • 渲染管线
  • 渲染通道
EchoEngine开发笔记-Render Architecture
https://jerryym.github.io/posts/echoengine/echoengine开发笔记-render-architecture/
Author
_进击のJerry_
Published at
2025-03-04