Пример #1
0
        public new void DrawInRect(GLKView view, CGRect rect)
        {
            if (designMode)
            {
                return;
            }

            // create the contexts if not done already
            if (context == null)
            {
                var glInterface = GRGlInterface.Create();
                context = GRContext.CreateGl(glInterface);
            }

            // get the new surface size
            var newSize = new SKSizeI((int)DrawableWidth, (int)DrawableHeight);

            // manage the drawing surface
            if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                // read the info from the buffer
                Gles.glGetIntegerv(Gles.GL_FRAMEBUFFER_BINDING, out var framebuffer);
                Gles.glGetIntegerv(Gles.GL_STENCIL_BITS, out var stencil);
                Gles.glGetIntegerv(Gles.GL_SAMPLES, out var samples);
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
                var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo);
                OnPaintSurface(e);
#pragma warning disable CS0618 // Type or member is obsolete
                DrawInSurface(e.Surface, e.RenderTarget);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp contents to GL
            canvas.Flush();
            context.Flush();
        }
Пример #2
0
        public override void DrawInCGLContext(CGLContext glContext, CGLPixelFormat pixelFormat, double timeInterval, ref CVTimeStamp timeStamp)
        {
            CGLContext.CurrentContext = glContext;

            if (context == null)
            {
                // get the bits for SkiaSharp
                var glInterface = GRGlInterface.CreateNativeGlInterface();
                context = GRContext.Create(GRBackend.OpenGL, glInterface);
            }

            // manage the drawing surface
            var surfaceWidth  = (int)(Bounds.Width * ContentsScale);
            var surfaceHeight = (int)(Bounds.Height * ContentsScale);
            var newSize       = new SKSizeI(surfaceWidth, surfaceHeight);

            if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                // read the info from the buffer
                Gles.glGetIntegerv(Gles.GL_FRAMEBUFFER_BINDING, out var framebuffer);
                Gles.glGetIntegerv(Gles.GL_STENCIL_BITS, out var stencil);
                Gles.glGetIntegerv(Gles.GL_SAMPLES, out var samples);
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
                var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo);
                OnPaintSurface(e);
#pragma warning disable CS0618 // Type or member is obsolete
                DrawInSurface(e.Surface, e.RenderTarget);
                SKDelegate?.DrawInSurface(e.Surface, e.RenderTarget);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp context to the GL context
            canvas.Flush();
            context.Flush();

            base.DrawInCGLContext(glContext, pixelFormat, timeInterval, ref timeStamp);
        }
Пример #3
0
        private void Render(int cornerCount = 100, int maxVisibleDistance = 200)
        {
            // create the field if needed or if the size changed
            if (field == null || field.width != glControl1.Width || field.height != glControl1.Height)
            {
                field = new IntroAnimation.Field(glControl1.Width, glControl1.Height, cornerCount);
            }

            // step the field forward in time
            field.StepForward(3);

            // Create a Skia surface using the OpenGL control
            SKColorType colorType     = SKColorType.Rgba8888;
            GRContext   contextOpenGL = GRContext.Create(GRBackend.OpenGL, GRGlInterface.CreateNativeGlInterface());

            GL.GetInteger(GetPName.FramebufferBinding, out var framebuffer);
            GRGlFramebufferInfo glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

            GL.GetInteger(GetPName.StencilBits, out var stencil);
            GRBackendRenderTarget renderTarget = new GRBackendRenderTarget(glControl1.Width, glControl1.Height, contextOpenGL.GetMaxSurfaceSampleCount(colorType), stencil, glInfo);
            SKSurface             surface      = SKSurface.Create(contextOpenGL, renderTarget, GRSurfaceOrigin.BottomLeft, colorType);
            SKCanvas canvas = surface.Canvas;

            // draw the stuff
            var bgColor = field.GetBackgroundColor();

            canvas.Clear(new SKColor(bgColor.R, bgColor.G, bgColor.B));

            // draw circles at every corner
            var paint = new SKPaint {
                Color = new SKColor(255, 255, 255), IsAntialias = true
            };
            float radius = 2;

            for (int cornerIndex = 0; cornerIndex < field.corners.Length; cornerIndex++)
            {
                canvas.DrawCircle((float)field.corners[cornerIndex].X, (float)field.corners[cornerIndex].Y, radius, paint);
            }

            // draw lines between every corner and every other corner
            for (int i = 0; i < field.corners.Length; i++)
            {
                for (int j = 0; j < field.corners.Length; j++)
                {
                    double distance = field.GetDistance(i, j);
                    if (distance < maxVisibleDistance && distance != 0)
                    {
                        SKPoint pt1 = new SKPoint((float)field.corners[i].X, (float)field.corners[i].Y);
                        SKPoint pt2 = new SKPoint((float)field.corners[j].X, (float)field.corners[j].Y);
                        double  distanceFraction = distance / maxVisibleDistance;
                        byte    alpha            = (byte)(255 - distanceFraction * 256);
                        var     linePaint        = new SKPaint {
                            Color = new SKColor(255, 255, 255, alpha), IsAntialias = true
                        };
                        canvas.DrawLine(pt1, pt2, linePaint);
                    }
                }
            }

            // Force a display
            surface.Canvas.Flush();
            glControl1.SwapBuffers();

            // dispose to prevent memory access violations while exiting
            renderTarget?.Dispose();
            contextOpenGL?.Dispose();
            canvas?.Dispose();
            surface?.Dispose();

            // update the FPS display
            Text = field.GetBenchmarkMessage();
        }
Пример #4
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES10.GlClear(GLES10.GlColorBufferBit | GLES10.GlDepthBufferBit | GLES10.GlStencilBufferBit);

            // create the contexts if not done already
            if (context == null)
            {
                var glInterface = GRGlInterface.Create();
                context = GRContext.CreateGl(glInterface);
            }

            // manage the drawing surface
            if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                // read the info from the buffer
                var buffer = new int[3];
                GLES20.GlGetIntegerv(GLES20.GlFramebufferBinding, buffer, 0);
                GLES20.GlGetIntegerv(GLES20.GlStencilBits, buffer, 1);
                GLES20.GlGetIntegerv(GLES20.GlSamples, buffer, 2);
                var samples    = buffer[2];
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                glInfo = new GRGlFramebufferInfo((uint)buffer[0], colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, buffer[1], glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
                var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo);
                OnPaintSurface(e);
#pragma warning disable CS0618 // Type or member is obsolete
                OnDrawFrame(e.Surface, e.RenderTarget);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp contents to GL
            canvas.Flush();
            context.Flush();
        }
Пример #5
0
        public virtual void Render()
        {
            if (glContext == null)
            {
                PrepareGLContexts();
            }

            EAGLContext.SetCurrentContext(glContext);

            // get the new surface size
            var newSize = lastSize;

            if (recreateSurface)
            {
                Gles.glGetRenderbufferParameteriv(Gles.GL_RENDERBUFFER, Gles.GL_RENDERBUFFER_WIDTH, out var bufferWidth);
                Gles.glGetRenderbufferParameteriv(Gles.GL_RENDERBUFFER, Gles.GL_RENDERBUFFER_HEIGHT, out var bufferHeight);
                newSize = new SKSizeI(bufferWidth, bufferHeight);
            }

            // manage the drawing surface
            if (recreateSurface || renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                // read the info from the buffer
                Gles.glGetIntegerv(Gles.GL_FRAMEBUFFER_BINDING, out var framebuffer);
                Gles.glGetIntegerv(Gles.GL_STENCIL_BITS, out var stencil);
                Gles.glGetIntegerv(Gles.GL_SAMPLES, out var samples);
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
#pragma warning disable CS0618 // Type or member is obsolete
                var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo);
                OnPaintSurface(e);
                DrawInSurface(e.Surface, e.RenderTarget);
                SKDelegate?.DrawInSurface(e.Surface, e.RenderTarget);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp context to the GL context
            canvas.Flush();
            context.Flush();

            // present the GL buffers
            glContext.PresentRenderBuffer(Gles.GL_RENDERBUFFER);
            EAGLContext.SetCurrentContext(null);
        }
Пример #6
0
        protected override void OnRenderFrame(Rect rect)
        {
            // clear everything
            Gles.glClear(Gles.GL_COLOR_BUFFER_BIT | Gles.GL_DEPTH_BUFFER_BIT | Gles.GL_STENCIL_BUFFER_BIT);

            // create the SkiaSharp context
            if (context == null)
            {
                glInterface = GRGlInterface.Create();
                context     = GRContext.CreateGl(glInterface);
            }

            // get the new surface size
            var newSize = new SKSizeI((int)rect.Width, (int)rect.Height);

            // manage the drawing surface
            if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                // read the info from the buffer
                Gles.glGetIntegerv(Gles.GL_FRAMEBUFFER_BINDING, out var framebuffer);
                Gles.glGetIntegerv(Gles.GL_STENCIL_BITS, out var stencil);
                Gles.glGetIntegerv(Gles.GL_SAMPLES, out var samples);
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }

                glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
#pragma warning disable CS0612 // Type or member is obsolete
                OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo));
#pragma warning restore CS0612 // Type or member is obsolete
            }

            // update the control
            canvas.Flush();
            context.Flush();
        }
Пример #7
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (designMode)
            {
                e.Graphics.Clear(BackColor);
                return;
            }

            base.OnPaint(e);

            MakeCurrent();

            // create the contexts if not done already
            if (grContext == null)
            {
                var glInterface = GRGlInterface.Create();
                grContext = GRContext.CreateGl(glInterface);
            }

            // get the new surface size
            var newSize = new SKSizeI(Width, Height);

            // manage the drawing surface
            if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid)
            {
                // create or update the dimensions
                lastSize = newSize;

                GL.GetInteger(GetPName.FramebufferBinding, out var framebuffer);
                GL.GetInteger(GetPName.StencilBits, out var stencil);
                GL.GetInteger(GetPName.Samples, out var samples);
                var maxSamples = grContext.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat());

                // destroy the old surface
                surface?.Dispose();
                surface = null;
                canvas  = null;

                // re-create the render target
                renderTarget?.Dispose();
                renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo);
            }

            // create the surface
            if (surface == null)
            {
                surface = SKSurface.Create(grContext, renderTarget, surfaceOrigin, colorType);
                canvas  = surface.Canvas;
            }

            using (new SKAutoCanvasRestore(canvas, true))
            {
                // start drawing
                OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo));
            }

            // update the control
            canvas.Flush();
            SwapBuffers();
        }
Пример #8
0
        public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, GRGlFramebufferInfo glInfo)
        {
            Surface             = surface;
            BackendRenderTarget = renderTarget;
            ColorType           = colorType;
            Origin = origin;
#pragma warning disable CS0612 // Type or member is obsolete
            rtDesc = CreateDesc(glInfo);
#pragma warning restore CS0612 // Type or member is obsolete
        }
Пример #9
0
        public static void Main(string[] args)
        {
            Glfw.SetErrorCallback((error, description) => { Console.WriteLine($"GLFW Error {error}: {description}"); });
            Glfw.Init();

            IntPtr primaryMonitorPtr = Glfw.GetPrimaryMonitor();

            Glfw.VidMode videoMode = Glfw.GetVideoMode(primaryMonitorPtr);
            Glfw.GetMonitorWorkarea(primaryMonitorPtr, out var workAreaX, out var workAreaY, out var workAreaWidth, out var workAreaHeight);

            // For a full-screen game, replace IntPtr.Zero with primaryMonitorPtr
            IntPtr monitorPtr = IntPtr.Zero;

            // Create a GLFW window
            var windowPtr = Glfw.CreateWindow(workAreaWidth, workAreaHeight, "C# tutorial for Mats", monitorPtr, IntPtr.Zero);

            Glfw.GetWindowSize(windowPtr, out var viewWidth, out var viewHeight);

            // Switch to full screen.
            // Glfw.SetWindowMonitor(windowPtr, primaryMonitorPtr, 0, 0, workAreaWidth, workAreaHeight, 60);

            // Make sure the OpenGL rendering context is set on the current thread,
            // otherwise Skia's GRContext.Create(GRBackend.OpenGL) will return null
            Glfw.MakeContextCurrent(windowPtr);

            var frameBufferInfo = new GRGlFramebufferInfo((uint)new UIntPtr(0), GRPixelConfig.Rgba8888.ToGlSizedFormat());

            using var backendRenderTarget = new GRBackendRenderTarget(viewWidth, viewHeight, 0, 8, frameBufferInfo);

            using var grContext = GRContext.Create(GRBackend.OpenGL);

            using var skSurface = SKSurface.Create(grContext, backendRenderTarget, GRSurfaceOrigin.BottomLeft, SKImageInfo.PlatformColorType);

            // get the canvas from the surface
            using var skCanvas = skSurface.Canvas;

            var scene = Level.Load();

            var frameDuration = TimeSpan.FromSeconds(1.0 / videoMode.RefreshRate);

            var stopwatch = new Stopwatch();

            using var fpsTextPaint = new SKPaint
                  {
                      Style       = SKPaintStyle.Fill,
                      Color       = SKColors.White,
                      IsAntialias = true,
                      TextSize    = 20,
                  };

            TimeSpan renderDuration = default;
            TimeSpan updateDuration = default;

            var viewScale     = viewWidth / Grid.Width * 0.95f;
            var viewTransform = new SKMatrix(
                viewScale, 0, viewWidth / 2f,
                0, viewScale, viewHeight / 2f,
                0, 0, 1);

            var inputState = new InputState(windowPtr, viewTransform);


            while (Glfw.WindowShouldClose(windowPtr) == Glfw.False)
            {
                stopwatch.Restart();

                // Let GLFW process any queued input events, like keyboard, mouse, ...
                Glfw.PollEvents();

                skCanvas.Save();

                skCanvas.SetMatrix(viewTransform);

                // Clear the drawing canvas
                skCanvas.Clear(SKColors.DimGray);

                // Draw to scene to the canvas
                scene.Draw(skCanvas);

                skCanvas.Restore();

                // skCanvas.DrawText($"Render: {renderDuration.TotalMilliseconds:0.0}ms  Update: {updateDuration.TotalMilliseconds:0.0}ms", fpsTextPaint.TextSize, fpsTextPaint.TextSize, fpsTextPaint);

                // Flush all pending Skia drawing commands
                grContext.Flush();

                // Present the canvas on the display
                Glfw.SwapBuffers(windowPtr);

                renderDuration = stopwatch.Elapsed;

                stopwatch.Restart();

                // Update the scene, moving it forward in time.
                scene.Update((float)frameDuration.TotalSeconds, inputState);

                inputState.Update();

                updateDuration = stopwatch.Elapsed;

                //Glfw.SetWindowTitle(windowPtr, );

                if (inputState.IsKeyDown(Key.Enter) && inputState.IsKeyDown(Key.LeftAlt))
                {
                    if (Glfw.GetWindowMonitor(windowPtr) == IntPtr.Zero)
                    {
                        // Switch to full screen.
                        Glfw.SetWindowMonitor(windowPtr, primaryMonitorPtr, 0, 0, Grid.Width, Grid.Height, 60);
                    }
                    else
                    {
                        // Switch to windowed mode
                        Glfw.SetWindowMonitor(windowPtr, IntPtr.Zero,
                                              workAreaX + (workAreaWidth - Grid.Width) / 2,
                                              workAreaY + (workAreaHeight - Grid.Height) / 2,
                                              Grid.Width,
                                              Grid.Height, 0);
                    }
                }

                // Glfw.SetWindowTitle(windowPtr, $"FPS = {1 / frameDuration.TotalSeconds:000.0}");
            }
        }