笔记7 Layer
对于应用,我们都需要layer去处理渲染顺序和用户事件响应。
- 渲染顺序层级,我们需要从底层往上处理渲染逻辑,将最新的一层,放在最后渲染。
- 对于事件处理,我们肯定需要曾最上层优先处理,然后层层往下处理。
然后我们优先来看Layer的抽象层。
class HAZEL_API Layer { public: Layer(const std::string& name = "Layer"); virtual ~Layer(); virtual void OnAttach() {} virtual void OnDetach() {} virtual void OnUpdate() {} virtual void OnImGuiRender(){} virtual void OnEvent(Event& event) { } inline const std::string& GetName() const { return m_DebugName; } protected: std::string m_DebugName; };
CPP
**OnAttach()**:在层被附加(激活)到应用程序时调用,通常用于初始化资源。(例如在使用imgui的时候,我们imgui肯定是在最上层,创建窗口的时候,OnAttach就需要创建imgui窗口和上下文等初始化操作)
**OnDetach()**:在层被移除(卸载)时调用,用于释放资源。(依旧以imgui为例,我们只需要在关闭imgui时销毁上下文和窗口等)
**OnUpdate()**:在每一帧更新时调用,处理与该层相关的逻辑(如渲染或物理计算)。
**OnEvent(Event& event)**:用于处理与该层相关的事件,如用户输入、窗口事件等。
**std::string m_DebugName;**暂时是用string作为不同的层的id
既然我们有了Layer,那我们也必然需要装载Layer的容器去统一管理。
目前,我们使用了Vector为的容器创建的LayerStack类,去统一管理Layer层级。
class HAZEL_API LayerStack { public: LayerStack(); ~LayerStack(); void PushLayer(Layer* layer); void PushOverlay(Layer* overlay); void PopLayer(Layer* layer); void PopOverlay(Layer* overlay); std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }//返回vector的头指针 std::vector<Layer*>::iterator end() { return m_Layers.end(); }///返回尾巴指针 private: std::vector<Layer*> m_Layers; //存放层级的容器 unsigned int m_LayerInsertIndex = 0; //普通层级的最后一个索引,原本是使用指针,但是改为使用索引了,后面看到我再补充。 };
CPP
对于LayerStack的设计,将层级主要分为了俩个层级—–普通层和覆盖层。
普通层依赖于特定的渲染和处理顺序,做为前半层级,覆盖层则优于普通层处理(一般类似ui和调式层),做为后半层级。

Layer就是普通层级。
void LayerStack::PushLayer(Layer* layer) { m_Layers.emplace(m_Layers.begin()+m_LayerInsertIndex, layer); m_LayerInsertIndex++; } void LayerStack::PopLayer(Layer* layer) { auto it = std::find(m_Layers.begin(), m_Layers.end(), layer); if (it != m_Layers.end()) { m_Layers.erase(it); m_LayerInsertIndex--; } }
CPP
PushLayer
- 这个函数通过
emplace
方法,将layer
插入到m_Layers.begin() + m_LayerInsertIndex
位置上。 - 每插入一个
layer
,m_LayerInsertIndex
都会自增 1,因此新插入的layer
总是位于之前插入的layer
的后面。 - 这种设计使得 “layer” 和 “overlay” 之间有一个明确的分界线,
PushLayer
的元素在前,PushOverlay
的元素在后。
PopLayer
- 利用find函数找到vector对应的层级,使用erase将后面的元素则整体前进一个单位。
OverLayer就是覆盖层
void LayerStack::PushOverlay(Layer* overlay) { m_Layers.emplace_back(overlay); } void LayerStack::PopOverlay(Layer* overlay) { auto it = std::find(m_Layers.begin(), m_Layers.end(), overlay); if (it != m_Layers.end()) m_Layers.erase(it); }
CPP
PushOverLayer
很简单就是直接放在vector的最后一层,使用emplace_back
最后的话,也是将layerStack对象放在引擎内的application中
