Hazel学习笔记:AssetsManager

Hazel学习笔记:AssetsManager 新增功能如下: 新增 Asset 类型,将 Texture、Shader、Scene都继承于 Asset 对象,用于 AssetsManager管理 AssetManager区分:MemoryAsset 和 LoadedAsset 区分临时内存资源和磁盘资源 GetAsset 采用懒加载策略 Hazel学习笔记:Editor2D Phase 0: 新增功能如下: EditorCommandHistory.h Undo、Redo实现 ctrl + z 操作撤销、回撤 IEditorCommand.h 封装任务 EditorContext.h 编辑器所需要的上下文 EditorDirtyTracker.h 编辑器状态追踪 EditorSelectionContext.h 封装当前选择上下文 EditorViewportSettings.h 视口参数设置 拆分 EditorLayer 功能 面板之间解耦 Phase 1: 将 Viewport 能力抽象,区分展示和 渲染,将 Overlay 渲染 和 场景渲染 封装成管线 处理。 新增 EditorViewportPanel 负责视口部分工作 添加选中实体边框(GetWorldTransform)、世界原点绘制 Phase 2: 新增世界网格绘制 网格支持动态裁剪、动态密度判断、主次网格分层 渲染顺序: Background Overlay Pass —— 网格、原点(位于场景内容下方) Scene Pass —— 场景内容 + 写入实体 ID 附件 Foreground Overlay Pass —— 选中框、碰撞体等(覆盖在场景内容上方)

2026-04-15   1分钟   SSmallOrange

Hazel学习笔记:编辑器

Hazel学习笔记:编辑器 经过一段时间的挣扎,终于决定要向完整的3D编辑器出发了,还是Hazel游戏引擎的框架进行完善,对于游戏脚本仍然沿用之前的 Lua 脚本,对于后端仍然保留OpenGL作为后端图形API,以此两点作为与原Hazel引擎的不同之处。 本篇内容不涉及ImGUI使用教程。 新增功能如下: UUID生成器、UUID组件 新增组件之间父子关系,子只保存对父的相对坐标 对每个组件而言,当父子关系发生变化时,坐标也要相应的进行变化 编辑器窗口 视图窗口(Viewport)、属性窗口(Property)、组件树、窗口支持拖拽 独立的Camera(EditorCamera) 鼠标拾取 引入 ImGui 的 ImGuizmo,使得实体支持手柄拖动修改(QWER:关闭平移旋转缩放) 引入 Line、Circle 绘制,增强编辑器 Debug 能力 添加Scene拷贝能力,用来支持播放、暂停功能。 添加 Project,定制项目文件格式,统一管理脚本、资源、场景文件 父子关系 以场景为单位,在场景中新增实体时,为每个实体附加一个UUID组件和关系组件: 1 2 3 4 5 6 7 8 9 Entity Scene::CreateEntityWithUUID(UUID uuid, const std::string& name) { Entity entity = { m_Registry.create(), this }; entity.AddComponent<IDComponent>().ID = uuid; // UUID entity.AddComponent<RelationshipComponent>(); // Relationship // ... m_EntityIDMap[uuid] = entity.m_EntityHandle; // uuid 与组件映射 return entity; } 定义常用组件接口: 查找: 1 2 3 4 5 6 Entity Scene::FindEntityByUUID(UUID uuid) { if (auto it = m_EntityIDMap.find(uuid); it != m_EntityIDMap.end()) return Entity{ it->second, this }; return Entity{}; } 实体销毁: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 void Scene::DestroyEntity(Entity entity) { // 递归销毁子实体 if (entity.HasComponent<RelationshipComponent>()) { auto children = entity.Children(); for (auto childId : children) { Entity child = FindEntityByUUID(childId); if (child) DestroyEntity(child); } // 移除自己 Entity parent = entity.GetParent(); if (parent) parent.RemoveChild(entity); } // 从 UUID 映射中移除 if (entity.HasComponent<IDComponent>()) m_EntityIDMap.erase(entity.GetComponent<IDComponent>().ID); m_Registry.destroy(entity.m_EntityHandle); } 取消实体的父: ...

2026-04-05   2分钟   SSmallOrange

Hazel学习笔记:游戏功能完善(持续更新)

Hazel学习笔记:游戏功能完善 由于Hazel剩下的内容非常多,我以前也没有接触过游戏、渲染部分,所以学起来比较吃力。这部分我将作为OpenGL、游戏相关知识的积累,沉淀一些个人理解,并持续更新。 ECS ECS是游戏中常用的架构,他之所以流行,是因为:他把对象的存储和使用分开,在不影响易用性的前提下,保证了性能。 如果没有ECS,我们应该如何处理游戏对象? 假如我们现在有一个路灯和一个玩家,他们作为游戏世界的一员,首先需要有自己的位置信息,现在要让这个路灯和这个玩家都具备发光的能力,那么我们很容易能想到: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Transform { public: void SetPos(vec3 pos) {} vec3 GetPos() {} private: vec3 pos; }; class Light { public: void StartLight(); void StopLight(); }; class StreetLight : Light, Transform { public: void StartLight() { /* ... */ } }; class Player : Light, Transform { public: void StartLight() { /* ... */ } } 后来游戏逐渐更新,玩家的灯光逻辑变得越来越复杂… ...

2026-01-20   13分钟   SSmallOrange

Hazel学习笔记:Renderer2D(持续更新)

Hazel学习笔记:Renderer2D部分 ​ 最近一段时间一直想拓展一下个人的技术栈,想学习一些图形学的知识,毕竟目前在做客户端相关的开发,学一些图形相关的知识应该也没有什么坏处,从我过去一段时间的工作经历来看:只要是学过的芝士,总有一天会用得上的。 ​ 正好翻B站看到了有人搬运了TheCherno 大佬的Hazel游戏引擎教程,就决定从这里入手学习,了解OpenGL和一些图形学的基础知识,并将一些芝士整理在此, 对于引擎基础部分的搭建就先略过(比如:日志部分(log)、项目搭建(Premake)、事件、窗口等,后面可以单开一节整理Premake和性能分析部分),重点整理他对OpenGL的封装部分,以及后面的Renderer2D的抽象。 ​ 整体架构 OpenGL封装 Hazel从OpenGL的“Hello World”入手,逐步减少原生OpenGL代码的编写,所以我们首先需要知道,原生OpenGL绘制一个三角形都需要哪些步骤? 首先,需要准备一些顶点数据: 1 2 3 4 5 6 float vertices[] = { // 位置 // 颜色 -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f }; 准备VAO/VBO: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 unsigned int vao, vbo; glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 位置属性,location = 0 glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); // 颜色属性,location = 1 glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glBindVertexArray(0); 准备着色器: ...

2025-11-24   6分钟   SSmallOrange