public void Draw(MTKView view) { if (mApplication != null) { mApplication.Render(); } }
public override void ViewDidLoad() { metalView = (MTKView)View; // Set the view to use the default device. metalView.Device = MTLDevice.SystemDefault; // Make sure the current device supports MetalPerformanceShaders. if (metalView.Device == null) { return; } bool deviceSupportsMPS = MPSKernel.Supports(metalView.Device); if (!deviceSupportsMPS) { return; } MetalPerformanceShadersDisabledLabel.Hidden = true; SetupView(); SetupMetal(); LoadAssets(); }
public void DrawableSizeWillChange(MTKView view, CGSize size) { float aspect = (float)Math.Abs(View.Bounds.Width / View.Bounds.Height); projectionMatrix = MathHelper.MatrixFromPerspectiveFovAspectLH(65f * (float)Math.PI / 180f, aspect, .1f, 100f); viewMatrix = Matrix4.Identity; }
private void InitRenderer() { _renderer = new Renderer(); var device = MTLDevice.SystemDefault; if (device == null) { throw new NotSupportedException("Metal is not supported"); } MTKView mtkView = new MTKView(View.Frame, device) { TranslatesAutoresizingMaskIntoConstraints = false }; View.AddSubview(mtkView); var constraints = new[] { mtkView.LeftAnchor.ConstraintEqualTo(View.LeftAnchor), mtkView.RightAnchor.ConstraintEqualTo(View.RightAnchor), mtkView.TopAnchor.ConstraintEqualTo(View.TopAnchor), mtkView.BottomAnchor.ConstraintEqualTo(View.BottomAnchor, 0.5f), }; NSLayoutConstraint.ActivateConstraints(constraints); _renderer.InitRenderer(mtkView, device); }
public SwapChain( GraphicsDevice graphicsDevice, MTKView metalView) { _graphicsDevice = graphicsDevice; _metalView = metalView; }
public void Draw(MTKView view) { // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // If we have a valid drawable, begin the commands to render into it if (renderPassDescriptor != null) { // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // Set context state renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); // Tell the render context we want to draw our primitives renderEncoder.DrawIndexedPrimitives(MTLPrimitiveType.Triangle, (nuint)indexData.Length, MTLIndexType.UInt16, indexBuffer, 0); // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
public void DrawableSizeWillChange(MTKView view, CoreGraphics.CGSize size) { if (mApplication != null) { mApplication.Reshape((uint)size.Width, (uint)size.Height); } }
public override void Draw(MTKView view) { #if BGFX Bgfx.Bgfx.Reset((int)view.Bounds.Size.Width, (int)view.Bounds.Size.Height, 0, 0); Bgfx.Bgfx.SetViewClear(0, (ClearTargets.Color | ClearTargets.Depth), 0x443355FF, 1.0f, 0); Bgfx.Bgfx.SetViewRect(0, 0, 0, (ushort)view.Bounds.Size.Width, (ushort)view.Bounds.Size.Height); var target = Vector3.Zero; var camera = new Vector3(0, 0, -5); var lookAtView = CreateLookAt(camera, target, Vector3.UnitY); var fov = MathOps.ToDegrees(60f); var projectionMatrix = CreatePerspectiveFieldOfView(fov, (float)(view.Bounds.Size.Width / view.Bounds.Size.Height), 0.1f, 100f); Bgfx.Bgfx.SetViewTransform(0, lookAtView.ToFloats(), projectionMatrix.ToFloats()); float offset = (float)_frame; var rotation = Matrix4x4.CreateFromYawPitchRoll(offset * 0.01f, offset * 0.01f, offset * 0.01f); Bgfx.Bgfx.SetTransform(rotation.ToFloats()); Bgfx.Bgfx.SetVertexBuffer(0, _vertexBuffer); Bgfx.Bgfx.SetIndexBuffer(_indexBuffer); Bgfx.Bgfx.Submit(0, _program); _frame = Bgfx.Bgfx.Frame(); System.Diagnostics.Debug.WriteLine($"Frame {_frame}"); #endif }
MTKView MakeMTKView() { mtkView = new MTKView(this.Frame, MTLDevice.SystemDefault); mtkView.BackgroundColor = UIColor.Blue; mtkView.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; mtkView.DepthStencilPixelFormat = MTLPixelFormat.Invalid; mtkView.EnableSetNeedsDisplay = false; return(mtkView); }
public void Draw(MTKView view) { // Update var time = clock.ElapsedMilliseconds / 1000.0f; var viewProj = Matrix4.Mult(this.view, this.proj); var worldViewProj = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2) * Matrix4.CreateRotationZ(time * .7f) * viewProj; worldViewProj = Matrix4.Transpose(worldViewProj); int rawsize = Marshal.SizeOf <Matrix4>(); var rawdata = new byte[rawsize]; GCHandle pinnedUniforms = GCHandle.Alloc(worldViewProj, GCHandleType.Pinned); IntPtr ptr = pinnedUniforms.AddrOfPinnedObject(); Marshal.Copy(ptr, rawdata, 0, rawsize); pinnedUniforms.Free(); Marshal.Copy(rawdata, 0, constantBuffer.Contents + rawsize, rawsize); // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // If we have a valid drawable, begin the commands to render into it if (renderPassDescriptor != null) { // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); renderEncoder.SetDepthStencilState(depthState); // Set context state renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf <Matrix4>(), 1); renderEncoder.SetFragmentTexture(this.texture, 0); renderEncoder.SetFragmentSamplerState(this.sampler, 0); // Tell the render context we want to draw our primitives renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (nuint)vertexData.Length); // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
void SetupView() { view = (MTKView)View; view.Delegate = this; view.Device = device; // Setup the render target, choose values based on your app view.SampleCount = 4; view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; }
public void Draw(MTKView view) { // Update this.time += this.clock.ElapsedMilliseconds / 1000.0f; if (this.time > 2) { this.time = 0; clock.Restart(); this.mipmapping++; if (this.mipmapping >= this.texture.MipmapLevelCount) { this.mipmapping = 0; } SetConstantBuffer(this.mipmapping, this.constantBuffer); } // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // If we have a valid drawable, begin the commands to render into it if (renderPassDescriptor != null) { // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // Set context state renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); renderEncoder.SetFragmentBuffer(constantBuffer, (nuint)sizeof(float), 1); renderEncoder.SetFragmentTexture(this.texture, 0); renderEncoder.SetFragmentSamplerState(this.sampler, 0); // Tell the render context we want to draw our primitives renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (uint)vertexData.Length); // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
public AmtPresentationLayer(MTKView view, IMgSwapchainCollection swapchainCollection) { mView = view; mLayers = new AmtLayerInfo[1]; mLayers[0] = new AmtLayerInfo { Inflight = new Semaphore(1, 1), }; mCollection = swapchainCollection; }
void IMTKViewDelegate.DrawableSizeWillChange(MTKView view, CGSize size) { CanvasSize = size.ToSKSize(); if (Paused && EnableSetNeedsDisplay) #if __IOS__ { SetNeedsDisplay(); } #elif __MACOS__ { NeedsDisplay = true; } #endif }
public MetalGraphicsView() { _graphicsDevice = new GraphicsDevice(); _metalView = new MTKView(CGRect.Empty, _graphicsDevice.Device); _metalView.ColorPixelFormat = global::Metal.MTLPixelFormat.BGRA8Unorm; _metalView.Delegate = this; AddSubview(_metalView); _swapChain = new SwapChain(_graphicsDevice, _metalView); }
public void Draw(MTKView view) { // Update var time = clock.ElapsedMilliseconds / 1000.0f; var viewProj = Matrix4.Mult(this.view, this.proj); var world = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2) * Matrix4.CreateRotationZ(time * .7f); var worldViewProj = world * viewProj; var worldInverse = Matrix4.Invert(world); param.World = Matrix4.Transpose(world); param.WorldInverseTranspose = worldInverse; param.WorldViewProjection = Matrix4.Transpose(worldViewProj); SetConstantBuffer(this.param, constantBuffer); // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // If we have a valid drawable, begin the commands to render into it if (renderPassDescriptor != null) { // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // Set context state renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf(this.param), 1); renderEncoder.SetFragmentBuffer(constantBuffer, (nuint)Marshal.SizeOf(this.param), 1); renderEncoder.SetFragmentTexture(this.texture, 0); renderEncoder.SetFragmentSamplerState(this.sampler, 0); // Tell the render context we want to draw our primitives renderEncoder.DrawIndexedPrimitives(MTLPrimitiveType.Triangle, (uint)indexDataArray.Length, MTLIndexType.UInt16, indexBuffer, 0); // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
public override void ViewDidLoad () { metalView = (MTKView)View; // Make sure the current device supports MetalPerformanceShaders. if (!metalView.Device.SupportsFeatureSet (MTLFeatureSet.iOS_GPUFamily2_v1)) return; MetalPerformanceShadersDisabledLabel.Hidden = true; SetupView (); SetupMetal (); LoadAssets (); }
public void Draw(MTKView view) { // Update var time = clock.ElapsedMilliseconds / 1000.0f; var viewProj = Matrix4.Mult(this.view, this.proj); var worldViewProj = Matrix4.CreateRotationY(time * 2) * Matrix4.Scale(0.0015f) * viewProj; worldViewProj = Matrix4.Transpose(worldViewProj); this.param.WorldViewProjection = worldViewProj; SetConstantBuffer(this.param, constantBuffer); // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // If we have a valid drawable, begin the commands to render into it if (renderPassDescriptor != null) { // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // Set context state renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(objMesh.VertexBuffers[0].Buffer, objMesh.VertexBuffers[0].Offset, 0); renderEncoder.SetVertexBuffer(constantBuffer, (nuint)Marshal.SizeOf <Matrix4>(), 1); renderEncoder.SetFragmentTexture(this.texture, 0); renderEncoder.SetFragmentSamplerState(this.sampler, 0); for (int i = 0; i < objMesh.Submeshes.Length; i++) { MTKSubmesh submesh = objMesh.Submeshes[i]; renderEncoder.DrawIndexedPrimitives(submesh.PrimitiveType, submesh.IndexCount, submesh.IndexType, submesh.IndexBuffer.Buffer, submesh.IndexBuffer.Offset); } // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
void IMTKViewDelegate.Draw(MTKView view) { if (designMode) { return; } if (backendContext.Device == null || backendContext.Queue == null || CurrentDrawable?.Texture == null) { return; } CanvasSize = DrawableSize.ToSKSize(); if (CanvasSize.Width <= 0 || CanvasSize.Height <= 0) { return; } // create the contexts if not done already context ??= GRContext.CreateMetal(backendContext); const SKColorType colorType = SKColorType.Bgra8888; const GRSurfaceOrigin surfaceOrigin = GRSurfaceOrigin.TopLeft; // create the render target var metalInfo = new GRMtlTextureInfo(CurrentDrawable.Texture); using var renderTarget = new GRBackendRenderTarget((int)CanvasSize.Width, (int)CanvasSize.Height, (int)SampleCount, metalInfo); // create the surface using var surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType); using var canvas = surface.Canvas; // start drawing var e = new SKPaintMetalSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType); OnPaintSurface(e); // flush the SkiaSharp contents canvas.Flush(); surface.Flush(); context.Flush(); // present using var commandBuffer = backendContext.Queue.CommandBuffer(); commandBuffer.PresentDrawable(CurrentDrawable); commandBuffer.Commit(); }
public AmtSwapchainKHR(MTKView view, IAmtSwapchainImageView color) { mImages = new AmtSwapchainKHRImageInfo[NO_OF_BUFFERS]; for (var i = 0; i < NO_OF_BUFFERS; ++i) { mImages[i] = new AmtSwapchainKHRImageInfo { Drawable = null, }; mImages[i].Inflight = new ManualResetEvent(true); } mView = view; mColorView = color; }
public AmtSwapchainCollection(MTKView view) { mApplicationView = view; var color = new AmtNullImageView(); mSwapchain = new AmtSwapchainKHR(view, color); Buffers = new MgSwapchainBuffer[] { new MgSwapchainBuffer { View = color, }, }; }
void RegisterMagnesiumSingletons(IMTLDevice localDevice) { Debug.Assert(mContainer != null); // METAL SPECIFIC var deviceQuery = new AmtDeviceQuery { NoOfCommandBufferSlots = 5 }; mContainer.RegisterSingleton <Magnesium.Metal.IAmtDeviceQuery>(deviceQuery); mContainer.RegisterSingleton <IMTLDevice>(localDevice); mApplicationView = (MTKView)View; mContainer.RegisterSingleton <MTKView>(mApplicationView); }
public override void ViewDidLoad () { metalView = (MTKView)View; // Make sure the current device supports MetalPerformanceShaders. bool? deviceSupportsPerformanceShaders = null; deviceSupportsPerformanceShaders = metalView.Device?.SupportsFeatureSet (MTLFeatureSet.iOS_GPUFamily2_v1); if (!deviceSupportsPerformanceShaders.HasValue || !deviceSupportsPerformanceShaders.Value) return; MetalPerformanceShadersDisabledLabel.Hidden = true; SetupView (); SetupMetal (); LoadAssets (); }
public void Draw(MTKView view) { // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // Compute commands IMTLComputeCommandEncoder computeCommandEncoder = commandBuffer.ComputeCommandEncoder; computeCommandEncoder.SetComputePipelineState(computePipelineState); computeCommandEncoder.SetBuffer(tessellationFactorsBuffer, 0, 2); computeCommandEncoder.DispatchThreadgroups(new MTLSize(1, 1, 1), new MTLSize(1, 1, 1)); computeCommandEncoder.EndEncoding(); // Render commands // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer var drawable = view.CurrentDrawable; // Obtain a renderPassDescriptor generated from the view's drawable textures MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderCommandEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // Set context state renderCommandEncoder.SetTriangleFillMode(MTLTriangleFillMode.Lines); renderCommandEncoder.SetDepthStencilState(depthState); renderCommandEncoder.SetRenderPipelineState(renderPipelineState); renderCommandEncoder.SetVertexBuffer(controlPointsBuffer, 0, 0); renderCommandEncoder.SetTessellationFactorBuffer(tessellationFactorsBuffer, 0, 0); // Tell the render context we want to draw our primitives renderCommandEncoder.DrawPatches(3, 0, 1, null, 0, 1, 0); // We're done encoding commands renderCommandEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
public void Draw(MTKView view) { inflightSemaphore.WaitOne(); Update(); IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); commandBuffer.Label = "Main Command Buffer"; MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // Create a render command encoder so we can render into something. IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); renderEncoder.Label = "Final Pass Encoder"; renderEncoder.SetViewport(new MTLViewport(0.0, 0.0, view.DrawableSize.Width, view.DrawableSize.Height, 0.0, 1.0)); renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); // Set the our per frame uniforms. renderEncoder.SetVertexBuffer(frameUniformBuffers[constantDataBufferIndex], 0, (nuint)(int)BufferIndex.FrameUniformBuffer); renderEncoder.PushDebugGroup("Render Meshes"); // Render each of our meshes. foreach (MetalKitEssentialsMesh mesh in meshes) { mesh.RenderWithEncoder(renderEncoder); } renderEncoder.PopDebugGroup(); renderEncoder.EndEncoding(); var drawable = view.CurrentDrawable; commandBuffer.AddCompletedHandler(_ => { inflightSemaphore.Release(); drawable.Dispose(); }); constantDataBufferIndex = (constantDataBufferIndex + 1) % maxInflightBuffers; commandBuffer.PresentDrawable(drawable); commandBuffer.Commit(); }
public override void ViewDidLoad() { metalView = (MTKView)View; // Make sure the current device supports MetalPerformanceShaders. bool?deviceSupportsPerformanceShaders = null; deviceSupportsPerformanceShaders = metalView.Device?.SupportsFeatureSet(MTLFeatureSet.iOS_GPUFamily2_v1); if (!deviceSupportsPerformanceShaders.HasValue || !deviceSupportsPerformanceShaders.Value) { return; } MetalPerformanceShadersDisabledLabel.Hidden = true; SetupView(); SetupMetal(); LoadAssets(); }
public void InitRenderer(MTKView view, IMTLDevice device) { #if BGFX var platformData = new PlatformData(); platformData.WindowHandle = view.Handle; platformData.Context = device.Handle; Bgfx.Bgfx.SetPlatformData(platformData); var settings = new InitSettings(); settings.Backend = RendererBackend.Metal; settings.Width = (int)view.Bounds.Width; settings.Height = (int)view.Bounds.Height; settings.ResetFlags = ResetFlags.Vsync; settings.PlatformData = platformData; //settings.limits.maxEncoders = 128; Bgfx.Bgfx.ManuallyRenderFrame(); Bgfx.Bgfx.Init(settings); var vertexLayout = new VertexLayout(); vertexLayout.Begin(RendererBackend.Metal); vertexLayout.Add(VertexAttributeUsage.Position, 3, VertexAttributeType.Float); vertexLayout.Add(VertexAttributeUsage.Color0, 4, VertexAttributeType.UInt8, true); vertexLayout.End(); var vertexBuffer = new VertexBuffer(MemoryBlock.FromArray(Data.cubeVertices), vertexLayout); var indexBuffer = new IndexBuffer(MemoryBlock.FromArray(Data.cubeTriList)); var vertexShader = LoadShader("vs_cubes.bin"); var fragmentShader = LoadShader("fs_cubes.bin"); var program = new Program(vertexShader, fragmentShader); _vertexBuffer = vertexBuffer; _indexBuffer = indexBuffer; _program = program; Bgfx.Bgfx.Touch(0); #endif view.Delegate = this; }
public void Draw(MTKView view) { if (vkContext == null) { vkContext = new Graphics.Platform.Vulkan.PlatformRenderContext(); PlatformRenderer.Initialize(vkContext); } if (vkSwapChain == null) { shouldUpdateMetalLayerSize = true; } if (shouldUpdateMetalLayerSize) { var screen = Window?.Screen ?? UIScreen.MainScreen; var drawableSize = Bounds.Size; drawableSize.Width *= screen.NativeScale; drawableSize.Height *= screen.NativeScale; metalLayer.DrawableSize = drawableSize; if (vkSwapChain == null) { vkSwapChain = new Graphics.Platform.Vulkan.Swapchain(vkContext, this.Handle, (int)metalLayer.DrawableSize.Width, (int)metalLayer.DrawableSize.Height); } else { vkSwapChain.Resize((int)metalLayer.DrawableSize.Width, (int)metalLayer.DrawableSize.Height); } shouldUpdateMetalLayerSize = false; } shouldUpdateMetalLayerSize = false; var curUpdateTime = stopwatch.Elapsed; if (prevUpdateTime == TimeSpan.Zero) { prevUpdateTime = curUpdateTime; } var delta = (float)(curUpdateTime - prevUpdateTime).TotalSeconds; UpdateFrame?.Invoke(delta); prevUpdateTime = curUpdateTime; RenderFrame?.Invoke(); }
public override void ViewDidLoad () { metalView = (MTKView)View; // Set the view to use the default device. metalView.Device = MTLDevice.SystemDefault; // Make sure the current device supports MetalPerformanceShaders. if (metalView.Device == null) return; bool deviceSupportsMPS = MPSKernel.Supports (metalView.Device); if (!deviceSupportsMPS) return; MetalPerformanceShadersDisabledLabel.Hidden = true; SetupView (); SetupMetal (); LoadAssets (); }
public void Draw (MTKView view) { inflightSemaphore.WaitOne (); Update (); IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer (); commandBuffer.Label = "Main Command Buffer"; MTLRenderPassDescriptor renderPassDescriptor = view.CurrentRenderPassDescriptor; // Create a render command encoder so we can render into something. IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder (renderPassDescriptor); renderEncoder.Label = "Final Pass Encoder"; renderEncoder.SetViewport (new MTLViewport (0.0, 0.0, view.DrawableSize.Width, view.DrawableSize.Height, 0.0, 1.0)); renderEncoder.SetDepthStencilState (depthState); renderEncoder.SetRenderPipelineState (pipelineState); // Set the our per frame uniforms. renderEncoder.SetVertexBuffer (frameUniformBuffers[constantDataBufferIndex], 0, (nuint)(int)BufferIndex.FrameUniformBuffer); renderEncoder.PushDebugGroup ("Render Meshes"); // Render each of our meshes. foreach (MetalKitEssentialsMesh mesh in meshes) mesh.RenderWithEncoder (renderEncoder); renderEncoder.PopDebugGroup (); renderEncoder.EndEncoding (); var drawable = view.CurrentDrawable; commandBuffer.AddCompletedHandler (_ => { inflightSemaphore.Release (); drawable.Dispose (); }); constantDataBufferIndex = (constantDataBufferIndex + 1) % maxInflightBuffers; commandBuffer.PresentDrawable (drawable); commandBuffer.Commit (); }
public override void ViewDidLoad() { base.ViewDidLoad(); // Set the view to use the default device device = MTLDevice.SystemDefault; if (device == null) { Console.WriteLine("Metal is not supported on this device"); View = new NSView(View.Frame); } // Create a new command queue commandQueue = device.CreateCommandQueue(); // Load all the shader files with a metal file extension in the project defaultLibrary = device.CreateDefaultLibrary(); // Setup view view = (MTKView)View; view.Delegate = this; view.Device = device; view.SampleCount = 1; view.DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; view.ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; view.PreferredFramesPerSecond = 60; view.ClearColor = new MTLClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction("quad_vertex"); // Load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction("quad_fragment"); // Create a vertex descriptor from the MTKMesh MTLVertexDescriptor vertexDescriptor = new MTLVertexDescriptor(); vertexDescriptor.Attributes[0].Format = MTLVertexFormat.Float4; vertexDescriptor.Attributes[0].BufferIndex = 0; vertexDescriptor.Attributes[0].Offset = 0; vertexDescriptor.Attributes[1].Format = MTLVertexFormat.Float2; vertexDescriptor.Attributes[1].BufferIndex = 0; vertexDescriptor.Attributes[1].Offset = 4 * sizeof(float); vertexDescriptor.Layouts[0].Stride = 6 * sizeof(float); vertexDescriptor.Layouts[0].StepRate = 1; vertexDescriptor.Layouts[0].StepFunction = MTLVertexStepFunction.PerVertex; this.vertexBuffer = device.CreateBuffer(vertexData, MTLResourceOptions.CpuCacheModeDefault);// (MTLResourceOptions)0); this.mipmapping = 0; this.constantBuffer = device.CreateBuffer(sizeof(float), MTLResourceOptions.CpuCacheModeDefault); SetConstantBuffer(this.mipmapping, constantBuffer); // Create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { SampleCount = view.SampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, VertexDescriptor = vertexDescriptor, DepthAttachmentPixelFormat = view.DepthStencilPixelFormat, StencilAttachmentPixelFormat = view.DepthStencilPixelFormat }; pipelineStateDescriptor.ColorAttachments[0].PixelFormat = view.ColorPixelFormat; NSError error; pipelineState = device.CreateRenderPipelineState(pipelineStateDescriptor, out error); if (pipelineState == null) { Console.WriteLine("Failed to created pipeline state, error {0}", error); } var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState(depthStateDesc); // Texture KTX NSUrl url = NSBundle.MainBundle.GetUrlForResource("crate", "ktx"); MTKTextureLoader mTKTextureLoader = new MTKTextureLoader(device); this.texture = mTKTextureLoader.FromUrl(url, new MTKTextureLoaderOptions(), out error); Console.WriteLine("Failed to created pipeline state, error {0}", error); MTLSamplerDescriptor samplerDescriptor = new MTLSamplerDescriptor() { MinFilter = MTLSamplerMinMagFilter.Linear, MagFilter = MTLSamplerMinMagFilter.Linear, MipFilter = MTLSamplerMipFilter.Linear, SAddressMode = MTLSamplerAddressMode.ClampToEdge, TAddressMode = MTLSamplerAddressMode.ClampToEdge, }; this.sampler = device.CreateSamplerState(samplerDescriptor); this.clock = new System.Diagnostics.Stopwatch(); this.clock.Start(); this.time = 0; }
void SetupView () { view = (MTKView)View; view.Delegate = this; view.Device = device; // Setup the render target, choose values based on your app. view.SampleCount = 4; view.DepthStencilPixelFormat = (MTLPixelFormat) 260; }
public void DrawableSizeWillChange(MTKView view, CoreGraphics.CGSize size) { }
public void Draw (MTKView view) { Render (); }
public void DrawableSizeWillChange (MTKView view, CGSize size) { // Called whenever view changes orientation or layout is changed }
public void Draw(MTKView view) { Render(); }
public void WillLayout(MTKView view, CoreGraphics.CGSize size) { // Called whenever view changes orientation or layout is changed }
public void DrawableSizeWillChange (MTKView view, CGSize size) { float aspect = (float)Math.Abs (View.Bounds.Width / View.Bounds.Height); projectionMatrix = MathHelper.MatrixFromPerspectiveFovAspectLH (65f * (float)Math.PI / 180f, aspect, .1f, 100f); viewMatrix = Matrix4.Identity; }
public void WillLayout (MTKView view, CoreGraphics.CGSize size) { // Called whenever view changes orientation or layout is changed }