From 5d94e417d88770bd54100699abad928f60738751 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Thu, 6 Feb 2025 09:23:04 +0800 Subject: [PATCH] history --- note/learn/learn.md | 2 +- note/learn/lib/devops/Docker.md | 4 + src/a/anki/{anki.md => anki card.md} | 20 +++- src/m/me/anki card/week1.md | 129 ++++++++++++++++++++ src/m/me/future.md | 77 ++++++++++++ src/m/me/算法.md | 65 +++++++++++ src/m/me/计划.md | 45 +++++++ src/z/zengine/参考文献/Air_Forward.md | 71 +++++++++++ src/z/zengine/参考文献/pxgj.md | 25 ++++ src/z/zengine/版本计划.md | 162 ++++++++++++++++++++++++++ src/z/zengine/资源.md | 3 +- 11 files changed, 599 insertions(+), 4 deletions(-) rename src/a/anki/{anki.md => anki card.md} (50%) create mode 100644 src/m/me/anki card/week1.md create mode 100644 src/m/me/future.md create mode 100644 src/m/me/算法.md create mode 100644 src/m/me/计划.md create mode 100644 src/z/zengine/参考文献/Air_Forward.md create mode 100644 src/z/zengine/参考文献/pxgj.md create mode 100644 src/z/zengine/版本计划.md diff --git a/note/learn/learn.md b/note/learn/learn.md index 50ed327..2630dc2 100644 --- a/note/learn/learn.md +++ b/note/learn/learn.md @@ -38,7 +38,7 @@ [[note/code/lang/zero/序列化]] ## tool -[[src/a/anki/anki]] +[[anki card]] [[obsidian]] ## theory [[编译]] diff --git a/note/learn/lib/devops/Docker.md b/note/learn/lib/devops/Docker.md index 0132ebb..7472f12 100644 --- a/note/learn/lib/devops/Docker.md +++ b/note/learn/lib/devops/Docker.md @@ -27,6 +27,10 @@ docker version ```shell pip install docker-compose +docker-compose down +docker-compose down --rmi all +docker system prune -a +docker-compose up --build ``` diff --git a/src/a/anki/anki.md b/src/a/anki/anki card.md similarity index 50% rename from src/a/anki/anki.md rename to src/a/anki/anki card.md index 0661951..ad11144 100644 --- a/src/a/anki/anki.md +++ b/src/a/anki/anki card.md @@ -35,4 +35,22 @@ ## 浏览器 - Anki 划词制卡助手 -- \ No newline at end of file + +# 文档 +## 笔记 +**笔记**:是知识点的核心数据结构,包含多个字段(Fields)。 +## 卡片 +**卡片**:是从笔记中生成的学习单元,实际出现在复习过程中的“问答对”。 +可以依据规则,批量从笔记中生成 +## 模板 +美化卡片样式,问答、填空 +- 问答题 + - 正到反 + - 反到正 +- 输入题 +- 填空题 +- 选择题 + +## 使用 +似乎应该先基于卡片样式,来设计笔记字段和内容 +所以先找合适的样式,再填充数据 diff --git a/src/m/me/anki card/week1.md b/src/m/me/anki card/week1.md new file mode 100644 index 0000000..b80675f --- /dev/null +++ b/src/m/me/anki card/week1.md @@ -0,0 +1,129 @@ +--- +aliases: +tags: +creation date: 2025-01-06 20:49 +modification date: Monday 6th January 2025 20:49:03 +--- +# day1 +## 填空题 + +### STL 的基本组成部分 + +STL 的基本组成部分是{{c1::容器}}、{{c1::迭代器}}、{{c1::分配器}}、{{c1::算法}}、{{c2::仿函数}}、{{c2::适配器}}。 + +容器 是一种数据结构 +迭代器 提供了访问遍历容器的方法 +分配器 内存分配,分配内存,移动内存,回收内存 +算法 操作容器中数据的模板函数 如 sort 接口 +仿函数 函数对象,仅仅是重载了函数操作符的struct +适配器 包装,提供新的接口,栈、队列、仿函数、迭代器 + +## 简答题 + +### 容器原理 + +- 2.请说说 STL 中常见的容器,并介绍一下实现原理 + 顺序容器 + - vector + - 插入、删除O(n),随机访问O(1) + - 尾部插入、删除O(1) + - deque + - 插入、删除O(n),随机访问O(1) + - 头尾插入、删除O(1) + - 分段内存,数组和链表的结合 + - list + - 插入、删除O(1),随机访问O(n) + 树容器 +- set、multiset、map、multimap +- 都是由红黑树实现,元素有序排放 +- set、map 成员唯一,map中包含键值对 +- multiset、multimap 元素可以重复 +- 插入、删除、随机访问O(logn) +哈希容器 +- unordered_set、unordered_multiset、unordered_map、unordered_multimap +- 都通过哈希表实现,元素无序排放 +- 插入、删除、随机访问O(1),最坏情况O(n) + +### 迭代器 + +- 3.迭代器的作用?为什么有指针还需要迭代器 + 迭代器是对容器一种访问封装,提供了遍历的接口 + 迭代器和容器是深度绑定的,指针不能实现容器的遍历 + 迭代器删除时,当前迭代器都会失效(内存重新分配的风险) + +### 容器内存分配 + +- 4.容器内存分配容易产生的问题 + 内存失效,容器元素扩容时会导致原内存失效。所以外界只能持有容器元素值类型 + 回收异常,传递容器给另外一个dll时,如果触发扩容,就可能会有异常行为 + 内存分配 , 数组容器有一个额外机制容量管理内存,其他容器则每次添加删除都会导致内存的分配和释放 + 解决办法 : 封装内存分配,全部交由一个第三方dll管理, 可以使用pmr容器 + 特定分配器 实现高效的内存管理 + +# day2 + +## 简答题 + +### C++11 的新特性 + +C++新特性主要包括包含语法改进和标准库扩充两个方面,主要包括以下11点: + +语法的改进 + +(1)统一的初始化方法 ,构造初始化可以使用=,此时不是表示赋值语法 + +(2)成员变量默认初始化 + +(3)auto关键字 用于定义变量,编译器可以自动判断的类型(前提:定义一个变量时对其进行初始化) + +(4)decltype 求表达式的类型 + +(5)智能指针 shared_ptr + +(6)空指针 nullptr(原来NULL),类型不一样,NULL是宏 c++指向 0 ,c指向 (void*)0 + +(7)基于范围的for循环 + +(8)右值引用和move语义 让程序员有意识减少进行深拷贝操作 + +标准库扩充(往STL里新加进一些模板类,比较好用) + +(9)无序容器(哈希表) 用法和功能同map一模一样,区别在于哈希表的效率更高 + +(10)正则表达式 可以认为正则表达式实质上是一个字符串,该字符串描述了一种特定模式的字符串 + +(11)Lambda表达式 + +### Lambda +Lambda 使用细节 + +参数 auto,结合 std::visit 可以实现函数组的定义 + +[=,&FindFieldFn, &compiler] 可以实现默认值传递,特殊对象引用传递 + +[=, this] [=, 指针] ,全部都是值拷贝,指针对象仅拷贝指针 + +## 输入题 + +### 智能指针 + +智能指针有{{c1::**shared_ptr**}}、{{c1::**unique_ptr**}、{{c1::**weak_ptr**}}、{{c2::**auto_ptr**}}(c++11已弃用) + +使用指南指针进行资源生命周期管理,RAII 借助编译器自动添加的析构函数,来自动实现资源的回收 + +unique_ptr 去掉拷贝构造,独占资源,只能通过移动构造转移所有权 + +shared_ptr 共享资源和计数指针,容易出现循环引用 + +weak_ptr 弱引用指针,相当于安全指针,不负责管理资源生命周期 + +auto_ptr 所有权指针,支持拷贝构造转移所有权,容易误用导致崩溃 + +shared_ptr 和 weak_ptr 会共享一个24字节的堆计数内存块 +### 类型转换 + +简述一下 C++11 中四种类型转换{{c1::**const_cast**}}、{{c1::**static_cast**}、{{c1::**dynamic_cast**}}、{{c2::**reinterpret_cast**}} + +const_cast 去除常量限制,但是常量优化可能读的是字面值,和内存值不一样 +static_cast 最常用,实现各种隐式转换 +dynamic_cast 查询虚表来判断转换是否合法,所以只有包含虚表的类型才能进行转化 +reinterpret_cast 重新解释内存,实现任意转换,但不安全 \ No newline at end of file diff --git a/src/m/me/future.md b/src/m/me/future.md new file mode 100644 index 0000000..d74c657 --- /dev/null +++ b/src/m/me/future.md @@ -0,0 +1,77 @@ +--- +aliases: +tags: +creation date: 2025-01-03 09:33 +modification date: Friday 3rd January 2025 09:33:40 +--- +# 性能优化 +## 包体 +分 母包、子包,每个包都包含必要的地图资源,以及全部进包的特殊目录 +标记资源使用情况,图集图像缩为一个点 + +## 图集 +大的背景图建议单独存放 +## 预加载 +### 剧情 +开场剧情预加载,场景shader录制,避免场景闪一下 +剧情预加载,避免帧率变化,如果加载时间长,会吞掉一部分运动时间 +有个bug,相机比剧情快一帧,帧率变化就会导致画面抖动 +### 模型、特效 +特效看不到,预加载 +模型闪TPose,预加载 + +## 代码 +Profiler 看函数消耗,分析性能热点 + +# 寻路 +跳点、寻路点 分层寻路 + +# 动画 + + +# 魔法编辑器 +技能编辑器 +### 特殊效果 +- 相机震屏 +- 径向模糊 +- 人物残影 +- 残血特效 +- 人物溶解 +- 边缘光 + +红点系统 +## ui +- 场景渲染 +- 特性渲染 +- 模型渲染 +- 剧情渲染 +- 相机、光源 +## 技能系统 +- 技能使用 (支持连击) + - 客户端请求释放技能 + - 服务器通知客户端使用技能 + - 找到技能或连击技能,播放魔法 +- 伤害飘字 + - 服务器发送伤害数据 + - 客户端进行伤害拆分 + - 伤害拆分是假的,是依据碰撞魔法配置来拆分的 + - 被击特效 (无动作) + - 会从伤害源魔法,找到对应被击特效 +- 死亡特写 + - 由主角击杀的特殊npc会进入死亡特写 + - 播放剧情视角 + - 慢放、虚化、隐藏UI、禁止移动 +- 推怪效果 (打击感优化) + - 依据技能和npc配置,播放受击动作 + - 可推怪由客户端控制 + - 客户端实现推怪效果 + - 可推怪由服务器控制 + - 服务器实现 +## Buff系统 +- Buff 支持 +- 魔法效果 +## Lua +- 事件回调注册 + - 添加调试日志 +## 多语言 + diff --git a/src/m/me/算法.md b/src/m/me/算法.md new file mode 100644 index 0000000..56416a5 --- /dev/null +++ b/src/m/me/算法.md @@ -0,0 +1,65 @@ +--- +aliases: +tags: +creation date: 2025-01-18 11:55 +modification date: Saturday 18th January 2025 11:55:34 +--- +# 数组 +## 原地交换 +- 循环交换 + - 进入下一个循环时,递增就行 + - 如果i 和 i+1都在循环中,那么所有元素都在唯一的循环中 +- 左右移动 + - 观察规律,等于两次逆向交换 +## 第k位 + - 分治 + - 每次把数据分为大于、等于、小于三堆 +## 前k位 +- 最大堆、最小堆 +- 节省移动开销 +## 唯一奇数重复 +- 异或 +## 超一半的众数 +- 不同数字互相抵消,剩下的数字 +## 最大子序列和 +- 求首尾之间的 + - 最小子序列和 + - 最大子序列和 + - 数据和 +- 计算最大子序列和 与 数据和 - 最小子序列和 的最大值 +## 回文子串 +- 动态规划 + - 空间换时间,存储中间结果 +- 马拉车算法 + - 在回文子串内部的中心点,可以利用对称点的信息 + - 直接从对称点的半径开始扩展 +# 动态规划 +## 实现原理 +- 空间换时间,存储中间结果 +- 空间换递归,然后反推递归 +- 从特殊到一般,从1推到n + - 如果求的是一个值,这个递推比较方便 + - 如果求的是一个乱序序列,这就很难了 +- 自上而下,暴力递归搜索 + - 从大问题解到小问题,符合解题直觉,不必完全掌握依赖关系 + - 有重复计算 观察是否有重复的函数调用、子问题计算 + - 空间换时间 + - 栈空间溢出 + - 递归转循环 + - 第k个元素有f(k)种分布 +- 自下而上,动态规划搜索 + - 从小问题推到大问题, 如果推导简单,可以跳过DFS搜索 + - 如果DFS解题原型更简单,可以把DFS优化成动态规范 + - 计算效率高、不会栈空间溢出 + - 从自上而下出发,找出依赖路径,然后反向填表 +## 小程序 +## 计算器 +- 构造后序语法子树 +- 构建操作符栈 + - 依据优先级入栈出栈 + - 考虑括号,弹出剩下的操作符 + - 出栈到语法树中 +- 使用栈计算语法树运行结果 + + + diff --git a/src/m/me/计划.md b/src/m/me/计划.md new file mode 100644 index 0000000..1ff0dc1 --- /dev/null +++ b/src/m/me/计划.md @@ -0,0 +1,45 @@ +--- +aliases: +tags: +creation date: 2025-01-06 09:17 +modification date: Monday 6th January 2025 09:17:24 +--- +# 目标 +是否需要借助Anki学习 +- 复习计算机基础 + - 长期练习 + - 每天都要,包括复习之前的、学习新知识 + - 看面经放松、知乎、博客 +- 每天做4道算法题 + - 长期练习 + - 练习+总结 + - 每周一个大厂测试仿真 +- 学习总结Games101,202,104 + - 60节课,101 安排四天 + - 202 一周可以吗? + - 104 一周 +- 工作总结 + - 总结做过的 + - 学习不了解的 + - 学习不了解的游戏玩法实现 +- 引擎开发 + - 总结实现的 + - 记录缺失的 + - 阅读开源项目 +# 第一周 1.06~1.13 +- 第一天 + - 计划方案,Anki学习 + - 环境搭建 ssh => docker => anki + - anki + - + - 学习光线追踪 + - 复习C++基础 + 3 篇面经 + 20道个练习题 + - 二叉树练习*4,学习红黑树、均衡二叉树实现 + - 阅读airforward项目 + - 预计持续3天 + - 阅读、比较 + - 任务系统 + - 持续3天 + - 流程 + - 实现 +- diff --git a/src/z/zengine/参考文献/Air_Forward.md b/src/z/zengine/参考文献/Air_Forward.md new file mode 100644 index 0000000..e584846 --- /dev/null +++ b/src/z/zengine/参考文献/Air_Forward.md @@ -0,0 +1,71 @@ +--- +aliases: +tags: +creation date: 2025-01-08 13:56 +modification date: Wednesday 8th January 2025 13:56:02 +--- +# Air_Forward +[github](https://github.com/freestriker/Air_Forward) + +这个项目比较简单,需要赶工在一周内(代码时间中)抄一个效果出来 1.08 ~ 1.15 + +## 多线程 + +### 资源主线程 + +- 对资源进行垃圾回收 + - 这样死循环判断是否性能不太好 + - 看错了,这是在资源主线程中,每秒回收的 + - 感觉实际上回收时间可以延长一点,因为有时候需要使用预加载功能 + - 每个资源的回收时间应该不一样吧 + - 同时提供一个切换地图时的主动回收 + +### 加载子线程 + +- 分为四个任务子线程,争抢同一个条件变量 +- 使用了协程的内容,暂时不知道有什么作用 + - 这里把资源包装成了std::future对象 + - 应该是不如我的RSCHandle对象的 + - 这里通过guid 实现了资源的弱引用 +- 这里资源加载,是把文件读取也放在线程里了 + - 我的文件io放在了主线程,是否需要拆分,meta文件在主线程,然后资源文件放到任务线程去 +- 这里加载资源时是同步的,而且和GPU的通信也是同步的 + - 命令提交、同步应该是没有我设计的好的 + - 我的命令是批量 和 定时同步,并且采用了动态GPU缓冲区 + +### 逻辑线程 ECS +- 这里每帧遍历所有物体,然后查找对应的component 更新 + + +### 渲染主线程 + +### 渲染子线程 + + + +## 资源管理 + +资源拆分为 + +资源实例 + +唯一,和资源文件一一对应 + +- MeshInstance +- _ShaderInstance +- TextureCubeInstance + - 包含一个采样器,采样器其实是可以共享的,这里设计有点浪费 + +资源 + +每个资源对象私有,资源实例则是共享 + +- 那么如何查找对应的资源呢? + +- 我的好像反过来了,是否有必要拆分成两个呢? + - 我提供的访问接口将会是一个mesh 和 meshcomponent 一一对应 + - 似乎没有必要额外包装一层 + - 关键是需要实现智能指针式的资源管理 + + + diff --git a/src/z/zengine/参考文献/pxgj.md b/src/z/zengine/参考文献/pxgj.md new file mode 100644 index 0000000..be25c81 --- /dev/null +++ b/src/z/zengine/参考文献/pxgj.md @@ -0,0 +1,25 @@ +--- +aliases: +tags: +creation date: 2025-01-10 13:20 +modification date: Friday 10th January 2025 13:20:17 +--- +# 任务 +### 自动任务 +- stReqNpcCoordUserCmd + - 客户端请求NPC寻路 +- stRetNpcCoordUserCmd + - 服务器返回NPC寻路 + - 开始寻路 +- 检测寻路结束 + - 手动打断 + - 寻路到NPC附近,结束寻路 +- stClickNpcScriptUserCmd + - 客户端请求点击npc + - 手动点击npc 也会触发 +- 开始对话 +- 下一阶段 + - 对话结束后,服务器依据配置 + - 通知下一个npc的寻路 + - 开始循环 + diff --git a/src/z/zengine/版本计划.md b/src/z/zengine/版本计划.md new file mode 100644 index 0000000..bc82eb5 --- /dev/null +++ b/src/z/zengine/版本计划.md @@ -0,0 +1,162 @@ +--- +aliases: +tags: +creation date: 2025-01-04 11:22 +modification date: Saturday 4th January 2025 11:22:39 +--- +# Games101 +## 顶点着色器 +### 数据输入 +- 顶点布局 + - 每个顶点独有,且渲染中不变的数据 + - 模型顶点坐标、uv贴图、蒙皮骨骼 +- 可变独占 + - 每个顶点独有,直接映射为纹理,通过uv坐标访问 +- 共享资源 + - 每个顶点共享,经常变化的数据 + - MVP矩阵 、光照信息 +### 空间变化 +考虑相同模型的不同物体 +- 模型空间 + - [x] 来自美术提供的源文件,共用同一份GPU顶点缓冲区 + - [ ] 加载模型骨骼动画,顶点蒙皮缓冲区 +- 动画空间 + 动画可以不一样,动画进度也可以不一样 + - 骨骼动画 + - CPU更新每根骨骼的位置 + - 加权计算蒙皮骨骼变换 + - 一个顶点加权4根骨骼就够了 + - 纹理动画 + - 普通关键帧动画 + - 骨骼动画烘培成纹理动画 +- MVP矩阵 + - 世界空间 + - 模型变换矩阵 * 动画矩阵 + - 对单位向量进行变换,计算很方便 + - 模型坐标、模型xyz旋转、模型缩放 + - M = T * R * S , 先缩放,再旋转,最后平移 + - 如何计算xyz旋转矩阵呢? + - 固定一个轴,然后计算另外两个轴旋转后的坐标,能直接写出绕轴的旋转矩阵 + - 三个矩阵相乘就是最终旋转矩阵,顺序呢?UE是先Z再X再Y + - 相机空间 + - 相机透视矩阵 * 世界空间 + - 要变换回单位向量,计算很复杂 + - 可以放过来求逆 + - 单位向量进行变换 + - 正交矩阵的逆是矩阵转置 + - 单位向量依然是单位向量 + - 单位向量依然互相垂直 + - 正交矩阵只改变了单位向量的方向 + - 相机坐标、相机朝向、相机UP方向 + - 相机朝向要变为-z方向,up方向要变为y方向 + - x 方向由 -z 和 y 叉乘得到 + - 投影空间 + - 相机投影矩阵 * 相机空间 + - 正交投影 + - 相机空间投影到立方体[-1,1]^3 + - 要变换回单位向量 + - 先平移再缩放 + - 透视投影 + - 正交投影矩阵(线性) * 透视投影矩阵(非线性) + - 非线性变化特点 + - 把四棱锥挤压成长方体 + - 压缩有一个系数比n/z,三个坐标都有变化,z坐标变化未知 + - z坐标在近平面和远平面,需要保持z不变 + - 列出方程,求解矩阵 + - An + B = nn + - Af + B = ff + - n 0 0 0 + - 0 n 0 0 + - 0 0 n+f -nf + - 0 0 1 0 + - MVP矩阵 = 相机投影矩阵 * 相机矩阵 * 模型矩阵(TRS) +## 光线追踪 +### 空间划分 +- 网格 + - 体素游戏 + - 实现简单,空间开销大 + - 寻路方便、划分简单 +- 四叉树、八叉树 + 空间划分成四/八份, 检测子空间物体数量,数量太多就递归划分子空间 + - 和维度相关,分叉太多 + - 跨节点物体存储浪费 + - 动态物体会频繁变更节点树 +- BSP树 + 二叉树,每次使用超平面分割空间,分割时采取空间或物体均匀划分 + - 构建复杂,适合室内场景优化 + - 不适合处理动态物体,需要重新构建BSP树 +- KD树 + - 超平面是轴对齐的特殊BSP树 +- BVH树 +### 数学算法 +- 判断点和平面的关系 + +# 多线程 + +手机端,多线程拆分太细,会导致新的问题发热、耗电快 + +所以当任务量较小时,应该退化为单线程 + +## 实现 + +### 任务 + +- 对任务进行封装,变成一个可执行单元 +- 从线程池获取线程,执行任务 +- 线程调度,优先级、CPU大小核 + +### 线程安全 + +- 原子操作 + - std::atomic +- 加锁 +- 无锁 + - 如果操作是线性的 + - 可以使用CAS循环操作 +- 同步、异步 + - 条件变量、信号量 + +## 任务 + +### IO + +- 我希望序列化的对象内存都是临时内存 +- 序列化要有一个单独的内存分配器 + +### 渲染 + +- 封装记录API命令,然后再交给渲染线程 + - 只能降低api调用耗时,但是现代api开销没那么大 +- 复制对象状态,传递给渲染线程绘制 + - 空间换时间,性能更好 + - 可见性检测、批处理、api调用 + +## 粒子 + + + +### 物理 + +### 动画 + +## Job系统 + +- 比如物理线程中,可以一次开多个小线程,并行计数,然后等待计算结果 + + + +## 内存管理 + +- 初始化后,大小不变的堆数组 + - 需要快速申请、快速释放 +- 存储相同子类型的特殊数组 + - 顶点缓冲区 +- 存储子类型的特殊数组,要求访问连续 +- 帧缓存区、全局缓冲区、可回收缓冲区 + +## 异步回调 + +- 这样对异步资源需要进行封装 +- 需要能让资源还能正常组装,而没有深度依赖 +- 需要知道何时加载完毕 +- 可以由异步切换到同步 diff --git a/src/z/zengine/资源.md b/src/z/zengine/资源.md index a2f2ecd..1a9c8cb 100644 --- a/src/z/zengine/资源.md +++ b/src/z/zengine/资源.md @@ -59,8 +59,7 @@ filemanager 是地址管理平台,通过path可以找到资源,可能在本 - 如果资源已加载就能找到 资源,如果知道谁持有,就可以通过guid找对方要,否则需要记住path - - +**没有考虑资源回收** ## URL