示例#1
0
        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();
        }
示例#2
0
        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 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();
        }
示例#4
0
        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 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();
        }
        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 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();
        }
示例#8
0
        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);
        }
示例#9
0
        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();
        }
示例#10
0
        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();
        }
示例#11
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();
        }
示例#12
0
        void PerformRequests(long key)
        {
            AmtQueueSubmission request;

            if (mSubmissions.TryGetValue(key, out request))
            {
                int requirements = request.Waits.Length;
                int checks       = 0;
                foreach (var signal in request.Waits)
                {
                    if (signal.IsSignalled)
                    {
                        ++checks;
                    }
                }
                // render
                if (checks >= requirements)
                {
                    mRenderer.Render(request);

                    if (request.Swapchains != null)
                    {
                        foreach (var info in request.Swapchains)
                        {
                            IMTLCommandBuffer presentCmd = mPresentQueue.CommandBuffer();
                            var imageInfo = info.Swapchain.Images[info.ImageIndex];

                            presentCmd.AddCompletedHandler((buffer) =>
                            {
                                imageInfo.Drawable.Dispose();
                                imageInfo.Inflight.Set();
                            });
                            presentCmd.PresentDrawable(imageInfo.Drawable);
                            presentCmd.Commit();
                        }
                    }

                    AmtQueueSubmission removedItem;
                    mSubmissions.TryRemove(key, out removedItem);
                }
            }
        }
        void Render()
        {
            // Create a new command buffer for each renderpass to the current drawable.
            IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer();

            // Initialize MetalPerformanceShaders gaussianBlur with Sigma = 10.0f.
            var gaussianblur = new MPSImageGaussianBlur(metalView.Device, 10f);

            var drawable = ((CAMetalLayer)metalView.Layer).NextDrawable();

            // Run MetalPerformanceShader gaussianblur.
            gaussianblur.EncodeToCommandBuffer(commandBuffer, sourceTexture, drawable.Texture);

            // Schedule a present using the current drawable.
            commandBuffer.PresentDrawable(drawable);
            // Finalize command buffer.
            commandBuffer.Commit();
            commandBuffer.WaitUntilCompleted();

            // To reuse a CAMetalDrawable object’s texture, you must deallocate the drawable after presenting it.
            drawable.Dispose();
        }
示例#14
0
 private void PlatformCommit()
 {
     _deviceCommandBuffer.Commit();
 }
示例#15
0
 private void PlatformCommit()
 {
     _commandBuffer.Commit();
 }
示例#16
0
        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);
            this.cubeParameters.WorldViewProjection = worldViewProj;
            this.SetConstantBuffer(this.cubeParameters, this.cubeConstantBuffer);

            // 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;

            renderPassDescriptor.ColorAttachments[0].Texture    = this.colorFrameBufferTexture;
            renderPassDescriptor.ColorAttachments[0].ClearColor = new MTLClearColor(0.5f, 0.75f, 1, 1);

            // If we have a valid drawable, begin the commands to render into it
            if (renderPassDescriptor != null)
            {
                //--------------------------------
                // Draw Triangle
                //--------------------------------

                // Create a render command encoder so we can render into something
                IMTLRenderCommandEncoder triangleRenderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);
                triangleRenderEncoder.SetDepthStencilState(depthStencilState);

                triangleRenderEncoder.SetRenderPipelineState(trianglePipelineState);
                triangleRenderEncoder.SetVertexBuffer(triangleVertexBuffer, 0, 0);

                // Tell the render context we want to draw our primitives
                triangleRenderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (nuint)triangleVertexData.Length);

                triangleRenderEncoder.EndEncoding();

                //--------------------------------
                // Draw Cube
                //--------------------------------
                renderPassDescriptor.ColorAttachments[0].Texture    = drawable.Texture;
                renderPassDescriptor.ColorAttachments[0].ClearColor = mtkView.ClearColor;
                IMTLRenderCommandEncoder cubeRenderEncoder = commandBuffer.CreateRenderCommandEncoder(renderPassDescriptor);
                cubeRenderEncoder.SetDepthStencilState(depthStencilState);

                // Set context state
                cubeRenderEncoder.SetRenderPipelineState(cubePipelineState);
                cubeRenderEncoder.SetVertexBuffer(cubeVertexBuffer, 0, 0);
                cubeRenderEncoder.SetVertexBuffer(cubeConstantBuffer, (nuint)Marshal.SizeOf(this.cubeParameters), 1);
                cubeRenderEncoder.SetFragmentTexture(this.colorFrameBufferTexture, 0);
                cubeRenderEncoder.SetFragmentSamplerState(this.sampler, 0);

                // Tell the render context we want to draw our primitives
                cubeRenderEncoder.DrawPrimitives(MTLPrimitiveType.Triangle, 0, (nuint)cubeVertexData.Length);

                // We're done encoding commands
                cubeRenderEncoder.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();
        }
示例#17
0
 public override void Swap()
 {
     _cmdBuffer.PresentDrawable(_drawable);
     _cmdBuffer.Commit();
 }
示例#18
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();
        }