Ejemplo n.º 1
0
        /// <summary>
        /// Render a set of asssets on the screen.
        /// </summary>
        public override void Render(Asset[] assets)
        {
            base.Render(assets);


            CommandBuffers[CurrentFrame] = GraphicDevice.Handle.AllocateCommandBuffers(Commands[CurrentFrame], CommandBufferLevel.Primary, (uint)Swapchain.Images.Count());


            for (int index = 0; index < Swapchain.Images.Count(); index++)
            {
                var commandBuffer = CommandBuffers[CurrentFrame][index];

                commandBuffer.Begin(CommandBufferUsageFlags.SimultaneousUse);

                commandBuffer.BeginRenderPass(DefaultRenderPass.Handle, Swapchain.VideoBuffers[index].Handler, new Rect2D(Swapchain.SurfaceSize), (ClearValue)(0F, 1F, 0F, 1F), SubpassContents.Inline);

                if (assets != null)
                {
                    foreach (Asset asset in assets)
                    {
                        // - Gets the mesh from the mesh store
                        var mesh = GeometryDispatcher.Get(asset.Mesh);

                        VertexManager.Bind(commandBuffer);

                        IndexManager.Bind(commandBuffer, (int)mesh.Indexes.Offset);

                        commandBuffer.BindPipeline(PipelineBindPoint.Graphics, Pipeline.PipelineInstance);

                        commandBuffer.DrawIndexed((uint)mesh.Indexes.Count, (uint)mesh.Indexes.Count / 3, 0, 0, 0);
                    }
                }

                commandBuffer.EndRenderPass();

                commandBuffer.End();
            }


            uint nextImage = Swapchain.Handle.AcquireNextImage(uint.MaxValue, ImageAvailableSemaphores[CurrentFrame], null);

            if (ImagesInFlight[(int)nextImage] != null)
            {
                GraphicDevice.Handle.WaitForFences(ImagesInFlight[(int)nextImage], true, UInt64.MaxValue);
            }

            // - Mark the image as now being in use by this frame
            ImagesInFlight[(int)nextImage] = InFlightFences[CurrentFrame];

            try
            {
                GraphicDevice.Handle.ResetFences(InFlightFences[CurrentFrame]);

                GraphicDevice.GraphicQueue.Submit
                (
                    new SubmitInfo
                {
                    CommandBuffers           = new[] { CommandBuffers[CurrentFrame][nextImage] },
                    SignalSemaphores         = new[] { RenderFinishedSemaphores[CurrentFrame] },
                    WaitDestinationStageMask = new[] { PipelineStageFlags.ColorAttachmentOutput },
                    WaitSemaphores           = new[] { ImageAvailableSemaphores[CurrentFrame] }
                },
                    InFlightFences[CurrentFrame]
                );
            }
            catch (DeviceLostException)
            {
                InvalidateDevice();
            }

            try
            {
                var present = GraphicDevice.PresentQueue.Present(RenderFinishedSemaphores[CurrentFrame], Swapchain.Handle, nextImage, new Result[1]);

                switch (present)
                {
                case Result.Suboptimal:
                    InvalidateGraphics();
                    break;
                }

                if (present == Result.Success)
                {
                    GraphicDevice.Handle.WaitForFences(InFlightFences[CurrentFrame], true, UInt64.MaxValue);
                    Commands[(CurrentFrame + 1) % MaxFrameInFlight].FreeCommandBuffers(CommandBuffers[(CurrentFrame + 1) % MaxFrameInFlight]);
                    CommandBuffers[(CurrentFrame + 1) % MaxFrameInFlight] = null;
                }
            }
            catch
            {
                InvalidateGraphics();
            }
            finally
            {
            }

            CurrentFrame = (CurrentFrame + 1) % MaxFrameInFlight;
        }