From 6593f462e48d77f06c01c6767473ad6aba1485d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=BA=A2=E5=B8=BD?= <761716178@qq.com> Date: Tue, 28 Nov 2023 12:48:19 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E8=B0=83=E6=95=B4gl=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Skia/GlView.cs | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/CPF.Skia/GlView.cs b/CPF.Skia/GlView.cs index 467d8d5..af93c99 100644 --- a/CPF.Skia/GlView.cs +++ b/CPF.Skia/GlView.cs @@ -112,28 +112,34 @@ namespace CPF.Skia gl.BindTexture(GlConsts.GL_TEXTURE_2D, oldTexture); 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); + //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}"); + // //System.Diagnostics.Debug.WriteLine($"{oldfb},{oldRenderbuffer},{oldTexture}"); - //恢复状态 - gl.MatrixMode(GlConsts.GL_MODELVIEW); - gl.PopMatrix(); - gl.MatrixMode(GlConsts.GL_PROJECTION); - gl.PopMatrix(); - gl.PopAttrib(); + //恢复状态 + gl.MatrixMode(GlConsts.GL_MODELVIEW); + gl.PopMatrix(); + gl.MatrixMode(GlConsts.GL_PROJECTION); + gl.PopMatrix(); + gl.PopAttrib(); - skia.SKCanvas.DrawSurface(surface, 0, 0); - } - } + // 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) From ae429785900fba6550806787118e3c169bcaa732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=BA=A2=E5=B8=BD?= <761716178@qq.com> Date: Wed, 29 Nov 2023 10:59:22 +0800 Subject: [PATCH 2/5] =?UTF-8?q?OpenGL=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Windows/WindowImpl.cs | 2 +- CPF/OpenGL/IGlContext.cs | 4 +- CPF/UIElement.cs | 2 +- ConsoleApp1/ConsoleApp1.csproj | 11 ++- ConsoleApp1/GLView.cs | 174 +++++++++++++++++++++++++++++++++ ConsoleApp1/Program.cs | 20 +++- ConsoleApp1/Window2.cs | 36 +++---- 7 files changed, 219 insertions(+), 30 deletions(-) create mode 100644 ConsoleApp1/GLView.cs diff --git a/CPF.Windows/WindowImpl.cs b/CPF.Windows/WindowImpl.cs index 400b7b2..1a02deb 100644 --- a/CPF.Windows/WindowImpl.cs +++ b/CPF.Windows/WindowImpl.cs @@ -807,6 +807,7 @@ namespace CPF.Windows } break; case WindowsMessage.WM_DESTROY: + Closed?.Invoke(); if (handle != IntPtr.Zero) { try @@ -857,7 +858,6 @@ namespace CPF.Windows RenderBitmap = null; } handle = IntPtr.Zero; - Closed?.Invoke(); foreach (var item in invokeQueue) { item.SendOrPostCallback(item.Data); diff --git a/CPF/OpenGL/IGlContext.cs b/CPF/OpenGL/IGlContext.cs index 3ad27da..d1b82dc 100644 --- a/CPF/OpenGL/IGlContext.cs +++ b/CPF/OpenGL/IGlContext.cs @@ -12,7 +12,7 @@ namespace CPF.OpenGL /// 用来获取和保存Skia创建的GRContext /// IDisposable GRContext { get; set; } - //void MakeCurrent(); + void MakeCurrent(); //void SwapBuffers(); //void Dispose(); //public abstract GRGlTextureInfo CreateTexture(SKSizeI textureSize); @@ -35,7 +35,7 @@ namespace CPF.OpenGL public static class OpenglEx { static bool loaded; - private static void Load(IGlContext context) + public static void Load(IGlContext context) { if (!loaded) { diff --git a/CPF/UIElement.cs b/CPF/UIElement.cs index 51b616a..4057dac 100644 --- a/CPF/UIElement.cs +++ b/CPF/UIElement.cs @@ -3046,7 +3046,7 @@ namespace CPF /// 子级,一般自定义组件的时候使用 /// [NotCpfProperty] - internal protected virtual UIElementCollection Children + internal protected UIElementCollection Children { get { diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj index 0967888..df73f42 100644 --- a/ConsoleApp1/ConsoleApp1.csproj +++ b/ConsoleApp1/ConsoleApp1.csproj @@ -1,7 +1,7 @@  - netcoreapp3.0;net40;net5;net6;net8 + netcoreapp3.0;net40;net5;net6 WinExe @@ -102,11 +102,12 @@ - + --> + + Net4 false diff --git a/ConsoleApp1/GLView.cs b/ConsoleApp1/GLView.cs new file mode 100644 index 0000000..717174b --- /dev/null +++ b/ConsoleApp1/GLView.cs @@ -0,0 +1,174 @@ +#if !NET40&&!NETCOREAPP3_0 +using CPF; +using CPF.Animation; +using CPF.Charts; +using CPF.Controls; +using CPF.Drawing; +using CPF.Shapes; +using CPF.Skia; +using CPF.Styling; +using CPF.Svg; +using CPF.OpenGL; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SkiaSharp; +using Silk.NET.OpenGLES; +using static System.Net.Mime.MediaTypeNames; + +namespace ConsoleApp1 +{ + [CPF.Design.DesignerLoadStyle("res://$safeprojectname$/Stylesheet1.css")]//用于设计的时候加载样式 + public class GLView : UIElement + { + GL _gl; + public uint Id { get; set; } + + public uint ColorBuffer { get; set; } + + public uint DepthRenderBuffer { get; set; } + Size oldSize; + SKImage image; + + uint vao; + uint shaderProgram; + //IGlContext context; + protected unsafe override void OnRender(DrawingContext dc) + { + 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; + //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.0f, 0.5f, 0.0f + }; + + _gl.GenBuffers(1, out uint vbo); + _gl.BindBuffer(GLEnum.ArrayBuffer, vbo); + _gl.BufferData(GLEnum.ArrayBuffer, (nuint)vertices.Length * sizeof(float), vertices, GLEnum.StaticDraw); + + _gl.GenVertexArrays(1, out vao); + _gl.BindVertexArray(vao); + _gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), null); + _gl.EnableVertexAttribArray(0); + + string vertexShaderSource = @"#version 330 core + layout (location = 0) in vec3 aPos; + void main() + { + gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + } + "; + + string fragmentShaderSource = @"#version 330 core + out vec4 FragColor; + void main() + { + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); + } + "; + + uint vertexShader = _gl.CreateShader(GLEnum.VertexShader); + _gl.ShaderSource(vertexShader, vertexShaderSource); + _gl.CompileShader(vertexShader); + + uint fragmentShader = _gl.CreateShader(GLEnum.FragmentShader); + _gl.ShaderSource(fragmentShader, fragmentShaderSource); + _gl.CompileShader(fragmentShader); + + shaderProgram = _gl.CreateProgram(); + _gl.AttachShader(shaderProgram, vertexShader); + _gl.AttachShader(shaderProgram, fragmentShader); + _gl.LinkProgram(shaderProgram); + + _gl.DeleteShader(vertexShader); + _gl.DeleteShader(fragmentShader); + } + 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) + { + //_gl.ClearColor(0.5f, 0, 0, 0.5f); + //_gl.Clear(ClearBufferMask.ColorBufferBit); + _gl.UseProgram(shaderProgram); + _gl.BindVertexArray(vao); + _gl.DrawArrays(GLEnum.Triangles, 0, 3); + } + + protected override void Dispose(bool disposing) + { + 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 \ No newline at end of file diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index b137afa..760b9f2 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -38,7 +38,7 @@ namespace ConsoleApp1 #if Net4 (OperatingSystemType.Windows, new WindowsPlatform(), new CPF.GDIPlus.GDIPlusDrawingFactory { ClearType = true }) #else - (OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory { }) + (OperatingSystemType.Windows, new WindowsPlatform(false), new SkiaDrawingFactory { UseGPU=true }) , (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = false }) , (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false }) #endif @@ -87,9 +87,21 @@ namespace ConsoleApp1 ////Thread.Sleep(10000); ////Application.AllowDeveloperTool = false; ////Application.DisablePopupClose = true; + - //Console.SetOut(new tr()); - //Console.WriteLine("123"); + //data aa = new data(); + //aa.test.test.test.Name = "11111"; + //model.Test1.test = aa; + + //var test1 = new TextBlock + //{ + // [nameof(TextBlock.Text)] = new CPF.Obx(a => a.Test1.test.test.test.test.Name), + //}; + //test1.DataContext=model; + + //aa = new data(); + //aa.test.test.test.Name = "666666"; + //model.Test1.test = aa; Application.Run(new Window2 { DataContext = model, CommandContext = model }); //Application.Run(new Window @@ -139,7 +151,7 @@ namespace ConsoleApp1 } class tr : TextWriter { - public override Encoding Encoding => Encoding.Unicode; + public override Encoding Encoding => Encoding.Unicode; public override void Write(string value) { diff --git a/ConsoleApp1/Window2.cs b/ConsoleApp1/Window2.cs index c26d849..06f3d34 100644 --- a/ConsoleApp1/Window2.cs +++ b/ConsoleApp1/Window2.cs @@ -738,15 +738,17 @@ namespace ConsoleApp1 MarginTop = 450, Height = 58, Width = 121, - },//#if !Net4 - //new CPF.Skia.GlView - //{ - // MarginRight = 56, - // MarginTop = 44, - // Height = 132, - // Width = 151, - //}, - //#endif + }, + #if !Net4&&!NETCOREAPP3_0 + new GLView + { + MarginRight = 56, + MarginTop = 44, + Height = 132, + Width = 151, + [nameof(GLView.DoubleClick)]=new CommandDescribe((s,e)=>{ s.Dispose(); }), + }, + #endif new Button { Commands = @@ -2444,14 +2446,14 @@ new TabItemTemplate{ BindingMode.OneWay), Name = "hmbb" }, - new TextBox - { - Width = 130, - Height= 60, - Background =Color.Gray, - [nameof(TextBox.Text)]= new Obx(a => a.Test1.test.test.test.test.Name, - BindingMode.OneWayToSource), - }, + //new TextBox + //{ + // Width = 130, + // Height= 60, + // Background =Color.Gray, + // [nameof(TextBox.Text)]= new Obx(a => a.Test1.test.test.test.test.Name, + // BindingMode.OneWayToSource), + //}, new Button { Content="创建对象", From 0b613adc2ce5d23a0fcaddbac6d9e67456c9ae53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=BA=A2=E5=B8=BD?= <761716178@qq.com> Date: Wed, 29 Nov 2023 16:38:58 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E8=BF=9B=E4=B8=80=E6=AD=A5=E5=AE=8C?= =?UTF-8?q?=E5=96=84GLView=EF=BC=8C=E6=94=AF=E6=8C=81OpenGL=E7=BB=98?= =?UTF-8?q?=E5=88=B6=E7=9A=84=E6=8E=A7=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Skia/GlView.cs | 254 ++++++++++++++------------------------- CPF/OpenGL/IGlContext.cs | 114 ++++++++++-------- ConsoleApp1/GLView.cs | 179 ++++++++------------------- ConsoleApp1/Program.cs | 7 +- ConsoleApp1/Window2.cs | 35 +++--- 5 files changed, 230 insertions(+), 359 deletions(-) diff --git a/CPF.Skia/GlView.cs b/CPF.Skia/GlView.cs index af93c99..e2aa4a3 100644 --- a/CPF.Skia/GlView.cs +++ b/CPF.Skia/GlView.cs @@ -9,16 +9,18 @@ using System.Runtime.InteropServices; namespace CPF.Skia { /// - /// 支持OpenGL绘制的控件 + /// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true } /// - public class GlView : CPF.UIElement + public class GLView : UIElement { - int fb; - int texture; - //int[] g_Renderbuffer; + int Id; + int ColorBuffer; + int DepthRenderBuffer; Size oldSize; - bool f; - protected override void OnRender(DrawingContext dc) + SKImage image; + + //IGlContext context; + protected unsafe override void OnRender(DrawingContext dc) { var size1 = ActualSize; 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 skia = dc as SkiaDrawingContext; - var gl = skia.GlContext; + var _gl = skia.GlContext; - var fbs = new int[1]; - if (fb == 0) + if (Id == 0) { - gl.GenFramebuffers(1, fbs); - fb = fbs[0]; + Id = _gl.GenFramebuffer(); + 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) { 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); - //gl.DeleteRenderbuffers(1, g_Renderbuffer); + 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())); - gl.GenTextures(1, textures); - 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; + image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888); } - //var framebufferInfo = new GRGlFramebufferInfo((uint)fb, SKColorType.Rgba8888.ToGlSizedFormat()); - - //gl.GetIntegerv(GlConsts.GL_FRAMEBUFFER_BINDING, out var framebuffer); - //gl.GetIntegerv(3415, out var stencil); - //gl.GetIntegerv(32937, out var samples); - gl.BindRenderbuffer(GlConsts.GL_RENDERBUFFER, oldRenderbuffer); - gl.BindTexture(GlConsts.GL_TEXTURE_2D, oldTexture); - 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); + _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); } - Random random = new Random(); - protected void OnGlRender(IGlContext gl, PixelSize viewPort) + + protected virtual void OnGLRender(IGlContext gl) { - gl.MatrixMode(GlConsts.GL_PROJECTION); - // 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); - + this.RaiseEvent(new GLEventArgs(gl), nameof(GLRender)); } + protected virtual void OnGLLoaded(IGlContext gl) + { + this.RaiseEvent(new GLEventArgs(gl), nameof(GLLoaded)); + } + + public event EventHandler GLLoaded + { + add { AddHandler(value); } + remove { RemoveHandler(value); } + } + public event EventHandler GLRender + { + add { AddHandler(value); } + remove { RemoveHandler(value); } + } + + 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); - 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)] - //private static extern void glOrtho(double left, double right, double bottom, double top, double zNear, double zFar); + public class GLEventArgs : EventArgs + { + public GLEventArgs(IGlContext gl) + { + Context = gl; + } + public IGlContext Context { get;private set; } } } diff --git a/CPF/OpenGL/IGlContext.cs b/CPF/OpenGL/IGlContext.cs index d1b82dc..cebcb75 100644 --- a/CPF/OpenGL/IGlContext.cs +++ b/CPF/OpenGL/IGlContext.cs @@ -124,13 +124,13 @@ namespace CPF.OpenGL flush(); } - [GlImport("glFinish")] - static Action finish; - public static void Finish(this IGlContext context) - { - Load(context); - finish(); - } + //[GlImport("glFinish")] + //static Action finish; + //public static void Finish(this IGlContext context) + //{ + // Load(context); + // finish(); + //} public delegate IntPtr GlGetString(int v); [GlImport("glGetString")] @@ -163,6 +163,13 @@ namespace CPF.OpenGL 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); [GlImport("glDeleteFramebuffers")] static GlDeleteFramebuffers deleteFramebuffers; @@ -211,6 +218,12 @@ namespace CPF.OpenGL Load(context); 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); [GlImport("glDeleteRenderbuffers")] @@ -258,6 +271,13 @@ namespace CPF.OpenGL Load(context); 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); [GlImport("glBindTexture")] @@ -378,41 +398,41 @@ namespace CPF.OpenGL deleteShader(shader); } - public delegate void GlColor4f(float red, float green, float blue, float alpha); - [GlImport("glColor4f")] - static GlColor4f color4f; - public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha) - { - Load(context); - color4f(red, green, blue, alpha); - } + //public delegate void GlColor4f(float red, float green, float blue, float alpha); + //[GlImport("glColor4f")] + //static GlColor4f color4f; + //public static void Color4f(this IGlContext context, float red, float green, float blue, float alpha) + //{ + // Load(context); + // color4f(red, green, blue, alpha); + //} - public delegate void GlBegin(uint mode); - [GlImport("glBegin")] - static GlBegin begin; - public static void Begin(this IGlContext context, uint mode) - { - Load(context); - begin(mode); - } + //public delegate void GlBegin(uint mode); + //[GlImport("glBegin")] + //static GlBegin begin; + //public static void Begin(this IGlContext context, uint mode) + //{ + // Load(context); + // begin(mode); + //} - public delegate void GlVertex3f(float x, float y, float z); - [GlImport("glVertex3f")] - static GlVertex3f vertex3f; - public static void Vertex3f(this IGlContext context, float x, float y, float z) - { - Load(context); - vertex3f(x, y, z); - } + //public delegate void GlVertex3f(float x, float y, float z); + //[GlImport("glVertex3f")] + //static GlVertex3f vertex3f; + //public static void Vertex3f(this IGlContext context, float x, float y, float z) + //{ + // Load(context); + // vertex3f(x, y, z); + //} - public delegate void GlEnd(); - [GlImport("glEnd")] - static GlEnd end; - public static void End(this IGlContext context) - { - Load(context); - end(); - } + //public delegate void GlEnd(); + //[GlImport("glEnd")] + //static GlEnd end; + //public static void End(this IGlContext context) + //{ + // Load(context); + // end(); + //} public delegate void GlLoadIdentity(); [GlImport("glLoadIdentity")] @@ -477,14 +497,14 @@ namespace CPF.OpenGL popAttrib(); } - public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar); - [GlImport("glOrtho")] - static GlOrtho ortho; - public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar) - { - Load(context); - ortho(left, right, bottom, top, zNear, zFar); - } + //public delegate void GlOrtho(double left, double right, double bottom, double top, double zNear, double zFar); + //[GlImport("glOrtho")] + //static GlOrtho ortho; + //public static void Ortho(this IGlContext context, double left, double right, double bottom, double top, double zNear, double zFar) + //{ + // Load(context); + // ortho(left, right, bottom, top, zNear, zFar); + //} public delegate void GlGetFloatv(uint pname, float[] params_notkeyword); [GlImport("glGetFloatv")] diff --git a/ConsoleApp1/GLView.cs b/ConsoleApp1/GLView.cs index 717174b..766807e 100644 --- a/ConsoleApp1/GLView.cs +++ b/ConsoleApp1/GLView.cs @@ -1,84 +1,47 @@ -#if !NET40&&!NETCOREAPP3_0 +#if !NET40 using CPF; -using CPF.Animation; -using CPF.Charts; -using CPF.Controls; using CPF.Drawing; -using CPF.Shapes; -using CPF.Skia; -using CPF.Styling; -using CPF.Svg; using CPF.OpenGL; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using CPF.Skia; using SkiaSharp; -using Silk.NET.OpenGLES; -using static System.Net.Mime.MediaTypeNames; +using System; namespace ConsoleApp1 { [CPF.Design.DesignerLoadStyle("res://$safeprojectname$/Stylesheet1.css")]//用于设计的时候加载样式 - public class GLView : UIElement + public class GLView : CPF.Skia.GLView { - GL _gl; - public uint Id { get; set; } - - public uint ColorBuffer { get; set; } - - public uint DepthRenderBuffer { get; set; } - Size oldSize; - SKImage image; +#if !NETCOREAPP3_0 + Silk.NET.OpenGLES.GL _gl; uint vao; uint shaderProgram; - //IGlContext context; - protected unsafe override void OnRender(DrawingContext dc) + + protected unsafe override void OnGLLoaded(IGlContext gl) { - 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; - //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 = { + _gl = Silk.NET.OpenGLES.GL.GetApi(gl.GetProcAddress); + _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.0f, 0.5f, 0.0f }; - _gl.GenBuffers(1, out uint vbo); - _gl.BindBuffer(GLEnum.ArrayBuffer, vbo); - _gl.BufferData(GLEnum.ArrayBuffer, (nuint)vertices.Length * sizeof(float), vertices, GLEnum.StaticDraw); + _gl.GenBuffers(1, out uint vbo); + _gl.GenVertexArrays(1, out vao); - _gl.GenVertexArrays(1, out vao); - _gl.BindVertexArray(vao); - _gl.VertexAttribPointer(0, 3, GLEnum.Float, false, 3 * sizeof(float), null); - _gl.EnableVertexAttribArray(0); + _gl.BindBuffer(Silk.NET.OpenGLES.GLEnum.ArrayBuffer, vbo); + _gl.BindVertexArray(vao); - string vertexShaderSource = @"#version 330 core + _gl.BufferData(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; void main() { @@ -86,7 +49,7 @@ namespace ConsoleApp1 } "; - string fragmentShaderSource = @"#version 330 core + string fragmentShaderSource = @"#version 330 core out vec4 FragColor; void main() { @@ -94,81 +57,43 @@ namespace ConsoleApp1 } "; - uint vertexShader = _gl.CreateShader(GLEnum.VertexShader); - _gl.ShaderSource(vertexShader, vertexShaderSource); - _gl.CompileShader(vertexShader); + uint vertexShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.VertexShader); + _gl.ShaderSource(vertexShader, vertexShaderSource); + _gl.CompileShader(vertexShader); - uint fragmentShader = _gl.CreateShader(GLEnum.FragmentShader); - _gl.ShaderSource(fragmentShader, fragmentShaderSource); - _gl.CompileShader(fragmentShader); + uint fragmentShader = _gl.CreateShader(Silk.NET.OpenGLES.GLEnum.FragmentShader); + _gl.ShaderSource(fragmentShader, fragmentShaderSource); + _gl.CompileShader(fragmentShader); - shaderProgram = _gl.CreateProgram(); - _gl.AttachShader(shaderProgram, vertexShader); - _gl.AttachShader(shaderProgram, fragmentShader); - _gl.LinkProgram(shaderProgram); + shaderProgram = _gl.CreateProgram(); + _gl.AttachShader(shaderProgram, vertexShader); + _gl.AttachShader(shaderProgram, fragmentShader); + _gl.LinkProgram(shaderProgram); - _gl.DeleteShader(vertexShader); - _gl.DeleteShader(fragmentShader); - } - 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); + _gl.DeleteShader(vertexShader); + _gl.DeleteShader(fragmentShader); + base.OnGLLoaded(gl); } - 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.Clear(ClearBufferMask.ColorBufferBit); + _gl.ClearColor(0.5f, 1, 0, 0.5f); + _gl.Clear(Silk.NET.OpenGLES.ClearBufferMask.ColorBufferBit | Silk.NET.OpenGLES.ClearBufferMask.DepthBufferBit | Silk.NET.OpenGLES.ClearBufferMask.StencilBufferBit); + _gl.UseProgram(shaderProgram); + _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) - { - 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 \ No newline at end of file diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 760b9f2..e710cab 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -38,7 +38,12 @@ namespace ConsoleApp1 #if Net4 (OperatingSystemType.Windows, new WindowsPlatform(), new CPF.GDIPlus.GDIPlusDrawingFactory { ClearType = true }) #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.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false }) #endif diff --git a/ConsoleApp1/Window2.cs b/ConsoleApp1/Window2.cs index 06f3d34..2f9d4eb 100644 --- a/ConsoleApp1/Window2.cs +++ b/ConsoleApp1/Window2.cs @@ -472,9 +472,8 @@ namespace ConsoleApp1 }, new ScrollViewer { - MarginLeft = 421, - HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled, - VerticalScrollBarVisibility= ScrollBarVisibility.Visible, + MarginLeft = 421,//HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled, + //VerticalScrollBarVisibility= ScrollBarVisibility.Visible, Commands = { { @@ -499,6 +498,15 @@ namespace ConsoleApp1 // Name = nameof(pic), // 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 { Width="100%", @@ -562,6 +570,7 @@ namespace ConsoleApp1 }, } }, +#endif Height=300, MarginTop=19, MarginRight=29 @@ -739,17 +748,7 @@ namespace ConsoleApp1 Height = 58, Width = 121, }, - #if !Net4&&!NETCOREAPP3_0 - new GLView - { - MarginRight = 56, - MarginTop = 44, - Height = 132, - Width = 151, - [nameof(GLView.DoubleClick)]=new CommandDescribe((s,e)=>{ s.Dispose(); }), - }, - #endif - new Button + new Button { Commands = { @@ -1388,8 +1387,7 @@ namespace ConsoleApp1 MarginLeft = 252, MarginTop = 76, Height = 23, - Width = 219, - //[nameof(Slider.Value)]= new Obx(a => a.Type.Name), + Width = 219,//[nameof(Slider.Value)]= new Obx(a => a.Type.Name), [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, Children= { - new TextBlock { [nameof(TextBlock.Text)]= new Obx(a => a.Test1.test.test.test.test.Name, BindingMode.OneWay), Name = "hmbb" - }, - //new TextBox + },//new TextBox //{ // Width = 130, // Height= 60, @@ -2486,7 +2482,6 @@ new TabItemTemplate{ }, } }, - } } }, From 23289bbf15cced88c21b974593d5b87a620a693e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=BA=A2=E5=B8=BD?= <761716178@qq.com> Date: Wed, 29 Nov 2023 21:06:01 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E8=A7=A3=E5=86=B3GLView=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Skia/GlView.cs | 41 +++++++++++++++++++++++------ CPF.Skia/SkiaDrawingContext.cs | 9 +++++-- CPF/Binding.cs | 48 +++++++++++++++++++++++----------- ConsoleApp1/GLView.cs | 5 ++-- ConsoleApp1/Window2.cs | 25 ++++++++++++------ 5 files changed, 92 insertions(+), 36 deletions(-) diff --git a/CPF.Skia/GlView.cs b/CPF.Skia/GlView.cs index e2aa4a3..4038d16 100644 --- a/CPF.Skia/GlView.cs +++ b/CPF.Skia/GlView.cs @@ -18,19 +18,27 @@ namespace CPF.Skia int DepthRenderBuffer; Size oldSize; SKImage image; + SKPaint paint; + GRBackendTexture backendTexture; //IGlContext context; protected unsafe override void OnRender(DrawingContext dc) { - var size1 = ActualSize; - if (size1.Width <= 0 || size1.Height <= 0 || DesignMode) + var cSize = ActualSize; + if (cSize.Width <= 0 || cSize.Height <= 0 || DesignMode) { return; } - 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(cSize.Width * Root.RenderScaling), (int)Math.Round(cSize.Height * Root.RenderScaling)); var skia = dc as SkiaDrawingContext; var _gl = skia.GlContext; + if (paint == null) + { + paint = new SKPaint(); + } + paint.IsAntialias = IsAntiAlias; + paint.FilterQuality = IsAntiAlias ? SKFilterQuality.Medium : SKFilterQuality.None; if (Id == 0) { @@ -48,9 +56,9 @@ namespace CPF.Skia OnGLLoaded(_gl); } - if (size1 != oldSize) + if (cSize != oldSize) { - oldSize = size1; + oldSize = cSize; _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); @@ -73,7 +81,11 @@ namespace CPF.Skia { 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())); + if (backendTexture != null) + { + backendTexture.Dispose(); + } + backendTexture = new GRBackendTexture((int)(size.Width), (int)(size.Height), false, new GRGlTextureInfo(0x0DE1, (uint)ColorBuffer, SKColorType.Rgba8888.ToGlSizedFormat())); image = SKImage.FromTexture((GRContext)skia.GlContext.GRContext, backendTexture, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888); } @@ -84,7 +96,9 @@ namespace CPF.Skia _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); + _gl.BindFramebuffer(GlConsts.GL_FRAMEBUFFER, 0); + //_gl.Flush(); + skia.SKCanvas.DrawImage(image, new SKRect(0, 0, size.Width, size.Height), new SKRect(0, 0, cSize.Width, cSize.Height), paint); } @@ -117,12 +131,23 @@ namespace CPF.Skia OpenglEx.DeleteFramebuffers(null, 1, new int[] { Id }); OpenglEx.DeleteTextures(null, 1, new int[] { ColorBuffer }); OpenglEx.DeleteRenderbuffers(null, 1, new int[] { DepthRenderBuffer }); + Id = 0; } if (image != null) { image.Dispose(); image = null; } + if (paint != null) + { + paint.Dispose(); + paint = null; + } + if (backendTexture != null) + { + backendTexture.Dispose(); + backendTexture = null; + } base.Dispose(disposing); } } @@ -133,6 +158,6 @@ namespace CPF.Skia { Context = gl; } - public IGlContext Context { get;private set; } + public IGlContext Context { get; private set; } } } diff --git a/CPF.Skia/SkiaDrawingContext.cs b/CPF.Skia/SkiaDrawingContext.cs index 772167c..6e34ae6 100644 --- a/CPF.Skia/SkiaDrawingContext.cs +++ b/CPF.Skia/SkiaDrawingContext.cs @@ -156,6 +156,11 @@ namespace CPF.Skia surface.Dispose(); surface = null; } + if (gRContext != null) + { + //gRContext.Flush(); + gRContext.ResetContext(); + } //if (grContext != null) //{ // //grContext.Flush(); @@ -729,7 +734,7 @@ namespace CPF.Skia } lines = newText.Split('\n'); var ws = paint.Paint.MeasureAllChar(lines[0]); - + var wsEnd = new List<(string, float)>(); for (int i = ws.Count - 1; i >= 0; i--) { @@ -742,7 +747,7 @@ namespace CPF.Skia { //lenEnd = (lenEnd.Item1, lenEnd.Item2, newText.Substring(newText.Length - lenEnd.Item1, lenEnd.Item1)); lenEnd.Item3 = newText.Substring(newText.Length - lenEnd.Item1, lenEnd.Item1); - if (lenEnd.Item3.Length>2) + if (lenEnd.Item3.Length > 2) { lenEnd.Item3 = lenEnd.Item3.Substring(1, lenEnd.Item3.Length - 1); } diff --git a/CPF/Binding.cs b/CPF/Binding.cs index b529cf2..f58af5c 100644 --- a/CPF/Binding.cs +++ b/CPF/Binding.cs @@ -226,15 +226,31 @@ namespace CPF BindingMode = bindingMode; } internal Binding() { } - + /// + /// 多级绑定的属性集合 + /// + string[] sourcePropertyNames; internal bool IsDataContext = true; + + string sourcePropertyName; /// /// 数据源字段名 /// public string SourcePropertyName { - get; - internal set; + get { return sourcePropertyName; } + internal set + { + sourcePropertyName = value; + if (value != null) + { + sourcePropertyNames = SourcePropertyName.Split('.'); + } + else + { + sourcePropertyNames = null; + } + } } /// /// 链式绑定下标 @@ -362,7 +378,7 @@ namespace CPF current.Push(this); try { - + if (Source == null || !Source.IsAlive) { if (Owner.HasProperty(TargetPropertyName)) @@ -389,8 +405,9 @@ namespace CPF value = Source.Target.GetPropretyValue(SourcePropertyName); }*/ value = GetPropertySource(SourcePropertyName, Source.Target); - if (value != null) { - value = value.GetPropretyValue(SourcePropertyName.Split('.').LastOrDefault()); + if (value != null) + { + value = value.GetPropretyValue(sourcePropertyNames.LastOrDefault()); } if (Convert != null) { @@ -456,7 +473,7 @@ namespace CPF { if (!b.SetValue(nv, SourcePropertyName)) { - /*var SourcePropertyNames = SourcePropertyName.Split('.'); + /*var SourcePropertyNames = sourcePropertyNames; if (SourcePropertyNames.Length == 1) { b.SetValue(SourcePropertyName, nv); @@ -466,12 +483,13 @@ namespace CPF { Target = Target.GetPropretyValue(SourcePropertyNames[i]) as CpfObject; }*/ - var SourcePropertyNames = SourcePropertyName.Split('.'); + var SourcePropertyNames = sourcePropertyNames; var Target = GetPropertySource(SourcePropertyName, b); - if (Target != null) { + if (Target != null) + { Target.SetValue(SourcePropertyNames.LastOrDefault(), nv); } - + //b.Type.GetProperty(SourcePropertyName).FastSetValue(b, nv); } } @@ -551,7 +569,7 @@ namespace CPF } void PropertyChanged(object sender, PropertyChangedEventArgs e) { - var Temp_SourcePropertyName = SourcePropertyName.Split('.').LastOrDefault(); + var Temp_SourcePropertyName = sourcePropertyNames.LastOrDefault(); if (Temp_SourcePropertyName == e.PropertyName) { //CPFObject s = sender as CPFObject; @@ -576,11 +594,11 @@ namespace CPF } } } - internal object GetPropertySource(string SourcePropertyName,object Source) + internal object GetPropertySource(string SourcePropertyName, object Source) { try { - var SourcePropertyNames = SourcePropertyName.Split('.'); + var SourcePropertyNames = sourcePropertyNames; if (SourcePropertyNames.Length == 1) { return Source; @@ -610,7 +628,7 @@ namespace CPF BindingMode == BindingMode.OneWay || BindingMode == BindingMode.OneTime) { - var SourcePropertyNames = SourcePropertyName.Split('.'); + var SourcePropertyNames = sourcePropertyNames; var Temp_Target = GetPropertySource(SourcePropertyName, Source.Target); var data = (Temp_Target as CpfObject)?.GetValue(SourcePropertyNames.LastOrDefault()); Owner.SetPropretyValue(TargetPropertyName, data); @@ -624,7 +642,7 @@ namespace CPF //{ // throw new Exception("错误"); //} - var SourcePropertyNames = SourcePropertyName.Split('.'); + var SourcePropertyNames = sourcePropertyNames; if (SourcePropertyNames.Length == 1) { RegisterPropertyChanged(notify, PropertyChanged); diff --git a/ConsoleApp1/GLView.cs b/ConsoleApp1/GLView.cs index 766807e..1047285 100644 --- a/ConsoleApp1/GLView.cs +++ b/ConsoleApp1/GLView.cs @@ -72,7 +72,7 @@ namespace ConsoleApp1 _gl.DeleteShader(vertexShader); _gl.DeleteShader(fragmentShader); - base.OnGLLoaded(gl); + //base.OnGLLoaded(gl); } @@ -82,14 +82,13 @@ namespace ConsoleApp1 _gl.Clear(Silk.NET.OpenGLES.ClearBufferMask.ColorBufferBit | Silk.NET.OpenGLES.ClearBufferMask.DepthBufferBit | Silk.NET.OpenGLES.ClearBufferMask.StencilBufferBit); _gl.UseProgram(shaderProgram); - _gl.BindVertexArray(vao); _gl.DrawArrays(Silk.NET.OpenGLES.GLEnum.Triangles, 0, 3); _gl.BindVertexArray(0); _gl.UseProgram(0); - base.OnGLRender(gl); + //base.OnGLRender(gl); } #endif diff --git a/ConsoleApp1/Window2.cs b/ConsoleApp1/Window2.cs index 2f9d4eb..7ad5f38 100644 --- a/ConsoleApp1/Window2.cs +++ b/ConsoleApp1/Window2.cs @@ -472,6 +472,7 @@ namespace ConsoleApp1 }, new ScrollViewer { + Background = "url(res://ConsoleApp1/icon.png) Tile None 0,0,0,0", MarginLeft = 421,//HorizontalScrollBarVisibility= ScrollBarVisibility.Disabled, //VerticalScrollBarVisibility= ScrollBarVisibility.Visible, Commands = @@ -505,8 +506,9 @@ namespace ConsoleApp1 { Height = 336, Width = 421, + IsAntiAlias=true, }, -#else + #else new WrapPanel { Width="100%", @@ -570,7 +572,7 @@ namespace ConsoleApp1 }, } }, -#endif + #endif Height=300, MarginTop=19, MarginRight=29 @@ -625,7 +627,7 @@ namespace ConsoleApp1 Value=0.001, Bindings = { - + } }, new Button @@ -1967,7 +1969,7 @@ namespace ConsoleApp1 }, new Separator { - + }, new MenuItem { @@ -2465,8 +2467,6 @@ new TabItemTemplate{ Content="删除对象", [nameof(Button.Click)]=new CommandDescribe((s,e)=> { - data a = new data(); - a.test.test.Name = "666666"; (DataContext as MainModel).Test1.test.test = null; }) }, @@ -2476,7 +2476,7 @@ new TabItemTemplate{ [nameof(Button.Click)]=new CommandDescribe((s,e)=> { data a = new data(); - a.test.test.Name = "666666"; + a.test.test.Name = "8888"; (DataContext as MainModel).Test1.test.test = a; }) }, @@ -3456,10 +3456,19 @@ new TabItemTemplate{ { MaximizeBox = true, ShadowBlur = 10, - #if !DesignMode +#if !DesignMode //Effect = effect #endif }); + +//#if !Net4 && !NETCOREAPP3_0 +// Children.Add(new GLView +// { +// Height = "30%", +// Width = "30%", +// IsAntiAlias = true, +// }); +//#endif LoadStyleFile("res://ConsoleApp1/Stylesheet3.css"); //加载样式文件,文件需要设置为内嵌资源 Console.WriteLine(testBtn[DockPanel.Dock]); From 4e23e93d9dff9f7401818f2fdcee644e3dbaf533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E7=BA=A2=E5=B8=BD?= <761716178@qq.com> Date: Thu, 30 Nov 2023 15:12:23 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E7=AE=80=E5=8C=96=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E5=99=A8=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Skia/GlView.cs | 4 ++ CPF/BindingDescribe.cs | 53 +++++++++++++- CPF/Controls/ContentTemplate.cs | 53 +++++++++++++- CPF/Controls/ListBoxItem.cs | 7 +- CPF/CpfObject.cs | 23 +++++- CPF/Styling/Trigger.cs | 112 +++++++++++++++++++++++++++++- CPF/UIElement.cs | 17 +++++ ConsoleApp1/Program.cs | 2 +- ConsoleApp1/Window1.cs | 119 +++++++++++++++++++++++++++----- 9 files changed, 362 insertions(+), 28 deletions(-) diff --git a/CPF.Skia/GlView.cs b/CPF.Skia/GlView.cs index 4038d16..f2431c6 100644 --- a/CPF.Skia/GlView.cs +++ b/CPF.Skia/GlView.cs @@ -20,6 +20,10 @@ namespace CPF.Skia SKImage image; SKPaint paint; GRBackendTexture backendTexture; + /// + /// 支持OpenGL绘制的控件,在GLRender事件里绘制,开启GPU硬件加速才能使用 new SkiaDrawingFactory { UseGPU = true } + /// + public GLView() { } //IGlContext context; protected unsafe override void OnRender(DrawingContext dc) diff --git a/CPF/BindingDescribe.cs b/CPF/BindingDescribe.cs index 8bae5ac..ec0f1ce 100644 --- a/CPF/BindingDescribe.cs +++ b/CPF/BindingDescribe.cs @@ -17,29 +17,54 @@ namespace CPF { PropertyName = sourceProperty; } - + public BindingDescribe(string sourceProperty, BindingMode binding) { PropertyName = sourceProperty; BindingMode = binding; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// public BindingDescribe(object source, string sourceProperty, BindingMode binding) { PropertyName = sourceProperty; BindingMode = binding; Source = source; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// public BindingDescribe(object source, string sourceProperty) { PropertyName = sourceProperty; Source = source; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// public BindingDescribe(object source, string sourceProperty, Func convert) { PropertyName = sourceProperty; Source = source; Convert = convert; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// + /// public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert) { BindingMode = binding; @@ -47,6 +72,14 @@ namespace CPF Source = source; Convert = convert; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// + /// + /// public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack) { BindingMode = binding; @@ -55,6 +88,16 @@ namespace CPF Convert = convert; ConvertBack = convertBack; } + /// + /// 设置绑定 + /// + /// 如果是int或者byte,0是自己,1是Parent,2是Parent.Parent.... + /// + /// + /// + /// + /// + /// public BindingDescribe(object source, string sourceProperty, BindingMode binding, Func convert, Func convertBack, Action SourceToTargetError, Action TargetToSourceError) { BindingMode = binding; @@ -81,6 +124,10 @@ namespace CPF /// 简化绑定命令的命令,如果设置了该属性,则使用命令绑定 /// public CommandDescribe Command { get; set; } + /// + /// 简化触发器设置 + /// + public CPF.Styling.TriggerDescribe Trigger { get; set; } //public CpfObject Owner { get; internal set; } @@ -355,6 +402,10 @@ namespace CPF { return new BindingDescribe { Command = command }; } + public static implicit operator BindingDescribe(CPF.Styling.TriggerDescribe trigger) + { + return new BindingDescribe { Trigger = trigger }; + } public static implicit operator BindingDescribe((string sourceProperty, BindingMode binding) item) { return new BindingDescribe { PropertyName = item.sourceProperty, BindingMode = item.binding }; diff --git a/CPF/Controls/ContentTemplate.cs b/CPF/Controls/ContentTemplate.cs index ab2ef36..3a982fc 100644 --- a/CPF/Controls/ContentTemplate.cs +++ b/CPF/Controls/ContentTemplate.cs @@ -10,7 +10,7 @@ namespace CPF.Controls /// 内容模板 /// [Description("内容模板"), Browsable(false)] - public class ContentTemplate : Decorator + public class ContentTemplate : Control { [PropertyMetadata(null)] public object Content @@ -85,9 +85,56 @@ namespace CPF.Controls overridePropertys.Override(nameof(Width), new UIPropertyMetadataAttribute(typeof(FloatField), "100%", UIPropertyOptions.AffectsMeasure)); overridePropertys.Override(nameof(Height), new UIPropertyMetadataAttribute(typeof(FloatField), "100%", UIPropertyOptions.AffectsMeasure)); } - //protected override Size MeasureOverride(in Size availableSize) + + /// + /// 获取或设置 单一子元素。 + /// + [Browsable(false)] + protected UIElement Child + { + get { return GetValue(); } + set { SetValue(value); } + } + + [PropertyChanged(nameof(Child))] + void OnChild(object newValue, object oldValue, PropertyMetadataAttribute attribute) + { + var o = oldValue as UIElement; + if (o != null) + { + Children.Remove(o); + } + var c = newValue as UIElement; + if (c != null) + { + Children.Add(c); + } + } + //protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) //{ - // return base.MeasureOverride(availableSize); + // base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata); + // if (propertyName == nameof(Child)) + // { + // var o = oldValue as UIElement; + // if (o != null) + // { + // Children.Remove(o); + // } + // var c = newValue as UIElement; + // if (c != null) + // { + // Children.Add(c); + // } + // } //} + + protected override void OnUIElementRemoved(UIElementRemovedEventArgs e) + { + base.OnUIElementRemoved(e); + if (e.Element == Child) + { + Child = null; + } + } } } diff --git a/CPF/Controls/ListBoxItem.cs b/CPF/Controls/ListBoxItem.cs index 89fa0c7..b2c9fd7 100644 --- a/CPF/Controls/ListBoxItem.cs +++ b/CPF/Controls/ListBoxItem.cs @@ -90,8 +90,11 @@ namespace CPF.Controls Name = "contentPresenter", PresenterFor = this }); - Triggers.Add(new Styling.Trigger { Property = nameof(IsMouseOver), PropertyConditions = a => (bool)a && !IsSelected, Setters = { { nameof(Background), "229,243,251" } } }); - Triggers.Add(new Styling.Trigger { Property = nameof(IsSelected), Setters = { { nameof(Background), "203,233,246" } } }); + //Triggers.Add(new Styling.Trigger { Property = nameof(IsMouseOver), PropertyConditions = a => (bool)a && !IsSelected, Setters = { { nameof(Background), "229,243,251" } } }); + //Triggers.Add(new Styling.Trigger { Property = nameof(IsSelected), Setters = { { nameof(Background), "203,233,246" } } }); + + this[nameof(IsMouseOver)] = new Styling.TriggerDescribe(a => (bool)a && !IsSelected, (nameof(Background), "229,243,251")); + this[nameof(IsSelected)] = new Styling.TriggerDescribe((nameof(Background), "203,233,246")); } /// diff --git a/CPF/CpfObject.cs b/CPF/CpfObject.cs index b562a19..aaab87d 100644 --- a/CPF/CpfObject.cs +++ b/CPF/CpfObject.cs @@ -209,12 +209,33 @@ namespace CPF } } } + else if (value.Trigger != null) + { + OnAddTriggerDescribe(propertyName, value.Trigger); + } else { - Bindings.Add(propertyName, value.PropertyName, value.Source, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError); + if (value.Source is int layer) + { + Bindings.Add(propertyName, value.PropertyName, (byte)layer, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError); + } + if (value.Source is byte layer1) + { + Bindings.Add(propertyName, value.PropertyName, layer1, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError); + } + else + { + Bindings.Add(propertyName, value.PropertyName, value.Source, value.BindingMode, value.Convert, value.ConvertBack, value.SourceToTargetError, value.TargetToSourceError); + } } } } + + internal protected virtual void OnAddTriggerDescribe(string property, TriggerDescribe trigger) + { + + } + /// /// 读取或者设置附加属性,参数必须是附加属性 /// diff --git a/CPF/Styling/Trigger.cs b/CPF/Styling/Trigger.cs index de90d7f..0fdd4e3 100644 --- a/CPF/Styling/Trigger.cs +++ b/CPF/Styling/Trigger.cs @@ -43,8 +43,12 @@ namespace CPF.Styling this.PropertyConditions = DefaultPropertyConditions; } } - - bool DefaultPropertyConditions(object v) + /// + /// 属性为true的条件 + /// + /// + /// + public bool DefaultPropertyConditions(object v) { return (bool)v; } @@ -143,6 +147,110 @@ namespace CPF.Styling internal HybridDictionary> SetPropertys; } + public class TriggerDescribe + { + /// + /// 触发器 + /// + public TriggerDescribe(Relation TargetRelation, Func PropertyConditions, params (string, object)[] propertyAndValues) + { + this.TargetRelation = TargetRelation; + this.PropertyConditions = PropertyConditions; + this.Setters = propertyAndValues; + } + /// + /// 触发器 + /// + public TriggerDescribe(params (string, object)[] propertyAndValues) + { + this.Setters = propertyAndValues; + } + /// + /// 触发器 + /// + public TriggerDescribe(Func PropertyConditions, params (string, object)[] propertyAndValues) + { + this.PropertyConditions = PropertyConditions; + this.Setters = propertyAndValues; + } + /// + /// 触发器 + /// + /// + /// + /// + /// + /// + /// + /// + public TriggerDescribe(Relation TargetRelation = null, Func PropertyConditions = default, Storyboard Animation = null, TimeSpan? AnimationDuration = null, uint AnimationIterationCount = 1, EndBehavior AnimationEndBehavior = EndBehavior.Recovery, params (string, object)[] propertyAndValues) + { + this.TargetRelation = TargetRelation; + this.PropertyConditions = PropertyConditions; + this.PropertyConditions = PropertyConditions; + this.Setters = propertyAndValues; + this.Animation = Animation; + if (AnimationDuration.HasValue) + { + this.AnimationDuration = AnimationDuration.Value; + } + this.AnimationIterationCount = AnimationIterationCount; + this.AnimationEndBehavior = AnimationEndBehavior; + } + + + + /// + /// 满足条件之后播放的动画 + /// + public Storyboard Animation { get; set; } + + ///// + ///// 条件属性 + ///// + //public string Property { get; set; } + + /// + /// 属性条件,参数是属性值,返回条件结果 + /// + public Func PropertyConditions { get; set; } + + public (string, object)[] Setters { get; set; } + + /// + /// 相对位置元素,用来设置值或者动画 + /// + public Relation TargetRelation { get; set; } + + + /// + /// 动画持续时间 + /// + public TimeSpan AnimationDuration + { + get; + set; + } = TimeSpan.FromSeconds(0.5); + + /// + /// 动画播放次数,0为无限循环 + /// + public uint AnimationIterationCount + { + get; + set; + } = 1; + + /// + /// 动画结束之后的行为 + /// + public EndBehavior AnimationEndBehavior + { + get; + set; + } = EndBehavior.Recovery; + } + //public enum Conditions //{ // NotEqual, diff --git a/CPF/UIElement.cs b/CPF/UIElement.cs index 4057dac..95c67cd 100644 --- a/CPF/UIElement.cs +++ b/CPF/UIElement.cs @@ -3280,6 +3280,23 @@ namespace CPF } } + protected internal override void OnAddTriggerDescribe(string property, TriggerDescribe trigger) + { + var t = new Trigger { Animation = trigger.Animation, AnimationDuration = trigger.AnimationDuration, AnimationEndBehavior = trigger.AnimationEndBehavior, AnimationIterationCount = trigger.AnimationIterationCount, PropertyConditions = trigger.PropertyConditions, TargetRelation = trigger.TargetRelation, Property = property }; + if (trigger.Setters != null && trigger.Setters.Length > 0) + { + foreach (var item in trigger.Setters) + { + t.Setters.Add(item.Item1, item.Item2); + } + } + if (t.PropertyConditions == null) + { + t.PropertyConditions = t.DefaultPropertyConditions; + } + Triggers.Add(t); + } + //Styles styles; protected override void Dispose(bool disposing) diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index e710cab..cf295bb 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -45,7 +45,7 @@ namespace ConsoleApp1 #endif }) , (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 = true }) #endif ); diff --git a/ConsoleApp1/Window1.cs b/ConsoleApp1/Window1.cs index aebd668..20abfe9 100644 --- a/ConsoleApp1/Window1.cs +++ b/ConsoleApp1/Window1.cs @@ -105,7 +105,7 @@ namespace ConsoleApp1 }, new RowDefinition { - + } }, }); @@ -419,7 +419,7 @@ namespace ConsoleApp1 }, new Separator { - + }, new MenuItem { @@ -429,10 +429,13 @@ namespace ConsoleApp1 new MenuItem { Header = "21", - Commands = - { - {nameof(MenuItem.Click),MenuItemClick } - } + Commands = + { + { + nameof(MenuItem.Click), + MenuItemClick + } + } }, new MenuItem { @@ -444,7 +447,10 @@ namespace ConsoleApp1 Header = "221", Commands = { - {nameof(MenuItem.Click),MenuItemClick } + { + nameof(MenuItem.Click), + MenuItemClick + } } }, new MenuItem @@ -452,7 +458,10 @@ namespace ConsoleApp1 Header = "222", Commands = { - {nameof(MenuItem.Click),MenuItemClick } + { + nameof(MenuItem.Click), + MenuItemClick + } } } } @@ -468,10 +477,13 @@ namespace ConsoleApp1 new MenuItem { Header = "31", - Commands = - { - {nameof(MenuItem.Click),MenuItemClick } - } + Commands = + { + { + nameof(MenuItem.Click), + MenuItemClick + } + } }, new MenuItem { @@ -1362,7 +1374,8 @@ namespace ConsoleApp1 }, new ListBox { - //Background="#aaa", + MarginLeft = 57, + MarginTop = 63,//Background="#aaa", Name="listbox", IsVirtualizing=true,//VirtualizationMode= VirtualizationMode.Recycling, SelectionMode= SelectionMode.Extended, @@ -1372,7 +1385,18 @@ namespace ConsoleApp1 { Width="100%", FontSize=22, - Tag=this, + Tag=this, + Template=(e,c)=>{ + c.Add(new Border + { + Background="#f00", + Height = "100%", + Width = "100%", + BorderFill = null, + Name = "contentPresenter", + PresenterFor = this + }); + } }, Bindings= { @@ -1398,6 +1422,65 @@ namespace ConsoleApp1 } } },//new Button{ Content="排序" }, + new ListBox + { + MarginLeft = 463, + MarginTop = 44, + Height = 431, + Width = 283, + Background = "white", + BorderFill = new SolidColorFill + { + Color = Color.Silver + }, + BorderThickness = new Thickness(0, 1, 0, 0), + BorderType = BorderType.BorderThickness, + ItemsPanel = new StackPanel + { + Orientation = Orientation.Horizontal + }, + ItemTemplate = new ListBoxItem + { + Width = 100, + MarginRight = 1, + FontSize = 16f, + BorderFill = "Silver", + BorderThickness = new Thickness(1), + Margin = new ThicknessField(1), + CornerRadius = new CornerRadius(2), + IsAntiAlias = true, + UseLayoutRounding = true, + BorderType = BorderType.BorderThickness, + Template=(e,c)=>{ + Children.Add(new Border + { + Background="#f00", + Height = "100%", + Width = "100%", + BorderFill = null, + Name = "contentPresenter", + PresenterFor = this + }); + } + //ContentTemplate = new ContentTemplate + //{ + // Size = SizeField.Fill, + // Content = new StackPanel + // { + // Orientation = Orientation.Horizontal, + // Size = SizeField.Fill, + // Children = + // { + // new TextBlock + // { + // //[nameof(TextBlock.Text)] = new BindingDescribe("Title",BindingMode.OneWay) + // Text = "test" + // } + // } + // }, + //}, + }, + } } } }, @@ -1719,7 +1802,7 @@ namespace ConsoleApp1 nameof(DragEnter), (s,e)=> { - //(e as DragEventArgs).DragEffects= DragDropEffects.Link; + //(e as DragEventArgs).DragEffects= DragDropEffects.Link; } }, } @@ -1762,7 +1845,7 @@ namespace ConsoleApp1 Content="模糊,你撸多了", Effect=new BlurEffect { - + } }, new Button @@ -1789,7 +1872,7 @@ namespace ConsoleApp1 Content="灰色", Effect=new GrayScaleEffect { - + } }, new Picture @@ -1998,7 +2081,7 @@ namespace ConsoleApp1 { new RowDefinition { - + }, }, Children =