LOADING

加载过慢请开启缓存 浏览器默认开启

Layer

笔记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和调式层),做为后半层级。

image-20241109152258979

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 位置上。
  • 每插入一个 layerm_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中

image-20241109181111113