コード例 #1
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}");
            }
        }
コード例 #2
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
#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);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp contents to GL
            canvas.Flush();
            context.Flush();
        }
コード例 #3
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.CreateDefaultInterface();
                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));
            }

            // update the control
            canvas.Flush();
            SwapBuffers();
        }
コード例 #4
0
 protected override void OnUnload(EventArgs e)
 {
     base.OnUnload(e);
     this.context?.Dispose();
     this.context = null;
 }
コード例 #5
0
 public GlRenderTarget(GRContext grContext, IGlPlatformSurface glSurface)
 {
     _grContext = grContext;
     _surface   = glSurface.CreateGlRenderTarget();
 }
コード例 #6
0
        public FboSkiaSurface(GRContext grContext, IGlContext glContext, PixelSize pixelSize)
        {
            _grContext = grContext;
            _glContext = glContext;
            _pixelSize = pixelSize;
            var InternalFormat = glContext.Version.Type == GlProfileType.OpenGLES ? GL_RGBA : GL_RGBA8;
            var gl             = glContext.GlInterface;

            // Save old bindings
            gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var oldFbo);
            gl.GetIntegerv(GL_RENDERBUFFER_BINDING, out var oldRenderbuffer);
            gl.GetIntegerv(GL_TEXTURE_BINDING_2D, out var oldTexture);

            var arr = new int[2];

            // Generate FBO
            gl.GenFramebuffers(1, arr);
            _fbo = arr[0];
            gl.BindFramebuffer(GL_FRAMEBUFFER, _fbo);

            // Create a texture to render into
            gl.GenTextures(1, arr);
            _texture = arr[0];
            gl.BindTexture(GL_TEXTURE_2D, _texture);
            gl.TexImage2D(GL_TEXTURE_2D, 0,
                          InternalFormat, pixelSize.Width, pixelSize.Height,
                          0, GL_RGBA, GL_UNSIGNED_BYTE, IntPtr.Zero);
            gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            gl.FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);

            var success = false;

            foreach (var useStencil8 in TrueFalse)
            {
                gl.GenRenderbuffers(1, arr);
                _depthStencil = arr[0];
                gl.BindRenderbuffer(GL_RENDERBUFFER, _depthStencil);

                if (useStencil8)
                {
                    gl.RenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, pixelSize.Width, pixelSize.Height);
                    gl.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencil);
                }
                else
                {
                    gl.RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, pixelSize.Width, pixelSize.Height);
                    gl.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthStencil);
                    gl.FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencil);
                }

                var status = gl.CheckFramebufferStatus(GL_FRAMEBUFFER);
                if (status == GL_FRAMEBUFFER_COMPLETE)
                {
                    success = true;
                    break;
                }
                else
                {
                    gl.BindRenderbuffer(GL_RENDERBUFFER, oldRenderbuffer);
                    gl.DeleteRenderbuffers(1, arr);
                }
            }

            gl.BindRenderbuffer(GL_RENDERBUFFER, oldRenderbuffer);
            gl.BindTexture(GL_TEXTURE_2D, oldTexture);
            gl.BindFramebuffer(GL_FRAMEBUFFER, oldFbo);

            if (!success)
            {
                arr[0] = _fbo;
                gl.DeleteFramebuffers(1, arr);
                arr[0] = _texture;
                gl.DeleteTextures(1, arr);
                throw new OpenGlException("Unable to create FBO with stencil");
            }

            var target = new GRBackendRenderTarget(pixelSize.Width, pixelSize.Height, 0, 8,
                                                   new GRGlFramebufferInfo((uint)_fbo, SKColorType.Rgba8888.ToGlSizedFormat()));

            Surface = SKSurface.Create(_grContext, target,
                                       GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888);
            CanBlit = gl.BlitFramebuffer != null;
        }