mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-18 14:19:50 +08:00
R26_dev8 - First public commit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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...
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user