前言 這是一篇很水的文章,沒有任何技術含量,在 Github 已經有很多人對 Avalonia 的 OpenGL ES 支持進行了討論,但是我還是想寫一篇文章來記錄一下我是如何在 Avalonia 中使用 OpenGL ES 的。 介紹 在介紹 Avalonia 和 OpenGL ES 之前,我們先 ...
前言
這是一篇很水的文章,沒有任何技術含量,在 Github 已經有很多人對 Avalonia 的 OpenGL ES 支持進行了討論,但是我還是想寫一篇文章來記錄一下我是如何在 Avalonia 中使用 OpenGL ES 的。
介紹
在介紹 Avalonia 和 OpenGL ES 之前,我們先來瞭解一下什麼是 Avalonia 和 OpenGL ES 以及 Avalonia 是如何支持 OpenGL ES 的。
Angle 和 OpenGL ES
ANGLE 是一個開源的項目,它的目標是將 OpenGL ES 2.0、3.0 和 3.1 應用程式轉換為 Direct3D 11、Vulkan、Metal 和 OpenGL 3.0+ 應用程式。
ANGLE 通過將 OpenGL ES API 調用轉換為 Direct3D、Vulkan 或 Metal API 調用來實現這一目標。
ANGLE 也提供了一個實現 OpenGL ES 2.0、3.0 和 3.1 的庫,這樣就可以在不支持 OpenGL ES 的平臺上運行 OpenGL ES 應用程式。
以下是摘自 ANGLE 項目的介紹:
Level of OpenGL ES support via backing renderers
Direct3D 9 | Direct3D 11 | Desktop GL | GL ES | Vulkan | Metal | |
---|---|---|---|---|---|---|
OpenGL ES 2.0 | complete | complete | complete | complete | complete | complete |
OpenGL ES 3.0 | complete | complete | complete | complete | complete | |
OpenGL ES 3.1 | [incomplete][ES31OnD3D] | complete | complete | complete | ||
OpenGL ES 3.2 | in progress | in progress | complete |
Platform support via backing renderers
Direct3D 9 | Direct3D 11 | Desktop GL | GL ES | Vulkan | Metal | |
---|---|---|---|---|---|---|
Windows | complete | complete | complete | complete | complete | |
Linux | complete | complete | ||||
Mac OS X | complete | complete [1] | ||||
iOS | complete [2] | |||||
Chrome OS | complete | planned | ||||
Android | complete | complete | ||||
GGP (Stadia) | complete | |||||
Fuchsia | complete |
ANGLE 項目的地址:https://github.com/google/angle
Avalonia
Avalonia 是一個 .NET 平臺的 XAML 和 C# 的 UI 框架,它的目標是創建一個跨平臺的 UI 框架,支持 Windows、Linux 和 MacOS。(摘自 Avalonia 官網)
Avalonia 渲染 API 的實現是基於 SkiaSharp 的,SkiaSharp 是 Google 的 Skia 圖形庫的 .NET 實現。
為了實現硬體加速 SkiaSharp 是支持 OpenGL 和 OpenGL ES 渲染的,為了統一平臺,Avalonia 選擇了 ANGLE 作為 OpenGL ES 的實現。
Avalonia 項目的地址:https://github.com/AvaloniaUI/Avalonia
如何使用 OpenGL ES
Avalonia 中的 OpenGL ES 是通過 ANGLE 來實現的,在 Avalonia 項目中已經集成了 ANGLE,所以我們不需要再去關心 ANGLE 的集成問題。
在該框架中使用 OpenGL ES 的方式是通過 Avalonia 提供的 OpenGlControlBase 控制項來實現的,我們只需要集成 OpenGlControlBase 控制項並重寫 OnOpenGlInit 方法就可以獲取到 OpenGL ES 的 Context 以及函數指針了。
在 Avalonia 中使用 OpenGL ES 的步驟如下:(我這邊使用的是 Silk.NET 來調用 OpenGL ES 的函數)
using Silk.NET.OpenGLES;
namespace GraphicsHostApp.Graphics.OpenGL;
public class Renderer : OpenGlControlBase, IGraphicsHost<GL>
{
private GL _gl;
protected override void OnOpenGlInit(GlInterface gl)
{
// 獲取 OpenGL ES 的 函數指針。
_gl ??= GL.GetApi(gl.GetProcAddress);
// 後續初始化操作。
}
protected override void OnOpenGlDeinit(GlInterface gl)
{
// 釋放 OpenGL ES 的資源。
Code ...
// 釋放函數指針。
_gl.Dispose();
_gl = null;
}
protected override void OnOpenGlRender(GlInterface gl, int fb)
{
// 更新操作。
Code ...
// 渲染操作。 註:這裡需要註意的是,父類代碼並沒有更新視口,所以需要手動更新視口。gl.Viewport(0, 0, Width, Height);
Code ...
// 提交渲染到主迴圈中。
Dispatcher.UIThread.Post(RequestNextFrameRendering, DispatcherPriority.Render);
}
}
結語
Avalonia 是一個很不錯的 UI 框架,它的 OpenGL ES 支持也是很完善的,但是在使用 OpenGL ES 的時候需要註意的是 OpenGL ES 的 Context 是在 OpenGlControlBase 的 OnOpenGlInit 方法中創建的,所以在 OnOpenGlRender 方法中使用 OpenGL ES 的函數指針的時候需要註意 Context 是否已經創建了。
其次,OpenGL ES 的 Context 是線程相關的,所以在使用 OpenGL ES 的時候需要註意 Context 的線程問題。
在使用 OpenGL ES 擴展的時候要註意 ANGLE 是否支持該擴展,如果不支持的話需要自己去實現。
演示項目
- GraphicsHostApp (Avalonia 和 OpenGL ES 的演示項目,介紹瞭如何使用 C# 和 C++ 來實現 OpenGL ES 渲染。)