Hello2D 示例
通过一个最小的端到端示例,演示 TGFX 的核心渲染流程——创建 Device、获取 Context、创建 Surface、获取 Canvas、绑定 Shader 绘图、提交渲染并将结果保存为图片——在 5 分钟内看到你的第一个渲染结果。
渲染流程概览
完整示例代码
以下示例展示了如何用 TGFX 绘制一个锥形渐变圆角矩形并保存为 PNG 图片。代码分为 8 个步骤:
- 创建 Device — 创建 GPU 设备(此处使用 OpenGL 后端),作为与 GPU 交互的入口。
- 获取 Context — 从 Device 锁定 GPU 上下文,后续所有渲染操作都通过此上下文进行。
- 创建 Surface — 在 GPU 上分配 720×720 的渲染目标,启用 4× MSAA 抗锯齿以获得平滑边缘。
- 获取 Canvas — 从 Surface 取得绘图接口,并清空画布为透明背景。
- 创建渐变着色器 — 构建 cyan → magenta → yellow → cyan 的锥形渐变,颜色沿角度方向均匀环绕。
- 配置画笔并绘制 — 将渐变着色器绑定到 Paint,在 50px 内边距区域内绘制 620×620 的圆角矩形。
- 提交渲染 — 调用
flushAndSubmit将所有绘制指令提交到 GPU 执行。 - 读取像素并保存 — 从 Surface 回读渲染结果,编码为 PNG 并写入文件。
#include <filesystem>
#include <fstream>
#include "tgfx/core/Bitmap.h"
#include "tgfx/core/Canvas.h"
#include "tgfx/core/Paint.h"
#include "tgfx/core/Rect.h"
#include "tgfx/core/Shader.h"
#include "tgfx/core/Surface.h"
#include "tgfx/gpu/opengl/GLDevice.h"
#include "tgfx/platform/Print.h"
using namespace tgfx;
static void SaveFile(const std::shared_ptr<Data>& data, const std::string& output) {
std::filesystem::path path = output;
std::filesystem::create_directories(path.parent_path());
std::ofstream out(path, std::ios::binary);
out.write(reinterpret_cast<const char*>(data->data()),
static_cast<std::streamsize>(data->size()));
out.close();
}
int main() {
// 步骤 1 — 创建 GPU 设备(使用 OpenGL 后端)。
auto device = GLDevice::Make();
if (device == nullptr) {
PrintError("Failed to create the GLDevice!");
return -1;
}
// 步骤 2 — 从 Device 锁定 GPU 上下文。
auto context = device->lockContext();
if (context == nullptr) {
PrintError("Failed to lock the Context!");
return -1;
}
// 步骤 3 — 创建 720x720 的 Surface,启用 4x MSAA 抗锯齿。
constexpr int SurfaceSize = 720;
constexpr int ContentSize = 620;
constexpr int Padding = (SurfaceSize - ContentSize) / 2;
auto surface = Surface::Make(context, SurfaceSize, SurfaceSize, false, 4);
if (surface == nullptr) {
PrintError("Failed to create the Surface!");
device->unlock();
return -1;
}
// 步骤 4 — 获取 Canvas 并清空画布。
auto canvas = surface->getCanvas();
canvas->clear();
// 步骤 5 — 构建锥形渐变着色器(cyan -> magenta -> yellow -> cyan)。
Color cyan = {0.0f, 1.0f, 1.0f, 1.0f};
Color magenta = {1.0f, 0.0f, 1.0f, 1.0f};
Color yellow = {1.0f, 1.0f, 0.0f, 1.0f};
auto shader = Shader::MakeConicGradient(
{ContentSize / 2.0f, ContentSize / 2.0f}, // 中心点
0, 360, // 角度范围
{cyan, magenta, yellow, cyan}, // 颜色循环
{} // 均匀分布
);
// 步骤 6 — 配置画笔并绘制圆角矩形(50px 内边距,20px 圆角半径)。
Paint paint = {};
paint.setStyle(PaintStyle::Fill);
paint.setShader(shader);
canvas->save();
canvas->translate(Padding, Padding);
canvas->drawRoundRect(Rect::MakeXYWH(0, 0, ContentSize, ContentSize), 20, 20, paint);
canvas->restore();
// 步骤 7 — 将所有绘制指令提交到 GPU 执行。
context->flushAndSubmit(true);
// 步骤 8 — 从 Surface 回读像素并保存为 PNG。
Bitmap bitmap = {};
bitmap.allocPixels(surface->width(), surface->height());
auto pixels = bitmap.lockPixels();
auto success = surface->readPixels(bitmap.info(), pixels);
bitmap.unlockPixels();
if (!success) {
PrintError("Failed to read pixels from Surface!");
device->unlock();
return -1;
}
auto data = bitmap.encode(EncodedFormat::PNG);
if (data == nullptr) {
PrintError("Failed to encode bitmap to PNG!");
device->unlock();
return -1;
}
SaveFile(data, "out/hello2d.png");
device->unlock();
PrintLog("Hello2D image saved to out/hello2d.png");
return 0;
}
API 速查
| 步骤 | API | 说明 |
|---|---|---|
| 创建 GPU 设备 | GLDevice::Make() | 创建 OpenGL 设备,返回 std::shared_ptr<GLDevice> |
| 锁定上下文 | device->lockContext() | 获取 GPU 上下文指针,使用完毕后需调用 device->unlock() 释放 |
| 创建渲染目标 | Surface::Make(context, w, h, alphaOnly, sampleCount) | 在 GPU 上分配画布,sampleCount > 1 启用多重采样抗锯齿 |
| 获取绘图接口 | surface->getCanvas() | 返回 Surface 持有的 Canvas,生命周期由 Surface 管理 |
| 清空画布 | canvas->clear() | 重置画布内容(无参数为透明背景) |
| 创建渐变 | Shader::MakeConicGradient(...) | 构建锥形渐变着色器,支持多色标与自定义位置 |
| 设置画笔 | paint.setShader(shader) | 将着色器绑定到画笔 |
| 绘制圆角矩形 | canvas->drawRoundRect(rect, rx, ry, paint) | rx / ry 分别为水平和垂直方向的圆角半径 |
| 提交到 GPU | context->flushAndSubmit(syncCpu) | 刷新并提交所有待处理的绘制指令 |
| 回读像素 | surface->readPixels(info, pixels) | 将 Surface 渲染结果读取到 CPU 内存 |
| 编码图片 | bitmap.encode(EncodedFormat::PNG) | 将位图编码为指定格式(PNG / JPEG / WebP) |
渐变类型
TGFX 通过 Shader 的静态工厂方法提供四种内置渐变:
| 类型 | 工厂方法 | 效果 |
|---|---|---|
| 线性渐变 | Shader::MakeLinearGradient(start, end, colors, positions) | 沿两点连线方向过渡 |
| 径向渐变 | Shader::MakeRadialGradient(center, radius, colors, positions) | 从圆心向外扩散 |
| 锥形渐变 | Shader::MakeConicGradient(center, startAngle, endAngle, colors, positions) | 沿角度方向环绕 |
| 菱形渐变 | Shader::MakeDiamondGradient(center, radius, colors, positions) | 从中心向菱形顶点扩散 |
效果预览
运行示例代码后,将渲染一个 cyan → magenta → yellow 锥形渐变的圆角矩形,与各平台 Hello2D Demo 的 ConicGradient 效果一致:

内置 Demo 案例
各平台 Hello2D 项目内置了以下示例,可通过触摸或点击切换:
| 案例 | 演示内容 |
|---|---|
| ConicGradient | 锥形渐变填充圆角矩形 |
| ImageWithMipmap | 带 Mipmap 多级过滤的图片渲染 |
| ImageWithShadow | 椭圆裁剪 + DropShadow 阴影效果 |
| Layer3DTree | 3D 透视变换与立方体动画 |
| RichText | 多字体混排富文本渲染 |
| SimpleLayerTree | 综合场景:渐变背景 + 圆角图片 + 文字 + 进度条 |
[!TIP] 更多 API 用法与高级特性请参考
test/目录下的测试用例。
