void Render() { inflightSemaphore.WaitOne(); Update(); // Create a new command buffer for each renderpass to the current drawable IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); commandBuffer.Label = "MyCommand"; // 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; commandBuffer.AddCompletedHandler(buffer => { drawable.Dispose(); inflightSemaphore.Release(); }); // 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.Label = "MyRenderEncoder"; renderEncoder.SetDepthStencilState(depthState); // Set context state renderEncoder.PushDebugGroup("DrawCube"); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(boxMesh.VertexBuffers[0].Buffer, boxMesh.VertexBuffers[0].Offset, 0); renderEncoder.SetVertexBuffer(dynamicConstantBuffer, (nuint)Marshal.SizeOf <Uniforms>(), 1); MTKSubmesh submesh = boxMesh.Submeshes[0]; // Tell the render context we want to draw our primitives renderEncoder.DrawIndexedPrimitives(submesh.PrimitiveType, submesh.IndexCount, submesh.IndexType, submesh.IndexBuffer.Buffer, submesh.IndexBuffer.Offset); renderEncoder.PopDebugGroup(); // We're done encoding commands renderEncoder.EndEncoding(); // Schedule a present once the framebuffer is complete using the current drawable commandBuffer.PresentDrawable(drawable); } // The render 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 = (constantDataBufferIndex + 1) % MaxInflightBuffers; // Finalize rendering here & push the command buffer to the GPU commandBuffer.Commit(); }
void RenderBox(IMTLRenderCommandEncoder renderEncoder, GameView view, nuint offset, string name) { renderEncoder.PushDebugGroup(name); // set context state renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0); renderEncoder.SetVertexBuffer(dynamicConstantBuffer [constantDataBufferIndex], offset, 1); // tell the render context we want to draw our primitives renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, 36, 1); renderEncoder.PopDebugGroup(); }
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 void Encode(IMTLRenderCommandEncoder renderEncoder) { renderEncoder.PushDebugGroup("encode quad"); renderEncoder.SetFrontFacingWinding(MTLWinding.CounterClockwise); renderEncoder.SetDepthStencilState(depthState); renderEncoder.SetRenderPipelineState(pipelineState); renderEncoder.SetVertexBuffer(transformBuffer, 0, 2); renderEncoder.SetFragmentTexture(outTexture, 0); // Encode quad vertex and texture coordinate buffers mpQuad.Encode(renderEncoder); // tell the render context we want to draw our primitives renderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, 6, 1); renderEncoder.EndEncoding(); renderEncoder.PopDebugGroup(); }
public void Encode (IMTLRenderCommandEncoder renderEncoder) { renderEncoder.PushDebugGroup ("encode quad"); renderEncoder.SetFrontFacingWinding (MTLWinding.CounterClockwise); renderEncoder.SetDepthStencilState (depthState); renderEncoder.SetRenderPipelineState (pipelineState); renderEncoder.SetVertexBuffer (transformBuffer, 0, 2); renderEncoder.SetFragmentTexture (mpInTexture.MetalTexture, 0); // Encode quad vertex and texture coordinate buffers mpQuad.Encode (renderEncoder); // tell the render context we want to draw our primitives renderEncoder.DrawPrimitives (MTLPrimitiveType.Triangle, 0, 6, 1); renderEncoder.EndEncoding (); renderEncoder.PopDebugGroup (); }
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(); }
void RenderBox (IMTLRenderCommandEncoder renderEncoder, GameView view, nuint offset, string name) { renderEncoder.PushDebugGroup (name); // set context state renderEncoder.SetRenderPipelineState (pipelineState); renderEncoder.SetVertexBuffer (vertexBuffer, 0, 0); renderEncoder.SetVertexBuffer (dynamicConstantBuffer [constantDataBufferIndex], offset, 1); // tell the render context we want to draw our primitives renderEncoder.DrawPrimitives (MTLPrimitiveType.Triangle, 0, 36, 1); renderEncoder.PopDebugGroup (); }
public void Draw(MTKView view) { inflightSemaphore.WaitOne(); // Perofm any app logic, including updating any Metal buffers. Update(); // Create a new command buffer for each renderpass to the current drawable. IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer(); commandBuffer.Label = "Main Command Buffer"; // 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 renderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor); renderEncoder.Label = "Final Pass Encoder"; // Set context state. renderEncoder.SetViewport(new MTLViewport(0d, 0d, view.DrawableSize.Width, view.DrawableSize.Height, 0d, 1d)); 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(); // 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. */ var drawable = view.CurrentDrawable; commandBuffer.AddCompletedHandler(_ => { inflightSemaphore.Release(); drawable.Dispose(); }); /* * 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 = (constantDataBufferIndex + 1) % maxInflightBuffers; // 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(); }