Esempio n. 1
0
 public MTLRenderPassDescriptor GetRenderPassDescriptor(ICAMetalDrawable drawable)
 {
     if (drawable == null)
     {
         Console.WriteLine("ERROR: Failed to get a drawable!");
         renderPassDescriptor = null;
     }
     else
     {
         SetupRenderPassDescriptorForTexture(drawable.Texture);
     }
     return(renderPassDescriptor);
 }
Esempio n. 2
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();
        }
Esempio n. 3
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();
        }
Esempio n. 4
0
        public override MTLRenderPassDescriptor CreateRenderPassDescriptor()
        {
            MTLRenderPassDescriptor ret = MTLRenderPassDescriptor.New();
            var color0 = ret.colorAttachments[0];

            color0.texture    = _parentSwapchain.CurrentDrawable.texture;
            color0.loadAction = MTLLoadAction.Load;

            if (_depthTarget != null)
            {
                var depthAttachment = ret.depthAttachment;
                depthAttachment.texture    = _depthTexture.DeviceTexture;
                depthAttachment.loadAction = MTLLoadAction.Load;
            }

            return(ret);
        }
Esempio n. 5
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();
        }
Esempio n. 6
0
        public override void Init(IntPtr display, IntPtr window, uint samples, bool vsync, bool sRGB)
        {
            _display = display;
            _window  = window;

            while (!_dev.SupportsTextureSampleCount(samples))
            {
                samples >>= 1;
            }
            _samples = samples;

            _layer                 = new CAMetalLayer();
            _layer.Device          = _dev;
            _layer.PixelFormat     = sRGB ? MTLPixelFormat.BGRA8Unorm_sRGB : MTLPixelFormat.BGRA8Unorm;
            _layer.FramebufferOnly = true;

#if __IOS__
            UIView view = (UIView)ObjCRuntime.Runtime.GetNSObject(window);
            view.Layer.AddSublayer(_layer);
#else
            // Mac
            NSView view = (NSView)ObjCRuntime.Runtime.GetNSObject(window);
            view.Layer.AddSublayer(_layer);
#endif
            _cmdQueue = _dev.CreateCommandQueue();

            _descriptor = new MTLRenderPassDescriptor();
            _descriptor.ColorAttachments[0].ClearColor = new MTLClearColor(0.0, 1.0, 0.0, 0.0);

            if (samples > 1)
            {
                _descriptor.ColorAttachments[0].StoreAction = MTLStoreAction.MultisampleResolve;
            }
            else
            {
                _descriptor.ColorAttachments[0].StoreAction = MTLStoreAction.Store;
            }

            _descriptor.StencilAttachment.ClearStencil = 0;
            _descriptor.StencilAttachment.LoadAction   = MTLLoadAction.Clear;
            _descriptor.StencilAttachment.StoreAction  = MTLStoreAction.DontCare;

            _device = new Noesis.RenderDeviceMTL(_dev.Handle, sRGB);
        }
        public void Draw(MTKView view)
        {
            // Update

            // 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(depthStencilState);
                renderEncoder.SetCullMode(MTLCullMode.Front);
                renderEncoder.SetFrontFacingWinding(MTLWinding.CounterClockwise);
                renderEncoder.SetTriangleFillMode(MTLTriangleFillMode.Fill);

                // Set context state
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
                renderEncoder.SetVertexBuffer(instancedBuffer, 0, 1);

                // Tell the render context we want to draw our primitives
                renderEncoder.DrawIndexedPrimitives(MTLPrimitiveType.Triangle, (uint)indexData.Length, MTLIndexType.UInt16, indexBuffer, 0, 3);

                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)
        {
            // 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.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();
        }
Esempio n. 9
0
        public override MTLRenderPassDescriptor CreateRenderPassDescriptor()
        {
            MTLRenderPassDescriptor ret = MTLRenderPassDescriptor.New();

            for (int i = 0; i < ColorTargets.Count; i++)
            {
                FramebufferAttachment colorTarget = ColorTargets[i];
                MTLTexture            mtlTarget   = Util.AssertSubtype <Texture, MTLTexture>(colorTarget.Target);
                MTLRenderPassColorAttachmentDescriptor colorDescriptor = ret.colorAttachments[(uint)i];
                colorDescriptor.texture    = mtlTarget.DeviceTexture;
                colorDescriptor.loadAction = MTLLoadAction.Load;
                colorDescriptor.slice      = (UIntPtr)colorTarget.ArrayLayer;
                colorDescriptor.level      = (UIntPtr)colorTarget.MipLevel;
            }

            if (DepthTarget != null)
            {
                MTLTexture mtlDepthTarget = Util.AssertSubtype <Texture, MTLTexture>(DepthTarget.Value.Target);
                MTLRenderPassDepthAttachmentDescriptor depthDescriptor = ret.depthAttachment;
                depthDescriptor.loadAction  = MTLLoadAction.Load;
                depthDescriptor.storeAction = MTLStoreAction.Store;
                depthDescriptor.texture     = mtlDepthTarget.DeviceTexture;
                depthDescriptor.slice       = (UIntPtr)DepthTarget.Value.ArrayLayer;
                depthDescriptor.level       = (UIntPtr)DepthTarget.Value.MipLevel;

                if (FormatHelpers.IsStencilFormat(mtlDepthTarget.Format))
                {
                    MTLRenderPassStencilAttachmentDescriptor stencilDescriptor = ret.stencilAttachment;
                    stencilDescriptor.loadAction  = MTLLoadAction.Load;
                    stencilDescriptor.storeAction = MTLStoreAction.Store;
                    stencilDescriptor.texture     = mtlDepthTarget.DeviceTexture;
                    stencilDescriptor.slice       = (UIntPtr)DepthTarget.Value.ArrayLayer;
                }
            }

            return(ret);
        }
 private void PlatformConstruct()
 {
     DeviceDescriptor = new MTLRenderPassDescriptor();
 }
Esempio n. 11
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();
        }
Esempio n. 12
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
            {
                renderPassDescriptor = new MTLRenderPassDescriptor();
            }

            MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0];

            colorAttachment.Texture    = texture;
            colorAttachment.LoadAction = MTLLoadAction.Clear;
            colorAttachment.ClearColor = new MTLClearColor(0.65f, 0.65f, 0.65f, 1.0f);

            if (SampleCount > 1)
            {
                if (msaaTex == null || NeedUpdate(texture, msaaTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false);
                    desc.TextureType = MTLTextureType.k2DMultisample;
                    desc.SampleCount = SampleCount;
                    msaaTex          = device.CreateTexture(desc);
                }

                colorAttachment.Texture        = msaaTex;
                colorAttachment.ResolveTexture = texture;

                // set store action to resolve in this case
                colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve;
            }
            else
            {
                colorAttachment.StoreAction = MTLStoreAction.Store;
            }

            if (DepthPixelFormat != MTLPixelFormat.Invalid)
            {
                if (depthTex == null || NeedUpdate(texture, depthTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(DepthPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
                    depthAttachment.Texture     = depthTex;
                    depthAttachment.LoadAction  = MTLLoadAction.Clear;
                    depthAttachment.StoreAction = MTLStoreAction.DontCare;
                    depthAttachment.ClearDepth  = 1.0;
                }
            }

            if (StencilPixelFormat != MTLPixelFormat.Invalid)
            {
                if (stencilTex == null || NeedUpdate(texture, stencilTex))
                {
                    var desc = MTLTextureDescriptor.CreateTexture2DDescriptor(StencilPixelFormat, texture.Width, texture.Height, false);
                    desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
                    desc.SampleCount = SampleCount;
                    depthTex         = device.CreateTexture(desc);

                    MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
                    stencilAttachment.Texture      = depthTex;
                    stencilAttachment.LoadAction   = MTLLoadAction.Clear;
                    stencilAttachment.StoreAction  = MTLStoreAction.DontCare;
                    stencilAttachment.ClearStencil = 1;
                }
            }
        }
Esempio n. 13
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();
        }
Esempio n. 14
0
        public void Draw(MTKView view)
        {
            if (!SDPlugin.IsSDKReady)
            {
                return;
            }

            // Update sizes
            if (backgroundTextureSize.Width == 0 && backgroundTextureSize.Height == 0)
            {
                var size = MakeBackgroundTextureSize();
                backgroundTextureSize = size;
                UpdateMTKViewFrame();
            }

            // Draw meshes
            if (SDPlugin.ShowMesh)
            {
                MeshController.Update();
            }

            // Get pose and tracking quality
            var localOrientation = UIApplication.SharedApplication.StatusBarOrientation;

            float[] mPoseBuffer     = new float[16];
            int     trackingQuality = 0;

            unsafe
            {
                fixed(float *ptr = &mPoseBuffer[0])
                {
                    // R T
                    // 0 1
                    int bufferSize = 16;

                    trackingQuality = SDPlugin.SixDegreesSDK_GetPose(ptr, bufferSize);
                }
            }

            if (trackingQuality > 0)
            {
                // Update camera pose
                var        row0       = new SCNVector4(mPoseBuffer[0], mPoseBuffer[1], mPoseBuffer[2], mPoseBuffer[3]);
                var        row1       = new SCNVector4(mPoseBuffer[4], mPoseBuffer[5], mPoseBuffer[6], mPoseBuffer[7]);
                var        row2       = new SCNVector4(mPoseBuffer[8], mPoseBuffer[9], mPoseBuffer[10], mPoseBuffer[11]);
                var        row3       = new SCNVector4(mPoseBuffer[12], mPoseBuffer[13], mPoseBuffer[14], mPoseBuffer[15]);
                SCNMatrix4 poseMatrix = new SCNMatrix4(row0, row1, row2, row3);

                CameraNode.WorldTransform = poseMatrix;

                // Update camera projection
                var projectionTransform = MakeProjectionMatrix(localOrientation);
                CameraNode.Camera.ProjectionTransform = projectionTransform;
            }

            // Update vertex factory
            if (vertexFactory.IsComplete == false || orientation != localOrientation)
            {
                vertexFactory.Update(localOrientation, backgroundTextureSize);
            }
            orientation = localOrientation;

            // Draw background texture
            var texturePtr = SDPlugin.SixDegreesSDK_GetBackgroundTexture();

            if (texturePtr != IntPtr.Zero)
            {
                var obj = ObjCRuntime.Runtime.GetINativeObject <IMTLTexture>(texturePtr, false);
                Draw((IMTLTexture)obj);
            }

            if (commandQueue != null)
            {
                var    commandBuffer   = commandQueue.CommandBuffer();
                var    currentDrawable = mtkView.CurrentDrawable;
                double CurrentTime     = CAAnimation.CurrentMediaTime();
                var    screenScale     = UIScreen.MainScreen.Scale;
                var    viewport        = new CGRect(x: 0, y: 0,
                                                    width: mtkView.Frame.Width * screenScale,
                                                    height: mtkView.Frame.Height * screenScale);

                var renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor();
                renderPassDescriptor.ColorAttachments[0].Texture     = currentDrawable.Texture;
                renderPassDescriptor.ColorAttachments[0].LoadAction  = MTLLoadAction.Load;
                renderPassDescriptor.ColorAttachments[0].StoreAction = MTLStoreAction.Store;

                renderer.Render(CurrentTime,
                                viewport,
                                commandBuffer,
                                renderPassDescriptor);

                commandBuffer.PresentDrawable(currentDrawable);
                commandBuffer.Commit();
            }
        }
Esempio n. 15
0
 private void PlatformConstruct()
 {
     DeviceRenderPassDescriptor = AddDisposable(new MTLRenderPassDescriptor());
 }
Esempio n. 16
0
		public MTLRenderPassDescriptor GetRenderPassDescriptor (ICAMetalDrawable drawable)
		{
			if (drawable == null) {
				Console.WriteLine ("ERROR: Failed to get a drawable!");
				renderPassDescriptor = null;
			} else {
				SetupRenderPassDescriptorForTexture (drawable.Texture);
			}
			return renderPassDescriptor;
		}
Esempio n. 17
0
		void SetupRenderPassDescriptorForTexture (IMTLTexture texture)
		{
			if (renderPassDescriptor == null)
				renderPassDescriptor = new MTLRenderPassDescriptor ();

			MTLRenderPassColorAttachmentDescriptor colorAttachment = renderPassDescriptor.ColorAttachments [0];
			colorAttachment.Texture = texture;
			colorAttachment.LoadAction = MTLLoadAction.Clear;
			colorAttachment.ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f);

			if (SampleCount > 1) {
				if (msaaTex == null || NeedUpdate (texture, msaaTex)) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.BGRA8Unorm, texture.Width, texture.Height, false);
					desc.TextureType = MTLTextureType.k2DMultisample;
					desc.SampleCount = SampleCount;
					msaaTex = device.CreateTexture (desc);
				}

				colorAttachment.Texture = msaaTex;
				colorAttachment.ResolveTexture = texture;

				// set store action to resolve in this case
				colorAttachment.StoreAction = MTLStoreAction.MultisampleResolve;
			} else {
				colorAttachment.StoreAction = MTLStoreAction.Store;
			}

			if (DepthPixelFormat != MTLPixelFormat.Invalid && (depthTex == null || NeedUpdate (texture, depthTex))) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (DepthPixelFormat, texture.Width, texture.Height, false);
					desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
					desc.SampleCount = SampleCount;
					depthTex = device.CreateTexture (desc);

					MTLRenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.DepthAttachment;
					depthAttachment.Texture = depthTex;
					depthAttachment.LoadAction = MTLLoadAction.Clear;
					depthAttachment.StoreAction = MTLStoreAction.DontCare;
					depthAttachment.ClearDepth = 1.0;
			}

			if (StencilPixelFormat != MTLPixelFormat.Invalid && (stencilTex == null || NeedUpdate (texture, stencilTex))) {
					var desc = MTLTextureDescriptor.CreateTexture2DDescriptor (StencilPixelFormat, texture.Width, texture.Height, false);
					desc.TextureType = (SampleCount > 1) ? MTLTextureType.k2DMultisample : MTLTextureType.k2D;
					desc.SampleCount = SampleCount;
					stencilTex = device.CreateTexture (desc);

					MTLRenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.StencilAttachment;
					stencilAttachment.Texture = stencilTex;
					stencilAttachment.LoadAction = MTLLoadAction.Clear;
					stencilAttachment.StoreAction = MTLStoreAction.DontCare;
					stencilAttachment.ClearStencil = 0;
			}
		}
Esempio n. 18
0
        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);

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

                param.WorldViewProjection = Matrix4.Transpose(worldViewProj);
                param.IsTextured          = true;
                SetConstantBuffer(this.param, this.constantBuffer1);

                // Set context state
                renderEncoder.SetRenderPipelineState(pipelineState);
                renderEncoder.SetFrontFacingWinding(MTLWinding.Clockwise);
                renderEncoder.SetCullMode(MTLCullMode.None);

                renderEncoder.SetStencilReferenceValue(0);
                renderEncoder.SetDepthStencilState(depthStencilState1);

                renderEncoder.SetVertexBuffer(vertexBuffer, 0, 0);
                renderEncoder.SetFragmentTexture(this.texture, 0);
                renderEncoder.SetFragmentSamplerState(this.sampler, 0);
                renderEncoder.SetVertexBuffer(constantBuffer1, (nuint)Marshal.SizeOf(this.param), 1);
                renderEncoder.SetFragmentBuffer(constantBuffer1, (nuint)Marshal.SizeOf(this.param), 1);

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


                // Second Draw

                // Set constant buffer
                param.IsTextured          = false;
                worldViewProj             = Matrix4.CreateRotationX(time) * Matrix4.CreateRotationY(time * 2) * Matrix4.CreateRotationZ(time * .7f) * Matrix4.Scale(1.04f) * viewProj;
                param.WorldViewProjection = Matrix4.Transpose(worldViewProj);
                SetConstantBuffer(this.param, constantBuffer2);

                renderEncoder.SetStencilReferenceValue(1);
                renderEncoder.SetDepthStencilState(depthStencilState2);

                renderEncoder.SetVertexBuffer(constantBuffer2, (nuint)Marshal.SizeOf(this.param), 1);
                renderEncoder.SetFragmentBuffer(constantBuffer2, (nuint)Marshal.SizeOf(this.param), 1);

                // 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();
        }
Esempio n. 19
0
        void SetupRenderPassDescriptorForTexture(IMTLTexture texture)
        {
            if (renderPassDescriptor == null)
                renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor ();

            renderPassDescriptor.ColorAttachments [0].Texture = texture;
            renderPassDescriptor.ColorAttachments [0].LoadAction = MTLLoadAction.Clear;
            renderPassDescriptor.ColorAttachments [0].ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f);
            renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store;

            if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height)) {
                //  If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
                //  Then allocate one of the proper size
                MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
                depthTex = device.CreateTexture (desc);
                depthTex.Label = "Depth";

                renderPassDescriptor.DepthAttachment.Texture = depthTex;
                renderPassDescriptor.DepthAttachment.LoadAction = MTLLoadAction.Clear;
                renderPassDescriptor.DepthAttachment.ClearDepth = 1.0f;
                renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare;
            }
        }