Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# macOS
.DS_Store

# Build directories
/build/

# IDE / editor
.vscode/

# clangd / tooling
.cache/
compile_commands.json

# Logs
*.log
46 changes: 46 additions & 0 deletions docs/thoughts/event_system.md
Original file line number Diff line number Diff line change
@@ -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 的形式,直接根据宏分支实现
31 changes: 31 additions & 0 deletions docs/thoughts/pipeline_desc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 什么叫绘图

对于当前的 opengl 暴露的接口,我比较不满意,因为它仅仅是把 opengl 的接口换个说法而已,在使用的时候还是得知道 vao vbo 之类的东西

问题在于,我们想给使用者暴露怎么样的绘图语义?尤其是,什么叫“绘图语义”?

现在暴露了 set uniform 之类的语义,看起来和 “绘图” 本身无关,如果我想隐藏它,似乎又没办法描述我要做的事情,这是一个矛盾

本质上,这里存在一个混淆,即原教旨的“绘图”语义,与“光栅化绘图流程”,所提供的语义接口是不同的,虽然“光栅化绘图流程”本质是要提供某种程度的原教旨的“绘图”语义

简单来说,opengl 描述的,是用光栅化方法(包含了很多实现细节相关的配置)来描述“绘图”。但是这种具体的方法,其语义范围其实额外包含了“怎么做”,而不是仅仅“做什么”

当然,理论上说,最好我们能通过一个原教旨绘图语义,通过某种转换,变成一个“光栅化绘图流程”或者“光追绘图流程”或者别的什么流程。

我们是否要想办法做出这样的一个转换器呢?似乎也不是不可能的,但是复杂度似乎有点太高了

- 这里,我想原教旨的绘图语义,本质上就是描述画面/场景 本身,其中一种方法是 .obj + camera 配置。但是绘制语义本身太自由了,有各种不同的绘制方法,这个语义其实是相当难描述的,将这个语义抽象出来,本身就非常困难,因为信息太少太随意了。把这样随意的东西转换为某个 pipeline 想来要更复杂。

- 另一个想法是。的确 opengl 的接口很复杂,问题在于,它的任何一个配置,是否对绘制效果产生影响。如果是的,那么意味着,原教旨绘制语义,必须要有一样的复杂度(否则表达能力更弱,但显然这是不合理的)。除非能找到某种“视角”来大幅简化这样的描述细节(目前我没想到)

总结:我没想出来,什么东西是原教旨的绘制语义。最自然的想法是画家不断在画布上 apply 几何体,但是每个几何体如何描述?色彩、渐变是什么?难道需要将任何几何体的细节无限细分?这还好说,还有一个问题在于应用物理是困难的,在纯粹的绘制语义下不存在高光之类的东西,我只能描述成一个圆形的白色之类的东西。所以原教旨的绘制(我直觉中的绘制)似乎不完全只是填色与几何体,它其实包含了某种内涵的规则(比如说物体应该符合人类的几何直觉)?而这种规则也有可能是被打破的,或者部分被打破的?感觉这些都太模糊了。我压根没办法单纯描述“我要画什么”,因为这个语义有很多隐含的东西

# 提供什么

我想,提供一套符合某种规范的操作流程,比如光栅或者光追,是更简单的,而且和 opengl 之类的后端能对上

因此,目前的抽象不太好

我们应该暴露的是 “光栅化绘图流程” 所需要暴露的语义,而 set uniform 这个行为,本质上是 shader 的一部分。shader 是光栅化流程中,描述颜色的一部分,所以它确实是描述光栅化流程的一部分。同时,vao vbo 显然不是光栅化流程的一部分——它是光栅化流程具体实现方案的一部分,并非对光栅化流程本身的描述

总结:去描述光栅化流程——我们可以做一个 cpu 的光栅化流程,可以借此确认到底怎么描述光栅化本身
4 changes: 4 additions & 0 deletions include/fg/gfx/raster/desc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 描述一次 draw 的内容
// 包含了光栅过程的各种选项
// 这个东西应该是纯描述的,可序列化,可 dump
// 也许应该有静态优化能力?但是这个显然与 backend 相关
1 change: 1 addition & 0 deletions include/fg/gfx/raster/executor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// 执行一个 desc,进行绘制,根据 backend 分发
3 changes: 3 additions & 0 deletions include/fg/gfx/raster/shader_wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// 如果我们统一了 desc,那么就必须要表达出 shader 这个级别的语义
// 换句话说,我们得有一个 dsl,让 executor 能翻译成不同 backend
// 这个工作有点太 heavy 了,先用一个 shader wrapper 包一下,这里可以搞丑一点
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions include/fg/res/desc_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// 通用的 res desc
8 changes: 8 additions & 0 deletions include/fg/res/manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// 统一管理 res desc 的工具
// 一份数据可能有几个层次
// 1. path
// 2. cpu 存储数据
// 3. gpu 存储数据
// 在资源紧张的时候切换
// 应该有一个 id,方便序列化 pipeline desc
// id 直接用 path 是不是就行了
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.