opengl - 在 Skia 或 SkiaSharp 中使用 GPU 加速进行无头屏幕外渲染
问题描述
我在 .NET 5(更好的跨平台)中使用 SkiaSharp 进行屏幕外渲染,并且需要 GPU 加速。注意: C++ 版本的 Skia 也是可以使用的。
开发是在 Windows 上进行的。我没有使用 SkiaSharp.View,因为该程序是一个命令行工具。我刚刚创建了一个隐藏窗口。该窗口是使用 OpenTk 创建的,因为我在 GitHub 上看到了 Matthew 的示例,并且我将窗口的上下文设置为默认上下文。然后,我创建了一个帧缓冲区和渲染缓冲区,如本SO 解决方案中所述。最后,我尝试创建表面,但只从SKSurface.Create
.
// GL below is all OpenTK.Graphics.ES30.GL!
var window = new GameWindow(
GameWindowSettings.Default,
new NativeWindowSettings {
Size = new Vector2i(1, 1),
StartVisible = false,
Flags = OpenTK.Windowing.Common.ContextFlags.Offscreen,
APIVersion = new Version(3, 2) });
window.Context.MakeCurrent();
var gpuInterface = GRGlInterface.Create(); // Q: Is this interface correctly linked to the one OpenTk uses?
var grContext = GRContext.CreateGl(gpuInterface);
uint fbo = (uint)GL.GenFramebuffer();
uint rbo = (uint)GL.GenRenderbuffer();
GL.BindRenderbuffer(OpenTK.Graphics.ES30.RenderbufferTarget.Renderbuffer, rbo);
GL.RenderbufferStorage(OpenTK.Graphics.ES30.RenderbufferTarget.Renderbuffer, OpenTK.Graphics.ES30.RenderbufferInternalFormat.Rgba8, 800, 700);
GL.BindFramebuffer(OpenTK.Graphics.ES30.FramebufferTarget.DrawFramebuffer, fbo);
GL.FramebufferRenderbuffer(
OpenTK.Graphics.ES30.FramebufferTarget.DrawFramebuffer,
OpenTK.Graphics.ES30.FramebufferAttachment.ColorAttachment0,
OpenTK.Graphics.ES30.RenderbufferTarget.Renderbuffer,
rbo);
var sampleCounts = GL.GetInteger(OpenTK.Graphics.ES30.GetPName.Samples);
int stencilBits;
GL.GetFramebufferAttachmentParameter(
OpenTK.Graphics.ES30.FramebufferTarget.DrawFramebuffer,
OpenTK.Graphics.ES30.FramebufferAttachment.ColorAttachment0,
OpenTK.Graphics.ES30.FramebufferParameterName.FramebufferAttachmentStencilSize,
out stencilBits);
var target = new GRBackendRenderTarget(800, 700, sampleCounts, stencilBits, new GRGlFramebufferInfo(fbo, SKColorType.Bgra8888.ToGlSizedFormat()));
var surface = SKSurface.Create(grContext, target, GRSurfaceOrigin.TopLeft, SKColorType.Bgra8888);
// surface == null ?
此外,使用GL.GetError
.
任何帮助,将不胜感激。
解决方案
好的,我终于让它工作了。
关键是SkSurface和 RBO之间的像素格式不匹配。GRBackendRenderTarget
我不知道为什么OpenTk.Graphics.ES30.RenderbufferInternalFormat
不包含“Bgra8888”。因此SKColorType.Bgra8888
后者导致了问题。
由于RenderbufferInternalFormat
枚举中没有 BGRA,我不得不将整个东西切换到 RGBA,所以最后几行改为:
var target = new GRBackendRenderTarget(800, 700, 0, 0, new GRGlFramebufferInfo(0, SKColorType.Rgba8888.ToGlSizedFormat()));
var surface = SKSurface.Create(grContext, target, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888);
它有效。
但我想知道在创建 RBO 存储时如何切换到 Bgra。
推荐阅读
- c# - 如何在 EF6 和 asp.net core 3 之间建立连接
- java - 如何记录 doPost() 方法?
- javascript - Keycloak - 如何禁用两个(Angular)客户端应用程序之间的共享会话?
- ios - Swift 版本更新的正确语义版本控制更改
- django - 在 django 中访问不同用户的信息
- node.js - nodejs 客户端 s3 getSignedUrl 提供使用 AWS KMS 托管密钥指定服务器端加密的请求需要 AWS 签名版本 4
- python-3.x - 如何根据日期差异比较两个数据框
- vue.js - 在 vue-multiselect 中测试 vuex 操作时调用了 Jest 预期的模拟函数
- javascript - react-redux 应用中加载中断的情况如何处理
- angular - 角度嵌套路由与页面