예제 #1
0
        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();
        }
예제 #2
0
        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();
        }
예제 #3
0
 private void PlatformSetViewport(Viewport viewport)
 {
     _deviceCommandEncoder.SetViewport(viewport.ToMTLViewport());
     _deviceCommandEncoder.SetScissorRect(new MTLScissorRect(0, 0, (nuint)viewport.Width, (nuint)viewport.Height));
 }