From 4a251560595f2dc86dd3e448f193d6f17ca0a952 Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Tue, 19 May 2026 23:20:01 +0800 Subject: [PATCH 1/2] design new graphic module --- .gitignore | 15 ++++++ docs/thoughts/event_system.md | 46 +++++++++++++++++++ docs/thoughts/pipeline_desc.md | 31 +++++++++++++ .../fg/graphics/backends/cpu/execute/.gitkeep | 0 .../graphics/backends/cpu/resources/.gitkeep | 0 .../graphics/backends/opengl/execute/.gitkeep | 0 .../backends/opengl/resources/.gitkeep | 0 include/fg/graphics/executor.h | 1 + include/fg/graphics/pipeline_descriptor.h | 4 ++ include/fg/graphics/shader_wrapper.h | 3 ++ include/fg/{ => legacy}/graphics/gl_scene.h | 0 include/fg/{ => legacy}/graphics/opengl/gl.h | 0 include/fg/{ => legacy}/scene/view/camera.h | 0 .../fg/{ => legacy}/scene/view/projection.h | 0 include/fg/resources/resources_descriptor.h | 1 + include/fg/resources/resources_manager.h | 8 ++++ src/fg/{ => legacy}/graphics/gl_scene.cc | 0 src/fg/{ => legacy}/graphics/opengl/gl.cc | 0 src/fg/{ => legacy}/scene/view/camera.cc | 0 src/fg/{ => legacy}/scene/view/projection.cc | 0 20 files changed, 109 insertions(+) create mode 100644 .gitignore create mode 100644 docs/thoughts/event_system.md create mode 100644 docs/thoughts/pipeline_desc.md create mode 100644 include/fg/graphics/backends/cpu/execute/.gitkeep create mode 100644 include/fg/graphics/backends/cpu/resources/.gitkeep create mode 100644 include/fg/graphics/backends/opengl/execute/.gitkeep create mode 100644 include/fg/graphics/backends/opengl/resources/.gitkeep create mode 100644 include/fg/graphics/executor.h create mode 100644 include/fg/graphics/pipeline_descriptor.h create mode 100644 include/fg/graphics/shader_wrapper.h rename include/fg/{ => legacy}/graphics/gl_scene.h (100%) rename include/fg/{ => legacy}/graphics/opengl/gl.h (100%) rename include/fg/{ => legacy}/scene/view/camera.h (100%) rename include/fg/{ => legacy}/scene/view/projection.h (100%) create mode 100644 include/fg/resources/resources_descriptor.h create mode 100644 include/fg/resources/resources_manager.h rename src/fg/{ => legacy}/graphics/gl_scene.cc (100%) rename src/fg/{ => legacy}/graphics/opengl/gl.cc (100%) rename src/fg/{ => legacy}/scene/view/camera.cc (100%) rename src/fg/{ => legacy}/scene/view/projection.cc (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7d3280 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# macOS +.DS_Store + +# Build directories +/build/ + +# IDE / editor +.vscode/ + +# clangd / tooling +.cache/ +compile_commands.json + +# Logs +*.log diff --git a/docs/thoughts/event_system.md b/docs/thoughts/event_system.md new file mode 100644 index 0000000..ba370b7 --- /dev/null +++ b/docs/thoughts/event_system.md @@ -0,0 +1,46 @@ +# event list 怎么运作 + +现在的 event system (主要讨论 win32)其实比较简单,核心就是有一个 global 的 event list,窗口系统往里面塞, 我们的应用往外读取 + +这里需要一点基本的 message loop 知识 + +windows 每一个窗体对应一个 UI 线程,对应一个消息队列,os 会把消息放到这个队列里面 + +实际上 global event list 只让一个线程访问,所以不需要锁 + +于是最重要的两件事是: + +1. CollectEvents: 往 event list 塞 event + 通过系统调用 PeekMessage DispatchMessageW 进入 WindowProc (用户给窗体挂的 hook) + WindowProc 内处理系统 msg,转为 event 塞进 event list +2. PollEvent: 从 event list pop + 直接提供一个接口输出就可以了,毕竟 event list 是我们提供的 + +我看了 SDL 的写法,它似乎只有一个 Poll 的接口,在 Poll 内可能触发 CollectEvents,我觉得这个语义有点不太自然 +所以我改成了,需要手动 CollectEvents,然后在一个帧内通过循环 Poll 处理所有 event,这样才能把 Event 以组为单位进行处理,每组对应一帧中需要的操作 + +为了顺便支持 Mac,用了 glfw,系统接口不太一样,CollectEvents 的行为必须和系统相关,所以改成了一个 hook + +# event 丢失 + +我觉得 event 丢失是正常的,默认 ring buffer 有 128 个固定 slot,如果满了就会丢弃 +相当于一帧最多处理 128 个 event,我觉得这个数值完全足够了 + + +# window state 的维护 + +还有一套逻辑是关于 window state 的 +显然有大量的 mouse move 或者 keyboard 相关的 event,如果每个 event 都要手动记录状态更新,这太蠢了 + +window state 就是记录一个 window 固有属性的结构,包括当前的按键状态,鼠标位置等 + +这些状态是在 PollEvent 时自动更新的,所以可以直接检查当前 Window 的 state 获取信息 + +这一点也是参考了 SDL 的设计得到的 + +另外,应该保证 event 和 window 是对应的,所以加了 window id 和 register(不过我其实没有考虑多窗口,感觉也没啥多窗口的必要,所以目前是这样,看起来 register 也挺鸡肋的) + + +# others + +另外,这里本来是用一个继承来分发不同 platform 的,但是那样就有一个 vptr,感觉压根没必要,所以改成了持有 WindowImpl 的形式,直接根据宏分支实现 \ No newline at end of file diff --git a/docs/thoughts/pipeline_desc.md b/docs/thoughts/pipeline_desc.md new file mode 100644 index 0000000..36d9dae --- /dev/null +++ b/docs/thoughts/pipeline_desc.md @@ -0,0 +1,31 @@ +# 什么叫绘图 + +对于当前的 opengl 暴露的接口,我比较不满意,因为它仅仅是把 opengl 的接口换个说法而已,在使用的时候还是得知道 vao vbo 之类的东西 + +问题在于,我们想给使用者暴露怎么样的绘图语义?尤其是,什么叫“绘图语义”? + +现在暴露了 set uniform 之类的语义,看起来和 “绘图” 本身无关,如果我想隐藏它,似乎又没办法描述我要做的事情,这是一个矛盾 + +本质上,这里存在一个混淆,即原教旨的“绘图”语义,与“光栅化绘图流程”,所提供的语义接口是不同的,虽然“光栅化绘图流程”本质是要提供某种程度的原教旨的“绘图”语义 + +简单来说,opengl 描述的,是用光栅化方法(包含了很多实现细节相关的配置)来描述“绘图”。但是这种具体的方法,其语义范围其实额外包含了“怎么做”,而不是仅仅“做什么” + +当然,理论上说,最好我们能通过一个原教旨绘图语义,通过某种转换,变成一个“光栅化绘图流程”或者“光追绘图流程”或者别的什么流程。 + +我们是否要想办法做出这样的一个转换器呢?似乎也不是不可能的,但是复杂度似乎有点太高了 + +- 这里,我想原教旨的绘图语义,本质上就是描述画面/场景 本身,其中一种方法是 .obj + camera 配置。但是绘制语义本身太自由了,有各种不同的绘制方法,这个语义其实是相当难描述的,将这个语义抽象出来,本身就非常困难,因为信息太少太随意了。把这样随意的东西转换为某个 pipeline 想来要更复杂。 + +- 另一个想法是。的确 opengl 的接口很复杂,问题在于,它的任何一个配置,是否对绘制效果产生影响。如果是的,那么意味着,原教旨绘制语义,必须要有一样的复杂度(否则表达能力更弱,但显然这是不合理的)。除非能找到某种“视角”来大幅简化这样的描述细节(目前我没想到) + +总结:我没想出来,什么东西是原教旨的绘制语义。最自然的想法是画家不断在画布上 apply 几何体,但是每个几何体如何描述?色彩、渐变是什么?难道需要将任何几何体的细节无限细分?这还好说,还有一个问题在于应用物理是困难的,在纯粹的绘制语义下不存在高光之类的东西,我只能描述成一个圆形的白色之类的东西。所以原教旨的绘制(我直觉中的绘制)似乎不完全只是填色与几何体,它其实包含了某种内涵的规则(比如说物体应该符合人类的几何直觉)?而这种规则也有可能是被打破的,或者部分被打破的?感觉这些都太模糊了。我压根没办法单纯描述“我要画什么”,因为这个语义有很多隐含的东西 + +# 提供什么 + +我想,提供一套符合某种规范的操作流程,比如光栅或者光追,是更简单的,而且和 opengl 之类的后端能对上 + +因此,目前的抽象不太好 + +我们应该暴露的是 “光栅化绘图流程” 所需要暴露的语义,而 set uniform 这个行为,本质上是 shader 的一部分。shader 是光栅化流程中,描述颜色的一部分,所以它确实是描述光栅化流程的一部分。同时,vao vbo 显然不是光栅化流程的一部分——它是光栅化流程具体实现方案的一部分,并非对光栅化流程本身的描述 + +总结:去描述光栅化流程——我们可以做一个 cpu 的光栅化流程,可以借此确认到底怎么描述光栅化本身 \ No newline at end of file diff --git a/include/fg/graphics/backends/cpu/execute/.gitkeep b/include/fg/graphics/backends/cpu/execute/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/fg/graphics/backends/cpu/resources/.gitkeep b/include/fg/graphics/backends/cpu/resources/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/fg/graphics/backends/opengl/execute/.gitkeep b/include/fg/graphics/backends/opengl/execute/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/fg/graphics/backends/opengl/resources/.gitkeep b/include/fg/graphics/backends/opengl/resources/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/fg/graphics/executor.h b/include/fg/graphics/executor.h new file mode 100644 index 0000000..4a6f57d --- /dev/null +++ b/include/fg/graphics/executor.h @@ -0,0 +1 @@ +// 执行一个 desc,进行绘制,根据 backend 分发 diff --git a/include/fg/graphics/pipeline_descriptor.h b/include/fg/graphics/pipeline_descriptor.h new file mode 100644 index 0000000..cc20bd7 --- /dev/null +++ b/include/fg/graphics/pipeline_descriptor.h @@ -0,0 +1,4 @@ +// 描述一次 draw 的内容 +// 包含了光栅过程的各种选项 +// 这个东西应该是纯描述的,可序列化,可 dump +// 也许应该有静态优化能力?但是这个显然与 backend 相关 diff --git a/include/fg/graphics/shader_wrapper.h b/include/fg/graphics/shader_wrapper.h new file mode 100644 index 0000000..8b5181d --- /dev/null +++ b/include/fg/graphics/shader_wrapper.h @@ -0,0 +1,3 @@ +// 如果我们统一了 desc,那么就必须要表达出 shader 这个级别的语义 +// 换句话说,我们得有一个 dsl,让 executor 能翻译成不同 backend +// 这个工作有点太 heavy 了,先用一个 shader wrapper 包一下,这里可以搞丑一点 diff --git a/include/fg/graphics/gl_scene.h b/include/fg/legacy/graphics/gl_scene.h similarity index 100% rename from include/fg/graphics/gl_scene.h rename to include/fg/legacy/graphics/gl_scene.h diff --git a/include/fg/graphics/opengl/gl.h b/include/fg/legacy/graphics/opengl/gl.h similarity index 100% rename from include/fg/graphics/opengl/gl.h rename to include/fg/legacy/graphics/opengl/gl.h diff --git a/include/fg/scene/view/camera.h b/include/fg/legacy/scene/view/camera.h similarity index 100% rename from include/fg/scene/view/camera.h rename to include/fg/legacy/scene/view/camera.h diff --git a/include/fg/scene/view/projection.h b/include/fg/legacy/scene/view/projection.h similarity index 100% rename from include/fg/scene/view/projection.h rename to include/fg/legacy/scene/view/projection.h diff --git a/include/fg/resources/resources_descriptor.h b/include/fg/resources/resources_descriptor.h new file mode 100644 index 0000000..3c9aef6 --- /dev/null +++ b/include/fg/resources/resources_descriptor.h @@ -0,0 +1 @@ +// 通用的 res desc diff --git a/include/fg/resources/resources_manager.h b/include/fg/resources/resources_manager.h new file mode 100644 index 0000000..60ffc6d --- /dev/null +++ b/include/fg/resources/resources_manager.h @@ -0,0 +1,8 @@ +// 统一管理 res desc 的工具 +// 一份数据可能有几个层次 +// 1. path +// 2. cpu 存储数据 +// 3. gpu 存储数据 +// 在资源紧张的时候切换 +// 应该有一个 id,方便序列化 pipeline desc +// id 直接用 path 是不是就行了 diff --git a/src/fg/graphics/gl_scene.cc b/src/fg/legacy/graphics/gl_scene.cc similarity index 100% rename from src/fg/graphics/gl_scene.cc rename to src/fg/legacy/graphics/gl_scene.cc diff --git a/src/fg/graphics/opengl/gl.cc b/src/fg/legacy/graphics/opengl/gl.cc similarity index 100% rename from src/fg/graphics/opengl/gl.cc rename to src/fg/legacy/graphics/opengl/gl.cc diff --git a/src/fg/scene/view/camera.cc b/src/fg/legacy/scene/view/camera.cc similarity index 100% rename from src/fg/scene/view/camera.cc rename to src/fg/legacy/scene/view/camera.cc diff --git a/src/fg/scene/view/projection.cc b/src/fg/legacy/scene/view/projection.cc similarity index 100% rename from src/fg/scene/view/projection.cc rename to src/fg/legacy/scene/view/projection.cc From 38bed615437735c3ae7f2b93f5f3de1bfb2e6c49 Mon Sep 17 00:00:00 2001 From: feifei-111 <2364819892@qq.com> Date: Sat, 6 Jun 2026 10:21:07 +0800 Subject: [PATCH 2/2] refine code structure --- include/fg/{graphics/pipeline_descriptor.h => gfx/raster/desc.h} | 0 include/fg/{graphics => gfx/raster}/executor.h | 0 include/fg/{graphics => gfx/raster}/shader_wrapper.h | 0 include/fg/graphics/backends/cpu/execute/.gitkeep | 0 include/fg/graphics/backends/cpu/resources/.gitkeep | 0 include/fg/graphics/backends/opengl/execute/.gitkeep | 0 include/fg/graphics/backends/opengl/resources/.gitkeep | 0 include/fg/{resources/resources_descriptor.h => res/desc_base.h} | 0 include/fg/{resources/resources_manager.h => res/manager.h} | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename include/fg/{graphics/pipeline_descriptor.h => gfx/raster/desc.h} (100%) rename include/fg/{graphics => gfx/raster}/executor.h (100%) rename include/fg/{graphics => gfx/raster}/shader_wrapper.h (100%) delete mode 100644 include/fg/graphics/backends/cpu/execute/.gitkeep delete mode 100644 include/fg/graphics/backends/cpu/resources/.gitkeep delete mode 100644 include/fg/graphics/backends/opengl/execute/.gitkeep delete mode 100644 include/fg/graphics/backends/opengl/resources/.gitkeep rename include/fg/{resources/resources_descriptor.h => res/desc_base.h} (100%) rename include/fg/{resources/resources_manager.h => res/manager.h} (100%) diff --git a/include/fg/graphics/pipeline_descriptor.h b/include/fg/gfx/raster/desc.h similarity index 100% rename from include/fg/graphics/pipeline_descriptor.h rename to include/fg/gfx/raster/desc.h diff --git a/include/fg/graphics/executor.h b/include/fg/gfx/raster/executor.h similarity index 100% rename from include/fg/graphics/executor.h rename to include/fg/gfx/raster/executor.h diff --git a/include/fg/graphics/shader_wrapper.h b/include/fg/gfx/raster/shader_wrapper.h similarity index 100% rename from include/fg/graphics/shader_wrapper.h rename to include/fg/gfx/raster/shader_wrapper.h diff --git a/include/fg/graphics/backends/cpu/execute/.gitkeep b/include/fg/graphics/backends/cpu/execute/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/include/fg/graphics/backends/cpu/resources/.gitkeep b/include/fg/graphics/backends/cpu/resources/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/include/fg/graphics/backends/opengl/execute/.gitkeep b/include/fg/graphics/backends/opengl/execute/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/include/fg/graphics/backends/opengl/resources/.gitkeep b/include/fg/graphics/backends/opengl/resources/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/include/fg/resources/resources_descriptor.h b/include/fg/res/desc_base.h similarity index 100% rename from include/fg/resources/resources_descriptor.h rename to include/fg/res/desc_base.h diff --git a/include/fg/resources/resources_manager.h b/include/fg/res/manager.h similarity index 100% rename from include/fg/resources/resources_manager.h rename to include/fg/res/manager.h