diff --git a/Effects/FXB/SimpleDepthEffect.fxb b/Effects/FXB/SimpleDepthEffect.fxb new file mode 100644 index 0000000..e2baafe Binary files /dev/null and b/Effects/FXB/SimpleDepthEffect.fxb differ diff --git a/Effects/HLSL/SimpleDepthEffect.fx b/Effects/HLSL/SimpleDepthEffect.fx new file mode 100644 index 0000000..8b19a4e --- /dev/null +++ b/Effects/HLSL/SimpleDepthEffect.fx @@ -0,0 +1,36 @@ +#include "Macros.fxh" + +BEGIN_CONSTANTS + + float4x4 ModelViewProjection _vs(c0) _cb(c0); + +MATRIX_CONSTANTS + +END_CONSTANTS + +struct VertexShaderInput +{ + float4 Position : POSITION; +}; + +struct VertexShaderOutput +{ + float4 Position : SV_Position; +}; + +VertexShaderOutput main_vs(VertexShaderInput input) +{ + VertexShaderOutput output; + + output.Position = mul(float4(input.Position.xyz, 1.0), ModelViewProjection); + + return output; +} + +Technique SimpleDepth +{ + Pass + { + VertexShader = compile vs_3_0 main_vs(); + } +} diff --git a/Effects/SimpleDepthEffect.cs b/Effects/SimpleDepthEffect.cs new file mode 100644 index 0000000..f68f513 --- /dev/null +++ b/Effects/SimpleDepthEffect.cs @@ -0,0 +1,68 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace Kav +{ + public class SimpleDepthEffect : Effect + { + EffectParameter modelViewProjectionParam; + + Matrix model; + Matrix view; + Matrix projection; + + EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; + + public Matrix Model + { + get { return model; } + set + { + model = value; + dirtyFlags |= EffectDirtyFlags.WorldViewProj; + } + } + + public Matrix View + { + get { return view; } + set + { + view = value; + dirtyFlags |= EffectDirtyFlags.WorldViewProj; + } + } + + public Matrix Projection + { + get { return projection; } + set + { + projection = value; + dirtyFlags |= EffectDirtyFlags.WorldViewProj; + } + } + public SimpleDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffect) + { + CacheEffectParameters(); + } + + protected override void OnApply() + { + if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) + { + Matrix.Multiply(ref model, ref view, out Matrix modelView); + Matrix.Multiply(ref modelView, ref projection, out Matrix worldViewProj); + + modelViewProjectionParam.SetValue(worldViewProj); + + dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; + } + } + + private void CacheEffectParameters() + { + modelViewProjectionParam = Parameters["ModelViewProjection"]; + } + } +} diff --git a/Renderer.cs b/Renderer.cs index 4f71cac..79b078d 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -1,23 +1,89 @@ using System.Collections.Generic; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Kav { - public static class Renderer + public class Renderer { - public static void Render(GraphicsDevice graphicsDevice, Camera camera, IEnumerable models, IEnumerable pointLights) - { - var view = camera.View; - var projection = camera.Projection; + 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 models, IEnumerable pointLights) + { + Render(camera.View, camera.Projection, models, pointLights); + } + + // for shadow mapping + public void DepthRender(Matrix view, Matrix projection, IEnumerable<(Model, Matrix)> modelTransforms, IEnumerable pointLights) + { + GraphicsDevice.SetRenderTarget(DepthRenderTarget); + GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1, 0); + + SimpleDepthEffect.View = view; + SimpleDepthEffect.Projection = 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 models, IEnumerable pointLights) + { foreach (var model in models) { foreach (var modelMesh in model.Meshes) { foreach (var meshPart in modelMesh.MeshParts) { - graphicsDevice.SetVertexBuffer(meshPart.VertexBuffer); - graphicsDevice.Indices = meshPart.IndexBuffer; + GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer); + GraphicsDevice.Indices = meshPart.IndexBuffer; if (meshPart.Effect is TransformEffect transformEffect) { @@ -40,7 +106,7 @@ namespace Kav { pass.Apply(); - graphicsDevice.DrawIndexedPrimitives( + GraphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, 0, diff --git a/Resources.cs b/Resources.cs index e20f87b..4964b4a 100644 --- a/Resources.cs +++ b/Resources.cs @@ -16,7 +16,20 @@ namespace Kav } } + public static byte[] SimpleDepthEffect + { + get + { + if (simpleDepthEffect == null) + { + simpleDepthEffect = GetResource("SimpleDepthEffecT"); + } + return simpleDepthEffect; + } + } + private static byte[] pbrEffect; + private static byte[] simpleDepthEffect; private static byte[] GetResource(string name) {