加入 SpriteRegion 与基础 Tilemap 绘制
DrawContext 现在支持从 atlas 子区域绘制 SpriteRegion,并在 draw_sprite_ex 中加入屏幕裁剪,避免边缘 sprite 逐像素依赖 FrameBuffer 越界保护。新增基础 Tilemap 数据结构和 draw_tilemap,按视口可见范围遍历 tile,并在视口边缘进行像素级裁剪,支持 camera 像素级滚动时显示半个 tile。 Demo 增加小型滚动 tilemap 测试,复用现有测试 sprite 作为单 tile atlas。文档同步记录 SpriteRegion、Tilemap、viewport 裁剪语义和后续优化方向。 Constraint: IMX6U 热路径应避免全地图扫描和运行时资源解码 Constraint: 当前 tilemap 先保持单 atlas、固定 tile 尺寸的简单模型 Rejected: 直接每帧遍历整张 tilemap | 大地图上会浪费 CPU Rejected: 立即引入复杂地图资源系统 | 当前阶段只需要验证绘制链路 Confidence: high Scope-risk: moderate Directive: 扩展 Tilemap 时保持 tile 范围遍历 + 像素级边缘裁剪的语义 Tested: cmake --build build-win --config Release Not-tested: 尚未在 IMX6U 真机上验证 framebuffer/SDL 后端性能
This commit is contained in:
@@ -52,7 +52,7 @@ IMX6U-Game/
|
||||
职责:
|
||||
|
||||
- 管理 framebuffer、depthbuffer、渲染上下文。
|
||||
- 提供基础绘制接口:点、线、矩形、四边形、三角形、sprite、tile、简单文本等。
|
||||
- 提供基础绘制接口:点、线、矩形、四边形、三角形、sprite、SpriteRegion、tilemap、简单文本等。
|
||||
- 提供颜色、矩形、定点数、纹理、裁剪区域等基础数据结构。
|
||||
- 封装 SDL2 / framebuffer 显示提交、输入轮询、时间源。
|
||||
- 使用离线转换后的紧凑资源数据(例如 PNG 转头文件、bitmap font atlas),运行时不直接依赖 PNG/TTF 解码。
|
||||
@@ -186,16 +186,20 @@ namespace Gfx
|
||||
void draw_quad(PointI p0, PointI p1, PointI p2, PointI p3, Color32 color);
|
||||
void fill_quad(PointI p0, PointI p1, PointI p2, PointI p3, Color32 color);
|
||||
void draw_sprite(int32_t x, int32_t y, const RenderData::Image& image);
|
||||
void draw_sprite_region(int32_t x, int32_t y,
|
||||
const RenderData::SpriteRegion& region);
|
||||
void draw_text(const RenderData::BitmapFont& font, int32_t x, int32_t y,
|
||||
RenderData::Color color, const char* text);
|
||||
void draw_tilemap(const RenderData::Tilemap& tilemap,
|
||||
int32_t screen_x, int32_t screen_y,
|
||||
int32_t viewport_w, int32_t viewport_h,
|
||||
int32_t camera_x, int32_t camera_y);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
后续再扩展:
|
||||
|
||||
- `draw_sprite_region`
|
||||
- `draw_tilemap`
|
||||
- `set_clip_rect`
|
||||
- `set_camera_2d`
|
||||
- `batch sprite/tile`
|
||||
@@ -218,7 +222,7 @@ namespace Gfx
|
||||
|
||||
1. ~~先抽出统一 `IApp` 和 `AppManager`,让当前 demo 成为一个 app。~~
|
||||
2. ~~把 SDL2 初始化、输入、present 固定在平台层,应用层不直接碰 SDL。~~
|
||||
3. ~~建立 `Gfx::DrawContext`,先封装 clear、pixel、line、rect、quad。~~ **已完成**(`Gfx::DrawContext` 封装了 clear、draw_line、draw_triangle、draw_sprite、draw_text、present)
|
||||
3. ~~建立 `Gfx::DrawContext`,先封装 clear、pixel、line、rect、quad。~~ **已完成**(`Gfx::DrawContext` 封装了 clear、draw_line、draw_triangle、draw_sprite、draw_sprite_region、draw_text、draw_tilemap、present)
|
||||
4. ~~底层代码迁移到 `src/Gfx/`,Demo 入口迁移到 `src/Apps/Demo/`。~~ **已完成**
|
||||
5. 新增 Launcher app,只做最小菜单和应用切换。
|
||||
6. 新增 GameA/GameB 空壳,验证三应用切换。
|
||||
@@ -241,3 +245,15 @@ namespace Gfx
|
||||
- `tools/gen_font_atlas.py` 将共享像素字体转为 ASCII bitmap atlas,并输出同名 PNG 预览和 C++ 头文件。
|
||||
- 生成头文件、源 PNG/TTF 和转换脚本应一起纳入仓库,保证资源可追溯、可再生成。
|
||||
- 生成数据目前面向简单直接的调试/小型游戏资源;后续如果资源体积增长,应再评估 1-bit/8-bit mask、RLE 或自定义资源包格式。
|
||||
|
||||
## 10. SpriteRegion 与 Tilemap 约定
|
||||
|
||||
- `RenderData::SpriteRegion` 只描述某张 atlas 中的子区域,不拥有像素数据;它通过 `const Image* atlas` 引用源图。
|
||||
- `DrawContext::draw_sprite_ex` 是底层 sprite 绘制入口,负责源区域检查、目标屏幕裁剪、scale 和 flip;`draw_sprite_region` 系列只是对 atlas 子区域的语义包装。
|
||||
- `RenderData::Tilemap` 使用 `uint16_t` tile id 保存地图网格,`Tilemap::EmptyTile` (`0xFFFF`) 表示空 tile。
|
||||
- `Tilemap` 当前只支持一个 atlas、固定 tile 宽高和固定 `atlas_columns`;tile id 通过 `tile_id % atlas_columns` / `tile_id / atlas_columns` 映射到 atlas 中的源区域。
|
||||
- `DrawContext::draw_tilemap` 的裁剪分两层:
|
||||
- tilemap 层按 tile 计算需要尝试绘制的可见范围;
|
||||
- sprite 层按像素裁剪每个 tile,支持 camera 像素级滚动时显示半个 tile。
|
||||
- 带 `viewport_w` / `viewport_h` 的 `draw_tilemap` 重载用于子视口绘制,`screen_x` / `screen_y` 是视口左上角;旧重载默认视口延伸到 framebuffer 右下角。
|
||||
- 当前实现优先保证清晰语义和可验证行为;后续性能优化可增加 tile region 查表、不透明 tile 行拷贝、chunk/dirty rect 或专用 tile 快路径。
|
||||
|
||||
@@ -121,7 +121,8 @@
|
||||
- `tools/gen_font_atlas.py`:像素字体 TTF -> ASCII bitmap font atlas/header。
|
||||
- 生成像素格式统一为 `(R << 24) | (G << 16) | (B << 8) | A`,与 `RenderData::Color::to_rgba()` 和 `Core::FrameBuffer` 当前格式保持一致。
|
||||
- 源资源、生成脚本和生成头文件应同时提交,保证资源可追溯、可复现。
|
||||
- 运行时绘制 sprite/font 时只做裁剪、透明判断、颜色替换或必要的像素拷贝;不要在绘制函数内做文件 IO、图片解码、字体栅格化或动态分配。
|
||||
- 运行时绘制 sprite/font/tilemap 时只做裁剪、透明判断、颜色替换、tile id 查表或必要的像素拷贝;不要在绘制函数内做文件 IO、图片解码、字体栅格化或动态分配。
|
||||
- Tilemap 绘制应按视口可见范围遍历 tile,不能每帧无条件扫描整张地图;视口边缘允许通过 sprite 像素裁剪显示半个 tile。
|
||||
- 字体资源当前走像素风路径,生成端会把 alpha 阈值化为 0/255;如果未来要恢复抗锯齿字体,必须同步设计 framebuffer alpha blending,而不能只在绘制端把所有非 0 alpha 当作实心像素。
|
||||
|
||||
## 9. 新代码提交前检查清单
|
||||
|
||||
Reference in New Issue
Block a user