我有一个OpenGL应用程序,我想在其中使用Skia渲染文本。具体来说,我想将文本渲染为纹理,然后在我的代码中使用该纹理。
<Setup OpenGL>
auto context = GrContext::MakeGL();
auto info = SkImageInfo::MakeN32Premul(width, height);
auto surface = sk_sp(SkSurface::MakeRenderTarget(context.get(), SkBudgeted::kNo, info));
auto canvas = surface->getCanvas();
auto text_color = SkColor4f::FromColor(SkColorSetARGB(255, 0, 0, 255)); // text color is blue.
SkPaint paint2(text_color);
canvas->clear(SkColorSetARGB(255,0,255,0)); // clear with green color
auto text_blob = SkTextBlob::MakeFromString("Hello, World", SkFont(nullptr, 55));
canvas->drawTextBlob(text_blob.get(), 300, 100, paint2);
surface->flush(SkSurface::BackendSurfaceAccess::kPresent, GrFlushInfo());
auto texture = surface->getBackendTexture(SkSurface::kFlushRead_BackendHandleAccess);
GrGLTextureInfo texture_info;
if (!texture.isValid()) {
log_error("missing texture");
exit(1);
}
if (!texture.getGLTextureInfo(&texture_info)) {
log_error("missing texture info");
exit(1);
}
<Use texture_info.fID for rendering>
问题在于所得到的纹理为绿色,因此我知道画布已正确清除,但没有文本出现。
我本以为在渲染文本时犯了一个错误,但是如果我拍摄表面快照并将其保存到图像中,则文本确实会出现在保存的图像上。
auto snapI = surface->makeImageSnapshot();
auto pngImage = snapI->encodeToData();
SkFILEWStream out("foo.png");
(void)out.write(pngImage->data(), pngImage->size());
这将导致绿色图像上写有蓝色的“ Hello,World”。我知道我可以使用SkBitmap或将SkImage加载到纹理,但这是一个实时应用程序,如果可以避免,我不想承担CPU同步的成本。
似乎文本没有渲染到后端纹理。这应该发生吗?我想念什么?