1
0
mirror of https://gitee.com/csharpui/CPF.git synced 2025-04-05 17:37:51 +08:00
CPF/CPF.Skia/GlView.cs

139 lines
4.8 KiB
C#
Raw Normal View History

2023-11-21 23:05:03 +08:00
using CPF.Drawing;
using System;
using System.Collections.Generic;
using System.Text;
using SkiaSharp;
using CPF.OpenGL;
using System.Runtime.InteropServices;
namespace CPF.Skia
{
/// <summary>
/// 支持OpenGL绘制的控件在GLRender事件里绘制开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true }
2023-11-21 23:05:03 +08:00
/// </summary>
public class GLView : UIElement
2023-11-21 23:05:03 +08:00
{
int Id;
int ColorBuffer;
int DepthRenderBuffer;
2023-11-21 23:05:03 +08:00
Size oldSize;
SKImage image;
//IGlContext context;
protected unsafe override void OnRender(DrawingContext dc)
2023-11-21 23:05:03 +08:00
{
var size1 = ActualSize;
if (size1.Width <= 0 || size1.Height <= 0 || DesignMode)
{
return;
}
var size = new PixelSize((int)Math.Round(size1.Width * Root.RenderScaling), (int)Math.Round(size1.Height * Root.RenderScaling));
var skia = dc as SkiaDrawingContext;
var _gl = skia.GlContext;
2023-11-21 23:05:03 +08:00
if (Id == 0)
2023-11-21 23:05:03 +08:00
{
Id = _gl.GenFramebuffer();
ColorBuffer = _gl.GenTexture();
DepthRenderBuffer = _gl.GenRenderbuffer();
2023-11-21 23:05:03 +08:00
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, ColorBuffer);
2023-11-21 23:05:03 +08:00
_gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MIN_FILTER, (int)GlConsts.GL_LINEAR);
_gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MAG_FILTER, GlConsts.GL_LINEAR);
2023-11-21 23:05:03 +08:00
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
OnGLLoaded(_gl);
}
2023-11-21 23:05:03 +08:00
if (size1 != oldSize)
{
oldSize = size1;
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, ColorBuffer);
_gl.TexImage2D(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA, (int)size.Width, (int)size.Height, 0, GlConsts.GL_RGB, GlConsts.GL_UNSIGNED_BYTE, IntPtr.Zero);
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
2023-11-21 23:05:03 +08:00
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
_gl.RenderbufferStorage(GlConsts.GL_RENDERBUFFER, GlConsts.GL_DEPTH32F_STENCIL8, (int)size.Width, (int)size.Height);
2023-11-21 23:05:03 +08:00
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, 0);
2023-11-21 23:05:03 +08:00
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
2023-11-21 23:05:03 +08:00
_gl.FramebufferTexture2D(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_TEXTURE_2D, ColorBuffer, 0);
2023-11-21 23:05:03 +08:00
_gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_STENCIL_ATTACHMENT, GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0);
2023-11-21 23:05:03 +08:00
if (image != null)
{
image.Dispose();
}
GRBackendTexture backendTexture = new GRBackendTexture((int)(size.Width / Root.RenderScaling), (int)(size.Height / Root.RenderScaling), false, new GRGlTextureInfo(0x0DE1, (uint)ColorBuffer, SKColorType.Rgba8888.ToGlSizedFormat()));
2023-11-21 23:05:03 +08:00
image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
2023-11-21 23:05:03 +08:00
}
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
var vp = new float[4];
_gl.GetFloatv(GlConsts.GL_VIEWPORT, vp);
_gl.Viewport(0, 0, (int)size.Width, (int)size.Height);
OnGLRender(_gl);
_gl.Viewport((int)vp[0], (int)vp[1], (int)vp[2], (int)vp[3]);
skia.SKCanvas.DrawImage(image, 0, 0);
}
protected virtual void OnGLRender(IGlContext gl)
{
this.RaiseEvent(new GLEventArgs(gl), nameof(GLRender));
2023-11-21 23:05:03 +08:00
}
protected virtual void OnGLLoaded(IGlContext gl)
2023-11-21 23:05:03 +08:00
{
this.RaiseEvent(new GLEventArgs(gl), nameof(GLLoaded));
}
2023-11-21 23:05:03 +08:00
public event EventHandler<GLEventArgs> GLLoaded
{
add { AddHandler(value); }
remove { RemoveHandler(value); }
}
public event EventHandler<GLEventArgs> GLRender
{
add { AddHandler(value); }
remove { RemoveHandler(value); }
2023-11-21 23:05:03 +08:00
}
2023-11-21 23:05:03 +08:00
protected override void Dispose(bool disposing)
{
if (Id != 0)
2023-11-21 23:05:03 +08:00
{
OpenglEx.DeleteFramebuffers(null, 1, new int[] { Id });
OpenglEx.DeleteTextures(null, 1, new int[] { ColorBuffer });
OpenglEx.DeleteRenderbuffers(null, 1, new int[] { DepthRenderBuffer });
2023-11-21 23:05:03 +08:00
}
if (image != null)
2023-11-21 23:05:03 +08:00
{
image.Dispose();
image = null;
2023-11-21 23:05:03 +08:00
}
base.Dispose(disposing);
2023-11-21 23:05:03 +08:00
}
}
2023-11-21 23:05:03 +08:00
public class GLEventArgs : EventArgs
{
public GLEventArgs(IGlContext gl)
{
Context = gl;
}
public IGlContext Context { get;private set; }
2023-11-21 23:05:03 +08:00
}
}