mirror of
https://gitee.com/csharpui/CPF.git
synced 2025-07-17 01:46:22 +08:00
进一步完善GLView,支持OpenGL绘制的控件
This commit is contained in:
parent
ae42978590
commit
0b613adc2c
@ -9,16 +9,18 @@ using System.Runtime.InteropServices;
|
|||||||
namespace CPF.Skia
|
namespace CPF.Skia
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支持OpenGL绘制的控件
|
/// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true }
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class GlView : CPF.UIElement
|
public class GLView : UIElement
|
||||||
{
|
{
|
||||||
int fb;
|
int Id;
|
||||||
int texture;
|
int ColorBuffer;
|
||||||
//int[] g_Renderbuffer;
|
int DepthRenderBuffer;
|
||||||
Size oldSize;
|
Size oldSize;
|
||||||
bool f;
|
SKImage image;
|
||||||
protected override void OnRender(DrawingContext dc)
|
|
||||||
|
//IGlContext context;
|
||||||
|
protected unsafe override void OnRender(DrawingContext dc)
|
||||||
{
|
{
|
||||||
var size1 = ActualSize;
|
var size1 = ActualSize;
|
||||||
if (size1.Width <= 0 || size1.Height <= 0 || DesignMode)
|
if (size1.Width <= 0 || size1.Height <= 0 || DesignMode)
|
||||||
@ -28,185 +30,109 @@ namespace CPF.Skia
|
|||||||
|
|
||||||
var size = new PixelSize((int)Math.Round(size1.Width * Root.RenderScaling), (int)Math.Round(size1.Height * Root.RenderScaling));
|
var size = new PixelSize((int)Math.Round(size1.Width * Root.RenderScaling), (int)Math.Round(size1.Height * Root.RenderScaling));
|
||||||
var skia = dc as SkiaDrawingContext;
|
var skia = dc as SkiaDrawingContext;
|
||||||
var gl = skia.GlContext;
|
var _gl = skia.GlContext;
|
||||||
|
|
||||||
var fbs = new int[1];
|
if (Id == 0)
|
||||||
if (fb == 0)
|
|
||||||
{
|
{
|
||||||
gl.GenFramebuffers(1, fbs);
|
Id = _gl.GenFramebuffer();
|
||||||
fb = fbs[0];
|
ColorBuffer = _gl.GenTexture();
|
||||||
|
DepthRenderBuffer = _gl.GenRenderbuffer();
|
||||||
|
|
||||||
|
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, ColorBuffer);
|
||||||
|
|
||||||
|
_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);
|
||||||
|
|
||||||
|
_gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
|
||||||
|
OnGLLoaded(_gl);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
fbs[0] = fb;
|
|
||||||
}
|
|
||||||
gl.GetIntegerv(GlConsts.GL_FRAMEBUFFER_BINDING, out var oldfb);
|
|
||||||
gl.GetIntegerv(GlConsts.GL_TEXTURE_BINDING_2D, out var oldTexture);
|
|
||||||
gl.GetIntegerv(GlConsts.GL_RENDERBUFFER_BINDING, out var oldRenderbuffer);
|
|
||||||
gl.Enable(GlConsts.GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
//保存旧的状态
|
|
||||||
gl.PushAttrib(GlConsts.GL_VIEWPORT_BIT);
|
|
||||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
|
||||||
gl.PushMatrix();
|
|
||||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
|
||||||
gl.PushMatrix();
|
|
||||||
|
|
||||||
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, fb);
|
|
||||||
|
|
||||||
if (size1 != oldSize)
|
if (size1 != oldSize)
|
||||||
{
|
{
|
||||||
oldSize = size1;
|
oldSize = size1;
|
||||||
|
|
||||||
var textures = new int[1] { texture };
|
_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);
|
||||||
|
|
||||||
if (texture > 0)
|
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
|
||||||
|
_gl.RenderbufferStorage(GlConsts.GL_RENDERBUFFER, GlConsts.GL_DEPTH32F_STENCIL8, (int)size.Width, (int)size.Height);
|
||||||
|
|
||||||
|
_gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
|
||||||
|
|
||||||
|
_gl.FramebufferTexture2D(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_TEXTURE_2D, ColorBuffer, 0);
|
||||||
|
|
||||||
|
_gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_STENCIL_ATTACHMENT, GlConsts.GL_RENDERBUFFER, DepthRenderBuffer);
|
||||||
|
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
|
||||||
|
if (image != null)
|
||||||
{
|
{
|
||||||
gl.DeleteTextures(1, textures);
|
image.Dispose();
|
||||||
//gl.DeleteRenderbuffers(1, g_Renderbuffer);
|
|
||||||
}
|
}
|
||||||
|
GRBackendTexture backendTexture = new GRBackendTexture((int)(size.Width / Root.RenderScaling), (int)(size.Height / Root.RenderScaling), false, new GRGlTextureInfo(0x0DE1, (uint)ColorBuffer, SKColorType.Rgba8888.ToGlSizedFormat()));
|
||||||
|
|
||||||
gl.GenTextures(1, textures);
|
image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
|
||||||
texture = textures[0];
|
|
||||||
//gl.ActiveTexture(GlConsts.GL_TEXTURE0);
|
|
||||||
gl.BindTexture(GlConsts.GL_TEXTURE_2D, textures[0]);
|
|
||||||
gl.TexImage2D(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA8, (int)size.Width, (int)size.Height, 0, GlConsts.GL_RGBA, GlConsts.GL_UNSIGNED_BYTE, IntPtr.Zero);
|
|
||||||
gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MAG_FILTER, GlConsts.GL_NEAREST);
|
|
||||||
gl.TexParameteri(GlConsts.GL_TEXTURE_2D, GlConsts.GL_TEXTURE_MIN_FILTER, GlConsts.GL_NEAREST);
|
|
||||||
gl.FramebufferTexture2D(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_COLOR_ATTACHMENT0, GlConsts.GL_TEXTURE_2D, texture, 0);
|
|
||||||
//gl.BindTexture(GlConsts.GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
//g_Renderbuffer = new int[1];
|
|
||||||
//gl.GenRenderbuffers(1, g_Renderbuffer);
|
|
||||||
//gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
|
||||||
//gl.RenderbufferStorage(GlConsts.GL_RENDERBUFFER, GlConsts.GL_DEPTH_COMPONENT, (int)size.Width, (int)size.Height);
|
|
||||||
//gl.FramebufferRenderbuffer(GlConsts.GL_FRAMEBUFFER, GlConsts.GL_DEPTH_ATTACHMENT, GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
|
||||||
//gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER_EXT, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
//gl.BindTexture(GlConsts.GL_TEXTURE_2D, texture);
|
|
||||||
// gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, g_Renderbuffer[0]);
|
|
||||||
// GlConsts.GL_FRAMEBUFFER_COMPLETE
|
|
||||||
var status = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER);
|
|
||||||
gl.Viewport(0, 0, size.Width, size.Height);
|
|
||||||
|
|
||||||
|
|
||||||
//var MODELVIEW = new float[16];
|
|
||||||
//gl.GetFloatv(GlConsts.GL_MODELVIEW_MATRIX, MODELVIEW);
|
|
||||||
|
|
||||||
|
|
||||||
//var status = gl.CheckFramebufferStatus(GlConsts.GL_FRAMEBUFFER) == GlConsts.GL_FRAMEBUFFER_COMPLETE;
|
|
||||||
|
|
||||||
//if (!f)
|
|
||||||
{
|
|
||||||
OnGlRender(skia.GlContext, size);
|
|
||||||
f = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//var framebufferInfo = new GRGlFramebufferInfo((uint)fb, SKColorType.Rgba8888.ToGlSizedFormat());
|
_gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, Id);
|
||||||
|
var vp = new float[4];
|
||||||
//gl.GetIntegerv(GlConsts.GL_FRAMEBUFFER_BINDING, out var framebuffer);
|
_gl.GetFloatv(GlConsts.GL_VIEWPORT, vp);
|
||||||
//gl.GetIntegerv(3415, out var stencil);
|
_gl.Viewport(0, 0, (int)size.Width, (int)size.Height);
|
||||||
//gl.GetIntegerv(32937, out var samples);
|
OnGLRender(_gl);
|
||||||
gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, oldRenderbuffer);
|
_gl.Viewport((int)vp[0], (int)vp[1], (int)vp[2], (int)vp[3]);
|
||||||
gl.BindTexture(GlConsts.GL_TEXTURE_2D, oldTexture);
|
skia.SKCanvas.DrawImage(image, 0, 0);
|
||||||
gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, oldfb);
|
|
||||||
// using (var backendTexture = new GRBackendRenderTarget(size.Width, size.Height, samples, stencil, framebufferInfo))
|
|
||||||
//using (var backendTexture = new GRBackendTexture((int)size.Width, (int)size.Height, false, new GRGlTextureInfo { Format = GlConsts.GL_RGBA8, Id = (uint)texture, Target = GlConsts.GL_TEXTURE_2D }))
|
|
||||||
//{
|
|
||||||
// // using (var surface = SKSurface.Create((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888))
|
|
||||||
// using (var surface = SKSurface.Create((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.TopLeft, SKColorType.Rgba8888))
|
|
||||||
// {
|
|
||||||
// //if (surface == null)
|
|
||||||
// // return;
|
|
||||||
// //byte[] data = new byte[size.Width * size.Height * 4];
|
|
||||||
// //gl.GetTexImage(GlConsts.GL_TEXTURE_2D, 0, GlConsts.GL_RGBA, GlConsts.GL_UNSIGNED_BYTE, data);
|
|
||||||
|
|
||||||
// //System.Diagnostics.Debug.WriteLine($"{oldfb},{oldRenderbuffer},{oldTexture}");
|
|
||||||
|
|
||||||
//恢复状态
|
|
||||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
|
||||||
gl.PopMatrix();
|
|
||||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
|
||||||
gl.PopMatrix();
|
|
||||||
gl.PopAttrib();
|
|
||||||
|
|
||||||
// skia.SKCanvas.DrawSurface(surface, 0, 0);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
GRBackendTexture backendTexture = new GRBackendTexture((int)size.Width, (int)size.Height, false, new GRGlTextureInfo(0x0DE1, (uint)texture, SKColorType.Rgba8888.ToGlSizedFormat()));
|
|
||||||
|
|
||||||
var sKImage = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
|
|
||||||
skia.SKCanvas.DrawImage(sKImage, 0, 0);
|
|
||||||
//unsafe
|
|
||||||
//{
|
|
||||||
// fixed (byte* p = data)
|
|
||||||
// {
|
|
||||||
// using (var bitmap = new Bitmap(size.Width, size.Height, size.Width * 4, PixelFormat.Rgba, (IntPtr)p))
|
|
||||||
// {
|
|
||||||
// dc.DrawImage(bitmap, new Rect(0, 0, size.Width, size.Height), new Rect(0, 0, size.Width, size.Height));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//gl.DeleteTextures(1, textures);
|
|
||||||
//gl.DeleteRenderbuffers(1, g_Renderbuffer);
|
|
||||||
//gl.DeleteFramebuffers(1, fbs);
|
|
||||||
base.OnRender(dc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
protected void OnGlRender(IGlContext gl, PixelSize viewPort)
|
protected virtual void OnGLRender(IGlContext gl)
|
||||||
{
|
{
|
||||||
gl.MatrixMode(GlConsts.GL_PROJECTION);
|
this.RaiseEvent(new GLEventArgs(gl), nameof(GLRender));
|
||||||
// gl.LoadIdentity();
|
|
||||||
//gl.Ortho(-250, 250, -250, 250, -100, 100);
|
|
||||||
gl.MatrixMode(GlConsts.GL_MODELVIEW);
|
|
||||||
gl.LoadIdentity();
|
|
||||||
//var PROJECTION = new float[4];
|
|
||||||
//gl.GetFloatv(GlConsts.GL_VIEWPORT, PROJECTION);
|
|
||||||
gl.ClearColor((float)random.NextDouble(), 0.25f, 0.75f, 0.5f);
|
|
||||||
gl.Clear(GlConsts.GL_COLOR_BUFFER_BIT);
|
|
||||||
gl.Color4f(1, 1, 1, 1);
|
|
||||||
gl.Begin(GlConsts.GL_TRIANGLES); // Drawing Using Triangles
|
|
||||||
// gl.Color4f(1.0f, 0.0f, 0.0f, 1); // Set The Color To Red
|
|
||||||
gl.Vertex3f(0.0f, 0.0f, 0.0f); // Top
|
|
||||||
// gl.Color4f(0.0f, 1.0f, 0.0f, 1); // Set The Color To Green
|
|
||||||
gl.Vertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
|
|
||||||
// gl.Color4f(0.0f, 0.0f, 1.0f, 1); // Set The Color To Blue
|
|
||||||
gl.Vertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
|
|
||||||
// Drawing Using Triangles
|
|
||||||
// gl.Color4f(1.0f, 0.0f, 0.0f, 1); // Set The Color To Red
|
|
||||||
gl.Vertex3f((float)viewPort.Width, (float)viewPort.Height, 0.0f); // Top
|
|
||||||
// gl.Color4f(0.0f, 1.0f, 0.0f, 1); // Set The Color To Green
|
|
||||||
gl.Vertex3f(-1.0f, 21.0f, 0.0f); // Bottom Left
|
|
||||||
// gl.Color4f(0.0f, 0.0f, 1.0f, 1); // Set The Color To Blue
|
|
||||||
gl.Vertex3f(21.0f, 5.0f, 0.0f); // Bottom Right
|
|
||||||
gl.End();
|
|
||||||
|
|
||||||
var PROJECTION = new float[16];
|
|
||||||
gl.GetFloatv(GlConsts.GL_PROJECTION_MATRIX, PROJECTION);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnGLLoaded(IGlContext gl)
|
||||||
|
{
|
||||||
|
this.RaiseEvent(new GLEventArgs(gl), nameof(GLLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<GLEventArgs> GLLoaded
|
||||||
|
{
|
||||||
|
add { AddHandler(value); }
|
||||||
|
remove { RemoveHandler(value); }
|
||||||
|
}
|
||||||
|
public event EventHandler<GLEventArgs> GLRender
|
||||||
|
{
|
||||||
|
add { AddHandler(value); }
|
||||||
|
remove { RemoveHandler(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
if (Id != 0)
|
||||||
|
{
|
||||||
|
OpenglEx.DeleteFramebuffers(null, 1, new int[] { Id });
|
||||||
|
OpenglEx.DeleteTextures(null, 1, new int[] { ColorBuffer });
|
||||||
|
OpenglEx.DeleteRenderbuffers(null, 1, new int[] { DepthRenderBuffer });
|
||||||
|
}
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
image.Dispose();
|
||||||
|
image = null;
|
||||||
|
}
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
if (fb > 0)
|
|
||||||
{
|
|
||||||
OpenglEx.DeleteFramebuffers(null, 1, new int[] { fb });
|
|
||||||
fb = 0;
|
|
||||||
}
|
|
||||||
if (texture > 0)
|
|
||||||
{
|
|
||||||
OpenglEx.DeleteTextures(null, 1, new int[] { texture });
|
|
||||||
//OpenglEx.DeleteRenderbuffers(null, 1, g_Renderbuffer);
|
|
||||||
texture = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//[DllImport("opengl32", SetLastError = true)]
|
public class GLEventArgs : EventArgs
|
||||||
//private static extern void glOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
{
|
||||||
|
public GLEventArgs(IGlContext gl)
|
||||||
|
{
|
||||||
|
Context = gl;
|
||||||
|
}
|
||||||
|
public IGlContext Context { get;private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,13 +124,13 @@ namespace CPF.OpenGL
|
|||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
[GlImport("glFinish")]
|
//[GlImport("glFinish")]
|
||||||
static Action finish;
|
//static Action finish;
|
||||||
public static void Finish(this IGlContext context)
|
//public static void Finish(this IGlContext context)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
finish();
|
// finish();
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate IntPtr GlGetString(int v);
|
public delegate IntPtr GlGetString(int v);
|
||||||
[GlImport("glGetString")]
|
[GlImport("glGetString")]
|
||||||
@ -163,6 +163,13 @@ namespace CPF.OpenGL
|
|||||||
genFramebuffers(count, res);
|
genFramebuffers(count, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int GenFramebuffer(this IGlContext context)
|
||||||
|
{
|
||||||
|
int[] fbs = new int[1];
|
||||||
|
context.GenFramebuffers(1, fbs);
|
||||||
|
return fbs[0];
|
||||||
|
}
|
||||||
|
|
||||||
public delegate void GlDeleteFramebuffers(int count, int[] framebuffers);
|
public delegate void GlDeleteFramebuffers(int count, int[] framebuffers);
|
||||||
[GlImport("glDeleteFramebuffers")]
|
[GlImport("glDeleteFramebuffers")]
|
||||||
static GlDeleteFramebuffers deleteFramebuffers;
|
static GlDeleteFramebuffers deleteFramebuffers;
|
||||||
@ -211,6 +218,12 @@ namespace CPF.OpenGL
|
|||||||
Load(context);
|
Load(context);
|
||||||
genRenderbuffers(count, res);
|
genRenderbuffers(count, res);
|
||||||
}
|
}
|
||||||
|
public static int GenRenderbuffer(this IGlContext context)
|
||||||
|
{
|
||||||
|
var res = new int[1];
|
||||||
|
context.GenRenderbuffers(1, res);
|
||||||
|
return res[0];
|
||||||
|
}
|
||||||
|
|
||||||
public delegate void GlDeleteRenderbuffers(int count, int[] renderbuffers);
|
public delegate void GlDeleteRenderbuffers(int count, int[] renderbuffers);
|
||||||
[GlImport("glDeleteRenderbuffers")]
|
[GlImport("glDeleteRenderbuffers")]
|
||||||
@ -258,6 +271,13 @@ namespace CPF.OpenGL
|
|||||||
Load(context);
|
Load(context);
|
||||||
genTextures(count, res);
|
genTextures(count, res);
|
||||||
}
|
}
|
||||||
|
public static int GenTexture(this IGlContext context)
|
||||||
|
{
|
||||||
|
var res = new int[1];
|
||||||
|
context.GenTextures(1, res);
|
||||||
|
return res[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public delegate void GlBindTexture(int target, int fb);
|
public delegate void GlBindTexture(int target, int fb);
|
||||||
[GlImport("glBindTexture")]
|
[GlImport("glBindTexture")]
|
||||||
@ -378,41 +398,41 @@ namespace CPF.OpenGL
|
|||||||
deleteShader(shader);
|
deleteShader(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void GlColor4f(float red, float green, float blue, float alpha);
|
//public delegate void GlColor4f(float red, float green, float blue, float alpha);
|
||||||
[GlImport("glColor4f")]
|
//[GlImport("glColor4f")]
|
||||||
static GlColor4f color4f;
|
//static GlColor4f color4f;
|
||||||
public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha)
|
//public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
color4f(red, green, blue, alpha);
|
// color4f(red, green, blue, alpha);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate void GlBegin(uint mode);
|
//public delegate void GlBegin(uint mode);
|
||||||
[GlImport("glBegin")]
|
//[GlImport("glBegin")]
|
||||||
static GlBegin begin;
|
//static GlBegin begin;
|
||||||
public static void Begin(this IGlContext context, uint mode)
|
//public static void Begin(this IGlContext context, uint mode)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
begin(mode);
|
// begin(mode);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate void GlVertex3f(float x, float y, float z);
|
//public delegate void GlVertex3f(float x, float y, float z);
|
||||||
[GlImport("glVertex3f")]
|
//[GlImport("glVertex3f")]
|
||||||
static GlVertex3f vertex3f;
|
//static GlVertex3f vertex3f;
|
||||||
public static void Vertex3f(this IGlContext context, float x, float y, float z)
|
//public static void Vertex3f(this IGlContext context, float x, float y, float z)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
vertex3f(x, y, z);
|
// vertex3f(x, y, z);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate void GlEnd();
|
//public delegate void GlEnd();
|
||||||
[GlImport("glEnd")]
|
//[GlImport("glEnd")]
|
||||||
static GlEnd end;
|
//static GlEnd end;
|
||||||
public static void End(this IGlContext context)
|
//public static void End(this IGlContext context)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
end();
|
// end();
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate void GlLoadIdentity();
|
public delegate void GlLoadIdentity();
|
||||||
[GlImport("glLoadIdentity")]
|
[GlImport("glLoadIdentity")]
|
||||||
@ -477,14 +497,14 @@ namespace CPF.OpenGL
|
|||||||
popAttrib();
|
popAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
//public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar);
|
||||||
[GlImport("glOrtho")]
|
//[GlImport("glOrtho")]
|
||||||
static GlOrtho ortho;
|
//static GlOrtho ortho;
|
||||||
public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar)
|
//public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar)
|
||||||
{
|
//{
|
||||||
Load(context);
|
// Load(context);
|
||||||
ortho(left, right, bottom, top, zNear, zFar);
|
// ortho(left, right, bottom, top, zNear, zFar);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public delegate void GlGetFloatv(uint pname, float[] params_notkeyword);
|
public delegate void GlGetFloatv(uint pname, float[] params_notkeyword);
|
||||||
[GlImport("glGetFloatv")]
|
[GlImport("glGetFloatv")]
|
||||||
|
@ -1,84 +1,47 @@
|
|||||||
#if !NET40&&!NETCOREAPP3_0
|
#if !NET40
|
||||||
using CPF;
|
using CPF;
|
||||||
using CPF.Animation;
|
|
||||||
using CPF.Charts;
|
|
||||||
using CPF.Controls;
|
|
||||||
using CPF.Drawing;
|
using CPF.Drawing;
|
||||||
using CPF.Shapes;
|
|
||||||
using CPF.Skia;
|
|
||||||
using CPF.Styling;
|
|
||||||
using CPF.Svg;
|
|
||||||
using CPF.OpenGL;
|
using CPF.OpenGL;
|
||||||
using System;
|
using CPF.Skia;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Silk.NET.OpenGLES;
|
using System;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
|
||||||
|
|
||||||
namespace ConsoleApp1
|
namespace ConsoleApp1
|
||||||
{
|
{
|
||||||
[CPF.Design.DesignerLoadStyle("res://$safeprojectname$/Stylesheet1.css")]//用于设计的时候加载样式
|
[CPF.Design.DesignerLoadStyle("res://$safeprojectname$/Stylesheet1.css")]//用于设计的时候加载样式
|
||||||
public class GLView : UIElement
|
public class GLView : CPF.Skia.GLView
|
||||||
{
|
{
|
||||||
GL _gl;
|
#if !NETCOREAPP3_0
|
||||||
public uint Id { get; set; }
|
Silk.NET.OpenGLES.GL _gl;
|
||||||
|
|
||||||
public uint ColorBuffer { get; set; }
|
|
||||||
|
|
||||||
public uint DepthRenderBuffer { get; set; }
|
|
||||||
Size oldSize;
|
|
||||||
SKImage image;
|
|
||||||
|
|
||||||
uint vao;
|
uint vao;
|
||||||
uint shaderProgram;
|
uint shaderProgram;
|
||||||
//IGlContext context;
|
|
||||||
protected unsafe override void OnRender(DrawingContext dc)
|
protected unsafe override void OnGLLoaded(IGlContext gl)
|
||||||
{
|
{
|
||||||
var size1 = ActualSize;
|
_gl = Silk.NET.OpenGLES.GL.GetApi(gl.GetProcAddress);
|
||||||
if (size1.Width <= 0 || size1.Height <= 0 || DesignMode)
|
_gl.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
{
|
float[] vertices = {
|
||||||
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;
|
|
||||||
//context = gl;
|
|
||||||
OpenglEx.Load(gl);
|
|
||||||
if (_gl == null)
|
|
||||||
{
|
|
||||||
_gl = GL.GetApi(gl.GetProcAddress);
|
|
||||||
Id = _gl.GenFramebuffer();
|
|
||||||
ColorBuffer = _gl.GenTexture();
|
|
||||||
DepthRenderBuffer = _gl.GenRenderbuffer();
|
|
||||||
|
|
||||||
_gl.BindTexture(GLEnum.Texture2D, ColorBuffer);
|
|
||||||
|
|
||||||
_gl.TexParameter(GLEnum.Texture2D, GLEnum.TextureMinFilter, (int)GLEnum.Linear);
|
|
||||||
_gl.TexParameter(GLEnum.Texture2D, GLEnum.TextureMagFilter, (int)GLEnum.Linear);
|
|
||||||
|
|
||||||
_gl.BindTexture(GLEnum.Texture2D, 0);
|
|
||||||
|
|
||||||
|
|
||||||
_gl.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
||||||
float[] vertices = {
|
|
||||||
-0.5f, -0.5f, 0.0f,
|
-0.5f, -0.5f, 0.0f,
|
||||||
0.5f, -0.5f, 0.0f,
|
0.5f, -0.5f, 0.0f,
|
||||||
0.0f, 0.5f, 0.0f
|
0.0f, 0.5f, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
_gl.GenBuffers(1, out uint vbo);
|
_gl.GenBuffers(1, out uint vbo);
|
||||||
_gl.BindBuffer(GLEnum.ArrayBuffer, vbo);
|
_gl.GenVertexArrays(1, out vao);
|
||||||
_gl.BufferData<float>(GLEnum.ArrayBuffer, (nuint)vertices.Length * sizeof(float), vertices, GLEnum.StaticDraw);
|
|
||||||
|
|
||||||
_gl.GenVertexArrays(1, out vao);
|
_gl.BindBuffer(Silk.NET.OpenGLES.GLEnum.ArrayBuffer, vbo);
|
||||||
_gl.BindVertexArray(vao);
|
_gl.BindVertexArray(vao);
|
||||||
_gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), null);
|
|
||||||
_gl.EnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
string vertexShaderSource = @"#version 330 core
|
_gl.BufferData<float>(Silk.NET.OpenGLES.GLEnum.ArrayBuffer,vertices, Silk.NET.OpenGLES.GLEnum.StaticDraw);
|
||||||
|
|
||||||
|
_gl.VertexAttribPointer(0, 3, Silk.NET.OpenGLES.GLEnum.Float, false, 3 * sizeof(float), null);
|
||||||
|
_gl.EnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
_gl.BindVertexArray(0);
|
||||||
|
_gl.BindBuffer(Silk.NET.OpenGLES.GLEnum.ArrayBuffer, 0);
|
||||||
|
|
||||||
|
string vertexShaderSource = @"#version 330 core
|
||||||
layout (location = 0) in vec3 aPos;
|
layout (location = 0) in vec3 aPos;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -86,7 +49,7 @@ namespace ConsoleApp1
|
|||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|
||||||
string fragmentShaderSource = @"#version 330 core
|
string fragmentShaderSource = @"#version 330 core
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@ -94,81 +57,43 @@ namespace ConsoleApp1
|
|||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|
||||||
uint vertexShader = _gl.CreateShader(GLEnum.VertexShader);
|
uint vertexShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.VertexShader);
|
||||||
_gl.ShaderSource(vertexShader, vertexShaderSource);
|
_gl.ShaderSource(vertexShader, vertexShaderSource);
|
||||||
_gl.CompileShader(vertexShader);
|
_gl.CompileShader(vertexShader);
|
||||||
|
|
||||||
uint fragmentShader = _gl.CreateShader(GLEnum.FragmentShader);
|
uint fragmentShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.FragmentShader);
|
||||||
_gl.ShaderSource(fragmentShader, fragmentShaderSource);
|
_gl.ShaderSource(fragmentShader, fragmentShaderSource);
|
||||||
_gl.CompileShader(fragmentShader);
|
_gl.CompileShader(fragmentShader);
|
||||||
|
|
||||||
shaderProgram = _gl.CreateProgram();
|
shaderProgram = _gl.CreateProgram();
|
||||||
_gl.AttachShader(shaderProgram, vertexShader);
|
_gl.AttachShader(shaderProgram, vertexShader);
|
||||||
_gl.AttachShader(shaderProgram, fragmentShader);
|
_gl.AttachShader(shaderProgram, fragmentShader);
|
||||||
_gl.LinkProgram(shaderProgram);
|
_gl.LinkProgram(shaderProgram);
|
||||||
|
|
||||||
_gl.DeleteShader(vertexShader);
|
_gl.DeleteShader(vertexShader);
|
||||||
_gl.DeleteShader(fragmentShader);
|
_gl.DeleteShader(fragmentShader);
|
||||||
}
|
base.OnGLLoaded(gl);
|
||||||
if (size1 != oldSize)
|
|
||||||
{
|
|
||||||
oldSize = size1;
|
|
||||||
|
|
||||||
_gl.BindTexture(GLEnum.Texture2D, ColorBuffer);
|
|
||||||
_gl.TexImage2D(GLEnum.Texture2D, 0, (int)GLEnum.Rgba, (uint)size.Width, (uint)size.Height, 0, GLEnum.Rgb, GLEnum.UnsignedByte, null);
|
|
||||||
_gl.BindTexture(GLEnum.Texture2D, 0);
|
|
||||||
|
|
||||||
_gl.BindRenderbuffer(GLEnum.Renderbuffer, DepthRenderBuffer);
|
|
||||||
_gl.RenderbufferStorage(GLEnum.Renderbuffer, GLEnum.Depth32fStencil8, (uint)size.Width, (uint)size.Height);
|
|
||||||
|
|
||||||
_gl.BindRenderbuffer(GLEnum.Renderbuffer, 0);
|
|
||||||
|
|
||||||
_gl.BindFramebuffer(GLEnum.Framebuffer, Id);
|
|
||||||
|
|
||||||
_gl.FramebufferTexture2D(GLEnum.Framebuffer, GLEnum.ColorAttachment0, GLEnum.Texture2D, ColorBuffer, 0);
|
|
||||||
|
|
||||||
_gl.FramebufferRenderbuffer(GLEnum.Framebuffer, GLEnum.DepthStencilAttachment, GLEnum.Renderbuffer, DepthRenderBuffer);
|
|
||||||
_gl.BindFramebuffer(GLEnum.Framebuffer, 0);
|
|
||||||
|
|
||||||
|
|
||||||
GRBackendTexture backendTexture = new GRBackendTexture((int)(size.Width / Root.RenderScaling), (int)(size.Height / Root.RenderScaling), false, new GRGlTextureInfo(0x0DE1, (uint)ColorBuffer, SKColorType.Rgba8888.ToGlSizedFormat()));
|
|
||||||
|
|
||||||
image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gl.BindFramebuffer(FramebufferTarget.Framebuffer, Id);
|
|
||||||
var vp = new float[4];
|
|
||||||
gl.GetFloatv(GlConsts.GL_VIEWPORT, vp);
|
|
||||||
_gl.Viewport(0, 0, (uint)size.Width, (uint)size.Height);
|
|
||||||
OnGlRender(gl, size);
|
|
||||||
_gl.Viewport((int)vp[0], (int)vp[1], (uint)vp[2], (uint)vp[3]);
|
|
||||||
skia.SKCanvas.DrawImage(image, 0, 0);
|
|
||||||
base.OnRender(dc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Random random = new Random();
|
|
||||||
protected void OnGlRender(IGlContext gl, PixelSize viewPort)
|
protected override void OnGLRender(IGlContext gl)
|
||||||
{
|
{
|
||||||
//_gl.ClearColor(0.5f, 0, 0, 0.5f);
|
_gl.ClearColor(0.5f, 1, 0, 0.5f);
|
||||||
//_gl.Clear(ClearBufferMask.ColorBufferBit);
|
_gl.Clear(Silk.NET.OpenGLES.ClearBufferMask.ColorBufferBit | Silk.NET.OpenGLES.ClearBufferMask.DepthBufferBit | Silk.NET.OpenGLES.ClearBufferMask.StencilBufferBit);
|
||||||
|
|
||||||
_gl.UseProgram(shaderProgram);
|
_gl.UseProgram(shaderProgram);
|
||||||
|
|
||||||
_gl.BindVertexArray(vao);
|
_gl.BindVertexArray(vao);
|
||||||
_gl.DrawArrays(GLEnum.Triangles, 0, 3);
|
|
||||||
|
_gl.DrawArrays(Silk.NET.OpenGLES.GLEnum.Triangles, 0, 3);
|
||||||
|
|
||||||
|
_gl.BindVertexArray(0);
|
||||||
|
_gl.UseProgram(0);
|
||||||
|
base.OnGLRender(gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
#endif
|
||||||
{
|
|
||||||
if (_gl != null)
|
|
||||||
{
|
|
||||||
OpenglEx.DeleteFramebuffers(null, 1, new int[] { (int)Id });
|
|
||||||
OpenglEx.DeleteTextures(null, 1, new int[] { (int)ColorBuffer });
|
|
||||||
OpenglEx.DeleteRenderbuffers(null, 1, new int[] { (int)DepthRenderBuffer });
|
|
||||||
//_gl.DeleteFramebuffer(Id);
|
|
||||||
//_gl.DeleteTexture(ColorBuffer);
|
|
||||||
//_gl.DeleteRenderbuffer(DepthRenderBuffer);
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -38,7 +38,12 @@ namespace ConsoleApp1
|
|||||||
#if Net4
|
#if Net4
|
||||||
(OperatingSystemType.Windows, new WindowsPlatform(), new CPF.GDIPlus.GDIPlusDrawingFactory { ClearType = true })
|
(OperatingSystemType.Windows, new WindowsPlatform(), new CPF.GDIPlus.GDIPlusDrawingFactory { ClearType = true })
|
||||||
#else
|
#else
|
||||||
(OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory { UseGPU=true })
|
(OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory
|
||||||
|
{
|
||||||
|
#if NETCOREAPP3_1_OR_GREATER
|
||||||
|
UseGPU=true
|
||||||
|
#endif
|
||||||
|
})
|
||||||
, (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
, (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
||||||
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false })
|
||||||
#endif
|
#endif
|
||||||
|
@ -472,9 +472,8 @@ namespace ConsoleApp1
|
|||||||
},
|
},
|
||||||
new ScrollViewer
|
new ScrollViewer
|
||||||
{
|
{
|
||||||
MarginLeft = 421,
|
MarginLeft = 421,//HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled,
|
||||||
HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled,
|
//VerticalScrollBarVisibility= ScrollBarVisibility.Visible,
|
||||||
VerticalScrollBarVisibility= ScrollBarVisibility.Visible,
|
|
||||||
Commands =
|
Commands =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -499,6 +498,15 @@ namespace ConsoleApp1
|
|||||||
// Name = nameof(pic),
|
// Name = nameof(pic),
|
||||||
// Source="http://219.239.12.91:5001/bookimage//bookimage3/cate1826979600058c0bd3/file253320e4000582XXXX/253320e4000582XXXX.jpg"
|
// Source="http://219.239.12.91:5001/bookimage//bookimage3/cate1826979600058c0bd3/file253320e4000582XXXX/253320e4000582XXXX.jpg"
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
#if !Net4&&!NETCOREAPP3_0
|
||||||
|
new GLView
|
||||||
|
{
|
||||||
|
Height = 336,
|
||||||
|
Width = 421,
|
||||||
|
},
|
||||||
|
#else
|
||||||
new WrapPanel
|
new WrapPanel
|
||||||
{
|
{
|
||||||
Width="100%",
|
Width="100%",
|
||||||
@ -562,6 +570,7 @@ namespace ConsoleApp1
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
Height=300,
|
Height=300,
|
||||||
MarginTop=19,
|
MarginTop=19,
|
||||||
MarginRight=29
|
MarginRight=29
|
||||||
@ -739,17 +748,7 @@ namespace ConsoleApp1
|
|||||||
Height = 58,
|
Height = 58,
|
||||||
Width = 121,
|
Width = 121,
|
||||||
},
|
},
|
||||||
#if !Net4&&!NETCOREAPP3_0
|
new Button
|
||||||
new GLView
|
|
||||||
{
|
|
||||||
MarginRight = 56,
|
|
||||||
MarginTop = 44,
|
|
||||||
Height = 132,
|
|
||||||
Width = 151,
|
|
||||||
[nameof(GLView.DoubleClick)]=new CommandDescribe((s,e)=>{ s.Dispose(); }),
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
new Button
|
|
||||||
{
|
{
|
||||||
Commands =
|
Commands =
|
||||||
{
|
{
|
||||||
@ -1388,8 +1387,7 @@ namespace ConsoleApp1
|
|||||||
MarginLeft = 252,
|
MarginLeft = 252,
|
||||||
MarginTop = 76,
|
MarginTop = 76,
|
||||||
Height = 23,
|
Height = 23,
|
||||||
Width = 219,
|
Width = 219,//[nameof(Slider.Value)]= new Obx<MainModel>(a => a.Type.Name),
|
||||||
//[nameof(Slider.Value)]= new Obx<MainModel>(a => a.Type.Name),
|
|
||||||
[nameof(Slider.Value)]= new BindingDescribe(null, nameof(MainModel.ColumnWidth),BindingMode.OneWayToSource,null,a=>new GridLength((float)(double)a))
|
[nameof(Slider.Value)]= new BindingDescribe(null, nameof(MainModel.ColumnWidth),BindingMode.OneWayToSource,null,a=>new GridLength((float)(double)a))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -2439,14 +2437,12 @@ new TabItemTemplate{
|
|||||||
Orientation= Orientation.Vertical,
|
Orientation= Orientation.Vertical,
|
||||||
Children=
|
Children=
|
||||||
{
|
{
|
||||||
|
|
||||||
new TextBlock
|
new TextBlock
|
||||||
{
|
{
|
||||||
[nameof(TextBlock.Text)]= new Obx<MainModel>(a => a.Test1.test.test.test.test.Name,
|
[nameof(TextBlock.Text)]= new Obx<MainModel>(a => a.Test1.test.test.test.test.Name,
|
||||||
BindingMode.OneWay),
|
BindingMode.OneWay),
|
||||||
Name = "hmbb"
|
Name = "hmbb"
|
||||||
},
|
},//new TextBox
|
||||||
//new TextBox
|
|
||||||
//{
|
//{
|
||||||
// Width = 130,
|
// Width = 130,
|
||||||
// Height= 60,
|
// Height= 60,
|
||||||
@ -2486,7 +2482,6 @@ new TabItemTemplate{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user