入门
本指南会带你克隆 runtime、编译它,并使用真实的 GPU backend 把一个 .riv 文件显示到屏幕上。
前置条件
- 支持 C++17 的较新版本 clang 或 MSVC。
- git —— 构建脚本会自行克隆并引导
premake5。 - 与你选择的 renderer 对应的平台 SDK,例如 D3D 需要 Windows SDK,Metal 需要 Xcode,Vulkan 需要 Vulkan SDK 等。
备注
Rive 使用 clang 的 vector builtins。使用 clang 构建时,请尽量使用可用的最新版本;较旧工具链可能无法编译 renderer。
1. 克隆并构建 Runtime
git clone https://github.com/rive-app/rive-runtime.git
cd rive-runtime/renderer
runtime 提供了构建辅助脚本 build/build_rive.sh(Windows 上有 PowerShell 包装脚本 build_rive.ps1)。首次运行时,它会安装固定版本的 premake5,并根据平台分发到合适的构建系统(macOS/Linux 上为 gmake2,Windows 上为 MSBuild 等)。
macOS / Linux:
../build/build_rive.sh release
Windows:
..\build\build_rive.ps1 release
常见变体:
build_rive.sh(不带参数)—— 为宿主平台构建 debug 版本。build_rive.sh release clean—— clean rebuild。build_rive.sh ninja release—— 使用 Ninja 而不是 make。build_rive.sh ios release/build_rive.sh android release—— 交叉编译。
构建产物位于 out/release/(或 out/debug/)。你需要链接 librive.a(Windows 上为 rive.lib),以及每个 backend 对应的 renderer 库,例如 librive_pls_renderer.a。
2. 将 Headers 添加到项目
公共 include 根目录如下:
rive-runtime/include # rive-cpp core
rive-runtime/renderer/include # GPU renderer(仅当使用 rive::gpu 时需要)
最小 CMake 片段:
target_include_directories(my_app PRIVATE
${RIVE}/include
${RIVE}/renderer/include
)
target_link_libraries(my_app PRIVATE
rive
rive_pls_renderer
# 加上你的 backend,例如 Windows 上的 d3d11、dxgi
)
3. 加载 .riv 文件
#include "rive/file.hpp"
#include <fstream>
#include <iterator>
#include <vector>
using namespace rive;
std::vector<uint8_t> readFile(const char* path) {
std::ifstream in(path, std::ios::binary);
return {std::istreambuf_iterator<char>(in), {}};
}
// `factory` 是 Factory*,通常是你的 RenderContext(它继承 Factory)。
auto bytes = readFile("hero.riv");
ImportResult result;
rcp<File> file = File::import(bytes, factory, &result);
if (!file || result != ImportResult::success) {
// 文件损坏或版本不支持。
return;
}
4. 选择 Artboard 和 State Machine
#include "rive/artboard.hpp"
#include "rive/animation/state_machine_instance.hpp"
std::unique_ptr<ArtboardInstance> artboard = file->artboardDefault();
std::unique_ptr<StateMachineInstance> sm = artboard->defaultStateMachine();
if (!sm && artboard->stateMachineCount() > 0) {
sm = artboard->stateMachineAt(0);
}
5. Advance 与 Draw
渲染循环每帧包含三个阶段:advance、draw、flush。
#include "rive/renderer/rive_renderer.hpp"
#include "rive/renderer/render_context.hpp"
void renderFrame(float dt) {
sm->advanceAndApply(dt);
RenderContext::FrameDescriptor frame{};
frame.renderTargetWidth = windowWidth;
frame.renderTargetHeight = windowHeight;
frame.clearColor = 0xff202020; // ARGB
renderContext->beginFrame(frame);
RiveRenderer renderer(renderContext.get());
renderer.save();
renderer.align(Fit::contain,
Alignment::center,
AABB(0, 0, windowWidth, windowHeight),
artboard->bounds());
sm->draw(&renderer);
renderer.restore();
RenderContext::FlushResources flush{};
flush.renderTarget = renderTarget.get();
renderContext->flush(flush);
}
提示
对 advanceAndApply 使用固定时间步长(例如 1/120 秒),并累积真实经过时间。固定步长下状态机是确定性的,可在不同机器和帧率上复现播放结果。参见 Rendering Loop。
6. 转发输入
将指针事件路由回状态机,才能让 listener 与 hit-testing 正常工作:
#include "rive/renderer.hpp"
Mat2D align = computeAlignment(Fit::contain,
Alignment::center,
AABB(0, 0, w, h),
artboard->bounds());
Vec2D toArtboard(int x, int y) {
return align.invertOrIdentity() * Vec2D{(float)x, (float)y};
}
sm->pointerMove(toArtboard(mouseX, mouseY));
sm->pointerDown(toArtboard(mouseX, mouseY));
sm->pointerUp(toArtboard(mouseX, mouseY));
下一步
- Renderers:接入平台 GPU backend。
- State Machines:推进状态机、转发指针事件并响应状态变化。