CodeWalker/Rendering/Shaders/DistantLightsShader.cs
2017-09-21 20:33:05 +10:00

147 lines
4.4 KiB
C#

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