CPF C#跨平台UI框架,支持使用OpenGL来渲染,可以用来硬件加速播放视频或者显示3D模型
实现原理其实就是Skia用OpenGL后端,Skia里绑定GLView的OpenGL纹理,将纹理作为Skia的图像混合绘制。
在CPF里使用OpenGL,不能选择NetCore3.0和Net4,需要选择Netcore3.1以及之后的版本。
Nuget里安装最新版的CPF。另外安装Silk.net或者OpenTK来调用OpenGL绘制。
Program里需要开启GPU,设置 UseGPU = true
class Program { [STAThread] static void Main(string[] args) { Application.Initialize( (OperatingSystemType.Windows, new WindowsPlatform(), new SkiaDrawingFactory { UseGPU = true }) , (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = true })//如果需要支持Mac才需要 , (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = true })//如果需要支持Linux才需要 ); Application.Run(new Window2_1_Colors()); } }
界面上添加 CPF.Skia.GLView 控件,GLLoaded为GL加载完成事件,GLRender为GL绘制事件。OpenGL就在这两个事件里处理
Children.Add(new WindowFrame(this, new GLView { Width = "100%", Height = "100%", [nameof(GLView.GLLoaded)] = new CommandDescribe((s, e) => GLLoaded((GLView)s, (GLEventArgs)e)), [nameof(GLView.GLRender)] = new CommandDescribe((s, e) => GLRender((GLView)s, (GLEventArgs)e)), [nameof(GLView.MouseDown)] = new CommandDescribe((s, e) => MouseEvent((GLView)s, (MouseEventArgs)e)), [nameof(GLView.MouseUp)] = new CommandDescribe((s, e) => MouseEvent((GLView)s, (MouseEventArgs)e)), [nameof(GLView.MouseMove)] = new CommandDescribe((s, e) => MouseEvent((GLView)s, (MouseEventArgs)e)), }) { MaximizeBox = true });
Silk.Net初始化API
GL gl;//可以保存为全局的字段 void GLLoaded(GLView view, GLEventArgs args) { gl = GL.GetApi(args.Context.GetProcAddress); }
OpenTk初始化API
class Context : OpenTK.IBindingsContext {//定义API绑定的上下文 public IGlContext context; public IntPtr GetProcAddress(string procName) { return context.GetProcAddress(procName); } } void GLLoaded(GLView view, GLEventArgs args) {//初始化一次就行 GL.LoadBindings(new Context { context = args.Context }); }
在GLRender事件里绘制。默认情况下GLRender不会一直调用,因为绘制方式不是游戏那种实时刷新的。需要刷新的时候要主动调用Invalidate(),或者用定时器来实时调用Invalidate()。
void GLRender(GLView view, GLEventArgs args) { gl.Enable(GLEnum.DepthTest);//开启深度测试 gl.DepthMask(true); //其他绘制代码。。。。 //开启深度测试之后要关闭,否则会无法显示界面,同样的,如果开启了其他功能,绘制结束后记得关闭,否则可能影响界面绘制。因为和界面共享OpenGL的上下文。 gl.Disable(GLEnum.DepthTest); }