问题描述
我正在 .NET 5 中使用 SkiaSharp 进行离屏渲染(更好的跨平台),并且需要 GPU 加速。 注意:Skia 的 C++ 版本也可以接受,如果它有效。
开发是在 Windows 上进行的。我没有使用 SkiaSharp.View,因为该程序是一个命令行工具。我刚刚创建了一个隐藏窗口。该窗口是使用 OpenTk 创建的,因为我在 GitHub 上看到了 Matthew 的示例,并且我将窗口的上下文设为默认上下文。然后,我创建了一个帧缓冲区和渲染缓冲区,如本 SO solution 中所述。最后,我尝试创建表面,但只从 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.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 的 GRBackendRenderTarget
和 RBO 之间的像素格式不匹配。我不知道为什么 OpenTk.Graphics.ES30.RenderbufferInternalFormat
不包含“Bgra8888”。因此 SKColorType.Bgra8888
后来引起了问题。
由于 RenderbufferInternalFormat
枚举中没有 BGRA,我不得不将整个内容切换为 RGBA,因此最后几行更改为:
var target = new GRBackendRenderTarget(800,700,new GRGlFramebufferInfo(0,SKColorType.Rgba8888.ToGlSizedFormat()));
var surface = SKSurface.Create(grContext,target,GRSurfaceOrigin.TopLeft,SKColorType.Rgba8888);
它有效。
但是我想知道如何在创建 RBO 存储时切换到 Bgra。