制订规范
This commit is contained in:
@@ -12,13 +12,36 @@
|
||||
|-------------------|-----------------|---------------------------------|
|
||||
| Windows (x86/x64) | SDL2 窗口 | 验证渲染逻辑、算法正确性、快速迭代调试 |
|
||||
| Linux x86_64 | SDL2 窗口 | 验证 Linux 兼容性、CMake 构建、SDL2 系统依赖 |
|
||||
| ARM Linux (交叉编译) | `/dev/fb0` 直接写屏 | 最终在 IMX6U 开发板上运行的版本 |
|
||||
| ARM Linux (交叉编译) | SDL2 或 `/dev/fb0` | 最终在 IMX6U 开发板上运行的版本;优先目标以后续实际部署后端为准 |
|
||||
|
||||
**为什么分三套?**
|
||||
|
||||
- **Windows 编译**:开发主力机通常是 Windows,有 IDE 调试、有图形窗口,渲染算法对不对一眼就能看到。这个阶段完全不关心嵌入式细节。
|
||||
- **Linux x86 编译**:验证代码在 GCC/Clang 下有无警告、CMake 配置是否跨平台、系统 SDL2 依赖是否正确。很多嵌入式工具链的问题在 x86 Linux 上就能提前暴露。
|
||||
- **ARM 交叉编译**:最终在 IMX6U 上跑。这个版本去掉 SDL2,直接 mmap `/dev/fb0` 写屏,减少依赖和内存开销。
|
||||
- **ARM 交叉编译**:最终在 IMX6U 上跑。若目标板使用 SDL2,则 SDL2 仅作为显示/输入/计时适配层,核心渲染仍按 CPU framebuffer + 一次性提交设计;如需极简依赖,也保留 `/dev/fb0` 后端作为对照。
|
||||
|
||||
|
||||
## 开发规范与性能红线
|
||||
|
||||
IMX6U 运行时性能预算较紧,后续开发必须遵守 `docs/DEVELOPMENT_GUIDELINES.md`。如果目标板使用 SDL2,仍然要把 SDL2 限制在平台适配层,核心逻辑和渲染热路径不直接依赖 SDL:
|
||||
|
||||
- 核心逻辑和热路径默认不新增 `float` / `double`,需要小数时使用项目统一定点数;只在显示、调试、导入导出等边界层转换成浮点。
|
||||
- 主循环、每对象、每三角形/顶点/像素级代码中不得频繁创建 `std::vector` / `std::string` 等动态分配容器,应复用缓冲或使用固定容量结构。
|
||||
- PC/SDL 版本用于调试验证,不能把调试便利写法扩散到 ARM release 核心路径。
|
||||
- SDL2 后端只做显示、输入、计时和最终 framebuffer 提交,不在核心渲染/游戏逻辑中直接调用 SDL API。
|
||||
- 新增核心代码前按规范文档中的检查清单自查。
|
||||
|
||||
## 应用层与图形库拆分
|
||||
|
||||
项目后续按“两个游戏 + 一个启动器 + 一套底层图形库”组织,详细边界见 `docs/APP_AND_GFX_ARCHITECTURE.md`:
|
||||
|
||||
- `Gfx` / 底层图形库:只提供 framebuffer、SDL2/fb0 平台适配、输入/时间源、基础绘制能力,例如点、线、矩形、四边形、sprite、tile。
|
||||
- `Apps/Launcher`:负责游戏选择、全局设置和启动流程。
|
||||
- `Apps/GameA`、`Apps/GameB`:分别维护自己的游戏规则、状态、资源和渲染调用。
|
||||
- `Shared`:只放应用层共享但不属于底层图形库的 UI、存档、配置、资源索引等。
|
||||
- 依赖方向必须保持 `Apps -> Shared -> Gfx -> Platform`,底层图形库不能反向依赖具体游戏。
|
||||
|
||||
初期推荐单进程多应用模式:Launcher、GameA、GameB 共用同一个 SDL2 初始化、framebuffer 和主循环,通过统一 `IApp` 接口切换当前应用。
|
||||
|
||||
## 构建说明
|
||||
|
||||
@@ -70,46 +93,65 @@ cmake --build build-linux
|
||||
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
|
||||
```
|
||||
|
||||
构建(启用 Framebuffer 后端):
|
||||
本项目 ARM 端保留两类后端:
|
||||
|
||||
- **SDL2 后端**:目标是后续游戏主路径;SDL2 负责显示、输入、计时和最终 framebuffer 提交。
|
||||
- **Framebuffer 后端**:作为极简依赖和显示通路对照测试。
|
||||
|
||||
构建(Framebuffer 对照后端):
|
||||
```bash
|
||||
cmake -B build-arm \
|
||||
cmake -B build-arm-fb \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
|
||||
-DUSE_FRAMEBUFFER=ON .
|
||||
cmake --build build-arm
|
||||
cmake --build build-arm-fb
|
||||
```
|
||||
|
||||
构建(SDL2 后端,要求工具链/sysroot 可找到目标板 SDL2 开发库):
|
||||
```bash
|
||||
cmake -B build-arm-sdl \
|
||||
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
|
||||
-DUSE_FRAMEBUFFER=OFF .
|
||||
cmake --build build-arm-sdl
|
||||
```
|
||||
|
||||
部署到开发板:
|
||||
```bash
|
||||
scp build-arm/IMX6U-Game root@imx6u:/tmp/
|
||||
scp build-arm-sdl/IMX6U-Game root@imx6u:/tmp/
|
||||
# 或部署 framebuffer 对照版本:
|
||||
scp build-arm-fb/IMX6U-Game root@imx6u:/tmp/
|
||||
```
|
||||
|
||||
板子上运行(需要 root 权限访问 `/dev/fb0`):
|
||||
板子上运行:
|
||||
```bash
|
||||
sudo /tmp/IMX6U-Game
|
||||
/tmp/IMX6U-Game
|
||||
```
|
||||
|
||||
ARM 版本启动后会打印 framebuffer 参数(分辨率、bpp、像素格式)。按 `q` 键或 `Ctrl+C` 退出。
|
||||
Framebuffer 对照版本可能需要 root 权限访问 `/dev/fb0`。SDL2 版本是否需要额外环境变量或权限,取决于目标板 SDL2 视频驱动和显示栈配置。
|
||||
|
||||
## 显示后端架构
|
||||
|
||||
显示层通过抽象接口 `Platform::IDisplay` 与渲染逻辑解耦:
|
||||
显示层通过抽象接口 `Platform::IDisplay` 与渲染逻辑解耦。后续应用层和图形库拆分后,`Platform` 会收敛到 `Gfx` 的平台适配层:
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────┐
|
||||
│ 游戏/渲染逻辑(Camera、Rasterizer 等) │
|
||||
├──────────────────────────────────────┤
|
||||
│ Core::FrameBuffer(CPU 颜色缓冲区) │
|
||||
├──────────────────────────────────────┤
|
||||
│ Platform::IDisplay │
|
||||
│ - SDLDisplay : SDL2 窗口(PC) │
|
||||
│ - FBDisplay : /dev/fb0(ARM) │
|
||||
└──────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ Apps:Launcher / GameA / GameB │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Shared:UI、存档、配置、资源索引 │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Gfx:DrawContext、FrameBuffer、Draw2D、Math │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Platform::IDisplay │
|
||||
│ - SDLDisplay : SDL2 显示/输入/计时适配 │
|
||||
│ - FBDisplay : /dev/fb0 对照后端 │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
切换后端不需要修改任何渲染代码,只需要在 CMake 配置时开关 `USE_FRAMEBUFFER`。
|
||||
切换显示后端不应影响应用层和核心绘制逻辑;当前 CMake 通过 `USE_FRAMEBUFFER` 在 SDL2 与 framebuffer 后端间切换。
|
||||
|
||||
## 目录结构
|
||||
|
||||
当前源码仍处于早期验证布局:
|
||||
|
||||
```text
|
||||
IMX6U-Game/
|
||||
├─ cmake/
|
||||
@@ -119,38 +161,25 @@ IMX6U-Game/
|
||||
│ ├─ SDL2/ # Windows 用 SDL2 库(头文件 + lib + DLL)
|
||||
│ └─ SDL_image/ # SDL2_image 库(头文件 + lib + DLL)
|
||||
├─ src/
|
||||
│ ├─ Platform/
|
||||
│ │ ├─ Display.h # 显示抽象接口
|
||||
│ │ ├─ SDLDisplay.cpp # SDL2 窗口后端
|
||||
│ │ └─ FBDisplay.cpp # Linux Framebuffer 后端
|
||||
│ ├─ Core/
|
||||
│ │ ├─ FrameBuffer.h/.cpp # CPU 颜色缓冲
|
||||
│ │ ├─ DepthBuffer.h/.cpp # 深度缓冲
|
||||
│ │ └─ Renderer.h/.cpp # 渲染调度(预留)
|
||||
│ ├─ Math/
|
||||
│ │ ├─ Vector2.h / Vector3.h / Vector4.h
|
||||
│ │ ├─ Matrix4x4.h
|
||||
│ │ └─ MathUtil.h
|
||||
│ ├─ Rasterizer/
|
||||
│ │ ├─ Rasterizer.h/.cpp # 线段光栅化
|
||||
│ │ └─ TriangleRasterizer.h/.cpp # 三角形填充
|
||||
│ ├─ RenderData/
|
||||
│ │ ├─ Color.h
|
||||
│ │ ├─ BoundingBox.h
|
||||
│ │ └─ Triangle.h
|
||||
│ ├─ Scene/
|
||||
│ │ ├─ Camera.h/.cpp
|
||||
│ │ ├─ Vertex.h / Mesh.h / Model.h / Transform.h
|
||||
│ ├─ Asset/
|
||||
│ │ └─ ObjLoader.h/.cpp # OBJ 模型加载(预留)
|
||||
│ ├─ Shading/
|
||||
│ │ └─ BlinnPhongShader.h/.cpp # 着色(预留)
|
||||
│ ├─ Platform/ # 当前显示后端适配,后续归入 Gfx/Platform
|
||||
│ ├─ Core/ # FrameBuffer、DepthBuffer 等,后续归入 Gfx/Core
|
||||
│ ├─ Math/ # 当前 float 数学类型,后续补定点数并归入 Gfx/Math
|
||||
│ ├─ Rasterizer/ # 当前软光栅化代码,后续归入 Gfx/Draw2D 或 Gfx/Rasterizer
|
||||
│ ├─ RenderData/ # Color、Triangle 等基础渲染数据
|
||||
│ ├─ Scene/ # 当前 3D demo 场景数据
|
||||
│ ├─ Asset/ # 资源加载预留
|
||||
│ ├─ Shading/ # 着色预留
|
||||
│ ├─ test_fb.cpp # 独立 fb 测试(最小示例)
|
||||
│ └─ main.cpp
|
||||
│ └─ main.cpp # 当前 demo 入口,后续拆成 App 主循环
|
||||
├─ docs/
|
||||
│ ├─ DEVELOPMENT_GUIDELINES.md # IMX6U 性能红线
|
||||
│ └─ APP_AND_GFX_ARCHITECTURE.md # 应用层与图形库分层
|
||||
├─ CMakeLists.txt
|
||||
└─ README.md
|
||||
```
|
||||
|
||||
目标布局见 `docs/APP_AND_GFX_ARCHITECTURE.md`:后续会收敛为 `src/Gfx`、`src/Apps/Launcher`、`src/Apps/GameA`、`src/Apps/GameB`、`src/Shared`。
|
||||
|
||||
## 模块说明
|
||||
|
||||
### Core
|
||||
@@ -167,8 +196,8 @@ IMX6U-Game/
|
||||
|
||||
### Platform
|
||||
- **IDisplay**:显示后端抽象,解耦渲染与输出
|
||||
- **SDLDisplay**:PC 端用 SDL2 窗口实时查看效果
|
||||
- **FBDisplay**:ARM 端直接写 `/dev/fb0`
|
||||
- **SDLDisplay**:SDL2 后端,PC 调试和 IMX6U SDL2 目标路径共用这一类适配思想
|
||||
- **FBDisplay**:`/dev/fb0` 对照后端,用于极简显示通路验证
|
||||
|
||||
## 当前状态与后续
|
||||
|
||||
@@ -180,13 +209,13 @@ IMX6U-Game/
|
||||
|
||||
**待完成(按优先级):**
|
||||
1. FrameBuffer 性能优化(`memset` 清屏、去掉 `at()`、定点数/NEON)
|
||||
2. 输入抽象(键盘/触摸屏 evdev)
|
||||
3. 纹理贴图
|
||||
4. 2D 游戏层封装(Sprite、Tilemap)
|
||||
5. OBJ 模型加载与完整光照
|
||||
2. 应用层拆分(Launcher / GameA / GameB / Shared)和统一 `IApp` 主循环
|
||||
3. SDL2 输入抽象(键盘/触摸/按键状态快照)
|
||||
4. Gfx 基础 2D 绘制接口(矩形、四边形、Sprite、Tilemap)
|
||||
5. 纹理贴图、OBJ 模型加载与完整光照
|
||||
|
||||
## 说明
|
||||
|
||||
- 代码标准:**C++11**,确保兼容嵌入式老工具链
|
||||
- `test_fb.cpp` 是一个完全独立的 Linux framebuffer 最小测试,不依赖项目其他代码,用于快速验证板子显示通路
|
||||
- Windows 和 Linux x86 版本共享 `SDLDisplay`,ARM 版本单独使用 `FBDisplay`
|
||||
- Windows、Linux x86 和目标板 SDL2 路径共享 `SDLDisplay` 适配思想;`FBDisplay` 保留为 framebuffer 对照后端
|
||||
|
||||
Reference in New Issue
Block a user