Beispiel #1
0
        public void Execute(RenderContext context)
        {
            _renderList.Clear();

            context.Scene?.BuildRenderList(_renderList, context.Camera);

            foreach (var system in context.Game.GameSystems)
            {
                system.BuildRenderList(_renderList);
            }

            context.Game.RaiseBuildingRenderList(new BuildingRenderListEventArgs(
                                                     _renderList,
                                                     context.Camera));

            var commandEncoder = _commandList;

            commandEncoder.Begin();

            commandEncoder.SetFramebuffer(context.RenderTarget);

            commandEncoder.ClearColorTarget(0, ColorRgba.DimGray.ToColorRgbaF().ToRgbaFloat());
            commandEncoder.ClearDepthStencil(1);

            commandEncoder.SetViewport(0, context.Game.Viewport);

            UpdateGlobalConstantBuffers(commandEncoder, context);

            Texture cloudTexture;

            if (context.Scene != null &&
                context.Scene.Lighting.TimeOfDay != TimeOfDay.Night &&
                context.Scene.Lighting.EnableCloudShadows &&
                context.Scene.Terrain != null)
            {
                cloudTexture = context.Scene.Terrain.CloudTexture;
            }
            else
            {
                cloudTexture = context.Game.ContentManager.SolidWhiteTexture;
            }

            void doRenderPass(RenderBucket bucket)
            {
                Culler.Cull(bucket.RenderItems, bucket.CulledItems, context);

                if (bucket.CulledItems.Count == 0)
                {
                    return;
                }

                bucket.CulledItems.Sort();

                RenderItem?lastRenderItem = null;
                Matrix4x4? lastWorld      = null;

                foreach (var renderItem in bucket.CulledItems)
                {
                    if (lastRenderItem == null || lastRenderItem.Value.Effect != renderItem.Effect)
                    {
                        var effect = renderItem.Effect;

                        effect.Begin(commandEncoder);

                        SetDefaultConstantBuffers(renderItem.Material);

                        var cloudTextureParameter = renderItem.Effect.GetParameter("Global_CloudTexture", throwIfMissing: false);
                        if (cloudTextureParameter != null)
                        {
                            renderItem.Material.SetProperty("Global_CloudTexture", cloudTexture);
                        }
                    }

                    if (lastRenderItem == null || lastRenderItem.Value.Material != renderItem.Material)
                    {
                        renderItem.Material.ApplyPipelineState();
                        renderItem.Effect.ApplyPipelineState(commandEncoder);
                    }

                    if (lastRenderItem == null || lastRenderItem.Value.VertexBuffer0 != renderItem.VertexBuffer0)
                    {
                        commandEncoder.SetVertexBuffer(0, renderItem.VertexBuffer0);
                    }

                    if (lastRenderItem == null || lastRenderItem.Value.VertexBuffer1 != renderItem.VertexBuffer1)
                    {
                        if (renderItem.VertexBuffer1 != null)
                        {
                            commandEncoder.SetVertexBuffer(1, renderItem.VertexBuffer1);
                        }
                    }

                    var renderItemConstantsVSParameter = renderItem.Effect.GetParameter("RenderItemConstantsVS");
                    if (renderItemConstantsVSParameter != null)
                    {
                        if (lastWorld == null || lastWorld.Value != renderItem.World)
                        {
                            _renderItemConstantsBufferVS.Value.World = renderItem.World;
                            _renderItemConstantsBufferVS.Update(commandEncoder);

                            lastWorld = renderItem.World;
                        }

                        renderItem.Material.SetProperty(
                            "RenderItemConstantsVS",
                            _renderItemConstantsBufferVS.Buffer);
                    }

                    renderItem.Material.ApplyProperties();
                    renderItem.Effect.ApplyParameters(commandEncoder);

                    switch (renderItem.DrawCommand)
                    {
                    case DrawCommand.Draw:
                        commandEncoder.Draw(
                            renderItem.VertexCount,
                            1,
                            renderItem.VertexStart,
                            0);
                        break;

                    case DrawCommand.DrawIndexed:
                        commandEncoder.SetIndexBuffer(renderItem.IndexBuffer, IndexFormat.UInt16);
                        commandEncoder.DrawIndexed(
                            renderItem.IndexCount,
                            1,
                            renderItem.StartIndex,
                            0,
                            0);
                        break;

                    default:
                        throw new System.Exception();
                    }

                    lastRenderItem = renderItem;
                }
            }

            doRenderPass(_renderList.Opaque);
            doRenderPass(_renderList.Transparent);

            // GUI and camera-dependent 2D elements
            {
                _drawingContext.Begin(
                    commandEncoder,
                    context.Game.ContentManager.LinearClampSampler,
                    new SizeF(context.Game.Viewport.Width, context.Game.Viewport.Height));

                context.Game.Scene3D?.Render(_drawingContext);
                context.Game.Scene2D.Render(_drawingContext);

                context.Game.RaiseRendering2D(new Rendering2DEventArgs(_drawingContext));

                _drawingContext.End();
            }

            commandEncoder.End();

            context.GraphicsDevice.SubmitCommands(commandEncoder);

            context.GraphicsDevice.SwapBuffers();
        }
Beispiel #2
0
        public void Execute(RenderContext context)
        {
            _renderList.Clear();

            context.Scene.Scene3D?.World.Terrain.BuildRenderList(_renderList);

            context.Scene.Scene2D.WndWindowManager.BuildRenderList(_renderList);

            foreach (var system in context.Game.GameSystems)
            {
                system.BuildRenderList(_renderList);
            }

            var commandBuffer = context.GraphicsDevice.CommandQueue.GetCommandBuffer();

            var renderPassDescriptor = new RenderPassDescriptor();

            var clearColor = context.Camera.BackgroundColor.ToColorRgbaF();

            renderPassDescriptor.SetRenderTargetDescriptor(
                context.RenderTarget,
                LoadAction.Clear,
                clearColor);

            var depthStencilBuffer = _depthStencilBufferCache.Get(
                context.SwapChain.BackBufferWidth,
                context.SwapChain.BackBufferHeight);

            renderPassDescriptor.SetDepthStencilDescriptor(depthStencilBuffer);

            var commandEncoder = commandBuffer.GetCommandEncoder(renderPassDescriptor);

            commandEncoder.SetViewport(context.Camera.Viewport);

            UpdateGlobalConstantBuffers(commandEncoder, context);

            void doRenderPass(RenderBucket bucket)
            {
                Culler.Cull(bucket.RenderItems, bucket.CulledItems, context);

                if (bucket.CulledItems.Count == 0)
                {
                    return;
                }

                bucket.CulledItems.Sort();

                RenderItem?lastRenderItem = null;

                foreach (var renderItem in bucket.CulledItems)
                {
                    if (lastRenderItem == null || lastRenderItem.Value.Effect != renderItem.Effect)
                    {
                        var effect = renderItem.Effect;

                        effect.Begin(commandEncoder);

                        SetDefaultConstantBuffers(effect);
                    }

                    if (lastRenderItem == null || lastRenderItem.Value.VertexBuffer0 != renderItem.VertexBuffer0)
                    {
                        commandEncoder.SetVertexBuffer(0, renderItem.VertexBuffer0);
                    }

                    if (lastRenderItem == null || lastRenderItem.Value.VertexBuffer1 != renderItem.VertexBuffer1)
                    {
                        commandEncoder.SetVertexBuffer(1, renderItem.VertexBuffer1);
                    }

                    var renderItemConstantsVSParameter = renderItem.Effect.GetParameter("RenderItemConstantsVS", throwIfMissing: false);
                    if (renderItemConstantsVSParameter != null)
                    {
                        _renderItemConstantsBufferVS.Value.World = renderItem.World;
                        _renderItemConstantsBufferVS.Update();
                        renderItemConstantsVSParameter.SetData(_renderItemConstantsBufferVS.Buffer);
                    }

                    renderItem.Material.Apply();

                    renderItem.Effect.Apply(commandEncoder);

                    switch (renderItem.DrawCommand)
                    {
                    case DrawCommand.Draw:
                        commandEncoder.Draw(
                            PrimitiveType.TriangleList,
                            renderItem.VertexStart,
                            renderItem.VertexCount);
                        break;

                    case DrawCommand.DrawIndexed:
                        commandEncoder.DrawIndexed(
                            PrimitiveType.TriangleList,
                            renderItem.IndexCount,
                            renderItem.IndexBuffer,
                            renderItem.StartIndex);
                        break;

                    default:
                        throw new System.Exception();
                    }

                    lastRenderItem = renderItem;
                }
            }

            doRenderPass(_renderList.Opaque);
            doRenderPass(_renderList.Transparent);

            doRenderPass(_renderList.Gui);

            commandEncoder.Close();

            commandBuffer.CommitAndPresent(context.SwapChain);
        }