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 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 Configure (GameView view) { view.DepthPixelFormat = depthPixelFormat; view.StencilPixelFormat = stencilPixelFormat; view.SampleCount = sampleCount; dynamicConstantBuffer = new IMTLBuffer[max_inflight_buffers]; // allocate one region of memory for the constant buffer for (int i = 0; i < max_inflight_buffers; i++) { dynamicConstantBuffer [i] = device.CreateBuffer (max_bytes_per_frame, MTLResourceOptions.CpuCacheModeDefault); dynamicConstantBuffer [i].Label = string.Format ("ConstantBuffer{0}", i); } // load the fragment program into the library IMTLFunction fragmentProgram = defaultLibrary.CreateFunction ("lighting_fragment"); if (fragmentProgram == null) Console.WriteLine ("ERROR: Couldnt load fragment function from default library"); // load the vertex program into the library IMTLFunction vertexProgram = defaultLibrary.CreateFunction ("lighting_vertex"); if (vertexProgram == null) Console.WriteLine ("ERROR: Couldnt load vertex function from default library"); // setup the vertex buffers vertexBuffer = device.CreateBuffer<float> (cubeVertexData, MTLResourceOptions.CpuCacheModeDefault); vertexBuffer.Label = "Vertices"; // create a reusable pipeline state var pipelineStateDescriptor = new MTLRenderPipelineDescriptor { Label = "MyPipeline", SampleCount = sampleCount, VertexFunction = vertexProgram, FragmentFunction = fragmentProgram, DepthAttachmentPixelFormat = depthPixelFormat }; pipelineStateDescriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm; NSError error; pipelineState = device.CreateRenderPipelineState (pipelineStateDescriptor, out error); var depthStateDesc = new MTLDepthStencilDescriptor { DepthCompareFunction = MTLCompareFunction.Less, DepthWriteEnabled = true }; depthState = device.CreateDepthStencilState (depthStateDesc); }
public void Reshape (GameView view) { var aspect = (float)(view.Bounds.Size.Width / view.Bounds.Size.Height); projectionMatrix = CreateMatrixFromPerspective (FOVY, aspect, 0.1f, 100.0f); viewMatrix = LookAt (eye, center, up); }