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(); }
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); }