public void Render(GameView view) { inflightSemaphore.WaitOne(); PrepareToDraw(); IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); ICAMetalDrawable drawable = view.GetNextDrawable(); MTLRenderPassDescriptor renderPassDescriptor = view.GetRenderPassDescriptor(drawable); if (renderPassDescriptor == null) { Console.WriteLine("ERROR: Failed to get render pass descriptor from view!"); } IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); renderEncoder.SetDepthStencilState(depthState); RenderBox(renderEncoder, view, 0, "Box1"); RenderBox(renderEncoder, view, (nuint)Marshal.SizeOf <Uniforms> (), "Box2"); renderEncoder.EndEncoding(); commandBuffer.AddCompletedHandler((IMTLCommandBuffer buffer) => { drawable.Dispose(); inflightSemaphore.Release(); }); commandBuffer.PresentDrawable(drawable); commandBuffer.Commit(); constantDataBufferIndex = (constantDataBufferIndex + 1) % max_inflight_buffers; }
public void Render(ImageView view) { inflightSemaphore.WaitOne(); IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); // compute image processing on the (same) drawable texture Compute(commandBuffer); ICAMetalDrawable drawable = view.GetNextDrawable(); // create a render command encoder so we can render into something MTLRenderPassDescriptor renderPassDescriptor = view.GetRenderPassDescriptor(drawable); if (renderPassDescriptor == null) { inflightSemaphore.Release(); return; } // Get a render encoder IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); // render textured quad Encode(renderEncoder); commandBuffer.AddCompletedHandler((IMTLCommandBuffer buffer) => { inflightSemaphore.Release(); drawable.Dispose(); }); commandBuffer.PresentDrawable(drawable); commandBuffer.Commit(); }
public MTLRenderPassDescriptor GetRenderPassDescriptor (ICAMetalDrawable drawable) { if (drawable == null) { Console.WriteLine ("ERROR: Failed to get a drawable!"); return null; } SetupRenderPassDescriptorForTexture (drawable.Texture); return renderPassDescriptor; }
public MTLRenderPassDescriptor GetRenderPassDescriptor(ICAMetalDrawable drawable) { if (drawable == null) { Console.WriteLine("ERROR: Failed to get a drawable!"); return(null); } SetupRenderPassDescriptorForTexture(drawable.Texture); return(renderPassDescriptor); }
public ICAMetalDrawable GetNextDrawable() { ICAMetalDrawable currentDrawable = null; currentDrawable = metalLayer.NextDrawable(); if (currentDrawable == null) { Console.WriteLine("CurrentDrawable is null"); } return(currentDrawable); }
void Render() { inflightSemaphore.WaitOne(); Update(); // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); commandBuffer.Label = "MyCommand"; // Obtain a drawable texture for this render pass and set up the renderpass descriptor for the command encoder to render into ICAMetalDrawable drawable = GetCurrentDrawable(); SetupRenderPassDescriptorForTexture(drawable.Texture); // Create a render command encoder so we can render into something IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); renderEncoder.Label = "MyRenderEncoder"; renderEncoder.SetDepthStencilState(depthState); // Set context state renderEncoder.PushDebugGroup("DrawCube"); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); renderEncoder.SetVertexBuffer(dynamicConstantBuffer, (nuint)(Marshal.SizeOf(typeof(Uniforms)) * constantDataBufferIndex), 1); // Tell the render context we want to draw our primitives renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, 36, 1); renderEncoder.PopDebugGroup(); // We're done encoding commands renderEncoder.EndEncoding(); // Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer commandBuffer.AddCompletedHandler(buffer => { drawable.Dispose(); inflightSemaphore.Release(); }); // Schedule a present once the framebuffer is complete commandBuffer.PresentDrawable(drawable); // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); // The renderview assumes it can now increment the buffer index and that the previous index won't be touched until we cycle back around to the same index constantDataBufferIndex = (byte)((constantDataBufferIndex + 1) % max_inflight_buffers); }
public override void SetDefaultRenderTarget(int width, int height, bool doClearColor) { _drawable = _layer.NextDrawable(); MTLRenderPassColorAttachmentDescriptor attachment = _descriptor.ColorAttachments[0]; attachment.LoadAction = doClearColor ? MTLLoadAction.Clear : MTLLoadAction.DontCare; if (attachment.StoreAction == MTLStoreAction.MultisampleResolve) { attachment.ResolveTexture = _drawable.Texture; } else { attachment.Texture = _drawable.Texture; } _cmdEncoder = _cmdBuffer.CreateRenderCommandEncoder(_descriptor); _device.SetOnScreenEncoder(_cmdEncoder.Handle, (uint)_layer.PixelFormat, (uint)MTLPixelFormat.Stencil8, _samples); }