IMX6U-Game/README.md

193 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# IMX6U-Game
一个从 CPU 软光栅化渲染器向嵌入式游戏图形库迁移的项目。
核心目标是在 IMX6UARM Cortex-A7无 GPU 或极弱 GPU上运行纯 CPU 渲染的 2D/3D 图形。为此,代码保持 C++11 兼容显示后端可切换SDL2 窗口 vs Linux Framebuffer以支持跨平台开发和嵌入式部署。
## 编译目标与验证目的
本项目支持三套编译目标,分别对应开发流程的不同阶段:
| 目标平台 | 显示后端 | 验证目的 |
|---------|---------|---------|
| Windows (x86/x64) | SDL2 窗口 | 验证渲染逻辑、算法正确性、快速迭代调试 |
| Linux x86_64 | SDL2 窗口 | 验证 Linux 兼容性、CMake 构建、SDL2 系统依赖 |
| ARM Linux (交叉编译) | `/dev/fb0` 直接写屏 | 最终在 IMX6U 开发板上运行的版本 |
**为什么分三套?**
- **Windows 编译**:开发主力机通常是 Windows有 IDE 调试、有图形窗口,渲染算法对不对一眼就能看到。这个阶段完全不关心嵌入式细节。
- **Linux x86 编译**:验证代码在 GCC/Clang 下有无警告、CMake 配置是否跨平台、系统 SDL2 依赖是否正确。很多嵌入式工具链的问题在 x86 Linux 上就能提前暴露。
- **ARM 交叉编译**:最终在 IMX6U 上跑。这个版本去掉 SDL2直接 mmap `/dev/fb0` 写屏,减少依赖和内存开销。
## 构建说明
### 通用前置
```bash
# 克隆仓库后,确保子目录完整
cd IMX6U-Game
```
### WindowsVisual Studio / MSVC
仓库已自带 SDL2 开发库(`libs/Win/SDL2`),无需额外安装。
```bash
cmake -B build-win .
cmake --build build-win --config Release
```
运行:
```bash
./build-win/Release/IMX6U-Game.exe
```
### Linux x86_64Ubuntu / WSL2
需要系统 SDL2
```bash
sudo apt-get install libsdl2-dev cmake g++
```
构建:
```bash
cmake -B build-linux .
cmake --build build-linux
```
运行:
```bash
./build-linux/IMX6U-Game
```
### ARM 交叉编译IMX6U
需要交叉编译工具链:
```bash
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
```
构建(启用 Framebuffer 后端):
```bash
cmake -B build-arm \
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-linux-gnueabihf.cmake \
-DUSE_FRAMEBUFFER=ON .
cmake --build build-arm
```
部署到开发板:
```bash
scp build-arm/IMX6U-Game root@imx6u:/tmp/
```
板子上运行(需要 root 权限访问 `/dev/fb0`
```bash
sudo /tmp/IMX6U-Game
```
ARM 版本启动后会打印 framebuffer 参数分辨率、bpp、像素格式。按 `q` 键或 `Ctrl+C` 退出。
## 显示后端架构
显示层通过抽象接口 `Platform::IDisplay` 与渲染逻辑解耦:
```
┌──────────────────────────────────────┐
│ 游戏/渲染逻辑Camera、Rasterizer 等) │
├──────────────────────────────────────┤
│ Core::FrameBufferCPU 颜色缓冲区) │
├──────────────────────────────────────┤
│ Platform::IDisplay │
│ - SDLDisplay : SDL2 窗口PC
│ - FBDisplay : /dev/fb0ARM
└──────────────────────────────────────┘
```
切换后端不需要修改任何渲染代码,只需要在 CMake 配置时开关 `USE_FRAMEBUFFER`
## 目录结构
```text
IMX6U-Game/
├─ cmake/
│ └─ toolchain-arm-linux-gnueabihf.cmake # ARM 交叉编译工具链
├─ libs/
│ └─ Win/
│ ├─ 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 # 着色(预留)
│ ├─ test_fb.cpp # 独立 fb 测试(最小示例)
│ └─ main.cpp
├─ CMakeLists.txt
└─ README.md
```
## 模块说明
### Core
- **FrameBuffer**CPU 侧颜色缓冲,渲染结果先写在这里
- **DepthBuffer**:深度测试用 Z-buffer
### Math
- 通用数学类型:`Vector2/3/4`、`Matrix4x4`
- 纯头文件实现,无动态分配
### Rasterizer
- **Rasterizer**Bresenham 线段光栅化
- **TriangleRasterizer**:扫描线三角形填充 + 深度测试
### Platform
- **IDisplay**:显示后端抽象,解耦渲染与输出
- **SDLDisplay**PC 端用 SDL2 窗口实时查看效果
- **FBDisplay**ARM 端直接写 `/dev/fb0`
## 当前状态与后续
**已完成:**
- 可旋转立方体的 3D 渲染MVP 变换、背面剔除、扫描线填充、深度测试)
- 双平台显示后端SDL2 / Framebuffer
- C++11 兼容代码
- CMake 跨平台构建
**待完成(按优先级):**
1. FrameBuffer 性能优化(`memset` 清屏、去掉 `at()`、定点数/NEON
2. 输入抽象(键盘/触摸屏 evdev
3. 纹理贴图
4. 2D 游戏层封装Sprite、Tilemap
5. OBJ 模型加载与完整光照
## 说明
- 代码标准:**C++11**,确保兼容嵌入式老工具链
- `test_fb.cpp` 是一个完全独立的 Linux framebuffer 最小测试,不依赖项目其他代码,用于快速验证板子显示通路
- Windows 和 Linux x86 版本共享 `SDLDisplay`ARM 版本单独使用 `FBDisplay`