using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CodeWalker.GameFiles; using SharpDX; using SharpDX.Direct3D11; using System.IO; using SharpDX.DXGI; using Device = SharpDX.Direct3D11.Device; using Buffer = SharpDX.Direct3D11.Buffer; using MapFlags = SharpDX.Direct3D11.MapFlags; using CodeWalker.World; namespace CodeWalker.Rendering { public struct DistantLightsShaderVSSceneVars { public Matrix ViewProj; public Matrix ViewInv; public Vector3 CamPos; public float Pad0; } public class DistantLightsShader : Shader { bool disposed = false; VertexShader lightsvs; PixelShader lightsps; InputLayout layout; SamplerState texsampler; UnitQuad quad; GpuVarsBuffer VSSceneVars; public DistantLightsShader(Device device) { byte[] vsbytes = File.ReadAllBytes("Shaders\\DistantLightsVS.cso"); byte[] psbytes = File.ReadAllBytes("Shaders\\DistantLightsPS.cso"); lightsvs = new VertexShader(device, vsbytes); lightsps = new PixelShader(device, psbytes); layout = new InputLayout(device, vsbytes, new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0), }); texsampler = new SamplerState(device, new SamplerStateDescription() { AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, BorderColor = Color.Transparent, ComparisonFunction = Comparison.Always, Filter = Filter.MinMagMipLinear, MaximumAnisotropy = 1, MaximumLod = float.MaxValue, MinimumLod = 0, MipLodBias = 0, }); quad = new UnitQuad(device); VSSceneVars = new GpuVarsBuffer(device); } public override void SetShader(DeviceContext context) { context.VertexShader.Set(lightsvs); context.PixelShader.Set(lightsps); SetInputLayout(context, VertexType.PT); } public override bool SetInputLayout(DeviceContext context, VertexType type) { context.InputAssembler.InputLayout = layout; return true; } public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights) { VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix); VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix); VSSceneVars.Vars.CamPos = camera.Position; VSSceneVars.Update(context); VSSceneVars.SetVSCBuffer(context, 0); } public override void SetEntityVars(DeviceContext context, ref RenderableInst rend) { } public override void SetModelVars(DeviceContext context, RenderableModel model) { } public override void SetGeomVars(DeviceContext context, RenderableGeometry geom) { } public override void UnbindResources(DeviceContext context) { context.VertexShader.SetConstantBuffer(0, null); context.VertexShader.SetShaderResource(0, null); context.PixelShader.SetShaderResource(0, null); context.PixelShader.SetSampler(0, null); } public void RenderBatch(DeviceContext context, RenderableDistantLODLights lights) { context.VertexShader.SetShaderResource(0, lights.InstanceBuffer.SRV); context.PixelShader.SetShaderResource(0, lights.Texture.ShaderResourceView); context.PixelShader.SetSampler(0, texsampler); quad.DrawInstanced(context, lights.InstanceCount); } public void Dispose() { if (disposed) return; VSSceneVars.Dispose(); quad.Dispose(); texsampler.Dispose(); layout.Dispose(); //VSSceneVars.Dispose(); lightsps.Dispose(); lightsvs.Dispose(); disposed = true; } } }