R26_dev8 - First public commit

This commit is contained in:
dexyfex
2017-09-21 20:33:05 +10:00
Unverified
commit a8243c3e0e
391 changed files with 157678 additions and 0 deletions
+885
View File
@@ -0,0 +1,885 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct BasicShaderVSSceneVars
{
public Matrix ViewProj;
public Vector4 WindVector;
}
public struct BasicShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public uint HasSkeleton;
public uint HasTransforms;
public uint TintPaletteIndex;
public uint Pad1;
public Vector3 Scale;
public uint IsInstanced;
}
public struct BasicShaderVSModelVars
{
public Matrix Transform;
}
public struct BasicShaderVSGeomVars
{
public uint EnableTint;
public float TintYVal;
public uint IsDecal;
public uint EnableWind;
public Vector4 WindOverrideParams;
}
public struct BasicShaderPSSceneVars
{
public ShaderGlobalLightParams GlobalLights;
public uint EnableShadows;
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
public uint RenderModeIndex; //colour/texcoord index
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
}
public struct BasicShaderPSGeomVars
{
public uint EnableTexture;
public uint EnableTint;
public uint EnableNormalMap;
public uint EnableSpecMap;
public uint EnableDetailMap;
public uint IsDecal;
public uint IsEmissive;
public uint IsDistMap;
public float bumpiness;
public float AlphaScale;
public float HardAlphaBlend;
public float useTessellation;
public Vector4 detailSettings;
public Vector3 specMapIntMask;
public float specularIntensityMult;
public float specularFalloffMult;
public float specularFresnel;
public float wetnessMultiplier;
public uint SpecOnly;
}
public struct BasicShaderInstGlobalMatrix
{
public Vector4 Row1;
public Vector4 Row2;
public Vector4 Row3;
}
public struct BasicShaderInstGlobals
{
public BasicShaderInstGlobalMatrix M0;
public BasicShaderInstGlobalMatrix M1;
public BasicShaderInstGlobalMatrix M2;
public BasicShaderInstGlobalMatrix M3;
public BasicShaderInstGlobalMatrix M4;
public BasicShaderInstGlobalMatrix M5;
public BasicShaderInstGlobalMatrix M6;
public BasicShaderInstGlobalMatrix M7;
}
public struct BasicShaderInstLocals
{
public Vector3 vecBatchAabbMin;
public float instPad0;
public Vector3 vecBatchAabbDelta;
public float instPad1;
public Vector4 vecPlayerPos;
public Vector2 _vecCollParams;
public Vector2 instPad2;
public Vector4 fadeAlphaDistUmTimer;
public Vector4 uMovementParams;
public Vector4 _fakedGrassNormal;
public Vector3 gScaleRange;
public float instPad3;
public Vector4 gWindBendingGlobals;
public Vector2 gWindBendScaleVar;
public float gAlphaTest;
public float gAlphaToCoverageScale;
public Vector3 gLodFadeInstRange;
public uint gUseComputeShaderOutputBuffer;
}
public class BasicShader : Shader, IDisposable
{
bool disposed = false;
VertexShader basicvspnct;
VertexShader basicvspncct;
VertexShader basicvspncctt;
VertexShader basicvspnccttt;
VertexShader basicvspnctx;
VertexShader basicvspncctx;
VertexShader basicvspncttx;
VertexShader basicvspnccttx;
VertexShader basicvspnctttx;
VertexShader basicvspncctttx;
VertexShader basicvsbox;
VertexShader basicvssphere;
VertexShader basicvscapsule;
VertexShader basicvscylinder;
PixelShader basicps;
GpuVarsBuffer<BasicShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<BasicShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<BasicShaderVSModelVars> VSModelVars;
GpuVarsBuffer<BasicShaderVSGeomVars> VSGeomVars;
GpuVarsBuffer<BasicShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<BasicShaderPSGeomVars> PSGeomVars;
GpuVarsBuffer<BasicShaderInstGlobals> InstGlobalVars;
GpuVarsBuffer<BasicShaderInstLocals> InstLocalVars;
SamplerState texsampler;
SamplerState texsampleranis;
SamplerState texsamplertnt;
SamplerState texsamplertntyft;
UnitCube cube; //for collision box render
UnitSphere sphere; //for collision sphere render
UnitCapsule capsule; //for collision capsule render
UnitCylinder cylinder; //for collision cylinder render
public bool AnisotropicFilter = false;
public bool DecalMode = false;
public float AlphaScale = 1.0f;
public Vector4 WindVector = Vector4.Zero;
public WorldRenderMode RenderMode = WorldRenderMode.Default;
public int RenderVertexColourIndex = 1;
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
public bool SpecularEnable = true;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public BasicShader(Device device)
{
byte[] vspnctbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCT.cso");
byte[] vspncctbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCT.cso");
byte[] vspnccttbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTT.cso");
byte[] vspncctttbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTT.cso");
byte[] vspnctxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTX.cso");
byte[] vspncctxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTX.cso");
byte[] vspncttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTTX.cso");
byte[] vspnccttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTX.cso");
byte[] vspnctttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCTTTX.cso");
byte[] vspncctttxbytes = File.ReadAllBytes("Shaders\\BasicVS_PNCCTTTX.cso");
byte[] vsboxbytes = File.ReadAllBytes("Shaders\\BasicVS_Box.cso");
byte[] vsspherebytes = File.ReadAllBytes("Shaders\\BasicVS_Sphere.cso");
byte[] vscapsulebytes = File.ReadAllBytes("Shaders\\BasicVS_Capsule.cso");
byte[] vscylinderbytes = File.ReadAllBytes("Shaders\\BasicVS_Cylinder.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\BasicPS.cso");
basicvspnct = new VertexShader(device, vspnctbytes);
basicvspncct = new VertexShader(device, vspncctbytes);
basicvspncctt = new VertexShader(device, vspnccttbytes);
basicvspnccttt = new VertexShader(device, vspncctttbytes);
basicvspnctx = new VertexShader(device, vspnctxbytes);
basicvspncctx = new VertexShader(device, vspncctxbytes);
basicvspncttx = new VertexShader(device, vspncttxbytes);
basicvspnccttx = new VertexShader(device, vspnccttxbytes);
basicvspnctttx = new VertexShader(device, vspnctttxbytes);
basicvspncctttx = new VertexShader(device, vspncctttxbytes);
basicvsbox = new VertexShader(device, vsboxbytes);
basicvssphere = new VertexShader(device, vsspherebytes);
basicvscapsule = new VertexShader(device, vscapsulebytes);
basicvscylinder = new VertexShader(device, vscylinderbytes);
basicps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<BasicShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<BasicShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<BasicShaderVSModelVars>(device);
VSGeomVars = new GpuVarsBuffer<BasicShaderVSGeomVars>(device);
PSSceneVars = new GpuVarsBuffer<BasicShaderPSSceneVars>(device);
PSGeomVars = new GpuVarsBuffer<BasicShaderPSGeomVars>(device);
InstGlobalVars = new GpuVarsBuffer<BasicShaderInstGlobals>(device);
InstLocalVars = new GpuVarsBuffer<BasicShaderInstLocals>(device);
InitInstGlobalVars();
//supported layouts - requires Position, Normal, Colour, Texcoord
layouts.Add(VertexType.Default, new InputLayout(device, vspnctbytes, VertexTypeDefault.GetLayout()));
layouts.Add(VertexType.PNCH2, new InputLayout(device, vspnctbytes, VertexTypePNCH2.GetLayout()));
layouts.Add(VertexType.PCCNCT, new InputLayout(device, vspncctbytes, VertexTypePCCNCT.GetLayout()));
layouts.Add(VertexType.PCCNCCT, new InputLayout(device, vspncctbytes, VertexTypePCCNCCT.GetLayout()));
layouts.Add(VertexType.PNCCT, new InputLayout(device, vspncctbytes, VertexTypePNCCT.GetLayout()));
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vspnccttbytes, VertexTypePNCCTT.GetLayout()));
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vspncctttbytes, VertexTypePNCCTTTT.GetLayout()));
//normalmap layouts - requires Position, Normal, Colour, Texcoord, Tangent (X)
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vspnctxbytes, VertexTypeDefaultEx.GetLayout()));
layouts.Add(VertexType.PCCH2H4, new InputLayout(device, vspnctxbytes, VertexTypePCCH2H4.GetLayout()));
layouts.Add(VertexType.PCCNCTX, new InputLayout(device, vspncctxbytes, VertexTypePCCNCTX.GetLayout()));
layouts.Add(VertexType.PCCNCCTX, new InputLayout(device, vspncctxbytes, VertexTypePCCNCCTX.GetLayout()));
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vspncctxbytes, VertexTypePNCCTX.GetLayout()));
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vspncttxbytes, VertexTypePNCTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePNCCTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vspnccttxbytes, VertexTypePNCCTTX_2.GetLayout()));
layouts.Add(VertexType.PCCNCCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePCCNCCTTX.GetLayout()));
layouts.Add(VertexType.PNCTTTX, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX.GetLayout()));
layouts.Add(VertexType.PNCTTTX_2, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX_2.GetLayout()));
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTX_3.GetLayout()));
layouts.Add(VertexType.PNCTTTTX, new InputLayout(device, vspnctttxbytes, VertexTypePNCTTTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vspncctttxbytes, VertexTypePNCCTTTX.GetLayout()));
layouts.Add(VertexType.PCCNCTT, new InputLayout(device, vspnccttbytes, VertexTypePCCNCTT.GetLayout()));
layouts.Add(VertexType.PCCNCTTX, new InputLayout(device, vspnccttxbytes, VertexTypePCCNCTTX.GetLayout()));
layouts.Add(VertexType.PCCNCTTT, new InputLayout(device, vspncctttbytes, VertexTypePCCNCTTT.GetLayout()));
layouts.Add(VertexType.PNCTT, new InputLayout(device, vspnctbytes, VertexTypePNCTT.GetLayout()));
layouts.Add(VertexType.PNCTTT, new InputLayout(device, vspnctbytes, VertexTypePNCTTT.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsampleranis = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.Anisotropic,
MaximumAnisotropy = 8,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsamplertnt = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Clamp,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.White,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipPoint,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsamplertntyft = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.White,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipPoint,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
cube = new UnitCube(device, vsboxbytes, false, false, true);
sphere = new UnitSphere(device, vsspherebytes, 4);
capsule = new UnitCapsule(device, vscapsulebytes, 4);
cylinder = new UnitCylinder(device, vscylinderbytes, 8);
}
private void InitInstGlobalVars()
{
var m0 = Matrix3x3.RotationZ(0.00f * (float)Math.PI);
var m1 = Matrix3x3.RotationZ(0.25f * (float)Math.PI);
var m2 = Matrix3x3.RotationZ(0.50f * (float)Math.PI);
var m3 = Matrix3x3.RotationZ(0.75f * (float)Math.PI);
var m4 = Matrix3x3.RotationZ(1.00f * (float)Math.PI);
var m5 = Matrix3x3.RotationZ(1.25f * (float)Math.PI);
var m6 = Matrix3x3.RotationZ(1.50f * (float)Math.PI);
var m7 = Matrix3x3.RotationZ(1.75f * (float)Math.PI);
InstGlobalVars.Vars.M0.Row1 = new Vector4(m0.Row1, 1);
InstGlobalVars.Vars.M0.Row2 = new Vector4(m0.Row2, 1);
InstGlobalVars.Vars.M0.Row3 = new Vector4(m0.Row3, 1);
InstGlobalVars.Vars.M1.Row1 = new Vector4(m1.Row1, 1);
InstGlobalVars.Vars.M1.Row2 = new Vector4(m1.Row2, 1);
InstGlobalVars.Vars.M1.Row3 = new Vector4(m1.Row3, 1);
InstGlobalVars.Vars.M2.Row1 = new Vector4(m2.Row1, 1);
InstGlobalVars.Vars.M2.Row2 = new Vector4(m2.Row2, 1);
InstGlobalVars.Vars.M2.Row3 = new Vector4(m2.Row3, 1);
InstGlobalVars.Vars.M3.Row1 = new Vector4(m3.Row1, 1);
InstGlobalVars.Vars.M3.Row2 = new Vector4(m3.Row2, 1);
InstGlobalVars.Vars.M3.Row3 = new Vector4(m3.Row3, 1);
InstGlobalVars.Vars.M4.Row1 = new Vector4(m4.Row1, 1);
InstGlobalVars.Vars.M4.Row2 = new Vector4(m4.Row2, 1);
InstGlobalVars.Vars.M4.Row3 = new Vector4(m4.Row3, 1);
InstGlobalVars.Vars.M5.Row1 = new Vector4(m5.Row1, 1);
InstGlobalVars.Vars.M5.Row2 = new Vector4(m5.Row2, 1);
InstGlobalVars.Vars.M5.Row3 = new Vector4(m5.Row3, 1);
InstGlobalVars.Vars.M6.Row1 = new Vector4(m6.Row1, 1);
InstGlobalVars.Vars.M6.Row2 = new Vector4(m6.Row2, 1);
InstGlobalVars.Vars.M6.Row3 = new Vector4(m6.Row3, 1);
InstGlobalVars.Vars.M7.Row1 = new Vector4(m7.Row1, 1);
InstGlobalVars.Vars.M7.Row2 = new Vector4(m7.Row2, 1);
InstGlobalVars.Vars.M7.Row3 = new Vector4(m7.Row3, 1);
}
private void SetVertexShader(DeviceContext context, VertexType type)
{
VertexShader vs = basicvspnct;
switch (type)
{
case VertexType.Default:
case VertexType.PNCH2:
case VertexType.PNCTT:
case VertexType.PNCTTT:
vs = basicvspnct;
break;
case VertexType.PCCNCT:
case VertexType.PCCNCCT:
case VertexType.PNCCT:
vs = basicvspncct;
break;
case VertexType.PNCCTT://not used?
case VertexType.PCCNCTT:
vs = basicvspncctt;
break;
case VertexType.PNCCTTTT://not used?
case VertexType.PCCNCTTT:
vs = basicvspnccttt;
break;
case VertexType.DefaultEx:
case VertexType.PCCH2H4:
vs = basicvspnctx;
break;
case VertexType.PCCNCTX:
case VertexType.PCCNCCTX:
case VertexType.PNCCTX:
vs = basicvspncctx;
break;
case VertexType.PNCTTX:
vs = basicvspncttx;
break;
case VertexType.PNCCTTX://not used?
case VertexType.PNCCTTX_2://not used?
case VertexType.PCCNCCTTX://not used?
case VertexType.PCCNCTTX:
vs = basicvspnccttx;
break;
case VertexType.PNCTTTX:
case VertexType.PNCTTTX_2:
case VertexType.PNCTTTX_3:
case VertexType.PNCTTTTX: //not using last texcoords!
vs = basicvspnctttx;
break;
case VertexType.PNCCTTTX://not used?
vs = basicvspncctttx;
break;
default:
break;
}
context.VertexShader.Set(vs);
}
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(basicps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
SetVertexShader(context, type);
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
uint rendermode = 0;
uint rendermodeind = 1;
SpecularEnable = lights.SpecularEnabled;
switch (RenderMode)
{
case WorldRenderMode.VertexNormals:
rendermode = 1;
break;
case WorldRenderMode.VertexTangents:
rendermode = 2;
break;
case WorldRenderMode.VertexColour:
rendermode = 3;
rendermodeind = (uint)RenderVertexColourIndex;
break;
case WorldRenderMode.TextureCoord:
rendermode = 4;
rendermodeind = (uint)RenderTextureCoordIndex;
break;
case WorldRenderMode.SingleTexture:
rendermode = 8;//direct mode
break;
}
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Vars.WindVector = WindVector;
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
PSSceneVars.Vars.GlobalLights = lights.Params;
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
PSSceneVars.Vars.RenderMode = rendermode;
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 0);
if (shadowmap != null)
{
shadowmap.SetFinalRenderResources(context);
}
if (!InstGlobalVars.Flag) //on the first frame, update the instance globals
{
InstGlobalVars.Update(context);
InstGlobalVars.Flag = true;
}
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
VSEntityVars.Vars.IsInstanced = 0;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 3);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture = null;
RenderableTexture tintpal = null;
RenderableTexture bumptex = null;
RenderableTexture spectex = null;
RenderableTexture detltex = null;
bool isdistmap = false;
float tntpalind = 0.0f;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
if (RenderMode == WorldRenderMode.Default)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (itex == null) continue;
switch (ihash)
{
case MetaName.DiffuseSampler:
texture = itex;
break;
case MetaName.BumpSampler:
bumptex = itex;
break;
case MetaName.SpecSampler:
spectex = itex;
break;
case MetaName.DetailSampler:
detltex = itex;
break;
case MetaName.TintPaletteSampler:
tintpal = itex;
if (tintpal.Key != null)
{
//this is slightly dodgy but VSEntityVars should have the correct value in it...
tntpalind = (VSEntityVars.Vars.TintPaletteIndex + 0.5f) / tintpal.Key.Height;
}
break;
case MetaName.distanceMapSampler:
texture = itex;
isdistmap = true;
break;
case MetaName.heightSampler:
case MetaName.EnvironmentSampler:
break;
case MetaName.FlowSampler:
case MetaName.FogSampler:
case MetaName.FoamSampler:
if (texture == null) texture = itex;
break;
default:
if (texture == null) texture = itex;
break;
}
}
}
else if (RenderMode == WorldRenderMode.SingleTexture)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (ihash == RenderTextureSampler)
{
texture = itex;
break;
}
}
}
}
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
bool usebump = ((bumptex != null) && (bumptex.ShaderResourceView != null));
bool usespec = ((spectex != null) && (spectex.ShaderResourceView != null));
bool usedetl = ((detltex != null) && (detltex.ShaderResourceView != null));
bool usetint = ((tintpal != null) && (tintpal.ShaderResourceView != null));
uint tintflag = 0;
if (usetint) tintflag = 1;
uint windflag = geom.EnableWind ? 1u : 0u;
uint emflag = geom.IsEmissive ? 1u : 0u;
var shaderName = geom.DrawableGeom.Shader.Name;
var shaderFile = geom.DrawableGeom.Shader.FileName;
switch (shaderFile.Hash)
{
case 2245870123: //trees_normal_diffspec_tnt.sps
case 3334613197: //trees_tnt.sps
case 1229591973://{trees_normal_spec_tnt.sps}
if (usetint) tintflag = 2; //use 2nd vertex colour channel for tint...
break;
case 3880384844://{decal_spec_only.sps}w
case 600733812://{decal_amb_only.sps}
case 2842248626://{spec_decal.sps}
case 2457676400://{reflect_decal.sps}
case 2706821972://{mirror_decal.sps}
//if (RenderMode == WorldRenderMode.Default) usediff = false;
break;
}
uint pstintflag = tintflag;
if (VSEntityVars.Vars.IsInstanced>0)
{
pstintflag = 1;
switch (shaderFile.Hash)
{
case 916743331: //{grass_batch.sps}
windflag = 1;
break;
case 3833671083://{normal_spec_batch.sps}
windflag = 0;
break;
default:
break;
}
}
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
PSGeomVars.Vars.EnableTint = pstintflag;
PSGeomVars.Vars.EnableNormalMap = usebump ? 1u : 0u;
PSGeomVars.Vars.EnableSpecMap = usespec ? 1u : 0u;
PSGeomVars.Vars.EnableDetailMap = usedetl ? 1u : 0u;
PSGeomVars.Vars.IsDecal = DecalMode ? 1u : 0u;
PSGeomVars.Vars.IsEmissive = emflag;
PSGeomVars.Vars.IsDistMap = isdistmap ? 1u : 0u;
PSGeomVars.Vars.bumpiness = geom.bumpiness;
PSGeomVars.Vars.AlphaScale = isdistmap ? 1.0f : AlphaScale;
PSGeomVars.Vars.HardAlphaBlend = 0.0f; //todo: cutouts flag!
PSGeomVars.Vars.useTessellation = 0.0f;
PSGeomVars.Vars.detailSettings = geom.detailSettings;
PSGeomVars.Vars.specMapIntMask = geom.specMapIntMask;
PSGeomVars.Vars.specularIntensityMult = SpecularEnable ? geom.specularIntensityMult : 0.0f;
PSGeomVars.Vars.specularFalloffMult = geom.specularFalloffMult;
PSGeomVars.Vars.specularFresnel = geom.specularFresnel;
PSGeomVars.Vars.wetnessMultiplier = geom.wetnessMultiplier;
PSGeomVars.Vars.SpecOnly = geom.SpecOnly ? 1u : 0u;
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableTint = tintflag;
VSGeomVars.Vars.TintYVal = tntpalind;
VSGeomVars.Vars.IsDecal = DecalMode ? 1u : 0u;
VSGeomVars.Vars.EnableWind = windflag;
VSGeomVars.Vars.WindOverrideParams = geom.WindOverrideParams;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);
context.VertexShader.SetSampler(0, geom.IsFragment ? texsamplertntyft : texsamplertnt);
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
if (usediff)
{
texture.SetPSResource(context, 0);
}
if (usebump)
{
bumptex.SetPSResource(context, 2);
}
if (usespec)
{
spectex.SetPSResource(context, 3);
}
if (usedetl)
{
detltex.SetPSResource(context, 4);
}
if (usetint)
{
tintpal.SetVSResource(context, 0);
}
}
public void SetInstanceVars(DeviceContext context, RenderableInstanceBatch batch)
{
var gb = batch.Key;
VSEntityVars.Vars.CamRel = new Vector4(gb.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = Quaternion.Identity;
VSEntityVars.Vars.Scale = Vector3.One;
VSEntityVars.Vars.HasSkeleton = 0;
VSEntityVars.Vars.HasTransforms = 0;
VSEntityVars.Vars.TintPaletteIndex = 0;
VSEntityVars.Vars.IsInstanced = 1;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
InstGlobalVars.SetVSCBuffer(context, 5);
InstLocalVars.Vars.vecBatchAabbMin = gb.AABBMin;
InstLocalVars.Vars.vecBatchAabbDelta = gb.AABBMax - gb.AABBMin;
InstLocalVars.Vars.vecPlayerPos = new Vector4(gb.Position - gb.CamRel, 1.0f);
InstLocalVars.Vars._vecCollParams = new Vector2(2.0f, -3.0f);//range, offset
InstLocalVars.Vars.fadeAlphaDistUmTimer = new Vector4(0.0f);
InstLocalVars.Vars.uMovementParams = new Vector4(0.0f);
InstLocalVars.Vars._fakedGrassNormal = new Vector4(Vector3.Normalize(-gb.CamRel), 0.0f);
InstLocalVars.Vars.gScaleRange = gb.Batch.ScaleRange;
InstLocalVars.Vars.gWindBendingGlobals = new Vector4(WindVector.X, WindVector.Y, 1.0f, 1.0f);
InstLocalVars.Vars.gWindBendScaleVar = new Vector2(WindVector.Z, WindVector.W);
InstLocalVars.Vars.gAlphaTest = 0.0f;
InstLocalVars.Vars.gAlphaToCoverageScale = 1.0f;
InstLocalVars.Vars.gLodFadeInstRange = new Vector3(gb.Batch.LodInstFadeRange, gb.Batch.LodFadeStartDist, gb.Batch.lodDist);
InstLocalVars.Vars.gUseComputeShaderOutputBuffer = 0;
InstLocalVars.Update(context);
InstLocalVars.SetVSCBuffer(context, 6);
context.VertexShader.SetShaderResource(2, batch.GrassInstanceBuffer.SRV);
}
public void RenderBoundGeom(DeviceContext context, RenderableBoundGeometryInst inst)
{
VSEntityVars.Vars.CamRel = new Vector4(inst.Inst.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = inst.Inst.Orientation;
VSEntityVars.Vars.Scale = inst.Inst.Scale;
VSEntityVars.Vars.HasSkeleton = 0;
VSEntityVars.Vars.HasTransforms = 0; //todo! bounds transforms..?
VSEntityVars.Vars.TintPaletteIndex = 0;
VSEntityVars.Vars.IsInstanced = 0;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
PSGeomVars.Vars.EnableTexture = 0;
PSGeomVars.Vars.EnableTint = 0;
PSGeomVars.Vars.EnableNormalMap = 0;
PSGeomVars.Vars.EnableSpecMap = 0;
PSGeomVars.Vars.EnableDetailMap = 0;
PSGeomVars.Vars.IsDecal = 0;
PSGeomVars.Vars.IsEmissive = 0;
PSGeomVars.Vars.IsDistMap = 0;
PSGeomVars.Vars.bumpiness = 0;
PSGeomVars.Vars.AlphaScale = 1;
PSGeomVars.Vars.HardAlphaBlend = 0;
PSGeomVars.Vars.useTessellation = 0;
PSGeomVars.Vars.detailSettings = Vector4.Zero;
PSGeomVars.Vars.specMapIntMask = Vector3.Zero;
PSGeomVars.Vars.specularIntensityMult = 1.0f;
PSGeomVars.Vars.specularFalloffMult = 1.0f;
PSGeomVars.Vars.specularFresnel = 1.0f;
PSGeomVars.Vars.wetnessMultiplier = 0.0f;
PSGeomVars.Vars.SpecOnly = 0;
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableTint = 0;
VSGeomVars.Vars.TintYVal = 0.0f;
VSGeomVars.Vars.IsDecal = 0;
VSGeomVars.Vars.EnableWind = 0;
VSGeomVars.Vars.WindOverrideParams = Vector4.Zero;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);
if (inst.Geom.VertexBuffer != null) //render the triangles
{
SetVertexShader(context, VertexType.Default);
SetInputLayout(context, VertexType.Default);
inst.Geom.RenderTriangles(context);
}
//render the boxes
if (inst.Geom.BoxBuffer != null)
{
context.VertexShader.Set(basicvsbox);
context.VertexShader.SetShaderResource(1, inst.Geom.BoxBuffer.SRV);
cube.DrawInstanced(context, inst.Geom.BoxBuffer.StructCount);
}
//render the spheres
if (inst.Geom.SphereBuffer != null)
{
context.VertexShader.Set(basicvssphere);
context.VertexShader.SetShaderResource(1, inst.Geom.SphereBuffer.SRV);
sphere.DrawInstanced(context, inst.Geom.SphereBuffer.StructCount);
}
//render the capsules
if (inst.Geom.CapsuleBuffer != null)
{
context.VertexShader.Set(basicvscapsule);
context.VertexShader.SetShaderResource(1, inst.Geom.CapsuleBuffer.SRV);
capsule.DrawInstanced(context, inst.Geom.CapsuleBuffer.StructCount);
}
//render the cylinders
if (inst.Geom.CylinderBuffer != null)
{
context.VertexShader.Set(basicvscylinder);
context.VertexShader.SetShaderResource(1, inst.Geom.CylinderBuffer.SRV);
cylinder.DrawInstanced(context, inst.Geom.CylinderBuffer.StructCount);
}
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetShaderResource(1, null);//shadowmap
context.PixelShader.SetSampler(1, null); //shadowmap
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(4, null);
context.VertexShader.SetConstantBuffer(5, null);
context.VertexShader.SetConstantBuffer(6, null);
context.VertexShader.SetSampler(0, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.PixelShader.SetShaderResource(2, null);
context.PixelShader.SetShaderResource(3, null);
context.PixelShader.SetShaderResource(4, null);
context.VertexShader.SetShaderResource(0, null);
context.VertexShader.SetShaderResource(1, null);
context.VertexShader.SetShaderResource(2, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
cube.Dispose();
sphere.Dispose();
capsule.Dispose();
cylinder.Dispose();
texsampler.Dispose();
texsampleranis.Dispose();
texsamplertnt.Dispose();
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
VSGeomVars.Dispose();
PSSceneVars.Dispose();
PSGeomVars.Dispose();
InstGlobalVars.Dispose();
InstLocalVars.Dispose();
basicps.Dispose();
basicvspnct.Dispose();
basicvspncct.Dispose();
basicvspncctt.Dispose();
basicvspnccttt.Dispose();
basicvspnctx.Dispose();
basicvspncctx.Dispose();
basicvspncttx.Dispose();
basicvspnccttx.Dispose();
basicvspnctttx.Dispose();
basicvspncctttx.Dispose();
basicvsbox.Dispose();
basicvssphere.Dispose();
basicvscapsule.Dispose();
basicvscylinder.Dispose();
disposed = true;
}
}
}
+239
View File
@@ -0,0 +1,239 @@
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using CodeWalker.GameFiles;
using System.IO;
using SharpDX.DXGI;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct BoundingSphereVSSceneVars
{
public Matrix ViewProj;
public Matrix ViewInv;
public float SegmentCount;
public float VertexCount;
public float Pad1;
public float Pad2;
}
public struct BoundingSphereVSSphereVars
{
public Vector3 Center;
public float Radius;
}
public struct BoundingBoxVSSceneVars
{
public Matrix ViewProj;
}
public struct BoundingBoxVSBoxVars
{
public Quaternion Orientation;
public Vector4 BBMin;
public Vector4 BBRng; //max-min
public Vector3 CamRel;
public float Pad1;
public Vector3 Scale;
public float Pad2;
}
public struct BoundsPSColourVars
{
public Vector4 Colour;
}
public class BoundsShader : Shader, IDisposable
{
bool disposed = false;
BoundsShaderMode mode = BoundsShaderMode.Sphere;
VertexShader spherevs;
VertexShader boxvs;
PixelShader boundsps;
GpuVarsBuffer<BoundingSphereVSSceneVars> VSSphereSceneVars;
GpuVarsBuffer<BoundingSphereVSSphereVars> VSSphereVars;
GpuVarsBuffer<BoundingBoxVSSceneVars> VSBoxSceneVars;
GpuVarsBuffer<BoundingBoxVSBoxVars> VSBoxVars;
GpuVarsBuffer<BoundsPSColourVars> PSColourVars;
int SegmentCount = 64;
int VertexCount = 65;
UnitCube cube;
public BoundsShader(Device device)
{
byte[] spherevsbytes = File.ReadAllBytes("Shaders\\BoundingSphereVS.cso");
byte[] boxvsbytes = File.ReadAllBytes("Shaders\\BoundingBoxVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\BoundsPS.cso");
spherevs = new VertexShader(device, spherevsbytes);
boxvs = new VertexShader(device, boxvsbytes);
boundsps = new PixelShader(device, psbytes);
VSSphereSceneVars = new GpuVarsBuffer<BoundingSphereVSSceneVars>(device);
VSSphereVars = new GpuVarsBuffer<BoundingSphereVSSphereVars>(device);
VSBoxSceneVars = new GpuVarsBuffer<BoundingBoxVSSceneVars>(device);
VSBoxVars = new GpuVarsBuffer<BoundingBoxVSBoxVars>(device);
PSColourVars = new GpuVarsBuffer<BoundsPSColourVars>(device);
cube = new UnitCube(device, boxvsbytes, false, true, false);
}
public void SetMode(BoundsShaderMode m)
{
mode = m;
}
public override void SetShader(DeviceContext context)
{
switch (mode)
{
default:
case BoundsShaderMode.Sphere:
context.VertexShader.Set(spherevs);
break;
case BoundsShaderMode.Box:
context.VertexShader.Set(boxvs);
break;
}
context.PixelShader.Set(boundsps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
//switch (mode)
//{
// default:
// case BoundsShaderMode.Sphere:
// context.InputAssembler.InputLayout = null;
// break;
// case BoundsShaderMode.Box:
// context.InputAssembler.InputLayout = cube.InputLayout;
// break;
//}
return true;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
switch (mode)
{
default:
case BoundsShaderMode.Sphere:
VSSphereSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSphereSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
VSSphereSceneVars.Vars.SegmentCount = (float)SegmentCount;
VSSphereSceneVars.Vars.VertexCount = (float)VertexCount;
VSSphereSceneVars.Update(context);
VSSphereSceneVars.SetVSCBuffer(context, 0);
break;
case BoundsShaderMode.Box:
VSBoxSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSBoxSceneVars.Update(context);
VSBoxSceneVars.SetVSCBuffer(context, 0);
break;
}
}
public void SetSphereVars(DeviceContext context, Vector3 center, float radius)
{
VSSphereVars.Vars.Center = center;
VSSphereVars.Vars.Radius = radius;
VSSphereVars.Update(context);
VSSphereVars.SetVSCBuffer(context, 1);
}
public void SetBoxVars(DeviceContext context, Vector3 camrel, Vector3 bbmin, Vector3 bbmax, Quaternion orientation, Vector3 scale)
{
VSBoxVars.Vars.Orientation = orientation;
VSBoxVars.Vars.BBMin = new Vector4(bbmin, 0.0f);
VSBoxVars.Vars.BBRng = new Vector4(bbmax - bbmin, 0.0f);
VSBoxVars.Vars.CamRel = camrel;
VSBoxVars.Vars.Scale = scale;
VSBoxVars.Update(context);
VSBoxVars.SetVSCBuffer(context, 1);
}
public void SetColourVars(DeviceContext context, Vector4 colour)
{
PSColourVars.Vars.Colour = colour;
PSColourVars.Update(context);
PSColourVars.SetPSCBuffer(context, 0);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
//don't use this one
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
//don't use this
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
//don't use this
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void DrawSphere(DeviceContext context)
{
context.InputAssembler.InputLayout = null;
context.InputAssembler.SetIndexBuffer(null, Format.Unknown, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineStrip;
context.Draw(VertexCount, 0);
}
public void DrawBox(DeviceContext context)
{
cube.Draw(context);
}
public void Dispose()
{
if (disposed) return;
VSSphereSceneVars.Dispose();
VSSphereVars.Dispose();
VSBoxSceneVars.Dispose();
VSBoxVars.Dispose();
PSColourVars.Dispose();
cube.Dispose();
boundsps.Dispose();
boxvs.Dispose();
spherevs.Dispose();
disposed = true;
}
}
public enum BoundsShaderMode
{
None = 0,
Sphere = 1,
Box = 2,
}
}
+345
View File
@@ -0,0 +1,345 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct CableShaderVSSceneVars
{
public Matrix ViewProj;
}
public struct CableShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public uint HasSkeleton;
public uint HasTransforms;
public uint TintPaletteIndex;
public uint Pad1;
public Vector3 Scale;
public uint IsInstanced;
}
public struct CableShaderVSModelVars
{
public Matrix Transform;
}
public struct CableShaderVSGeomVars
{
public uint EnableTint;
public float TintYVal;
public uint IsDecal;
public uint Pad5;
}
public struct CableShaderPSSceneVars
{
public ShaderGlobalLightParams GlobalLights;
public uint EnableShadows;
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
public uint RenderModeIndex; //colour/texcoord index
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
}
public struct CableShaderPSGeomVars
{
public uint EnableTexture;
public uint EnableTint;
public uint Pad100;
public uint Pad101;
}
public class CableShader : Shader, IDisposable
{
bool disposed = false;
VertexShader vs;
PixelShader ps;
GpuVarsBuffer<CableShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<CableShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<CableShaderVSModelVars> VSModelVars;
GpuVarsBuffer<CableShaderVSGeomVars> VSGeomVars;
GpuVarsBuffer<CableShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<CableShaderPSGeomVars> PSGeomVars;
SamplerState texsampler;
public WorldRenderMode RenderMode = WorldRenderMode.Default;
public int RenderVertexColourIndex = 1;
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public CableShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\CableVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\CablePS.cso");
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<CableShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<CableShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<CableShaderVSModelVars>(device);
VSGeomVars = new GpuVarsBuffer<CableShaderVSGeomVars>(device);
PSSceneVars = new GpuVarsBuffer<CableShaderPSSceneVars>(device);
PSGeomVars = new GpuVarsBuffer<CableShaderPSGeomVars>(device);
//supported layout - requires Position, Normal, Colour, Texcoord
layouts.Add(VertexType.Default, new InputLayout(device, vsbytes, VertexTypeDefault.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
private void SetVertexShader(DeviceContext context, VertexType type)
{
switch (type)
{
case VertexType.Default:
break;
default:
break;
}
context.VertexShader.Set(vs);
}
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
SetVertexShader(context, type);
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
uint rendermode = 0;
uint rendermodeind = 1;
switch (RenderMode)
{
case WorldRenderMode.VertexNormals:
rendermode = 1;
break;
case WorldRenderMode.VertexTangents:
rendermode = 2;
break;
case WorldRenderMode.VertexColour:
rendermode = 3;
rendermodeind = (uint)RenderVertexColourIndex;
break;
case WorldRenderMode.TextureCoord:
rendermode = 4;
rendermodeind = (uint)RenderTextureCoordIndex;
break;
case WorldRenderMode.SingleTexture:
rendermode = 8;//direct mode
break;
}
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
PSSceneVars.Vars.GlobalLights = lights.Params;
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
PSSceneVars.Vars.RenderMode = rendermode;
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 0);
if (shadowmap != null)
{
shadowmap.SetFinalRenderResources(context);
}
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
VSEntityVars.Vars.IsInstanced = 0;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 3);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
if (RenderMode == WorldRenderMode.Default)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
switch (ihash)
{
case MetaName.DiffuseSampler:
texture = itex;
break;
}
}
////fallback try get first texture... eventaully remove this! (helps with water for now)
//int index = 0;
//while (((texture == null) || (texture.Texture2D == null)) && (index < geom.Textures.Length))
//{
// texture = geom.Textures[index];
// index++;
//}
}
else if (RenderMode == WorldRenderMode.SingleTexture)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (ihash == RenderTextureSampler)
{
texture = itex;
break;
}
}
}
}
bool usediff = ((texture != null) && (texture.Texture2D != null) && (texture.ShaderResourceView != null));
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
PSGeomVars.Vars.EnableTint = 0u;
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableTint = 0u;
VSGeomVars.Vars.TintYVal = 0u;
VSGeomVars.Vars.IsDecal = 0u;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);
//context.VertexShader.SetSampler(0, texsampler);
context.PixelShader.SetSampler(0, texsampler);
//context.PixelShader.SetSampler(1, texsamplerc);
if (usediff)
{
texture.SetPSResource(context, 0);
//context.PixelShader.SetShaderResource(0, difftex.ShaderResourceView);
}
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetShaderResource(1, null);//shadowmap
context.PixelShader.SetSampler(1, null); //shadowmap
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(4, null);
context.VertexShader.SetSampler(0, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.SetShaderResource(0, null);
context.VertexShader.SetShaderResource(1, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
if (texsampler != null)
{
texsampler.Dispose();
texsampler = null;
}
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
VSGeomVars.Dispose();
PSSceneVars.Dispose();
PSGeomVars.Dispose();
ps.Dispose();
vs.Dispose();
disposed = true;
}
}
}
+356
View File
@@ -0,0 +1,356 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeWalker.GameFiles;
using CodeWalker.World;
using SharpDX.Direct3D11;
using System.IO;
using SharpDX;
namespace CodeWalker.Rendering
{
public struct CloudsShaderVSSceneVars
{
public Matrix ViewProj;
public Matrix ViewInv;
}
public struct CloudsShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public Vector4 Scale;
}
public struct CloudsShaderVSModelVars
{
public Matrix Transform;
}
public struct CloudsShaderPSSceneVars
{
public Vector4 LightDirection;
public uint EnableHDR;
public uint Pad0;
public uint Pad1;
public uint Pad2;
}
public struct CloudsShaderCloudsLocals
{
public Vector3 gSkyColor; // Offset: 0 Size: 12 [unused]
public float gPad00;
public Vector3 gEastMinusWestColor; // Offset: 16 Size: 12 [unused]
public float gPad01;
public Vector3 gWestColor; // Offset: 32 Size: 12 [unused]
public float gPad02;
public Vector3 gSunDirection; // Offset: 48 Size: 12
public float gPad03;
public Vector3 gSunColor; // Offset: 64 Size: 12
public float gPad04;
public Vector3 gCloudColor; // Offset: 80 Size: 12 [unused]
public float gPad05;
public Vector3 gAmbientColor; // Offset: 96 Size: 12 [unused]
public float gPad06;
public Vector3 gBounceColor; // Offset: 112 Size: 12 [unused]
public float gPad07;
public Vector4 gDensityShiftScale; // Offset: 128 Size: 16 [unused]
public Vector4 gScatterG_GSquared_PhaseMult_Scale;// Offset: 144 Size: 16
public Vector4 gPiercingLightPower_Strength_NormalStrength_Thickness;// Offset: 160 Size: 16
public Vector3 gScaleDiffuseFillAmbient; // Offset: 176 Size: 12 [unused]
public float gPad08;
public Vector3 gWrapLighting_MSAARef; // Offset: 192 Size: 12 [unused]
public float gPad09;
public Vector4 gNearFarQMult; // Offset: 208 Size: 16 [unused]
public Vector3 gAnimCombine; // Offset: 224 Size: 12 [unused]
public float gPad10;
public Vector3 gAnimSculpt; // Offset: 240 Size: 12 [unused]
public float gPad11;
public Vector3 gAnimBlendWeights; // Offset: 256 Size: 12 [unused]
public float gPad12;
public Vector4 gUVOffsetArr0; // Offset: 272 Size: 32
public Vector4 gUVOffsetArr1; // Offset: 272 Size: 32
public Matrix gCloudViewProj; // Offset: 304 Size: 64
public Vector4 gCameraPos; // Offset: 368 Size: 16
public Vector2 gUVOffset1; // Offset: 384 Size: 8
public Vector2 gUVOffset2; // Offset: 392 Size: 8
public Vector2 gUVOffset3; // Offset: 400 Size: 8
public Vector2 gRescaleUV1; // Offset: 408 Size: 8
public Vector2 gRescaleUV2; // Offset: 416 Size: 8
public Vector2 gRescaleUV3; // Offset: 424 Size: 8
public float gSoftParticleRange; // Offset: 432 Size: 4 [unused]
public float gEnvMapAlphaScale; // Offset: 436 Size: 4 [unused]
public Vector2 cloudLayerAnimScale1; // Offset: 440 Size: 8
public Vector2 cloudLayerAnimScale2; // Offset: 448 Size: 8
public Vector2 cloudLayerAnimScale3; // Offset: 456 Size: 8
};
public class CloudsShader : Shader, IDisposable
{
bool disposed = false;
VertexShader vs;
PixelShader ps;
GpuVarsBuffer<CloudsShaderCloudsLocals> CloudsLocalVars;
GpuVarsBuffer<CloudsShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<CloudsShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<CloudsShaderVSModelVars> VSModelVars;
GpuVarsBuffer<CloudsShaderPSSceneVars> PSSceneVars;
SamplerState texsampler;
SamplerState texsampleranis;
InputLayout layout;
public bool EnableHDR { get; set; }
public bool AnisotropicFilter = false;
public CloudsShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\CloudsVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\CloudsPS.cso");
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
CloudsLocalVars = new GpuVarsBuffer<CloudsShaderCloudsLocals>(device);
VSSceneVars = new GpuVarsBuffer<CloudsShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<CloudsShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<CloudsShaderVSModelVars>(device);
PSSceneVars = new GpuVarsBuffer<CloudsShaderPSSceneVars>(device);
layout = new InputLayout(device, vsbytes, VertexTypeDefaultEx.GetLayout());
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsampleranis = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.Anisotropic,
MaximumAnisotropy = 8,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
public void UpdateCloudsLocals(Clouds clouds, ShaderGlobalLights lights)
{
CloudsLocalVars.Vars.gSunDirection = lights.CurrentSunDir;
CloudsLocalVars.Vars.gSunColor = ((Vector4)lights.Params.LightDirColour).XYZ();
CloudsLocalVars.Vars.gUVOffset1 = clouds.AnimOverrides.UVOffset1;
CloudsLocalVars.Vars.gUVOffset2 = clouds.AnimOverrides.UVOffset2;
CloudsLocalVars.Vars.gUVOffset3 = clouds.AnimOverrides.UVOffset3;
CloudsLocalVars.Vars.gRescaleUV1 = clouds.AnimOverrides.RescaleUV1;
CloudsLocalVars.Vars.gRescaleUV2 = clouds.AnimOverrides.RescaleUV2;
CloudsLocalVars.Vars.gRescaleUV3 = clouds.AnimOverrides.RescaleUV3;
CloudsLocalVars.Vars.cloudLayerAnimScale1 = clouds.AnimOverrides.cloudLayerAnimScale1;
CloudsLocalVars.Vars.cloudLayerAnimScale2 = clouds.AnimOverrides.cloudLayerAnimScale2;
CloudsLocalVars.Vars.cloudLayerAnimScale3 = clouds.AnimOverrides.cloudLayerAnimScale3;
CloudsLocalVars.Vars.gUVOffsetArr0 = Vector4.Zero;
CloudsLocalVars.Vars.gUVOffsetArr1 = Vector4.Zero;
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(vs);
context.PixelShader.Set(ps);
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
CloudsLocalVars.Update(context);
CloudsLocalVars.SetVSCBuffer(context, 0);
CloudsLocalVars.SetPSCBuffer(context, 0);
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 1);
PSSceneVars.Vars.LightDirection = new Vector4(lights.Params.LightDir, 0.0f);
PSSceneVars.Vars.EnableHDR = EnableHDR ? 1u : 0u;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 1);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = new Vector4(rend.Scale, 1.0f);
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
//currently not used..
//if (!model.UseTransform) return;
//VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
//VSModelVars.Update(context);
//VSModelVars.SetVSCBuffer(context, 3);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
switch (geom.DrawableGeom.Shader.FileName.Hash)
{
case 4103916155://{clouds_animsoft.sps}
case 1097000161://{clouds_altitude.sps}
case 1481470665://{clouds_soft.sps}
case 2184108982://{clouds_fast.sps}
case 4192928948://{clouds_anim.sps}
break;
default:
break;
}
RenderableTexture DensitySampler = null;
RenderableTexture NormalSampler = null;
RenderableTexture DetailDensitySampler = null;
RenderableTexture DetailNormalSampler = null;
RenderableTexture DetailDensity2Sampler = null;
RenderableTexture DetailNormal2Sampler = null;
RenderableTexture DepthMapTexSampler = null;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
switch (ihash)
{
case MetaName.DensitySampler:
DensitySampler = itex;
break;
case MetaName.normalSampler:
NormalSampler = itex;
break;
case MetaName.DetailDensitySampler:
DetailDensitySampler = itex;
break;
case MetaName.DetailNormalSampler:
DetailNormalSampler = itex;
break;
case MetaName.DetailDensity2Sampler:
DetailDensity2Sampler = itex;
break;
case MetaName.DetailNormal2Sampler:
DetailNormal2Sampler = itex;
break;
case MetaName.DepthMapTexSampler:
DepthMapTexSampler = itex;
break;
default:
break;
}
}
}
bool usedens = ((DensitySampler != null) && (DensitySampler.ShaderResourceView != null));
bool usenorm = ((NormalSampler != null) && (NormalSampler.ShaderResourceView != null));
bool usedden = ((DetailDensitySampler != null) && (DetailDensitySampler.ShaderResourceView != null));
bool usednrm = ((DetailNormalSampler != null) && (DetailNormalSampler.ShaderResourceView != null));
bool useddn2 = ((DetailDensity2Sampler != null) && (DetailDensity2Sampler.ShaderResourceView != null));
bool usednm2 = ((DetailNormal2Sampler != null) && (DetailNormal2Sampler.ShaderResourceView != null));
bool usedept = ((DepthMapTexSampler != null) && (DepthMapTexSampler.ShaderResourceView != null));
if (usedens)
{
DensitySampler.SetPSResource(context, 0);
}
if (usenorm)
{
NormalSampler.SetPSResource(context, 1);
}
if (usedden)
{
DetailDensitySampler.SetPSResource(context, 2);
}
if (usednrm)
{
DetailNormalSampler.SetPSResource(context, 3);
}
if (useddn2)
{
DetailDensity2Sampler.SetPSResource(context, 4);
}
if (usednm2)
{
DetailNormal2Sampler.SetPSResource(context, 5);
}
if (usedept)
{
DepthMapTexSampler.SetPSResource(context, 6);
}
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
if (type != VertexType.DefaultEx)
{
return false;
}
context.InputAssembler.InputLayout = layout;
return true;
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.PixelShader.SetConstantBuffer(1, null);
context.VertexShader.SetConstantBuffer(2, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
disposed = true;
texsampler.Dispose();
layout.Dispose();
CloudsLocalVars.Dispose();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
PSSceneVars.Dispose();
ps.Dispose();
vs.Dispose();
}
}
}
+146
View File
@@ -0,0 +1,146 @@
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;
}
}
}
+166
View File
@@ -0,0 +1,166 @@
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using CodeWalker.GameFiles;
using System.IO;
using SharpDX.DXGI;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct MarkerShaderVSSceneVars
{
public Matrix ViewProj;
public Matrix ViewInv;
public Vector4 ScreenScale; //xy = 1/wh
}
public struct MarkerShaderVSMarkerVars
{
public Vector4 CamRel;
public Vector2 Size;
public Vector2 Offset;
}
public class MarkerShader : Shader, IDisposable
{
bool disposed = false;
VertexShader markervs;
PixelShader markerps;
GpuVarsBuffer<MarkerShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<MarkerShaderVSMarkerVars> VSMarkerVars;
SamplerState texsampler;
InputLayout layout;
public MarkerShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\MarkerVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\MarkerPS.cso");
markervs = new VertexShader(device, vsbytes);
markerps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<MarkerShaderVSSceneVars>(device);
VSMarkerVars = new GpuVarsBuffer<MarkerShaderVSMarkerVars>(device);
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,
});
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(markervs);
context.PixelShader.Set(markerps);
}
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.ScreenScale = new Vector4(0.5f / camera.Width, 0.5f / camera.Height, camera.Width, camera.Height);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
}
public void SetMarkerVars(DeviceContext context, Vector3 camrel, Vector2 size, Vector2 offset)
{
VSMarkerVars.Vars.CamRel = new Vector4(camrel, 0.0f);
VSMarkerVars.Vars.Size = size;
VSMarkerVars.Vars.Offset = offset;
VSMarkerVars.Update(context);
VSMarkerVars.SetVSCBuffer(context, 1);
}
public void SetTexture(DeviceContext context, ShaderResourceView srv)
{
context.PixelShader.SetSampler(0, texsampler);
context.PixelShader.SetShaderResource(0, srv);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
//don't use this one
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
//don't use this
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
//don't use this
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
if (texsampler != null)
{
texsampler.Dispose();
texsampler = null;
}
layout.Dispose();
VSSceneVars.Dispose();
VSMarkerVars.Dispose();
markerps.Dispose();
markervs.Dispose();
disposed = true;
}
}
}
+246
View File
@@ -0,0 +1,246 @@
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using CodeWalker.GameFiles;
using System.IO;
using SharpDX.DXGI;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct PathShaderVSSceneVars
{
public Matrix ViewProj;
public Vector4 CameraPos;
public Vector4 LightColour;
}
public class PathShader : Shader, IDisposable
{
bool disposed = false;
VertexShader boxvs;
PixelShader boxps;
VertexShader dynvs;
VertexShader vs;
PixelShader ps;
GpuVarsBuffer<PathShaderVSSceneVars> VSSceneVars;
InputLayout layout;
UnitCube cube;
bool UseDynamicVerts = false;
GpuCBuffer<VertexTypePC> vertices; //for selection polys/lines use
public PathShader(Device device)
{
byte[] boxvsbytes = File.ReadAllBytes("Shaders\\PathBoxVS.cso");
byte[] boxpsbytes = File.ReadAllBytes("Shaders\\PathBoxPS.cso");
byte[] dynvsbytes = File.ReadAllBytes("Shaders\\PathDynVS.cso");
byte[] vsbytes = File.ReadAllBytes("Shaders\\PathVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\PathPS.cso");
boxvs = new VertexShader(device, boxvsbytes);
boxps = new PixelShader(device, boxpsbytes);
dynvs = new VertexShader(device, dynvsbytes);
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<PathShaderVSSceneVars>(device);
layout = new InputLayout(device, vsbytes, VertexTypePC.GetLayout());
cube = new UnitCube(device, boxvsbytes, true, false, true);
vertices = new GpuCBuffer<VertexTypePC>(device, 1000); //should be more than needed....
}
public override void SetShader(DeviceContext context)
{
if (UseDynamicVerts)
{
context.VertexShader.Set(dynvs);
//context.InputAssembler.SetVertexBuffers(0, null);
context.InputAssembler.SetIndexBuffer(null, Format.Unknown, 0);
}
else
{
context.VertexShader.Set(vs);
}
context.PixelShader.Set(ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
if (UseDynamicVerts)
{
context.InputAssembler.InputLayout = null;
}
else
{
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.CameraPos = new Vector4(camera.Position, 0.0f);
VSSceneVars.Vars.LightColour = new Vector4(1.0f, 1.0f, 1.0f, lights.HdrIntensity * 2.0f);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
//don't use this one
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
//don't use this
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
//don't use this
}
public void RenderBatches(DeviceContext context, List<RenderablePathBatch> batches, Camera camera, ShaderGlobalLights lights)
{
UseDynamicVerts = false;
SetShader(context);
SetInputLayout(context, VertexType.PC);
SetSceneVars(context, camera, null, lights);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
context.InputAssembler.SetIndexBuffer(null, Format.R16_UInt, 0);
for (int i = 0; i < batches.Count; i++)
{
var pbatch = batches[i];
if (pbatch.TriangleVertexBuffer == null) continue;
if (pbatch.TriangleVertexCount == 0) continue;
context.InputAssembler.SetVertexBuffers(0, pbatch.TriangleVBBinding);
context.Draw(pbatch.TriangleVertexCount, 0);
}
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.InputAssembler.SetIndexBuffer(null, Format.R16_UInt, 0);
for (int i = 0; i < batches.Count; i++)
{
var pbatch = batches[i];
if (pbatch.PathVertexBuffer == null) continue;
if (pbatch.PathVertexCount == 0) continue;
context.InputAssembler.SetVertexBuffers(0, pbatch.PathVBBinding);
context.Draw(pbatch.PathVertexCount, 0);
}
context.VertexShader.Set(boxvs);
context.PixelShader.Set(boxps);
VSSceneVars.SetVSCBuffer(context, 0);
foreach (var batch in batches)
{
if (batch.NodeBuffer == null) continue;
context.VertexShader.SetShaderResource(0, batch.NodeBuffer.SRV);
cube.DrawInstanced(context, batch.Nodes.Length);
}
UnbindResources(context);
}
public void RenderTriangles(DeviceContext context, List<VertexTypePC> verts, Camera camera, ShaderGlobalLights lights)
{
UseDynamicVerts = true;
SetShader(context);
SetInputLayout(context, VertexType.PC);
SetSceneVars(context, camera, null, lights);
vertices.Clear();
foreach (var vert in verts)
{
vertices.Add(vert);
}
vertices.Update(context);
vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
context.Draw(vertices.CurrentCount, 0);
}
public void RenderLines(DeviceContext context, List<VertexTypePC> verts, Camera camera, ShaderGlobalLights lights)
{
UseDynamicVerts = true;
SetShader(context);
SetInputLayout(context, VertexType.PC);
SetSceneVars(context, camera, null, lights);
vertices.Clear();
foreach (var vert in verts)
{
vertices.Add(vert);
}
vertices.Update(context);
vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.Draw(vertices.CurrentCount, 0);
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.VertexShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
disposed = true;
VSSceneVars.Dispose();
vertices.Dispose();
layout.Dispose();
cube.Dispose();
ps.Dispose();
vs.Dispose();
dynvs.Dispose();
boxvs.Dispose();
boxps.Dispose();
}
}
}
+688
View File
@@ -0,0 +1,688 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX.Direct3D11;
using System.IO;
using CodeWalker.GameFiles;
using CodeWalker.World;
using SharpDX;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
namespace CodeWalker.Rendering
{
public struct PostProcessorReduceCSVars
{
public uint dimx;
public uint dimy;
public uint Width;
public uint Height;
}
public struct PostProcessorLumBlendCSVars
{
public Vector4 blend;
}
public struct PostProcessorFilterSampleWeights
{
public Vector4 avSampleWeights00; //[15];
public Vector4 avSampleWeights01;
public Vector4 avSampleWeights02;
public Vector4 avSampleWeights03;
public Vector4 avSampleWeights04;
public Vector4 avSampleWeights05;
public Vector4 avSampleWeights06;
public Vector4 avSampleWeights07;
public Vector4 avSampleWeights08;
public Vector4 avSampleWeights09;
public Vector4 avSampleWeights10;
public Vector4 avSampleWeights11;
public Vector4 avSampleWeights12;
public Vector4 avSampleWeights13;
public Vector4 avSampleWeights14;
public Vector4 Get(int i)
{
switch (i)
{
default:
case 0: return avSampleWeights00;
case 1: return avSampleWeights01;
case 2: return avSampleWeights02;
case 3: return avSampleWeights03;
case 4: return avSampleWeights04;
case 5: return avSampleWeights05;
case 6: return avSampleWeights06;
case 7: return avSampleWeights07;
case 8: return avSampleWeights08;
case 9: return avSampleWeights09;
case 10: return avSampleWeights10;
case 11: return avSampleWeights11;
case 12: return avSampleWeights12;
case 13: return avSampleWeights13;
case 14: return avSampleWeights14;
}
}
public void Set(int i, Vector4 v)
{
switch (i)
{
case 0: avSampleWeights00 = v; break;
case 1: avSampleWeights01 = v; break;
case 2: avSampleWeights02 = v; break;
case 3: avSampleWeights03 = v; break;
case 4: avSampleWeights04 = v; break;
case 5: avSampleWeights05 = v; break;
case 6: avSampleWeights06 = v; break;
case 7: avSampleWeights07 = v; break;
case 8: avSampleWeights08 = v; break;
case 9: avSampleWeights09 = v; break;
case 10: avSampleWeights10 = v; break;
case 11: avSampleWeights11 = v; break;
case 12: avSampleWeights12 = v; break;
case 13: avSampleWeights13 = v; break;
case 14: avSampleWeights14 = v; break;
}
}
}
public struct PostProcessorFilterBPHCSVars
{
public PostProcessorFilterSampleWeights avSampleWeights;
public uint outputwidth;
public float finverse;
public int inputsize0;
public int inputsize1;
}
public struct PostProcessorFilterVCSVars
{
public PostProcessorFilterSampleWeights avSampleWeights;
public int outputsize0;
public int outputsize1;
public int inputsize0;
public int inputsize1;
}
public struct PostProcessorFinalPSVars
{
public Vector4 invPixelCount;
}
public class PostProcessor
{
ComputeShader ReduceTo1DCS;
ComputeShader ReduceTo0DCS;
ComputeShader LumBlendCS;
ComputeShader BloomFilterBPHCS;
ComputeShader BloomFilterVCS;
PixelShader CopyPixelsPS;
VertexShader FinalPassVS;
PixelShader FinalPassPS;
UnitQuad FinalPassQuad;
InputLayout FinalPassLayout;
GpuVarsBuffer<PostProcessorReduceCSVars> ReduceCSVars;
GpuVarsBuffer<PostProcessorLumBlendCSVars> LumBlendCSVars;
GpuVarsBuffer<PostProcessorFilterBPHCSVars> FilterBPHCSVars;
GpuVarsBuffer<PostProcessorFilterVCSVars> FilterVCSVars;
GpuVarsBuffer<PostProcessorFinalPSVars> FinalPSVars;
GpuTexture Primary;
GpuBuffer<float> Reduction0;
GpuBuffer<float> Reduction1;
GpuBuffer<float> LumBlendResult;
GpuBuffer<Vector4> Bloom0;
GpuBuffer<Vector4> Bloom1;
GpuTexture Bloom;
SamplerState SampleStatePoint;
SamplerState SampleStateLinear;
BlendState BlendState;
long WindowSizeVramUsage = 0;
int Width = 0;
int Height = 0;
ViewportF Viewport;
bool Multisampled = false;
bool EnableBloom = true;
float ElapsedTime = 0.0f;
public float LumBlendSpeed = 1.0f;
bool CS_FULL_PIXEL_REDUCTION = false;
public long VramUsage
{
get
{
return WindowSizeVramUsage;
}
}
RawViewportF[] vpOld = new RawViewportF[15];
public PostProcessor(DXManager dxman)
{
var device = dxman.device;
byte[] bReduceTo1DCS = File.ReadAllBytes("Shaders\\PPReduceTo1DCS.cso");
byte[] bReduceTo0DCS = File.ReadAllBytes("Shaders\\PPReduceTo0DCS.cso");
byte[] bLumBlendCS = File.ReadAllBytes("Shaders\\PPLumBlendCS.cso");
byte[] bBloomFilterBPHCS = File.ReadAllBytes("Shaders\\PPBloomFilterBPHCS.cso");
byte[] bBloomFilterVCS = File.ReadAllBytes("Shaders\\PPBloomFilterVCS.cso");
byte[] bCopyPixelsPS = File.ReadAllBytes("Shaders\\PPCopyPixelsPS.cso");
byte[] bFinalPassVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso");
byte[] bFinalPassPS = File.ReadAllBytes("Shaders\\PPFinalPassPS.cso");
ReduceTo1DCS = new ComputeShader(device, bReduceTo1DCS);
ReduceTo0DCS = new ComputeShader(device, bReduceTo0DCS);
LumBlendCS = new ComputeShader(device, bLumBlendCS);
BloomFilterBPHCS = new ComputeShader(device, bBloomFilterBPHCS);
BloomFilterVCS = new ComputeShader(device, bBloomFilterVCS);
CopyPixelsPS = new PixelShader(device, bCopyPixelsPS);
FinalPassVS = new VertexShader(device, bFinalPassVS);
FinalPassPS = new PixelShader(device, bFinalPassPS);
FinalPassQuad = new UnitQuad(device, true);
FinalPassLayout = new InputLayout(device, bFinalPassVS, new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
});
ReduceCSVars = new GpuVarsBuffer<PostProcessorReduceCSVars>(device);
LumBlendCSVars = new GpuVarsBuffer<PostProcessorLumBlendCSVars>(device);
FilterBPHCSVars = new GpuVarsBuffer<PostProcessorFilterBPHCSVars>(device);
FilterVCSVars = new GpuVarsBuffer<PostProcessorFilterVCSVars>(device);
FinalPSVars = new GpuVarsBuffer<PostProcessorFinalPSVars>(device);
TextureAddressMode a = TextureAddressMode.Clamp;
Color4 b = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
Comparison c = Comparison.Always;
SampleStatePoint = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipPoint, 0, 1.0f, 1.0f, 0.0f);
SampleStateLinear = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipLinear, 0, 1.0f, 1.0f, 0.0f);
BlendState = DXUtility.CreateBlendState(device, false, BlendOperation.Add, BlendOption.One, BlendOption.Zero, BlendOperation.Add, BlendOption.One, BlendOption.Zero, ColorWriteMaskFlags.All);
GetSampleWeights(ref FilterVCSVars.Vars.avSampleWeights, 3.0f, 1.25f); //init sample weights
FilterBPHCSVars.Vars.avSampleWeights = FilterVCSVars.Vars.avSampleWeights;
}
public void Dispose()
{
DisposeBuffers();
if (BlendState != null)
{
BlendState.Dispose();
BlendState = null;
}
if (SampleStateLinear != null)
{
SampleStateLinear.Dispose();
SampleStateLinear = null;
}
if (SampleStatePoint != null)
{
SampleStatePoint.Dispose();
SampleStatePoint = null;
}
if (FinalPSVars != null)
{
FinalPSVars.Dispose();
FinalPSVars = null;
}
if (FilterVCSVars != null)
{
FilterVCSVars.Dispose();
FilterVCSVars = null;
}
if (FilterBPHCSVars != null)
{
FilterBPHCSVars.Dispose();
FilterBPHCSVars = null;
}
if (LumBlendCSVars != null)
{
LumBlendCSVars.Dispose();
LumBlendCSVars = null;
}
if (ReduceCSVars != null)
{
ReduceCSVars.Dispose();
ReduceCSVars = null;
}
if (FinalPassLayout != null)
{
FinalPassLayout.Dispose();
FinalPassLayout = null;
}
if (FinalPassQuad != null)
{
FinalPassQuad.Dispose();
FinalPassQuad = null;
}
if (FinalPassPS != null)
{
FinalPassPS.Dispose();
FinalPassPS = null;
}
if (FinalPassVS != null)
{
FinalPassVS.Dispose();
FinalPassVS = null;
}
if (CopyPixelsPS != null)
{
CopyPixelsPS.Dispose();
CopyPixelsPS = null;
}
if (BloomFilterVCS != null)
{
BloomFilterVCS.Dispose();
BloomFilterVCS = null;
}
if (BloomFilterBPHCS != null)
{
BloomFilterBPHCS.Dispose();
BloomFilterBPHCS = null;
}
if (LumBlendCS != null)
{
LumBlendCS.Dispose();
LumBlendCS = null;
}
if (ReduceTo0DCS != null)
{
ReduceTo0DCS.Dispose();
ReduceTo0DCS = null;
}
if (ReduceTo1DCS != null)
{
ReduceTo1DCS.Dispose();
ReduceTo1DCS = null;
}
}
public void OnWindowResize(DXManager dxman)
{
DisposeBuffers();
var device = dxman.device;
int sc = dxman.multisamplecount;
int sq = dxman.multisamplequality;
Multisampled = (sc > 1);
int uw = Width = dxman.backbuffer.Description.Width;
int uh = Height = dxman.backbuffer.Description.Height;
Viewport = new ViewportF();
Viewport.Width = (float)uw;
Viewport.Height = (float)uh;
Viewport.MinDepth = 0.0f;
Viewport.MaxDepth = 1.0f;
Viewport.X = 0.0f;
Viewport.Y = 0.0f;
Format f = Format.R32G32B32A32_Float;
Format df = Format.D32_Float;
Primary = new GpuTexture(device, uw, uh, f, sc, sq, true, df);
WindowSizeVramUsage += Primary.VramUsage;
int rc = (int)(Math.Ceiling(uw / 8.0f) * Math.Ceiling(uh / 8.0f));
Reduction0 = new GpuBuffer<float>(device, 1, rc);
Reduction1 = new GpuBuffer<float>(device, 1, rc);
WindowSizeVramUsage += sizeof(float) * rc * 2;
LumBlendResult = new GpuBuffer<float>(device, 1, 1);
WindowSizeVramUsage += sizeof(float); //because 4 bytes matter
int tw = uw / 8;
int th = uh / 8;
rc = tw * th;
f = Format.R8G8B8A8_UNorm;
Bloom0 = new GpuBuffer<Vector4>(device, 1, rc);
Bloom1 = new GpuBuffer<Vector4>(device, 1, rc);
WindowSizeVramUsage += /*sizeof(V4F)*/ 16 * rc * 2;
Bloom = new GpuTexture(device, tw, th, f, 1, 0, false, df);
WindowSizeVramUsage += Bloom.VramUsage;
}
public void DisposeBuffers()
{
if (Bloom != null)
{
Bloom.Dispose();
Bloom = null;
}
if (Bloom0 != null)
{
Bloom0.Dispose();
Bloom0 = null;
}
if (Bloom1 != null)
{
Bloom1.Dispose();
Bloom1 = null;
}
if (LumBlendResult != null)
{
LumBlendResult.Dispose();
LumBlendResult = null;
}
if (Reduction0 != null)
{
Reduction0.Dispose();
Reduction0 = null;
}
if (Reduction1 != null)
{
Reduction1.Dispose();
Reduction1 = null;
}
if (Primary != null)
{
Primary.Dispose();
Primary = null;
}
WindowSizeVramUsage = 0;
}
public void Clear(DeviceContext context)
{
Color4 clearColour = new Color4(0.2f, 0.4f, 0.6f, 0.0f);
//Color4 clearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
Primary.Clear(context, clearColour);
}
public void ClearDepth(DeviceContext context)
{
Primary.ClearDepth(context);
}
public void SetPrimary(DeviceContext context)
{
Primary.SetRenderTarget(context);
context.Rasterizer.SetViewport(Viewport);
}
public void Render(DXManager dxman, float elapsed)
{
ElapsedTime = elapsed;
var context = dxman.context;
if (Multisampled)
{
int sr = 0;// D3D11CalcSubresource(0, 0, 1);
context.ResolveSubresource(Primary.TextureMS, sr, Primary.Texture, sr, Format.R32G32B32A32_Float);
}
context.OutputMerger.SetRenderTargets((RenderTargetView)null);
ProcessLuminance(context);
ProcessBloom(context);
dxman.SetDefaultRenderTarget(context);
context.OutputMerger.SetBlendState(BlendState, null, 0xFFFFFFFF);
FinalPass(context);
}
private void ProcessLuminance(DeviceContext context)
{
uint dimx, dimy;
if (CS_FULL_PIXEL_REDUCTION)
{
dimx = (uint)(Math.Ceiling(Width / 8.0f));
dimx = (uint)(Math.Ceiling(dimx / 2.0f));
dimy = (uint)(Math.Ceiling(Height / 8.0f));
dimy = (uint)(Math.Ceiling(dimy / 2.0f));
}
else
{
dimx = (uint)(Math.Ceiling(81.0f / 8.0f)); //ToneMappingTexSize = (int)pow(3.0f, NUM_TONEMAP_TEXTURES-1);
dimy = dimx;
}
ReduceCSVars.Vars.dimx = dimx;
ReduceCSVars.Vars.dimy = dimy;
ReduceCSVars.Vars.Width = (uint)Width;
ReduceCSVars.Vars.Height = (uint)Height;
ReduceCSVars.Update(context);
Compute(context, ReduceTo1DCS, ReduceCSVars.Buffer, Reduction0.UAV, (int)dimx, (int)dimy, 1, Primary.SRV);
uint dim = dimx * dimy;
uint nNumToReduce = dim;
dim = (uint)(Math.Ceiling(dim / 128.0f));
if (nNumToReduce > 1)
{
for (;;)
{
ReduceCSVars.Vars.dimx = nNumToReduce;
ReduceCSVars.Vars.dimy = dim;
ReduceCSVars.Vars.Width = 0;
ReduceCSVars.Vars.Height = 0;
ReduceCSVars.Update(context);
Compute(context, ReduceTo0DCS, ReduceCSVars.Buffer, Reduction1.UAV, (int)dim, 1, 1, Reduction0.SRV);
nNumToReduce = dim;
dim = (uint)(Math.Ceiling(dim / 128.0f));
if (nNumToReduce == 1) break;
var r0 = Reduction0;
Reduction0 = Reduction1;
Reduction1 = r0;
}
}
else
{
var r0 = Reduction0;
Reduction0 = Reduction1;
Reduction1 = r0;
}
LumBlendCSVars.Vars.blend = new Vector4(Math.Min(ElapsedTime * LumBlendSpeed, 1.0f));
LumBlendCSVars.Update(context);
Compute(context, LumBlendCS, LumBlendCSVars.Buffer, LumBlendResult.UAV, 1, 1, 1, Reduction1.SRV);
}
private void ProcessBloom(DeviceContext context)
{
if (EnableBloom)
{
// Bright pass and horizontal blur
ShaderResourceView view = Primary.SRV;
ShaderResourceView[] aRViews = { view, LumBlendResult.SRV };
//BloomFilterShaderVars cbFilter;
//GetSampleWeights(cbFilter.avSampleWeights, 3.0f, 1.25f);
FilterBPHCSVars.Vars.outputwidth = (uint)(Width / 8);
if (CS_FULL_PIXEL_REDUCTION)
{
FilterBPHCSVars.Vars.finverse = 1.0f / (Width * Height);
}
else
{
FilterBPHCSVars.Vars.finverse = 1.0f / (81 * 81); //(ToneMappingTexSize*ToneMappingTexSize);
}
FilterBPHCSVars.Vars.inputsize0 = (int)Width;
FilterBPHCSVars.Vars.inputsize1 = (int)Height;
FilterBPHCSVars.Update(context);
int x = (int)(Math.Ceiling((float)FilterBPHCSVars.Vars.outputwidth / (128 - 7 * 2)));
int y = (Height / 8);
Compute(context, BloomFilterBPHCS, FilterBPHCSVars.Buffer, Bloom1.UAV, x, y, 1, view, LumBlendResult.SRV);
// Vertical blur
FilterVCSVars.Vars.outputsize0 = (int)(Width / 8);
FilterVCSVars.Vars.outputsize1 = (int)(Height / 8);
FilterVCSVars.Vars.inputsize0 = (int)(Width / 8);
FilterVCSVars.Vars.inputsize1 = (int)(Height / 8);
FilterVCSVars.Update(context);
x = Width / 8;
y = (int)(Math.Ceiling((float)FilterVCSVars.Vars.outputsize1 / (128 - 7 * 2)));
Compute(context, BloomFilterVCS, FilterVCSVars.Buffer, Bloom0.UAV, x, y, 1, Bloom1.SRV, LumBlendResult.SRV);
}
CopyPixels(context, Width / 8, Height / 8, Bloom0.SRV, Bloom.RTV);
}
private void FinalPass(DeviceContext context)
{
context.Rasterizer.SetViewport(Viewport);
context.VertexShader.Set(FinalPassVS);
context.PixelShader.Set(FinalPassPS);
context.PixelShader.SetShaderResources(0, Primary.SRV, LumBlendResult.SRV, EnableBloom ? Bloom.SRV : null);
if (CS_FULL_PIXEL_REDUCTION)
{
//pcbCS[0] = 1.0f / (Width * Height);
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (Width * Height));
}
else
{
//pcbCS[0] = 1.0f / (81 * 81); //ToneMappingTexSize*ToneMappingTexSize
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (81 * 81));
}
FinalPSVars.Update(context);
FinalPSVars.SetPSCBuffer(context, 0);
context.PixelShader.SetSamplers(0, SampleStatePoint, SampleStateLinear);
context.InputAssembler.InputLayout = FinalPassLayout;
FinalPassQuad.Draw(context);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
context.PixelShader.SetShaderResources(0, null, null, null);
context.PixelShader.SetSamplers(0, null, null);
}
private float GaussianDistribution(float x, float y, float rho)
{
float g = 1.0f / (float)Math.Sqrt(2.0f * 3.14159265f * rho * rho);
g *= (float)Math.Exp(-(x * x + y * y) / (2 * rho * rho));
return g;
}
private void GetSampleWeights(ref PostProcessorFilterSampleWeights w, float fDeviation, float fMultiplier)
{
// Fill the center texel
float weight = 1.0f * GaussianDistribution(0, 0, fDeviation);
w.Set(7, new Vector4(weight, weight, weight, 1.0f));
// Fill the right side
for (int i = 1; i < 8; i++)
{
weight = fMultiplier * GaussianDistribution((float)i, 0, fDeviation);
w.Set(7 - i, new Vector4(weight, weight, weight, 1.0f));
}
// Copy to the left side
for (int i = 8; i < 15; i++)
{
w.Set(i, w.Get(14 - i));
}
// Debug convolution kernel which doesn't transform input data
/*ZeroMemory( avColorWeight, sizeof(D3DXVECTOR4)*15 );
w.Set(7, new Vector4( 1, 1, 1, 1 ));*/
}
private void Compute(DeviceContext context, ComputeShader cs, Buffer constantBuffer, UnorderedAccessView unorderedAccessView, int X, int Y, int Z, params ShaderResourceView[] resourceViews)
{
context.ComputeShader.Set(cs);
context.ComputeShader.SetShaderResources(0, resourceViews);
context.ComputeShader.SetUnorderedAccessView(0, unorderedAccessView);
if (constantBuffer != null)
{
//make sure buffer is updated first...
//D3D11_MAPPED_SUBRESOURCE mappedResource;
//dc->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
//memcpy(mappedResource.pData, constantData, constantDataSize);
//dc->Unmap(constantBuffer, 0);
context.ComputeShader.SetConstantBuffer(0, constantBuffer); //dc->CSSetConstantBuffers(0, 1, &constantBuffer);
}
context.Dispatch(X, Y, Z);
ShaderResourceView[] ppSRVNULL = { null, null, null };
context.ComputeShader.SetUnorderedAccessView(0, null);
context.ComputeShader.SetShaderResources(0, 3, ppSRVNULL);
context.ComputeShader.SetConstantBuffer(0, null);
}
private void CopyPixels(DeviceContext context, int w, int h, ShaderResourceView fromSRV, RenderTargetView toRTV)
{
context.VertexShader.Set(FinalPassVS);
context.PixelShader.Set(CopyPixelsPS);
ShaderResourceView[] aRViews = { fromSRV };
context.PixelShader.SetShaderResource(0, fromSRV);
RenderTargetView[] aRTViews = { toRTV };
context.OutputMerger.SetRenderTargets(toRTV);
//D3D11_MAPPED_SUBRESOURCE mappedResource;
//dc->Map(ReduceCSVars.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
//UINT* p = (UINT*)mappedResource.pData;
//p[0] = w;
//p[1] = h;
//dc->Unmap(ReduceCSVars.Get(), 0);
//ID3D11Buffer* ppCB[1] = { ReduceCSVars.Get() };
//dc->PSSetConstantBuffers(0, 1, ppCB);
ReduceCSVars.Vars.dimx = (uint)w;
ReduceCSVars.Vars.dimy = (uint)h;
ReduceCSVars.Update(context);
ReduceCSVars.SetPSCBuffer(context, 0);
//DrawFullScreenQuad11( pd3dImmediateContext, g_pDumpBufferPS, dwWidth, dwHeight );
//ViewportF[] vpOld = new ViewportF[15];// [D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX];
//UINT nViewPorts = 1;
//dc->RSGetViewports(&nViewPorts, vpOld);
context.Rasterizer.GetViewports(vpOld);
// Setup the viewport to match the backbuffer
ViewportF vp;
vp.Width = (float)Width;
vp.Height = (float)Height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.X = 0;
vp.Y = 0;
context.Rasterizer.SetViewport(vp);
context.InputAssembler.InputLayout = FinalPassLayout;
FinalPassQuad.Draw(context);
context.Rasterizer.SetViewports(vpOld); //reverting viewports maybe not necessary...
}
}
}
+30
View File
@@ -0,0 +1,30 @@
using CodeWalker.GameFiles;
using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public abstract class Shader
{
public abstract void SetShader(DeviceContext context);
public abstract bool SetInputLayout(DeviceContext context, VertexType type);
public abstract void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights);
public abstract void SetEntityVars(DeviceContext context, ref RenderableInst rend);
public abstract void SetModelVars(DeviceContext context, RenderableModel model);
public abstract void SetGeomVars(DeviceContext context, RenderableGeometry geom);
public abstract void UnbindResources(DeviceContext context);
//public abstract void Dispose();
}
}
+351
View File
@@ -0,0 +1,351 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct ShadowShaderVSSceneVars
{
public Matrix ViewProj;
public Vector4 WindVector;
}
public struct ShadowShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public uint HasSkeleton;
public uint HasTransforms;
public uint TintPaletteIndex;
public uint Pad1;
public Vector3 Scale;
public uint Pad2;
}
public struct ShadowShaderVSModelVars
{
public Matrix Transform;
}
//public struct ShadowShaderVSGeomVars
//{
// public uint EnableTint;
// public float TintYVal;
// public uint IsDecal;
// public uint Pad5;
//}
public struct ShadowShaderGeomVars
{
public uint EnableTexture;
public uint EnableTint;
public uint IsDecal;
public uint EnableWind;
public Vector4 WindOverrideParams;
}
public class ShadowShader : Shader, IDisposable
{
bool disposed = false;
VertexShader shadowvs;
PixelShader shadowps;
GpuVarsBuffer<ShadowShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<ShadowShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<ShadowShaderVSModelVars> VSModelVars;
GpuVarsBuffer<ShadowShaderGeomVars> GeomVars;
SamplerState texsampler;
SamplerState texsamplerc;
//public bool DecalMode = false;
public Vector4 WindVector { get; set; }
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public ShadowShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\ShadowVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\ShadowPS.cso");
shadowvs = new VertexShader(device, vsbytes);
shadowps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<ShadowShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<ShadowShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<ShadowShaderVSModelVars>(device);
GeomVars = new GpuVarsBuffer<ShadowShaderGeomVars>(device);
//supported layouts - requires Position, Normal, Colour, Texcoord
layouts.Add(VertexType.Default, new InputLayout(device, vsbytes, VertexTypeDefault.GetLayout()));
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vsbytes, VertexTypeDefaultEx.GetLayout()));
layouts.Add(VertexType.PNCCT, new InputLayout(device, vsbytes, VertexTypePNCCT.GetLayout()));
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vsbytes, VertexTypePNCCTTTT.GetLayout()));
layouts.Add(VertexType.PCCNCCTTX, new InputLayout(device, vsbytes, VertexTypePCCNCCTTX.GetLayout()));
layouts.Add(VertexType.PCCNCCT, new InputLayout(device, vsbytes, VertexTypePCCNCCT.GetLayout()));
layouts.Add(VertexType.PNCTTTX, new InputLayout(device, vsbytes, VertexTypePNCTTTX.GetLayout()));
layouts.Add(VertexType.PNCTTTX_2, new InputLayout(device, vsbytes, VertexTypePNCTTTX_2.GetLayout()));
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vsbytes, VertexTypePNCTTTX_3.GetLayout()));
layouts.Add(VertexType.PNCTTTTX, new InputLayout(device, vsbytes, VertexTypePNCTTTTX.GetLayout()));
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vsbytes, VertexTypePNCTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vsbytes, VertexTypePNCCTTX_2.GetLayout()));
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vsbytes, VertexTypePNCCTTTX.GetLayout()));
layouts.Add(VertexType.PCCNCCTX, new InputLayout(device, vsbytes, VertexTypePCCNCCTX.GetLayout()));
layouts.Add(VertexType.PCCNCTX, new InputLayout(device, vsbytes, VertexTypePCCNCTX.GetLayout()));
layouts.Add(VertexType.PCCNCT, new InputLayout(device, vsbytes, VertexTypePCCNCT.GetLayout()));
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vsbytes, VertexTypePNCCTT.GetLayout()));
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vsbytes, VertexTypePNCCTX.GetLayout()));
layouts.Add(VertexType.PNCH2, new InputLayout(device, vsbytes, VertexTypePNCH2.GetLayout()));
layouts.Add(VertexType.PCCH2H4, new InputLayout(device, vsbytes, VertexTypePCCH2H4.GetLayout()));
layouts.Add(VertexType.PCCNCTT, new InputLayout(device, vsbytes, VertexTypePCCNCTT.GetLayout()));
layouts.Add(VertexType.PCCNCTTX, new InputLayout(device, vsbytes, VertexTypePCCNCTTX.GetLayout()));
layouts.Add(VertexType.PCCNCTTT, new InputLayout(device, vsbytes, VertexTypePCCNCTTT.GetLayout()));
layouts.Add(VertexType.PNCTT, new InputLayout(device, vsbytes, VertexTypePNCTT.GetLayout()));
layouts.Add(VertexType.PNCTTT, new InputLayout(device, vsbytes, VertexTypePNCTTT.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsamplerc = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Clamp,
AddressV = TextureAddressMode.Clamp,
AddressW = TextureAddressMode.Clamp,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipPoint,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(shadowvs);
context.PixelShader.Set(shadowps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
}
public void SetSceneVars(DeviceContext context, Matrix shadowviewproj)
{
VSSceneVars.Vars.ViewProj = Matrix.Transpose(shadowviewproj);
VSSceneVars.Vars.WindVector = WindVector;
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 1);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 2);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
//RenderableTexture tintpal = null;
//float tntpalind = 0.0f;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
switch (ihash)
{
case MetaName.DiffuseSampler:
case MetaName.TextureSampler_layer0:
case MetaName.TextureSampler_layer1:
case MetaName.TextureSampler_layer2:
case MetaName.TextureSampler_layer3:
texture = itex;
break;
}
if (texture != null) break;
}
////try get default diffuse texture
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
//{
// texture = geom.Textures[geom.DiffuseSampler];
//}
//if ((texture == null) && (geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer0];
//}
//if ((texture == null) && (geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer1];
//}
//if ((texture == null) && (geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer2];
//}
//if ((texture == null) && (geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer3];
//}
//fallback try get first texture... eventaully remove this! (helps with water for now)
int index = 0;
while (((texture == null)) && (index < geom.RenderableTextures.Length))
{
texture = geom.RenderableTextures[index];
index++;
}
//if ((geom.PaletteTexture >= 0) && (geom.PaletteTexture < geom.Textures.Length))
//{
// tintpal = geom.Textures[geom.PaletteTexture];
// if (tintpal.Texture != null)
// {
// //this is slightly dodgy but vsentvarsdata should have the correct value in it...
// tntpalind = (vsentvarsdata.TintPaletteIndex + 0.5f) / tintpal.Texture.Height;
// }
//}
}
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
uint windflag = 0;
var shaderFile = geom.DrawableGeom.Shader.FileName;
switch (shaderFile.Hash)
{
case 2245870123: //trees_normal_diffspec_tnt.sps
case 3334613197: //trees_tnt.sps
case 1229591973://{trees_normal_spec_tnt.sps}
case 2322653400://{trees.sps}
case 3192134330://{trees_normal.sps}
case 1224713457://{trees_normal_spec.sps}
case 4265705004://{trees_normal_diffspec.sps}
windflag = 1;
break;
}
GeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
GeomVars.Vars.EnableTint = 0u;// usetint ? 1u : 0u;
GeomVars.Vars.IsDecal = 0u;// DecalMode ? 1u : 0u;
GeomVars.Vars.EnableWind = windflag;
GeomVars.Vars.WindOverrideParams = geom.WindOverrideParams;
GeomVars.Update(context);
GeomVars.SetPSCBuffer(context, 0);
GeomVars.SetVSCBuffer(context, 3);
context.VertexShader.SetSampler(0, texsamplerc);
context.PixelShader.SetSampler(0, texsampler);
//context.PixelShader.SetSampler(1, texsamplerc);
if (usediff)
{
texture.SetPSResource(context, 0);
}
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetSampler(0, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
if (texsampler != null)
{
texsampler.Dispose();
texsampler = null;
}
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
GeomVars.Dispose();
shadowps.Dispose();
shadowvs.Dispose();
disposed = true;
}
}
}
+410
View File
@@ -0,0 +1,410 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX.Direct3D11;
using System.IO;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct SkydomeShaderVSSceneVars
{
public Matrix ViewProj;
public Matrix ViewInv;
}
public struct SkydomeShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
}
public struct SkydomeShaderVSModelVars
{
public Matrix Transform;
}
public struct SkydomeShaderPSSceneVars
{
public Vector4 LightDirection;
public uint EnableHDR;
public uint Pad0;
public uint Pad1;
public uint Pad2;
}
public struct SkydomeShaderVSSunMoonVars
{
public Matrix ViewProj;
public Matrix ViewInv;
public Vector4 CamRel;
public Vector2 Size;
public Vector2 Offset;
}
public struct SkydomeShaderPSSunMoonVars
{
public Vector4 Colour;
}
public struct SkydomeShaderSkySystemLocals
{
public Vector4 azimuthEastColor; // Offset: 0 Size: 12
public Vector4 azimuthWestColor; // Offset: 16 Size: 12
public Vector3 azimuthTransitionColor; // Offset: 32 Size: 12
public float azimuthTransitionPosition; // Offset: 44 Size: 4
public Vector4 zenithColor; // Offset: 48 Size: 12
public Vector4 zenithTransitionColor; // Offset: 64 Size: 12
public Vector4 zenithConstants; // Offset: 80 Size: 16
public Vector4 skyPlaneColor; // Offset: 96 Size: 16 [unused]
public Vector4 skyPlaneParams; // Offset: 112 Size: 16 [unused]
public float hdrIntensity; // Offset: 128 Size: 4
public Vector3 sunColor; // Offset: 132 Size: 12
public Vector4 sunColorHdr; // Offset: 144 Size: 12
public Vector4 sunDiscColorHdr; // Offset: 160 Size: 12 [unused]
public Vector4 sunConstants; // Offset: 176 Size: 16
public Vector4 sunDirection; // Offset: 192 Size: 12
public Vector4 sunPosition; // Offset: 208 Size: 12 [unused]
public Vector4 cloudBaseMinusMidColour; // Offset: 224 Size: 12
public Vector4 cloudMidColour; // Offset: 240 Size: 12
public Vector4 cloudShadowMinusBaseColourTimesShadowStrength;// Offset: 256 Size: 12
public Vector4 cloudDetailConstants; // Offset: 272 Size: 16
public Vector4 cloudConstants1; // Offset: 288 Size: 16
public Vector4 cloudConstants2; // Offset: 304 Size: 16
public Vector4 smallCloudConstants; // Offset: 320 Size: 16
public Vector4 smallCloudColorHdr; // Offset: 336 Size: 12
public Vector4 effectsConstants; // Offset: 352 Size: 16
public float horizonLevel; // Offset: 368 Size: 4
public Vector3 speedConstants; // Offset: 372 Size: 12
public float starfieldIntensity; // Offset: 384 Size: 4
public Vector3 moonDirection; // Offset: 388 Size: 12
public Vector3 moonPosition; // Offset: 400 Size: 12 [unused]
public float moonIntensity; // Offset: 412 Size: 4 [unused]
public Vector4 lunarCycle; // Offset: 416 Size: 12
public Vector3 moonColor; // Offset: 432 Size: 12
public float noiseFrequency; // Offset: 444 Size: 4 [unused]
public float noiseScale; // Offset: 448 Size: 4 [unused]
public float noiseThreshold; // Offset: 452 Size: 4 [unused]
public float noiseSoftness; // Offset: 456 Size: 4 [unused]
public float noiseDensityOffset; // Offset: 460 Size: 4 [unused]
public Vector4 noisePhase; // Offset: 464 Size: 8 [unused]
}
public class SkydomeShader : Shader, IDisposable
{
bool disposed = false;
VertexShader skyvs;
PixelShader skyps;
VertexShader sunvs;
PixelShader sunps;
VertexShader moonvs;
PixelShader moonps;
GpuVarsBuffer<SkydomeShaderSkySystemLocals> SkyLocalVars;
GpuVarsBuffer<SkydomeShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<SkydomeShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<SkydomeShaderVSModelVars> VSModelVars;
GpuVarsBuffer<SkydomeShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<SkydomeShaderVSSunMoonVars> VSSunMoonVars;
GpuVarsBuffer<SkydomeShaderPSSunMoonVars> PSSunMoonVars;
SamplerState texsampler;
InputLayout skylayout;
InputLayout sunlayout;
InputLayout moonlayout;
UnitDisc sundisc;
UnitQuad moonquad;
public bool EnableHDR { get; set; }
public SkydomeShader(Device device)
{
byte[] skyvsbytes = File.ReadAllBytes("Shaders\\SkydomeVS.cso");
byte[] skypsbytes = File.ReadAllBytes("Shaders\\SkydomePS.cso");
byte[] sunvsbytes = File.ReadAllBytes("Shaders\\SkySunVS.cso");
byte[] sunpsbytes = File.ReadAllBytes("Shaders\\SkySunPS.cso");
byte[] moonvsbytes = File.ReadAllBytes("Shaders\\SkyMoonVS.cso");
byte[] moonpsbytes = File.ReadAllBytes("Shaders\\SkyMoonPS.cso");
skyvs = new VertexShader(device, skyvsbytes);
skyps = new PixelShader(device, skypsbytes);
sunvs = new VertexShader(device, sunvsbytes);
sunps = new PixelShader(device, sunpsbytes);
moonvs = new VertexShader(device, moonvsbytes);
moonps = new PixelShader(device, moonpsbytes);
SkyLocalVars = new GpuVarsBuffer<SkydomeShaderSkySystemLocals>(device);
VSSceneVars = new GpuVarsBuffer<SkydomeShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<SkydomeShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<SkydomeShaderVSModelVars>(device);
PSSceneVars = new GpuVarsBuffer<SkydomeShaderPSSceneVars>(device);
VSSunMoonVars = new GpuVarsBuffer<SkydomeShaderVSSunMoonVars>(device);
PSSunMoonVars = new GpuVarsBuffer<SkydomeShaderPSSunMoonVars>(device);
sundisc = new UnitDisc(device, 30, true);
sunlayout = new InputLayout(device, sunvsbytes, sundisc.GetLayout());
skylayout = new InputLayout(device, skyvsbytes, VertexTypePTT.GetLayout());
moonquad = new UnitQuad(device, true);
moonlayout = new InputLayout(device, moonvsbytes, moonquad.GetLayout());
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(skyvs);
context.PixelShader.Set(skyps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
if (type != VertexType.PTT)
{
return false;
}
context.InputAssembler.InputLayout = skylayout;
return true;
}
public void UpdateSkyLocals(Weather weather, ShaderGlobalLights lights)
{
var wv = weather.CurrentValues;
float skyhdr = EnableHDR ? wv.skyHdr : Math.Min(wv.skyHdr, 1.8f);
float sunhdr = EnableHDR ? wv.skySunHdr : Math.Min(wv.skySunHdr, 4.8f); //NO HDR - turn it down!!!
float scathdr = EnableHDR ? wv.skySunScatterInten : Math.Min(wv.skySunScatterInten, 1.8f);
Vector3 suncolhdr = wv.skySunCol * sunhdr;
Vector4 azecol = wv.skyAzimuthEastCol;
Vector4 azwcol = wv.skyAzimuthWestCol;
Vector4 aztcol = wv.skyAzimuthTransitionCol;
Vector4 zencol = wv.skyZenithCol;
Vector4 zetcol = wv.skyZenithTransitionCol;
Vector4 plncol = wv.skyPlane;
SkyLocalVars.Vars.azimuthEastColor = azecol;
SkyLocalVars.Vars.azimuthWestColor = azwcol;
SkyLocalVars.Vars.azimuthTransitionColor = aztcol.XYZ();
SkyLocalVars.Vars.azimuthTransitionPosition = wv.skyAzimuthTransition;
SkyLocalVars.Vars.zenithColor = zencol;
SkyLocalVars.Vars.zenithTransitionColor = zetcol;
SkyLocalVars.Vars.zenithConstants = wv.skyZenithTransition;
SkyLocalVars.Vars.skyPlaneColor = plncol;
SkyLocalVars.Vars.skyPlaneParams = Vector4.Zero;
SkyLocalVars.Vars.hdrIntensity = skyhdr;
SkyLocalVars.Vars.sunColor = wv.skySunCol;
SkyLocalVars.Vars.sunColorHdr = new Vector4(suncolhdr, sunhdr);
SkyLocalVars.Vars.sunDiscColorHdr = new Vector4(wv.skySunDiscCol, wv.skySunDiscSize);
//SkyLocalVars.Vars.sunConstants = new Vector4(wv.skySunMie, scathdr);
//SkyLocalVars.Vars.sunConstants.X = wv.skySunMie.X; //mie phase
//SkyLocalVars.Vars.sunConstants.Y = wv.skySunMie.Y; //mie scatter
//SkyLocalVars.Vars.sunConstants.Z = 0.5f / wv.skySunInfluenceRadius;// * 0.01f; // 0.0025f; //mie size/"range"
//SkyLocalVars.Vars.sunConstants.W = wv.skySunMie.Z;// * scathdr; //mie hdr intensity
SkyLocalVars.Vars.sunConstants.X = wv.skySunMie.X * wv.skySunMie.Y; //mie phase
SkyLocalVars.Vars.sunConstants.Y = wv.skySunMie.Y;// 1.0f /wv.skySunMie.Y;// 1.7f;// wv.skySunMie.Y; //mie scatter
SkyLocalVars.Vars.sunConstants.Z = 0.00003f * wv.skySunInfluenceRadius;// * wv.skySunMie.X;// wv.skySunMie.Z;///720.0f;// * 0.01f; // 0.0025f; //mie size/"range"
SkyLocalVars.Vars.sunConstants.W = wv.skySunMie.Z;// * scathdr; //mie intensity multiplier
SkyLocalVars.Vars.sunDirection = new Vector4(-lights.CurrentSunDir, 0);// wv.sunDirection, 0);
SkyLocalVars.Vars.sunPosition = new Vector4(-lights.CurrentSunDir, 0); //not used
SkyLocalVars.Vars.cloudBaseMinusMidColour = Vector4.Zero;
SkyLocalVars.Vars.cloudMidColour = Vector4.Zero;
SkyLocalVars.Vars.cloudShadowMinusBaseColourTimesShadowStrength = Vector4.Zero;
SkyLocalVars.Vars.cloudDetailConstants = Vector4.Zero;
SkyLocalVars.Vars.cloudConstants1 = Vector4.Zero;
SkyLocalVars.Vars.cloudConstants2 = Vector4.Zero;
SkyLocalVars.Vars.smallCloudConstants = Vector4.Zero;
SkyLocalVars.Vars.smallCloudColorHdr = Vector4.Zero;
SkyLocalVars.Vars.effectsConstants = Vector4.Zero;
SkyLocalVars.Vars.horizonLevel = 0;
SkyLocalVars.Vars.speedConstants = Vector3.Zero;
SkyLocalVars.Vars.starfieldIntensity = wv.skyStarsIten * 5.0f; //makes stars brighter....
SkyLocalVars.Vars.moonDirection = wv.moonDirection;
SkyLocalVars.Vars.moonPosition = Vector3.Zero;//need to update this?
SkyLocalVars.Vars.moonIntensity = wv.skyMoonIten;
SkyLocalVars.Vars.lunarCycle = Vector4.Zero;
SkyLocalVars.Vars.moonColor = wv.skyMoonCol;
SkyLocalVars.Vars.noiseFrequency = 0;
SkyLocalVars.Vars.noiseScale = 0;
SkyLocalVars.Vars.noiseThreshold = 0;
SkyLocalVars.Vars.noiseSoftness = 0;
SkyLocalVars.Vars.noiseDensityOffset = 0;
SkyLocalVars.Vars.noisePhase = Vector4.Zero;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
SkyLocalVars.Update(context);
SkyLocalVars.SetVSCBuffer(context, 0);
SkyLocalVars.SetPSCBuffer(context, 0);
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 1);
PSSceneVars.Vars.LightDirection = new Vector4(lights.Params.LightDir, 0.0f);
PSSceneVars.Vars.EnableHDR = EnableHDR ? 1u : 0u;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 1);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 3);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
//don't use this version
}
public void SetTextures(DeviceContext context, RenderableTexture starfield)
{
if (starfield != null)
{
context.PixelShader.SetSampler(0, texsampler);
starfield.SetPSResource(context, 0);
}
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.PixelShader.SetConstantBuffer(1, null);
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void RenderSun(DeviceContext context, Camera camera, Weather weather, ShaderGlobalLights lights)
{
context.VertexShader.Set(sunvs);
context.PixelShader.Set(sunps);
VSSunMoonVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSunMoonVars.Vars.ViewInv = Matrix.Transpose(camera.ViewInvMatrix);
VSSunMoonVars.Vars.CamRel = new Vector4(lights.CurrentSunDir, 0);
VSSunMoonVars.Vars.Size = new Vector2(weather.CurrentValues.skySunDiscSize * 0.008f);
VSSunMoonVars.Vars.Offset = Vector2.Zero;
VSSunMoonVars.Update(context);
VSSunMoonVars.SetVSCBuffer(context, 0);
PSSunMoonVars.Vars.Colour = new Vector4(weather.CurrentValues.skySunDiscCol * weather.CurrentValues.skySunHdr, 1);
PSSunMoonVars.Update(context);
PSSunMoonVars.SetPSCBuffer(context, 0);
context.InputAssembler.InputLayout = sunlayout;
sundisc.Draw(context);
}
public void RenderMoon(DeviceContext context, Camera camera, Weather weather, ShaderGlobalLights lights, RenderableTexture moontex)
{
context.VertexShader.Set(moonvs);
context.PixelShader.Set(moonps);
Quaternion ori = Quaternion.Invert(Quaternion.LookAtRH(Vector3.Zero, lights.CurrentMoonDir, lights.MoonAxis));
Matrix omat = ori.ToMatrix();
VSSunMoonVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSunMoonVars.Vars.ViewInv = Matrix.Transpose(omat);// camera.ViewInvMatrix);
VSSunMoonVars.Vars.CamRel = new Vector4(lights.CurrentMoonDir, 0);
VSSunMoonVars.Vars.Size = new Vector2(weather.CurrentValues.skyMoonDiscSize * 0.008f);
VSSunMoonVars.Vars.Offset = Vector2.Zero;
VSSunMoonVars.Update(context);
VSSunMoonVars.SetVSCBuffer(context, 0);
PSSunMoonVars.Vars.Colour = new Vector4(weather.CurrentValues.skyMoonCol * weather.CurrentValues.skyMoonIten, weather.CurrentValues.skyMoonIten);
PSSunMoonVars.Update(context);
PSSunMoonVars.SetPSCBuffer(context, 0);
context.PixelShader.SetSampler(0, texsampler);
moontex.SetPSResource(context, 0);
context.InputAssembler.InputLayout = moonlayout;
moonquad.Draw(context);
}
public void Dispose()
{
if (disposed) return;
disposed = true;
texsampler.Dispose();
sundisc.Dispose();
moonquad.Dispose();
skylayout.Dispose();
sunlayout.Dispose();
moonlayout.Dispose();
VSSunMoonVars.Dispose();
PSSunMoonVars.Dispose();
SkyLocalVars.Dispose();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
PSSceneVars.Dispose();
skyps.Dispose();
skyvs.Dispose();
sunps.Dispose();
sunvs.Dispose();
moonps.Dispose();
moonvs.Dispose();
}
}
}
+645
View File
@@ -0,0 +1,645 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct TerrainShaderVSSceneVars
{
public Matrix ViewProj;
}
public struct TerrainShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public uint HasSkeleton;
public uint HasTransforms;
public uint TintPaletteIndex;
public uint Pad1;
public Vector3 Scale;
public uint Pad2;
}
public struct TerrainShaderVSModelVars
{
public Matrix Transform;
}
public struct TerrainShaderVSGeomVars
{
public uint EnableTint;
public float TintYVal;
public uint Pad4;
public uint Pad5;
}
public struct TerrainShaderPSSceneVars
{
public ShaderGlobalLightParams GlobalLights;
public uint EnableShadows;
public uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
public uint RenderModeIndex; //colour/texcoord index
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
}
public struct TerrainShaderPSGeomVars
{
public uint EnableTexture0;
public uint EnableTexture1;
public uint EnableTexture2;
public uint EnableTexture3;
public uint EnableTexture4;
public uint EnableTextureMask;
public uint EnableNormalMap;
public uint ShaderName;
public uint EnableTint;
public uint EnableVertexColour;
public float bumpiness;
public uint Pad102;
}
public class TerrainShader : Shader, IDisposable
{
bool disposed = false;
VertexShader pncctvs;
VertexShader pnccttvs;
VertexShader pnccttxvs;
VertexShader pncctttxvs;
VertexShader pncctxvs;
VertexShader pnctttxvs;
VertexShader pncttxvs;
PixelShader terrainps;
GpuVarsBuffer<TerrainShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<TerrainShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<TerrainShaderVSModelVars> VSModelVars;
GpuVarsBuffer<TerrainShaderVSGeomVars> VSGeomVars;
GpuVarsBuffer<TerrainShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<TerrainShaderPSGeomVars> PSGeomVars;
SamplerState texsampler;
SamplerState texsampleranis;
SamplerState texsamplertnt;
public bool AnisotropicFilter = false;
public WorldRenderMode RenderMode = WorldRenderMode.Default;
public int RenderVertexColourIndex = 1;
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public TerrainShader(Device device)
{
byte[] vspncct = File.ReadAllBytes("Shaders\\TerrainVS_PNCCT.cso");
byte[] vspncctt = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTT.cso");
byte[] vspnccttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTTX.cso");
byte[] vspncctttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTTTX.cso");
byte[] vspncctx = File.ReadAllBytes("Shaders\\TerrainVS_PNCCTX.cso");
byte[] vspnctttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTTX.cso");
byte[] vspncttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTX.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\TerrainPS.cso");
pncctvs = new VertexShader(device, vspncct);
pnccttvs = new VertexShader(device, vspncctt);
pnccttxvs = new VertexShader(device, vspnccttx);
pncctttxvs = new VertexShader(device, vspncctttx);
pncctxvs = new VertexShader(device, vspncctx);
pnctttxvs = new VertexShader(device, vspnctttx);
pncttxvs = new VertexShader(device, vspncttx);
terrainps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<TerrainShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<TerrainShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<TerrainShaderVSModelVars>(device);
VSGeomVars = new GpuVarsBuffer<TerrainShaderVSGeomVars>(device);
PSSceneVars = new GpuVarsBuffer<TerrainShaderPSSceneVars>(device);
PSGeomVars = new GpuVarsBuffer<TerrainShaderPSGeomVars>(device);
//supported layouts - requires Position, Normal, Colour, Texcoord
layouts.Add(VertexType.PNCCT, new InputLayout(device, vspncct, VertexTypePNCCT.GetLayout()));
layouts.Add(VertexType.PNCCTT, new InputLayout(device, vspncctt, VertexTypePNCCTT.GetLayout()));
layouts.Add(VertexType.PNCTTX, new InputLayout(device, vspncttx, VertexTypePNCTTX.GetLayout()));
layouts.Add(VertexType.PNCTTTX_3, new InputLayout(device, vspnctttx, VertexTypePNCTTTX_3.GetLayout()));
layouts.Add(VertexType.PNCCTX, new InputLayout(device, vspncctx, VertexTypePNCCTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX, new InputLayout(device, vspnccttx, VertexTypePNCCTTX.GetLayout()));
layouts.Add(VertexType.PNCCTTX_2, new InputLayout(device, vspnccttx, VertexTypePNCCTTX_2.GetLayout()));
layouts.Add(VertexType.PNCCTTTX, new InputLayout(device, vspncctttx, VertexTypePNCCTTTX.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsampleranis = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.Anisotropic,
MaximumAnisotropy = 8,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsamplertnt = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.White,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipPoint,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
private void SetVertexShader(DeviceContext context, uint shaderhash)
{
//no longer used.
//PNCCT terrain_cb_w_4lyr_lod (terrain_cb_w_4lyr_lod.sps)
//PNCCTT terrain_cb_w_4lyr_2tex_blend_lod (terrain_cb_w_4lyr_2tex_blend_lod.sps)
//PNCTTX terrain_cb_w_4lyr_cm (terrain_cb_w_4lyr_cm.sps)
//PNCTTX terrain_cb_w_4lyr_cm_tnt (terrain_cb_w_4lyr_cm_tnt.sps)
//PNCTTTX_3 terrain_cb_w_4lyr_cm_pxm (terrain_cb_w_4lyr_cm_pxm.sps)
//PNCTTTX_3 terrain_cb_w_4lyr_cm_pxm_tnt (terrain_cb_w_4lyr_cm_pxm_tnt.sps)
//PNCCTX terrain_cb_w_4lyr (terrain_cb_w_4lyr.sps)
//PNCCTX terrain_cb_w_4lyr_spec (terrain_cb_w_4lyr_spec.sps)
//PNCCTTX terrain_cb_w_4lyr_2tex (terrain_cb_w_4lyr_2tex.sps)
//PNCCTTX terrain_cb_w_4lyr_2tex_blend (terrain_cb_w_4lyr_2tex_blend.sps)
//PNCCTTX_2 terrain_cb_w_4lyr_pxm (terrain_cb_w_4lyr_pxm.sps)
//PNCCTTX_2 terrain_cb_w_4lyr_pxm_spm (terrain_cb_w_4lyr_pxm_spm.sps)
//PNCCTTX_2 terrain_cb_w_4lyr_spec_pxm (terrain_cb_w_4lyr_spec_pxm.sps)
//PNCCTTTX terrain_cb_w_4lyr_2tex_pxm (terrain_cb_w_4lyr_2tex_pxm.sps)
//PNCCTTTX terrain_cb_w_4lyr_2tex_blend_pxm (terrain_cb_w_4lyr_2tex_blend_pxm.sps)
//PNCCTTTX terrain_cb_w_4lyr_2tex_blend_pxm_spm (terrain_cb_w_4lyr_2tex_blend_pxm_spm.sps)
VertexType vt = VertexType.Default;
switch (shaderhash)
{
case 295525123: //terrain_cb_w_4lyr_cm (terrain_cb_w_4lyr_cm.sps) vt: PNCTTX
case 417637541: //terrain_cb_w_4lyr_cm_tnt (terrain_cb_w_4lyr_cm_tnt.sps) vt: PNCTTX
vt = VertexType.PNCTTX;
break;
case 3965214311: //terrain_cb_w_4lyr_cm_pxm_tnt (terrain_cb_w_4lyr_cm_pxm_tnt.sps) vt: PNCTTTX_3
case 4186046662: //terrain_cb_w_4lyr_cm_pxm (terrain_cb_w_4lyr_cm_pxm.sps) vt: PNCTTTX_3
vt = VertexType.PNCTTTX; //cs6_08_struct08
break;
case 3051127652: //terrain_cb_w_4lyr (terrain_cb_w_4lyr.sps) vt: PNCCTX
case 646532852: //terrain_cb_w_4lyr_spec (terrain_cb_w_4lyr_spec.sps) vt: PNCCTX
vt = VertexType.PNCCTX; //hw1_07_grnd_c..
break;
case 2535953532: //terrain_cb_w_4lyr_2tex_blend_lod (terrain_cb_w_4lyr_2tex_blend_lod.sps) vt: PNCCTT
vt = VertexType.PNCCTT; //cs1_12_riverbed1_lod..
break;
case 137526804: //terrain_cb_w_4lyr_lod (terrain_cb_w_4lyr_lod.sps) vt: PNCCT
vt = VertexType.PNCCT; //brdgeplatform_01_lod..
break;
case 2316006813: //terrain_cb_w_4lyr_2tex_blend (terrain_cb_w_4lyr_2tex_blend.sps) vt: PNCCTTX
case 3112820305: //terrain_cb_w_4lyr_2tex (terrain_cb_w_4lyr_2tex.sps) vt: PNCCTTX
case 2601000386: //terrain_cb_w_4lyr_spec_pxm (terrain_cb_w_4lyr_spec_pxm.sps) vt: PNCCTTX_2
case 4105814572: //terrain_cb_w_4lyr_pxm (terrain_cb_w_4lyr_pxm.sps) vt: PNCCTTX_2
case 3400824277: //terrain_cb_w_4lyr_pxm_spm (terrain_cb_w_4lyr_pxm_spm.sps) vt: PNCCTTX_2
vt = VertexType.PNCCTTX; //ch2_04_land02b, ch2_06_terrain01a .. vb_35_beacha
break;
case 653544224: //terrain_cb_w_4lyr_2tex_blend_pxm_spm (terrain_cb_w_4lyr_2tex_blend_pxm_spm.sps) vt: PNCCTTTX
case 2486206885: //terrain_cb_w_4lyr_2tex_blend_pxm (terrain_cb_w_4lyr_2tex_blend_pxm.sps) vt: PNCCTTTX
case 1888432890: //terrain_cb_w_4lyr_2tex_pxm (terrain_cb_w_4lyr_2tex_pxm.sps) vt: PNCCTTTX
vt = VertexType.PNCCTTTX; //ch1_04b_vineland01..
break;
default:
break;
}
SetVertexShader(context, vt);
}
private void SetVertexShader(DeviceContext context, VertexType type)
{
VertexShader vs = pnccttxvs;
switch (type)
{
case VertexType.PNCCT: vs = pncctvs; break;
case VertexType.PNCCTT: vs = pnccttvs; break;
case VertexType.PNCTTX: vs = pncttxvs; break;
case VertexType.PNCTTTX_3: vs = pnctttxvs; break;
case VertexType.PNCCTX: vs = pncctxvs; break;
case VertexType.PNCCTTX: vs = pnccttxvs; break;
case VertexType.PNCCTTX_2: vs = pnccttxvs; break;
case VertexType.PNCCTTTX: vs = pncctttxvs; break;
}
context.VertexShader.Set(vs);
}
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(terrainps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
SetVertexShader(context, type); //need to use the correct VS.
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
uint rendermode = 0;
uint rendermodeind = 1;
switch (RenderMode)
{
case WorldRenderMode.VertexNormals:
rendermode = 1;
break;
case WorldRenderMode.VertexTangents:
rendermode = 2;
break;
case WorldRenderMode.VertexColour:
rendermode = 3;
rendermodeind = (uint)RenderVertexColourIndex;
break;
case WorldRenderMode.TextureCoord:
rendermode = 4;
rendermodeind = (uint)RenderTextureCoordIndex;
break;
case WorldRenderMode.SingleTexture:
switch (RenderTextureSampler)
{
case MetaName.DiffuseSampler:
rendermode = 5;
break;
case MetaName.BumpSampler:
rendermode = 6;
break;
case MetaName.SpecSampler:
rendermode = 7;
break;
default:
rendermode = 8;
break;
}
break;
}
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
PSSceneVars.Vars.GlobalLights = lights.Params;
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
PSSceneVars.Vars.RenderMode = rendermode;
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 0);
if (shadowmap != null)
{
shadowmap.SetFinalRenderResources(context);
}
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
VSEntityVars.Vars.TintPaletteIndex = rend.TintPaletteIndex;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 3);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture0 = null;
RenderableTexture texture1 = null;
RenderableTexture texture2 = null;
RenderableTexture texture3 = null;
RenderableTexture texture4 = null;
RenderableTexture texturemask = null;
RenderableTexture tintpal = null;
RenderableTexture normals0 = null;
RenderableTexture normals1 = null;
RenderableTexture normals2 = null;
RenderableTexture normals3 = null;
RenderableTexture normals4 = null;
float tntpalind = 0.0f;
bool usevc = true;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
switch (ihash)
{
case MetaName.DiffuseSampler:
texture0 = itex;
break;
case MetaName.TextureSampler_layer0:
texture1 = itex;
break;
case MetaName.TextureSampler_layer1:
texture2 = itex;
break;
case MetaName.TextureSampler_layer2:
texture3 = itex;
break;
case MetaName.TextureSampler_layer3:
texture4 = itex;
break;
case MetaName.BumpSampler:
normals0 = itex;
break;
case MetaName.BumpSampler_layer0:
normals1 = itex;
break;
case MetaName.BumpSampler_layer1:
normals2 = itex;
break;
case MetaName.BumpSampler_layer2:
normals3 = itex;
break;
case MetaName.BumpSampler_layer3:
normals4 = itex;
break;
case MetaName.lookupSampler:
texturemask = itex;
break;
case MetaName.TintPaletteSampler:
tintpal = itex;
if (tintpal.Key != null)
{
//this is slightly dodgy but vsentvarsdata should have the correct value in it...
tntpalind = (VSEntityVars.Vars.TintPaletteIndex + 0.5f) / tintpal.Key.Height;
}
break;
}
}
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
//{
// texture0 = geom.Textures[geom.DiffuseSampler];
//}
//if ((geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
//{
// texture1 = geom.Textures[geom.TextureSampler_layer0];
//}
//if ((geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
//{
// texture2 = geom.Textures[geom.TextureSampler_layer1];
//}
//if ((geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
//{
// texture3 = geom.Textures[geom.TextureSampler_layer2];
//}
//if ((geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
//{
// texture4 = geom.Textures[geom.TextureSampler_layer3];
//}
//if ((geom.BumpSampler >= 0) && (geom.BumpSampler < geom.Textures.Length))
//{
// normals0 = geom.Textures[geom.BumpSampler];
//}
//if ((geom.BumpSampler_layer0 >= 0) && (geom.BumpSampler_layer0 < geom.Textures.Length))
//{
// normals1 = geom.Textures[geom.BumpSampler_layer0];
//}
//if ((geom.BumpSampler_layer1 >= 0) && (geom.BumpSampler_layer1 < geom.Textures.Length))
//{
// normals2 = geom.Textures[geom.BumpSampler_layer1];
//}
//if ((geom.BumpSampler_layer2 >= 0) && (geom.BumpSampler_layer2 < geom.Textures.Length))
//{
// normals3 = geom.Textures[geom.BumpSampler_layer2];
//}
//if ((geom.BumpSampler_layer3 >= 0) && (geom.BumpSampler_layer3 < geom.Textures.Length))
//{
// normals4 = geom.Textures[geom.BumpSampler_layer3];
//}
//if ((geom.lookupSampler >= 0) && (geom.lookupSampler < geom.Textures.Length))
//{
// texturemask = geom.Textures[geom.lookupSampler];
//}
//if ((geom.TintPaletteSampler >= 0) && (geom.TintPaletteSampler < geom.Textures.Length))
//{
// tintpal = geom.Textures[geom.TintPaletteSampler];
// if (tintpal.Texture != null)
// {
// //this is slightly dodgy but vsentvarsdata should have the correct value in it...
// tntpalind = (vsentvarsdata.TintPaletteIndex + 0.5f) / tintpal.Texture.Height;
// }
//}
}
if (RenderMode == WorldRenderMode.SingleTexture)
{
usevc = false;
switch (RenderTextureSampler)
{
case MetaName.DiffuseSampler:
case MetaName.BumpSampler:
case MetaName.SpecSampler:
break;
default:
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (ihash == RenderTextureSampler)
{
texture0 = itex;
break;
}
}
//int directtexind = geom.GetTextureSamplerIndex(RenderTextureSampler);
//if ((directtexind >= 0) && (directtexind < geom.Textures.Length))
//{
// texture0 = geom.Textures[directtexind];
//}
break;
}
}
bool usediff0 = ((texture0 != null) && (texture0.ShaderResourceView != null));
bool usediff1 = ((texture1 != null) && (texture1.ShaderResourceView != null));
bool usediff2 = ((texture2 != null) && (texture2.ShaderResourceView != null));
bool usediff3 = ((texture3 != null) && (texture3.ShaderResourceView != null));
bool usediff4 = ((texture4 != null) && (texture4.ShaderResourceView != null));
bool usemask = ((texturemask != null) && (texturemask.ShaderResourceView != null));
bool usetint = ((tintpal != null) && (tintpal.ShaderResourceView != null));
bool usenm = (((normals0 != null) && (normals0.ShaderResourceView != null)) || ((normals1 != null) && (normals1.ShaderResourceView != null)));
float bumpiness = 1.0f;
if (usenm)
{
bumpiness = geom.bumpiness;
}
PSGeomVars.Vars.EnableTexture0 = usediff0 ? 1u : 0u;
PSGeomVars.Vars.EnableTexture1 = usediff1 ? 1u : 0u;
PSGeomVars.Vars.EnableTexture2 = usediff2 ? 1u : 0u;
PSGeomVars.Vars.EnableTexture3 = usediff3 ? 1u : 0u;
PSGeomVars.Vars.EnableTexture4 = usediff4 ? 1u : 0u;
PSGeomVars.Vars.EnableTextureMask = usemask ? 1u : 0u;
PSGeomVars.Vars.EnableNormalMap = usenm ? 1u : 0u;
PSGeomVars.Vars.ShaderName = geom.DrawableGeom.Shader.Name.Hash;
PSGeomVars.Vars.EnableTint = usetint ? 1u : 0u;
PSGeomVars.Vars.EnableVertexColour = usevc ? 1u : 0u;
PSGeomVars.Vars.bumpiness = bumpiness;//
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableTint = usetint ? 1u : 0u;
VSGeomVars.Vars.TintYVal = tntpalind;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 4);
context.VertexShader.SetSampler(0, texsamplertnt);
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
if (usediff0) texture0.SetPSResource(context, 0);
if (usediff1) texture1.SetPSResource(context, 2);
if (usediff2) texture2.SetPSResource(context, 3);
if (usediff3) texture3.SetPSResource(context, 4);
if (usediff4) texture4.SetPSResource(context, 5);
if (usemask) texturemask.SetPSResource(context, 6);
if (usetint) tintpal.SetVSResource(context, 0);
if (normals0 != null) normals0.SetPSResource(context, 7);
if (normals1 != null) normals1.SetPSResource(context, 8);
if (normals2 != null) normals2.SetPSResource(context, 9);
if (normals3 != null) normals3.SetPSResource(context, 10);
if (normals4 != null) normals4.SetPSResource(context, 11);
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetShaderResource(1, null);//shadowmap
context.PixelShader.SetSampler(1, null); //shadowmap
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(4, null);
context.VertexShader.SetSampler(0, null);
context.PixelShader.SetSampler(0, null);
context.VertexShader.SetShaderResource(0, null);
context.PixelShader.SetShaderResource(0, null);
context.PixelShader.SetShaderResource(2, null);
context.PixelShader.SetShaderResource(3, null);
context.PixelShader.SetShaderResource(4, null);
context.PixelShader.SetShaderResource(5, null);
context.PixelShader.SetShaderResource(6, null);
context.PixelShader.SetShaderResource(7, null);
context.PixelShader.SetShaderResource(8, null);
context.PixelShader.SetShaderResource(9, null);
context.PixelShader.SetShaderResource(10, null);
context.PixelShader.SetShaderResource(11, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
if (texsampler != null)
{
texsampler.Dispose();
texsampler = null;
}
if (texsampleranis != null)
{
texsampleranis.Dispose();
texsampleranis = null;
}
if (texsamplertnt != null)
{
texsamplertnt.Dispose();
texsamplertnt = null;
}
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
VSGeomVars.Dispose();
PSSceneVars.Dispose();
PSGeomVars.Dispose();
terrainps.Dispose();
pncctvs.Dispose();
pnccttvs.Dispose();
pnccttxvs.Dispose();
pncctttxvs.Dispose();
pncctxvs.Dispose();
pnctttxvs.Dispose();
pncttxvs.Dispose();
disposed = true;
}
}
}
+320
View File
@@ -0,0 +1,320 @@
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using MapFlags = SharpDX.Direct3D11.MapFlags;
using SharpDX;
using CodeWalker.GameFiles;
using CodeWalker.World;
namespace CodeWalker.Rendering
{
public struct TreesLodShaderVSSceneVars
{
public Matrix ViewProj;
}
public struct TreesLodShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public uint HasSkeleton;
public uint HasTransforms;
public uint Pad0;
public uint Pad1;
public Vector3 Scale;
public uint Pad2;
}
public struct TreesLodShaderVSModelVars
{
public Matrix Transform;
}
public struct TreesLodShaderVSGeometryVars
{
public Vector4 AlphaTest;
public Vector4 AlphaScale;
public Vector4 UseTreeNormals;
public Vector4 treeLod2Normal;
public Vector4 treeLod2Params;
}
public struct TreesLodShaderPSSceneVars
{
public ShaderGlobalLightParams GlobalLights;
}
public struct TreesLodShaderPSEntityVars
{
public uint EnableTexture;
public uint Pad1;
public uint Pad2;
public uint Pad3;
}
public class TreesLodShader : Shader, IDisposable
{
bool disposed = false;
VertexShader basicvs;
PixelShader basicps;
GpuVarsBuffer<TreesLodShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<TreesLodShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<TreesLodShaderVSModelVars> VSModelVars;
GpuVarsBuffer<TreesLodShaderVSGeometryVars> VSGeomVars;
GpuVarsBuffer<TreesLodShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<TreesLodShaderPSEntityVars> PSEntityVars;
SamplerState texsampler;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public TreesLodShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\TreesLodVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\TreesLodPS.cso");
basicvs = new VertexShader(device, vsbytes);
basicps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<TreesLodShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<TreesLodShaderVSEntityVars>(device);
VSModelVars = new GpuVarsBuffer<TreesLodShaderVSModelVars>(device);
VSGeomVars = new GpuVarsBuffer<TreesLodShaderVSGeometryVars>(device);
PSSceneVars = new GpuVarsBuffer<TreesLodShaderPSSceneVars>(device);
PSEntityVars = new GpuVarsBuffer<TreesLodShaderPSEntityVars>(device);
//layouts.Add(VertexType.PNCCT, new InputLayout(device, vsbytes, VertexTypePNCCT.GetLayout()));
layouts.Add(VertexType.PNCCTTTT, new InputLayout(device, vsbytes, VertexTypePNCCTTTT.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(basicvs);
context.PixelShader.Set(basicps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
PSSceneVars.Vars.GlobalLights = lights.Params;
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 0);
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Vars.HasSkeleton = rend.Renderable.HasSkeleton ? 1u : 0;
VSEntityVars.Vars.HasTransforms = rend.Renderable.HasTransforms ? 1u : 0;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 1);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
if (!model.UseTransform) return;
VSModelVars.Vars.Transform = Matrix.Transpose(model.Transform);
VSModelVars.Update(context);
VSModelVars.SetVSCBuffer(context, 2);
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture = null; // ((geom.Textures != null) && (geom.Textures.Length > 0)) ? geom.Textures[0] : null;
//trees_lod2
//PNCCTTTT: texcoord2 seems to be 0-1 for the billboard, vertex pos is billboard root.
//param for billboard dir... (treeLod2Normal)
//trees_lod
//PNCCT:
if (geom.VertexType != VertexType.PNCCTTTT)
{ }
var shader = geom.DrawableGeom.Shader;
if (shader.Name.Hash == 1874959840)
{
int nparams = 0;
MetaName[] hashes = null;
ShaderParameter[] sparams = null;
if (shader.ParametersList != null)
{
nparams = shader.ParametersList.Hashes.Length;
hashes = shader.ParametersList.Hashes;
sparams = shader.ParametersList.Parameters;
}
for (int i = 0; i < nparams; i++)
{
var h = shader.ParametersList.Hashes[i];
switch (h)
{
case MetaName.AlphaTest: VSGeomVars.Vars.AlphaTest = (Vector4)sparams[i].Data; break;
case MetaName.AlphaScale: VSGeomVars.Vars.AlphaScale = (Vector4)sparams[i].Data; break;
case MetaName.UseTreeNormals: VSGeomVars.Vars.UseTreeNormals = (Vector4)sparams[i].Data; break;
case MetaName.treeLod2Normal: VSGeomVars.Vars.treeLod2Normal = (Vector4)sparams[i].Data; break;
case MetaName.treeLod2Params: VSGeomVars.Vars.treeLod2Params = (Vector4)sparams[i].Data; break;
}
}
}
else
{
VSGeomVars.Vars.AlphaTest = Vector4.Zero;
VSGeomVars.Vars.AlphaScale = Vector4.Zero;
VSGeomVars.Vars.UseTreeNormals = Vector4.Zero;
VSGeomVars.Vars.treeLod2Normal = Vector4.Zero;
VSGeomVars.Vars.treeLod2Params = Vector4.Zero;
}
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 3);
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
switch (ihash)
{
case MetaName.DiffuseSampler:
texture = itex;
break;
}
if (texture != null) break;
}
////try get default diffuse texture
//if ((geom.DiffuseSampler >= 0) && (geom.DiffuseSampler < geom.Textures.Length))
//{
// texture = geom.Textures[geom.DiffuseSampler];
//}
//if ((texture == null) && (geom.TextureSampler_layer0 >= 0) && (geom.TextureSampler_layer0 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer0];
//}
//if ((texture == null) && (geom.TextureSampler_layer1 >= 0) && (geom.TextureSampler_layer1 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer1];
//}
//if ((texture == null) && (geom.TextureSampler_layer2 >= 0) && (geom.TextureSampler_layer2 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer2];
//}
//if ((texture == null) && (geom.TextureSampler_layer3 >= 0) && (geom.TextureSampler_layer3 < geom.Textures.Length))
//{
// texture = geom.Textures[geom.TextureSampler_layer3];
//}
//fallback try get first texture...
int index = 0;
while (((texture == null) || (texture.Texture2D == null)) && (index < geom.RenderableTextures.Length))
{
texture = geom.RenderableTextures[index];
index++;
}
}
bool usediff = ((texture != null) && (texture.Texture2D != null) && (texture.ShaderResourceView != null));
PSEntityVars.Vars.EnableTexture = usediff ? 1u : 0u;
PSEntityVars.Update(context);
PSEntityVars.SetPSCBuffer(context, 1);
if (usediff)
{
context.PixelShader.SetSampler(0, texsampler);
//context.PixelShader.SetShaderResource(0, difftex.ShaderResourceView);
texture.SetPSResource(context, 0);
}
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null);
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(1, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
if (texsampler != null)
{
texsampler.Dispose();
texsampler = null;
}
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSModelVars.Dispose();
VSGeomVars.Dispose();
PSSceneVars.Dispose();
PSEntityVars.Dispose();
basicps.Dispose();
basicvs.Dispose();
disposed = true;
}
}
}
+564
View File
@@ -0,0 +1,564 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeWalker.GameFiles;
using CodeWalker.World;
using SharpDX.Direct3D11;
using SharpDX;
using System.IO;
namespace CodeWalker.Rendering
{
public struct WaterShaderVSSceneVars
{
public Matrix ViewProj;
public Vector4 WaterVector;
public float ScaledTime;
public float ScnPad0;
public float ScnPad1;
public float ScnPad2;
}
public struct WaterShaderVSEntityVars
{
public Vector4 CamRel;
public Quaternion Orientation;
public Vector3 Scale;
public uint EntPad0;
}
public struct WaterShaderVSGeomVars
{
public Vector4 WaterParams;
public uint EnableFlow;
public uint ShaderMode;
public uint GeoPad1;
public uint GeoPad2;
public float RippleSpeed;
public float GeoPad3;
public float GeoPad4;
public float GeoPad5;
}
public struct WaterShaderPSSceneVars
{
public ShaderGlobalLightParams GlobalLights;
public uint EnableShadows;
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
public uint RenderModeIndex; //colour/texcoord index
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
public uint EnableWaterbumps;//if the waterbump textures are ready..
public uint EnableFogtex; //if the fog texture is ready
public uint ScnPad1;
public uint ScnPad2;
public Vector4 gFlowParams;
public Vector4 CameraPos;
public Vector4 WaterFogParams; //xy = base location, zw = inverse size
}
public struct WaterShaderPSGeomVars
{
public uint EnableTexture;
public uint EnableBumpMap;
public uint EnableFoamMap;
public uint ShaderMode;
public float SpecularIntensity;
public float SpecularFalloff;
public float GeoPad1;
public float GeoPad2;
public float WaveOffset; //for terrainfoam
public float WaterHeight; //for terrainfoam
public float WaveMovement; //for terrainfoam
public float HeightOpacity; //for terrainfoam
public float RippleSpeed;
public float RippleScale;
public float RippleBumpiness;
public float GeoPad3;
}
public class WaterShader : Shader
{
bool disposed = false;
VertexShader vspt;
VertexShader vspct;
VertexShader vspnct;
VertexShader vspnctx;
PixelShader ps;
GpuVarsBuffer<WaterShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<WaterShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<WaterShaderVSGeomVars> VSGeomVars;
GpuVarsBuffer<WaterShaderPSSceneVars> PSSceneVars;
GpuVarsBuffer<WaterShaderPSGeomVars> PSGeomVars;
SamplerState texsampler;
SamplerState texsampleranis;
SamplerState texsamplerflow;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public bool AnisotropicFilter = false;
public WorldRenderMode RenderMode = WorldRenderMode.Default;
public int RenderVertexColourIndex = 1;
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public MetaName RenderTextureSampler = MetaName.DiffuseSampler;
public double CurrentRealTime = 0;
public float CurrentElapsedTime = 0;
public bool SpecularEnable = true;
public RenderableTexture waterbump { get; set; }
public RenderableTexture waterbump2 { get; set; }
public RenderableTexture waterfog { get; set; }
//check dt1_21_reflproxy and dt1_05_reflproxy
public WaterShader(Device device)
{
byte[] vsptbytes = File.ReadAllBytes("Shaders\\WaterVS_PT.cso");
byte[] vspctbytes = File.ReadAllBytes("Shaders\\WaterVS_PCT.cso");
byte[] vspnctbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCT.cso");
byte[] vspnctxbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCTX.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\WaterPS.cso");
vspt = new VertexShader(device, vsptbytes);
vspct = new VertexShader(device, vspctbytes);
vspnct = new VertexShader(device, vspnctbytes);
vspnctx = new VertexShader(device, vspnctxbytes);
ps = new PixelShader(device, psbytes);
VSSceneVars = new GpuVarsBuffer<WaterShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<WaterShaderVSEntityVars>(device);
VSGeomVars = new GpuVarsBuffer<WaterShaderVSGeomVars>(device);
PSSceneVars = new GpuVarsBuffer<WaterShaderPSSceneVars>(device);
PSGeomVars = new GpuVarsBuffer<WaterShaderPSGeomVars>(device);
layouts.Add(VertexType.PT, new InputLayout(device, vsptbytes, VertexTypePT.GetLayout()));
layouts.Add(VertexType.PCT, new InputLayout(device, vspctbytes, VertexTypePCT.GetLayout()));
layouts.Add(VertexType.Default, new InputLayout(device, vspnctbytes, VertexTypeDefault.GetLayout()));
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vspnctxbytes, VertexTypeDefaultEx.GetLayout()));
texsampler = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipLinear,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsampleranis = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.Black,
ComparisonFunction = Comparison.Always,
Filter = Filter.Anisotropic,
MaximumAnisotropy = 8,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
texsamplerflow = new SamplerState(device, new SamplerStateDescription()
{
AddressU = TextureAddressMode.Clamp,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
BorderColor = Color.White,
ComparisonFunction = Comparison.Always,
Filter = Filter.MinMagMipPoint,
MaximumAnisotropy = 1,
MaximumLod = float.MaxValue,
MinimumLod = 0,
MipLodBias = 0,
});
}
private void SetVertexShader(DeviceContext context, VertexType type)
{
VertexShader vs = vspnct;
switch (type)
{
case VertexType.PT:
vs = vspt;
break;
case VertexType.PCT:
vs = vspct;
break;
case VertexType.Default:
vs = vspnct;
break;
case VertexType.DefaultEx:
vs = vspnctx;
break;
default:
break;
}
context.VertexShader.Set(vs);
}
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
InputLayout l;
if (layouts.TryGetValue(type, out l))
{
SetVertexShader(context, type);
context.InputAssembler.InputLayout = l;
return true;
}
return false;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
uint rendermode = 0;
uint rendermodeind = 1;
SpecularEnable = lights.SpecularEnabled;
switch (RenderMode)
{
case WorldRenderMode.VertexNormals:
rendermode = 1;
break;
case WorldRenderMode.VertexTangents:
rendermode = 2;
break;
case WorldRenderMode.VertexColour:
rendermode = 3;
rendermodeind = (uint)RenderVertexColourIndex;
break;
case WorldRenderMode.TextureCoord:
rendermode = 4;
rendermodeind = (uint)RenderTextureCoordIndex;
break;
case WorldRenderMode.SingleTexture:
rendermode = 8;//direct mode
break;
}
float phspd = 4.0f;
float phspdi = 1.0f / phspd;
float phspdh = phspd * 0.5f;
float t = (float)(CurrentRealTime - (Math.Floor(CurrentRealTime * 0.001) * 1000.0))*1.0f;
float ta = t * 2.0f;
float tb = ta + (phspdh);
float t1 = (ta * phspdi - (float)Math.Floor(ta * phspdi)) * phspd;
float t2 = (tb * phspdi - (float)Math.Floor(tb * phspdi)) * phspd;
float s1 = ((t1 < phspdh) ? t1 : phspd - t1) * phspdi * 1.0f;
float s2 = ((t2 < phspdh) ? t2 : phspd - t2) * phspdi * 1.0f;
//float s1 = ((float)Math.Cos(t1 * phspdi * Math.PI * 2) + 1.0f) * 0.5f;
//float s2 = ((float)Math.Cos(t2 * phspdi * Math.PI * 2) + 1.0f) * 0.5f;
float gFlowX = t1*0.5f;
float gFlowY = t2*0.5f;
float gFlowZ = s1;
float gFlowW = s2;
Vector2 fogtexMin = new Vector2(-4000.0f, -4000.0f); //aka water quads min/max
Vector2 fogtexMax = new Vector2(4500.0f, 8000.0f);
Vector2 fogtexInv = 1.0f / (fogtexMax - fogtexMin);
bool usewaterbumps = (waterbump != null) && (waterbump.ShaderResourceView != null) && (waterbump2 != null) && (waterbump2.ShaderResourceView != null);
bool usefogtex = (waterfog != null) && (waterfog.ShaderResourceView != null);
VSSceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
VSSceneVars.Vars.WaterVector = Vector4.Zero;
VSSceneVars.Vars.ScaledTime = t * 0.1f;
VSSceneVars.Update(context);
VSSceneVars.SetVSCBuffer(context, 0);
PSSceneVars.Vars.GlobalLights = lights.Params;
PSSceneVars.Vars.EnableShadows = (shadowmap != null) ? 1u : 0u;
PSSceneVars.Vars.RenderMode = rendermode;
PSSceneVars.Vars.RenderModeIndex = rendermodeind;
PSSceneVars.Vars.RenderSamplerCoord = (uint)RenderTextureSamplerCoord;
PSSceneVars.Vars.EnableWaterbumps = usewaterbumps ? 1u : 0u;
PSSceneVars.Vars.EnableFogtex = usefogtex ? 1u : 0u;
PSSceneVars.Vars.gFlowParams = new Vector4(gFlowX, gFlowY, gFlowZ, gFlowW);
PSSceneVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
PSSceneVars.Vars.WaterFogParams = new Vector4(fogtexMin, fogtexInv.X, fogtexInv.Y);
PSSceneVars.Update(context);
PSSceneVars.SetPSCBuffer(context, 0);
if (shadowmap != null)
{
shadowmap.SetFinalRenderResources(context);
}
if (usewaterbumps)
{
context.PixelShader.SetShaderResource(4, waterbump.ShaderResourceView);
context.PixelShader.SetShaderResource(5, waterbump2.ShaderResourceView);
}
if (usefogtex)
{
context.PixelShader.SetShaderResource(6, waterfog.ShaderResourceView);
}
}
public override void SetEntityVars(DeviceContext context, ref RenderableInst rend)
{
VSEntityVars.Vars.CamRel = new Vector4(rend.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = rend.Orientation;
VSEntityVars.Vars.Scale = rend.Scale;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
}
public override void SetModelVars(DeviceContext context, RenderableModel model)
{
}
public override void SetGeomVars(DeviceContext context, RenderableGeometry geom)
{
RenderableTexture texture = null;
RenderableTexture bumptex = null;
RenderableTexture flowtex = null;
RenderableTexture foamtex = null;
RenderableTexture fogtex = null;
if ((geom.RenderableTextures != null) && (geom.RenderableTextures.Length > 0))
{
if (RenderMode == WorldRenderMode.Default)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (itex == null) continue;
switch (ihash)
{
case MetaName.DiffuseSampler:
texture = itex;
break;
case MetaName.BumpSampler:
bumptex = itex;
break;
case MetaName.FlowSampler:
flowtex = itex;
break;
case MetaName.FoamSampler:
foamtex = itex;
break;
case MetaName.FogSampler:
fogtex = itex;
break;
default:
if (texture == null) texture = itex;
break;
}
}
}
else if (RenderMode == WorldRenderMode.SingleTexture)
{
for (int i = 0; i < geom.RenderableTextures.Length; i++)
{
var itex = geom.RenderableTextures[i];
var ihash = geom.TextureParamHashes[i];
if (ihash == RenderTextureSampler)
{
texture = itex;
break;
}
}
}
}
bool usediff = ((texture != null) && (texture.ShaderResourceView != null));
bool usebump = ((bumptex != null) && (bumptex.ShaderResourceView != null));
bool useflow = ((flowtex != null) && (flowtex.ShaderResourceView != null));
bool usefoam = ((foamtex != null) && (foamtex.ShaderResourceView != null));
bool usefog = ((fogtex != null) && (fogtex.ShaderResourceView != null));
uint shaderMode = 0;
var shaderFile = geom.DrawableGeom.Shader.FileName;
switch (shaderFile.Hash)
{
case 1529202445://{water_river.sps}
case 4064804434://{water_riverlod.sps}
case 2871265627://{water_riverocean.sps}
case 1507348828://{water_rivershallow.sps}
case 3945561843://{water_fountain.sps}
case 4234404348://{water_shallow.sps}
case 1077877097://{water_poolenv.sps}
break;
case 1471966282://{water_decal.sps} (should this be in decal batch?)
case 3053856997://{water_riverfoam.sps}
shaderMode = 1;
break;
case 3066724854://{water_terrainfoam.sps}
shaderMode = 2;
break;
default:
break;
}
PSGeomVars.Vars.EnableTexture = usediff ? 1u : 0u;
PSGeomVars.Vars.EnableBumpMap = usebump ? 1u : 0u;
PSGeomVars.Vars.EnableFoamMap = usefoam ? 1u : 0u;
PSGeomVars.Vars.ShaderMode = shaderMode;
PSGeomVars.Vars.SpecularIntensity = SpecularEnable ? 1.0f : 0.0f;// geom.specularIntensityMult;
PSGeomVars.Vars.SpecularFalloff = 1.0f;// geom.specularFalloffMult;
PSGeomVars.Vars.WaveOffset = geom.WaveOffset; //for terrainfoam
PSGeomVars.Vars.WaterHeight = geom.WaterHeight; //for terrainfoam
PSGeomVars.Vars.WaveMovement = geom.WaveMovement; //for terrainfoam
PSGeomVars.Vars.HeightOpacity = geom.HeightOpacity; //for terrainfoam
PSGeomVars.Vars.RippleSpeed = geom.RippleSpeed;
PSGeomVars.Vars.RippleScale = geom.RippleScale;
PSGeomVars.Vars.RippleBumpiness = geom.RippleBumpiness;
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableFlow = useflow ? 1u : 0u;
VSGeomVars.Vars.ShaderMode = shaderMode;
VSGeomVars.Vars.WaterParams = Vector4.Zero;
VSGeomVars.Vars.RippleSpeed = geom.RippleSpeed;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 3);
context.VertexShader.SetSampler(0, texsamplerflow);
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
if (usediff)
{
texture.SetPSResource(context, 0);
}
if (usebump)
{
bumptex.SetPSResource(context, 2);
}
if (usefoam)
{
foamtex.SetPSResource(context, 3);
}
if (useflow)
{
flowtex.SetVSResource(context, 0);
}
}
public void RenderWaterQuad(DeviceContext context, RenderableWaterQuad quad)
{
SetInputLayout(context, VertexType.PCT);
VSEntityVars.Vars.CamRel = new Vector4(quad.CamRel, 0.0f);
VSEntityVars.Vars.Orientation = Quaternion.Identity;
VSEntityVars.Vars.Scale = Vector3.One;
VSEntityVars.Update(context);
VSEntityVars.SetVSCBuffer(context, 2);
PSGeomVars.Vars.EnableTexture = 0;
PSGeomVars.Vars.EnableBumpMap = 0;
PSGeomVars.Vars.EnableFoamMap = 0;
PSGeomVars.Vars.ShaderMode = 0; //normal water render
PSGeomVars.Vars.SpecularIntensity = SpecularEnable ? 4.2f : 0.0f;// geom.specularIntensityMult;
PSGeomVars.Vars.SpecularFalloff = 1600.0f;// geom.specularFalloffMult;
PSGeomVars.Vars.WaveOffset = 0.0f;// geom.WaveOffset; //for terrainfoam
PSGeomVars.Vars.WaterHeight = 0.0f;// geom.WaterHeight; //for terrainfoam
PSGeomVars.Vars.WaveMovement = 0.0f;// geom.WaveMovement; //for terrainfoam
PSGeomVars.Vars.HeightOpacity = 0.0f;// geom.HeightOpacity; //for terrainfoam
PSGeomVars.Vars.RippleSpeed = 2.1f;// geom.RippleSpeed;
PSGeomVars.Vars.RippleScale = 0.02f;// geom.RippleScale;
PSGeomVars.Vars.RippleBumpiness = 4.5f;// geom.RippleBumpiness;
PSGeomVars.Update(context);
PSGeomVars.SetPSCBuffer(context, 2);
VSGeomVars.Vars.EnableFlow = 0; //no flow for water quads...
VSGeomVars.Vars.ShaderMode = 0; //normal water
VSGeomVars.Vars.WaterParams = Vector4.Zero;
VSGeomVars.Vars.RippleSpeed = 1.0f;// geom.RippleSpeed;
VSGeomVars.Update(context);
VSGeomVars.SetVSCBuffer(context, 3);
context.VertexShader.SetSampler(0, texsamplerflow);
context.PixelShader.SetSampler(0, AnisotropicFilter ? texsampleranis : texsampler);
quad.Render(context);
}
public override void UnbindResources(DeviceContext context)
{
context.VertexShader.SetConstantBuffer(0, null);
context.PixelShader.SetConstantBuffer(0, null);
context.VertexShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetConstantBuffer(1, null); //shadowmap
context.PixelShader.SetShaderResource(1, null);//shadowmap
context.PixelShader.SetSampler(1, null); //shadowmap
context.VertexShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(3, null);
context.PixelShader.SetConstantBuffer(2, null);
context.VertexShader.SetConstantBuffer(4, null);
context.VertexShader.SetConstantBuffer(5, null);
context.VertexShader.SetConstantBuffer(6, null);
context.VertexShader.SetSampler(0, null);
context.PixelShader.SetSampler(0, null);
context.PixelShader.SetShaderResource(0, null);
context.PixelShader.SetShaderResource(2, null);
context.PixelShader.SetShaderResource(3, null);
context.PixelShader.SetShaderResource(4, null);
context.PixelShader.SetShaderResource(5, null);
context.VertexShader.SetShaderResource(0, null);
context.VertexShader.SetShaderResource(1, null);
context.VertexShader.SetShaderResource(2, null);
context.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void Dispose()
{
if (disposed) return;
texsampler.Dispose();
texsampleranis.Dispose();
texsamplerflow.Dispose();
foreach (InputLayout layout in layouts.Values)
{
layout.Dispose();
}
layouts.Clear();
VSSceneVars.Dispose();
VSEntityVars.Dispose();
VSGeomVars.Dispose();
PSSceneVars.Dispose();
PSGeomVars.Dispose();
ps.Dispose();
vspt.Dispose();
vspct.Dispose();
vspnct.Dispose();
vspnctx.Dispose();
disposed = true;
}
}
}
+617
View File
@@ -0,0 +1,617 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeWalker.GameFiles;
using CodeWalker.World;
using SharpDX.Direct3D11;
using SharpDX;
using System.IO;
namespace CodeWalker.Rendering
{
public struct WidgetShaderSceneVars
{
public Matrix ViewProj;
public uint Mode; //0=Vertices, 1=Arc
public float Size; //world units
public float SegScale; //arc angle / number of segments
public float SegOffset; //angle offset of arc
public Vector3 CamRel; //center position
public uint CullBack; //culls pixels behind 0,0,0
public Color4 Colour; //colour for arc
public Vector3 Axis1; //axis 1 of arc
public float WidgetPad2;
public Vector3 Axis2; //axis 2 of arc
public float WidgetPad3;
}
public class WidgetShader : Shader
{
VertexShader vs;
PixelShader ps;
GpuVarsBuffer<WidgetShaderSceneVars> SceneVars;
GpuCBuffer<WidgetShaderVertex> Vertices;
public WidgetShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\WidgetVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\WidgetPS.cso");
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
SceneVars = new GpuVarsBuffer<WidgetShaderSceneVars>(device);
Vertices = new GpuCBuffer<WidgetShaderVertex>(device, 150); //should be more than needed....
}
public void Dispose()
{
Vertices.Dispose();
SceneVars.Dispose();
ps.Dispose();
vs.Dispose();
}
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(vs);
context.PixelShader.Set(ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
{
context.InputAssembler.InputLayout = null;
context.InputAssembler.SetIndexBuffer(null, SharpDX.DXGI.Format.Unknown, 0);
return true;
}
public override void SetSceneVars(DeviceContext context, Camera camera, Shadowmap shadowmap, ShaderGlobalLights lights)
{
SceneVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
SceneVars.Update(context);
SceneVars.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.VertexShader.Set(null);
context.PixelShader.Set(null);
}
public void DrawDefaultWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size)
{
SetShader(context);
SetInputLayout(context, VertexType.Default);
SceneVars.Vars.Mode = 0; //vertices mode
SceneVars.Vars.CamRel = camrel;
SetSceneVars(context, cam, null, null);
Vector3 xdir = ori.Multiply(Vector3.UnitX);
Vector3 ydir = ori.Multiply(Vector3.UnitY);
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
Color4 xcolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
Color4 ycolour = new Color4(0.8f, 0.0f, 0.0f, 1.0f);
Color4 zcolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
Vector3[] axes = { xdir, ydir, zdir };
Vector3[] sides = { ydir, xdir, xdir };
Color4[] colours = { xcolour, ycolour, zcolour };
float linestart = 0.0f * size;
float lineend = 1.0f * size;
float arrowstart = 0.9f * size;
float arrowend = 1.0f * size;
float arrowrad = 0.05f * size;
//draw lines...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
WidgetAxis sa = (WidgetAxis)(1 << i);
Color4 axcol = colours[i];
//main axis lines
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
//arrow heads
Vector3 astart = axes[i] * arrowstart;
Vector3 aend = axes[i] * arrowend;
Vector3 aside = sides[i] * arrowrad;
Vertices.Add(new WidgetShaderVertex(aend, axcol));
Vertices.Add(new WidgetShaderVertex(astart + aside, axcol));
Vertices.Add(new WidgetShaderVertex(aend, axcol));
Vertices.Add(new WidgetShaderVertex(astart - aside, axcol));
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.Draw(Vertices.CurrentCount, 0);
UnbindResources(context);
}
public void DrawPositionWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
{
SetShader(context);
SetInputLayout(context, VertexType.Default);
SceneVars.Vars.Mode = 0; //vertices mode
SceneVars.Vars.CamRel = camrel;
SetSceneVars(context, cam, null, null);
Vector3 xdir = ori.Multiply(Vector3.UnitX);
Vector3 ydir = ori.Multiply(Vector3.UnitY);
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
Color4 selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
Color4 selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);
Vector3[] axes = { xdir, ydir, zdir };
Vector3[] sides1 = { ydir, zdir, xdir };
Vector3[] sides2 = { zdir, xdir, ydir };
WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
Color4[] colours = { xcolour, ycolour, zcolour };
Color4[] coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
for (int i = 0; i < 3; i++) coloursdark[i].Alpha = 1.0f;
float linestart = 0.2f * size;
float lineend = 1.0f * size;
float sideval = 0.4f * size;
float arrowstart = 1.0f * size;
float arrowend = 1.33f * size;
float arrowrad = 0.06f * size;
float hexx = 0.5f;
float hexy = 0.86602540378443864676372317075294f; //sqrt(0.75)
Vector2[] arrowv =
{
new Vector2(-1, 0) * arrowrad,
new Vector2(-hexx, hexy) * arrowrad,
new Vector2(hexx, hexy) * arrowrad,
new Vector2(1, 0) * arrowrad,
new Vector2(hexx, -hexy) * arrowrad,
new Vector2(-hexx, -hexy) * arrowrad,
new Vector2(-1, 0) * arrowrad
};
//draw lines...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
WidgetAxis sa = (WidgetAxis)(1 << i);
bool axsel = ((selax & sa) > 0);
Color4 axcol = axsel ? selaxcol : colours[i];
//axis side square lines
Vector3 ax = axes[i] * sideval;
Vector3 s1 = sides1[i] * sideval;
Vector3 s2 = sides2[i] * sideval;
Color4 sc1 = (axsel && ((selax & sideax1[i]) > 0)) ? selaxcol : colours[i];
Color4 sc2 = (axsel && ((selax & sideax2[i]) > 0)) ? selaxcol : colours[i];
Vertices.Add(new WidgetShaderVertex(ax, sc1));
Vertices.Add(new WidgetShaderVertex(ax + s1, sc1));
Vertices.Add(new WidgetShaderVertex(ax, sc2));
Vertices.Add(new WidgetShaderVertex(ax + s2, sc2));
//main axis lines - draw after side lines to be on top
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.Draw(Vertices.CurrentCount, 0);
//draw triangles...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
//axis arrows - kind of inefficient, but meh
Vector3 aend = axes[i] * arrowend;
Vector3 astart = axes[i] * arrowstart;
for (int n = 0; n < 6; n++)
{
Vector2 a1 = arrowv[n];
Vector2 a2 = arrowv[n + 1];
Vector3 ap1 = astart + sides1[i] * a1.Y + sides2[i] * a1.X;
Vector3 ap2 = astart + sides1[i] * a2.Y + sides2[i] * a2.X;
Vertices.Add(new WidgetShaderVertex(aend, colours[i]));
Vertices.Add(new WidgetShaderVertex(ap1, colours[i]));
Vertices.Add(new WidgetShaderVertex(ap2, colours[i]));
Vertices.Add(new WidgetShaderVertex(astart, coloursdark[i]));
Vertices.Add(new WidgetShaderVertex(ap2, coloursdark[i]));
Vertices.Add(new WidgetShaderVertex(ap1, coloursdark[i]));
}
//selection planes
WidgetAxis sa = (WidgetAxis)(1 << i);
if (((selax & sa) > 0))
{
Vector3 ax = axes[i] * sideval;
for (int n = i + 1; n < 3; n++)
{
WidgetAxis tsa = (WidgetAxis)(1 << n);
if (((selax & tsa) > 0))
{
Vector3 tax = axes[n] * sideval;
Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
Vertices.Add(new WidgetShaderVertex(ax, selplcol));
Vertices.Add(new WidgetShaderVertex(tax, selplcol));
Vertices.Add(new WidgetShaderVertex(tax + ax, selplcol));
Vertices.Add(new WidgetShaderVertex(tax, selplcol));
Vertices.Add(new WidgetShaderVertex(ax, selplcol));
}
}
}
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
context.Draw(Vertices.CurrentCount, 0);
UnbindResources(context);
}
public void DrawRotationWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax, WidgetAxis drawax)
{
SetShader(context);
SetInputLayout(context, VertexType.Default);
SceneVars.Vars.Mode = 0; //vertices mode
SceneVars.Vars.CamRel = camrel;
SetSceneVars(context, cam, null, null);
Vector3 xdir = ori.Multiply(Vector3.UnitX);
Vector3 ydir = ori.Multiply(Vector3.UnitY);
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
Color4 icolour = new Color4(0.5f, 0.5f, 0.5f, 1.0f);
Color4 ocolour = new Color4(0.7f, 0.7f, 0.7f, 1.0f);
Color4 scolour = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
Vector3[] axes = { xdir, ydir, zdir };
Vector3[] sides = { ydir, xdir, xdir };
Color4[] colours = { xcolour, ycolour, zcolour };
float linestart = 0.0f * size;
float lineend = 0.3f * size;
float ocircsize = 1.0f * size;
float icircsize = 0.75f * size;
//draw lines...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
WidgetAxis sa = (WidgetAxis)(1 << i);
bool axsel = ((selax & sa) > 0);
Color4 axcol = axsel ? colours[i] : icolour;
//main axis lines
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.Draw(Vertices.CurrentCount, 0);
//linestrip for arcs and circles
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineStrip;
Vector3 sdir = Vector3.Normalize(camrel);
//if (cam.IsMapView || cam.IsOrthographic)
//{
// sdir = cam.ViewDirection;
//}
float ad1 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitY));
float ad2 = Math.Abs(Vector3.Dot(sdir, Vector3.UnitZ));
Vector3 ax1 = Vector3.Normalize(Vector3.Cross(sdir, (ad1 > ad2) ? Vector3.UnitY : Vector3.UnitZ));
Vector3 ax2 = Vector3.Normalize(Vector3.Cross(sdir, ax1));
//drawing circles
int segcount = 40;
int vertcount = segcount + 1;
SceneVars.Vars.Mode = 1; //arc mode
SceneVars.Vars.SegScale = ((float)Math.PI) * 2.0f / segcount; //arc angle / number of segments
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
SceneVars.Vars.Axis1 = ax1; //axis 1 of arc
SceneVars.Vars.Axis2 = ax2; //axis 2 of arc
SceneVars.Vars.CullBack = 0; //culls pixels behind 0,0,0
//outer circle
if (drawax == WidgetAxis.XYZ)
{
SceneVars.Vars.Size = ocircsize; //world units
SceneVars.Vars.Colour = (selax == WidgetAxis.XYZ) ? scolour : ocolour; //colour for arc
SetSceneVars(context, cam, null, null);
context.Draw(vertcount, 0);
}
//inner circle
SceneVars.Vars.Size = icircsize; //world units
SceneVars.Vars.Colour = icolour; //colour for arc
SetSceneVars(context, cam, null, null);
context.Draw(vertcount, 0);
//drawing arcs - culling done in PS
SceneVars.Vars.Size = icircsize; //world units
SceneVars.Vars.CullBack = 1; //culls pixels behind 0,0,0
if ((drawax & WidgetAxis.X) != 0)
{
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
SceneVars.Vars.Axis1 = ydir; //axis 1 of arc
SceneVars.Vars.Axis2 = zdir; //axis 2 of arc
SceneVars.Vars.Colour = (selax == WidgetAxis.X) ? scolour : xcolour; //colour for arc
SetSceneVars(context, cam, null, null);
context.Draw(vertcount, 0);
}
if ((drawax & WidgetAxis.Y) != 0)
{
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
SceneVars.Vars.Axis1 = xdir; //axis 1 of arc
SceneVars.Vars.Axis2 = zdir; //axis 2 of arc
SceneVars.Vars.Colour = (selax == WidgetAxis.Y) ? scolour : ycolour; //colour for arc
SetSceneVars(context, cam, null, null);
context.Draw(vertcount, 0);
}
if ((drawax & WidgetAxis.Z) != 0)
{
SceneVars.Vars.SegOffset = 0.0f; //angle offset of arc
SceneVars.Vars.Axis1 = xdir; //axis 1 of arc
SceneVars.Vars.Axis2 = ydir; //axis 2 of arc
SceneVars.Vars.Colour = (selax == WidgetAxis.Z) ? scolour : zcolour; //colour for arc
SetSceneVars(context, cam, null, null);
context.Draw(vertcount, 0);
}
UnbindResources(context);
}
public void DrawScaleWidget(DeviceContext context, Camera cam, Vector3 camrel, Quaternion ori, float size, WidgetAxis selax)
{
SetShader(context);
SetInputLayout(context, VertexType.Default);
SceneVars.Vars.Mode = 0; //vertices mode
SceneVars.Vars.CamRel = camrel;
SetSceneVars(context, cam, null, null);
Vector3 xdir = ori.Multiply(Vector3.UnitX);
Vector3 ydir = ori.Multiply(Vector3.UnitY);
Vector3 zdir = ori.Multiply(Vector3.UnitZ);
Color4 xcolour = new Color4(1.0f, 0.0f, 0.0f, 1.0f);
Color4 ycolour = new Color4(0.0f, 1.0f, 0.0f, 1.0f);
Color4 zcolour = new Color4(0.0f, 0.0f, 1.0f, 1.0f);
Color4 selaxcol = new Color4(1.0f, 1.0f, 0.0f, 1.0f);
Color4 selplcol = new Color4(1.0f, 1.0f, 0.0f, 0.5f);
Vector3[] axes = { xdir, ydir, zdir };
Vector3[] sides1 = { ydir, zdir, xdir };
Vector3[] sides2 = { zdir, xdir, ydir };
WidgetAxis[] sideax1 = { WidgetAxis.Y, WidgetAxis.Z, WidgetAxis.X };
WidgetAxis[] sideax2 = { WidgetAxis.Z, WidgetAxis.X, WidgetAxis.Y };
Color4[] colours = { xcolour, ycolour, zcolour };
Color4[] coloursn = { ycolour, zcolour, xcolour };
Color4[] coloursdark = { xcolour * 0.5f, ycolour * 0.5f, zcolour * 0.5f };
for (int i = 0; i < 3; i++) coloursdark[i].Alpha = 1.0f;
float linestart = 0.0f * size;
float lineend = 1.33f * size;
float innertri = 0.7f * size;
float outertri = 1.0f * size;
float cubestart = 1.28f * size;
float cubeend = 1.33f * size;
float cubesize = 0.025f * size;
//draw lines...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
WidgetAxis sa = (WidgetAxis)(1 << i);
bool axsel = ((selax & sa) > 0);
Color4 axcol = axsel ? selaxcol : colours[i];
WidgetAxis triaxn = sideax1[i];
bool trisel = axsel && ((selax & triaxn) > 0);
Color4 tricol = trisel ? selaxcol : colours[i];
Color4 trincol = trisel ? selaxcol : coloursn[i];
Vector3 inner1 = axes[i] * innertri;
Vector3 inner2 = sides1[i] * innertri;
Vector3 innera = (inner1 + inner2) * 0.5f;
Vector3 outer1 = axes[i] * outertri;
Vector3 outer2 = sides1[i] * outertri;
Vector3 outera = (outer1 + outer2) * 0.5f;
//triangle axis lines
Vertices.Add(new WidgetShaderVertex(inner1, tricol));
Vertices.Add(new WidgetShaderVertex(innera, tricol));
Vertices.Add(new WidgetShaderVertex(innera, trincol));
Vertices.Add(new WidgetShaderVertex(inner2, trincol));
Vertices.Add(new WidgetShaderVertex(outer1, tricol));
Vertices.Add(new WidgetShaderVertex(outera, tricol));
Vertices.Add(new WidgetShaderVertex(outera, trincol));
Vertices.Add(new WidgetShaderVertex(outer2, trincol));
//main axis lines - draw after side lines to be on top
Vertices.Add(new WidgetShaderVertex(axes[i] * linestart, axcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * lineend, axcol));
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
context.Draw(Vertices.CurrentCount, 0);
//draw triangles...
Vertices.Clear();
for (int i = 0; i < 3; i++)
{
//axis end cubes - kind of inefficient, but meh
Vector3 cend = axes[i] * cubeend;
Vector3 cstart = axes[i] * cubestart;
Vector3 cside1 = sides1[i] * cubesize;
Vector3 cside2 = sides2[i] * cubesize;
Vector3 cv1 = cstart + cside1 - cside2;
Vector3 cv2 = cstart - cside1 - cside2;
Vector3 cv3 = cend + cside1 - cside2;
Vector3 cv4 = cend - cside1 - cside2;
Vector3 cv5 = cstart + cside1 + cside2;
Vector3 cv6 = cstart - cside1 + cside2;
Vector3 cv7 = cend + cside1 + cside2;
Vector3 cv8 = cend - cside1 + cside2;
Color4 col = colours[i];
Color4 cold = coloursdark[i];
Vertices.Add(new WidgetShaderVertex(cv1, cold));
Vertices.Add(new WidgetShaderVertex(cv2, cold));
Vertices.Add(new WidgetShaderVertex(cv5, cold));
Vertices.Add(new WidgetShaderVertex(cv5, cold));
Vertices.Add(new WidgetShaderVertex(cv2, cold));
Vertices.Add(new WidgetShaderVertex(cv6, cold));
Vertices.Add(new WidgetShaderVertex(cv3, col));
Vertices.Add(new WidgetShaderVertex(cv4, col));
Vertices.Add(new WidgetShaderVertex(cv7, col));
Vertices.Add(new WidgetShaderVertex(cv7, col));
Vertices.Add(new WidgetShaderVertex(cv4, col));
Vertices.Add(new WidgetShaderVertex(cv8, col));
Vertices.Add(new WidgetShaderVertex(cv1, col));
Vertices.Add(new WidgetShaderVertex(cv2, col));
Vertices.Add(new WidgetShaderVertex(cv3, col));
Vertices.Add(new WidgetShaderVertex(cv3, col));
Vertices.Add(new WidgetShaderVertex(cv2, col));
Vertices.Add(new WidgetShaderVertex(cv4, col));
Vertices.Add(new WidgetShaderVertex(cv5, col));
Vertices.Add(new WidgetShaderVertex(cv6, col));
Vertices.Add(new WidgetShaderVertex(cv7, col));
Vertices.Add(new WidgetShaderVertex(cv7, col));
Vertices.Add(new WidgetShaderVertex(cv6, col));
Vertices.Add(new WidgetShaderVertex(cv8, col));
Vertices.Add(new WidgetShaderVertex(cv1, col));
Vertices.Add(new WidgetShaderVertex(cv5, col));
Vertices.Add(new WidgetShaderVertex(cv3, col));
Vertices.Add(new WidgetShaderVertex(cv3, col));
Vertices.Add(new WidgetShaderVertex(cv5, col));
Vertices.Add(new WidgetShaderVertex(cv7, col));
Vertices.Add(new WidgetShaderVertex(cv2, col));
Vertices.Add(new WidgetShaderVertex(cv6, col));
Vertices.Add(new WidgetShaderVertex(cv4, col));
Vertices.Add(new WidgetShaderVertex(cv4, col));
Vertices.Add(new WidgetShaderVertex(cv6, col));
Vertices.Add(new WidgetShaderVertex(cv8, col));
//selection triangles
if (selax == WidgetAxis.XYZ)
{
//all axes - just draw inner triangle
Vertices.Add(new WidgetShaderVertex(Vector3.Zero, selplcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
}
else
{
WidgetAxis sa = (WidgetAxis)(1 << i);
WidgetAxis na = sideax1[i];
if (((selax & sa) > 0) && ((selax & na) > 0))
{
Vertices.Add(new WidgetShaderVertex(axes[i] * innertri, selplcol));
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
Vertices.Add(new WidgetShaderVertex(axes[i] * outertri, selplcol));
Vertices.Add(new WidgetShaderVertex(sides1[i] * innertri, selplcol));
Vertices.Add(new WidgetShaderVertex(sides1[i] * outertri, selplcol));
}
}
}
Vertices.Update(context);
Vertices.SetVSResource(context, 0);
context.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;
context.Draw(Vertices.CurrentCount, 0);
UnbindResources(context);
}
}
public struct WidgetShaderVertex
{
public Vector4 Position;
public Color4 Colour;
public WidgetShaderVertex(Vector3 p, Color4 c)
{
Position = new Vector4(p, 0.0f);
Colour = c;
}
}
}