2017-09-21 18:33:05 +08:00
|
|
|
|
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;
|
2019-10-31 14:11:12 +08:00
|
|
|
|
public ShaderParamNames RenderTextureSampler = ShaderParamNames.DiffuseSampler;
|
2017-09-21 18:33:05 +08:00
|
|
|
|
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);
|
|
|
|
|
|
2019-11-11 19:28:37 +08:00
|
|
|
|
layouts.Add(VertexType.PT, new InputLayout(device, vsptbytes, VertexTypeGTAV.GetLayout(VertexType.PT)));
|
|
|
|
|
layouts.Add(VertexType.PCT, new InputLayout(device, vspctbytes, VertexTypeGTAV.GetLayout(VertexType.PCT)));
|
|
|
|
|
layouts.Add(VertexType.Default, new InputLayout(device, vspnctbytes, VertexTypeGTAV.GetLayout(VertexType.Default)));
|
|
|
|
|
layouts.Add(VertexType.DefaultEx, new InputLayout(device, vspnctxbytes, VertexTypeGTAV.GetLayout(VertexType.DefaultEx)));
|
2017-09-21 18:33:05 +08:00
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2019-10-31 14:11:12 +08:00
|
|
|
|
case ShaderParamNames.DiffuseSampler:
|
2017-09-21 18:33:05 +08:00
|
|
|
|
texture = itex;
|
|
|
|
|
break;
|
2019-10-31 14:11:12 +08:00
|
|
|
|
case ShaderParamNames.BumpSampler:
|
2017-09-21 18:33:05 +08:00
|
|
|
|
bumptex = itex;
|
|
|
|
|
break;
|
2019-10-31 14:11:12 +08:00
|
|
|
|
case ShaderParamNames.FlowSampler:
|
2017-09-21 18:33:05 +08:00
|
|
|
|
flowtex = itex;
|
|
|
|
|
break;
|
2019-10-31 14:11:12 +08:00
|
|
|
|
case ShaderParamNames.FoamSampler:
|
2017-09-21 18:33:05 +08:00
|
|
|
|
foamtex = itex;
|
|
|
|
|
break;
|
2019-10-31 14:11:12 +08:00
|
|
|
|
case ShaderParamNames.FogSampler:
|
2017-09-21 18:33:05 +08:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|