using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Kav { public class Renderer { private GraphicsDevice GraphicsDevice { get; } private int RenderDimensionsX { get; } private int RenderDimensionsY { get; } private RenderTarget2D DepthRenderTarget { get; } private SimpleDepthEffect SimpleDepthEffect { get; } public Renderer(GraphicsDevice graphicsDevice, int renderDimensionsX, int renderDimensionsY) { GraphicsDevice = graphicsDevice; RenderDimensionsX = renderDimensionsX; RenderDimensionsY = renderDimensionsY; DepthRenderTarget = new RenderTarget2D( GraphicsDevice, renderDimensionsX, renderDimensionsY, false, SurfaceFormat.Color, DepthFormat.Depth24 ); SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice); } public void Render( Camera camera, IEnumerable<(Model, Matrix)> modelTransforms, IEnumerable pointLights, IEnumerable directionalLights ) { Render(camera.View, camera.Projection, modelTransforms, pointLights, directionalLights); } // for shadow mapping public void DepthRender(IEnumerable<(Model, Matrix)> modelTransforms, DirectionalLight directionalLight) { GraphicsDevice.SetRenderTarget(DepthRenderTarget); GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1, 0); SimpleDepthEffect.View = directionalLight.View; SimpleDepthEffect.Projection = directionalLight.Projection; foreach (var (model, transform) in modelTransforms) { foreach (var modelMesh in model.Meshes) { foreach (var meshPart in modelMesh.MeshParts) { GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer); GraphicsDevice.Indices = meshPart.IndexBuffer; SimpleDepthEffect.Model = transform; foreach (var pass in SimpleDepthEffect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, 0, meshPart.VertexBuffer.VertexCount, 0, meshPart.Triangles.Length ); } } } } } private void Render( Matrix view, Matrix projection, IEnumerable<(Model, Matrix)> modelTransforms, IEnumerable pointLights, IEnumerable directionalLights ) { foreach (var (model, transform) in modelTransforms) { foreach (var modelMesh in model.Meshes) { foreach (var meshPart in modelMesh.MeshParts) { GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer); GraphicsDevice.Indices = meshPart.IndexBuffer; if (meshPart.Effect is TransformEffect transformEffect) { transformEffect.World = transform; transformEffect.View = view; transformEffect.Projection = projection; } if (meshPart.Effect is PointLightEffect pointLightEffect) { int i = 0; foreach (var pointLight in pointLights) { if (i > pointLightEffect.MaxPointLights) { break; } pointLightEffect.PointLights[i] = pointLight; i++; } } if (meshPart.Effect is DirectionalLightEffect directionalLightEffect) { int i = 0; foreach (var directionalLight in directionalLights) { if (i > directionalLightEffect.MaxDirectionalLights) { break; } directionalLightEffect.DirectionalLights[i] = directionalLight; i++; } } foreach (var pass in meshPart.Effect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, 0, meshPart.VertexBuffer.VertexCount, 0, meshPart.Triangles.Length ); } } } } } } }