加入离线 sprite 与位图字体转换流程

Demo 现在通过生成的 C++ 头文件使用测试 sprite 和像素风 bitmap font,避免在运行时解码 PNG/TTF。同步补充资源转换文档,明确源资源、生成脚本和生成头文件需要一起提交,保证后续可追溯和可重新生成。
Constraint: IMX6U 运行时路径应尽量轻量,避免图片/字体解码开销
Constraint: 生成像素沿用当前 framebuffer 的 uint32_t RGBA 格式
Rejected: 运行时加载 PNG/TTF | 会增加解码依赖和运行时成本
Confidence: high
Scope-risk: moderate
Directive: 修改 sprite 或字体时,必须同步提交源资源、转换脚本和生成头文件
Tested: cmake -B build-win .; cmake --build build-win --config Release
Not-tested: 尚未在 IMX6U 真机上验证 ARM framebuffer/SDL 后端
This commit is contained in:
SepComet
2026-06-06 23:55:27 +08:00
parent 3e735e27b0
commit 213fa7e961
17 changed files with 1968 additions and 16 deletions
+66 -3
View File
@@ -57,7 +57,7 @@ cd IMX6U-Game
仓库已自带 SDL2 开发库(`libs/Win/SDL2`),无需额外安装。
```bash
cmake -B build-win .m
cmake -B build-win .
cmake --build build-win --config Release
```
@@ -128,6 +128,61 @@ scp build-arm-fb/IMX6U-Game root@imx6u:/tmp/
Framebuffer 对照版本可能需要 root 权限访问 `/dev/fb0`。SDL2 版本是否需要额外环境变量或权限,取决于目标板 SDL2 视频驱动和显示栈配置。
## 资源转换工具
项目运行时不依赖 PNG/TTF 解码库。图片和字体资源在离线阶段转换成 C++ 头文件,运行时直接以 `uint32_t` 数组访问,像素格式统一为:
```text
(R << 24) | (G << 16) | (B << 8) | A
```
当前转换工具位于 `tools/`,需要 Python 和 Pillow:
```bash
pip install pillow
```
### Sprite 转换
普通 PNG sprite 使用 `tools/png_to_header.py` 转换:
```bash
python tools/png_to_header.py assets/sprite/test_sprite.png assets/sprite/test_sprite.h test_sprite
```
生成的头文件会包含:
```cpp
test_sprite_width
test_sprite_height
test_sprite_pixels
```
透明像素仍保留 alpha;当前 demo 通过 `RenderData::Image(..., 0x00000000)` 把全透明像素作为 color key 跳过。
### Bitmap Font 转换
像素字体图集使用 `tools/gen_font_atlas.py` 生成:
```bash
python tools/gen_font_atlas.py assets/font
```
脚本默认优先读取:
```text
assets/font/ndrtyyl-prqyys-undertale-hebrew-uppercase.ttf
```
输出:
```text
assets/font/font_atlas.png
assets/font/font_atlas.h
```
字体范围为 ASCII 32~126,按 16 列排列。生成端会把字体 alpha 阈值化为 0/255,以匹配当前 `DrawContext::draw_text` 的像素风路径;运行时只把非透明像素替换成调用方指定颜色。
## 显示后端架构
显示层通过抽象接口 `Platform::IDisplay` 与渲染逻辑解耦。后续应用层和图形库拆分后,`Platform` 会收敛到 `Gfx` 的平台适配层:
@@ -158,6 +213,12 @@ IMX6U-Game/
│ └─ Win/
│ ├─ SDL2/ # Windows 用 SDL2 库(头文件 + lib + DLL)
│ └─ SDL_image/ # SDL2_image 库(头文件 + lib + DLL)
├─ assets/
│ ├─ font/ # 像素字体源文件、font_atlas.png、font_atlas.h
│ └─ sprite/ # PNG sprite 源文件及转换后的头文件
├─ tools/
│ ├─ gen_font_atlas.py # TTF -> bitmap font atlas/header
│ └─ png_to_header.py # PNG -> uint32_t RGBA header
├─ src/
│ ├─ Gfx/ # 底层图形库:可复用、无具体游戏规则
│ │ ├─ Draw2D/ # DrawContext 统一绘制入口
@@ -183,7 +244,7 @@ IMX6U-Game/
## 模块说明
### Draw2D
- **DrawContext**:统一绘制入口,封装 FrameBuffer、DepthBuffer、Rasterizer、TriangleRasterizer,对外提供 `clear`、`draw_line`、`draw_triangle`、`present` 接口
- **DrawContext**:统一绘制入口,封装 FrameBuffer、DepthBuffer、Rasterizer、TriangleRasterizer,对外提供 `clear`、`draw_line`、`draw_triangle`、`draw_sprite`、`draw_text`、`present` 接口
### Core
- **FrameBuffer**:CPU 侧颜色缓冲,渲染结果先写在这里
@@ -207,6 +268,8 @@ IMX6U-Game/
**已完成:**
- 可旋转立方体的 3D 渲染(MVP 变换、背面剔除、扫描线填充、深度测试)
- 双平台显示后端(SDL2 / Framebuffer)
- 离线资源转换工具:PNG sprite -> C++ 头文件,像素字体 -> bitmap atlas/header
- 基础 2D sprite 与 bitmap font 文本绘制,当前 demo 显示 FPS 文本和测试 sprite
- Gfx 目录规范化,代码收敛到 `src/Gfx/`
- `Gfx::DrawContext` 统一绘制入口,封装现有绘制能力
- C++11 兼容代码
@@ -216,7 +279,7 @@ IMX6U-Game/
1. FrameBuffer 性能优化(`memset` 清屏、去掉 `at()`、定点数/NEON)
2. 应用层拆分(Launcher / GameA / GameB / Shared)和统一 `IApp` 主循环
3. SDL2 输入抽象(键盘/触摸/按键状态快照)
4. Gfx 基础 2D 绘制接口(矩形、四边形、Sprite、Tilemap)
4. Gfx 基础 2D 绘制接口(矩形、四边形、Tilemap,继续完善 Sprite/Text 的裁剪和批处理)
5. 纹理贴图、OBJ 模型加载与完整光照
## 说明