211 lines
5.9 KiB
C#
211 lines
5.9 KiB
C#
using Kav.Data;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
namespace Kav
|
|
{
|
|
public class DiffuseLitSpriteEffect : Effect
|
|
{
|
|
EffectParameter ambientColorParam;
|
|
|
|
EffectParameter directionalLightDirectionParam;
|
|
EffectParameter directionalLightColorParam;
|
|
|
|
EffectParameter uvOffsetAndDimensionsParam;
|
|
|
|
EffectParameter worldParam;
|
|
EffectParameter worldViewProjectionParam;
|
|
EffectParameter worldInverseTransposeParam;
|
|
|
|
EffectParameter shaderIndexParam;
|
|
|
|
Texture2D texture;
|
|
Texture2D normal;
|
|
|
|
bool normalMapEnabled = false;
|
|
|
|
Vector3 ambientColor;
|
|
|
|
Vector3 directionalLightDirection;
|
|
Vector3 directionalLightColor;
|
|
|
|
Matrix world = Matrix.Identity;
|
|
Matrix view = Matrix.Identity;
|
|
Matrix projection = Matrix.Identity;
|
|
|
|
Vector2 uvOffset;
|
|
Vector2 subTextureDimensions;
|
|
|
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
|
|
|
public bool NormalMapEnabled
|
|
{
|
|
get { return normalMapEnabled; }
|
|
set
|
|
{
|
|
if (normalMapEnabled != value)
|
|
{
|
|
normalMapEnabled = value;
|
|
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Matrix World
|
|
{
|
|
get { return world; }
|
|
set
|
|
{
|
|
world = value;
|
|
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj;
|
|
}
|
|
}
|
|
|
|
public Matrix View
|
|
{
|
|
get { return view; }
|
|
set
|
|
{
|
|
view = value;
|
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition;
|
|
}
|
|
}
|
|
|
|
public Matrix Projection
|
|
{
|
|
get { return projection; }
|
|
set
|
|
{
|
|
projection = value;
|
|
dirtyFlags |= EffectDirtyFlags.WorldViewProj;
|
|
}
|
|
}
|
|
|
|
public int MaxPointLights { get; } = 8;
|
|
|
|
public Vector3 AmbientColor
|
|
{
|
|
get { return ambientColor; }
|
|
set
|
|
{
|
|
ambientColor = value;
|
|
ambientColorParam.SetValue(ambientColor);
|
|
}
|
|
}
|
|
|
|
public PointLightCollection PointLights { get; private set; }
|
|
|
|
public Vector3 DirectionalLightDirection
|
|
{
|
|
get { return directionalLightDirection; }
|
|
set
|
|
{
|
|
directionalLightDirection = value;
|
|
directionalLightDirectionParam.SetValue(directionalLightDirection);
|
|
}
|
|
}
|
|
|
|
public Vector3 DirectionalLightColor
|
|
{
|
|
get { return directionalLightColor; }
|
|
set
|
|
{
|
|
directionalLightColor = value;
|
|
directionalLightColorParam.SetValue(directionalLightColor);
|
|
}
|
|
}
|
|
|
|
public Vector2 UVOffset
|
|
{
|
|
get { return uvOffset; }
|
|
set
|
|
{
|
|
uvOffset = value;
|
|
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
|
}
|
|
}
|
|
|
|
public Vector2 SubTextureDimensions
|
|
{
|
|
get { return subTextureDimensions; }
|
|
set
|
|
{
|
|
subTextureDimensions = value;
|
|
dirtyFlags |= EffectDirtyFlags.UVOrDimensions;
|
|
}
|
|
}
|
|
|
|
public DiffuseLitSpriteEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.DiffuseLitSpriteEffect)
|
|
{
|
|
CacheEffectParameters();
|
|
|
|
PointLights = new PointLightCollection(
|
|
Parameters["PointLightPositions"],
|
|
Parameters["PointLightColors"],
|
|
MaxPointLights
|
|
);
|
|
}
|
|
|
|
protected override void OnApply()
|
|
{
|
|
if ((dirtyFlags & EffectDirtyFlags.World) != 0)
|
|
{
|
|
worldParam.SetValue(world);
|
|
|
|
Matrix.Invert(ref world, out Matrix worldInverse);
|
|
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
|
|
worldInverseTransposeParam.SetValue(worldInverseTranspose);
|
|
|
|
dirtyFlags &= ~EffectDirtyFlags.World;
|
|
}
|
|
|
|
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
|
|
{
|
|
Matrix.Multiply(ref world, ref view, out Matrix worldView);
|
|
Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj);
|
|
worldViewProjectionParam.SetValue(worldViewProj);
|
|
|
|
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
|
|
}
|
|
|
|
if ((dirtyFlags & EffectDirtyFlags.UVOrDimensions) != 0)
|
|
{
|
|
uvOffsetAndDimensionsParam.SetValue(new Vector4(
|
|
UVOffset.X, UVOffset.Y,
|
|
SubTextureDimensions.X, SubTextureDimensions.Y
|
|
));
|
|
|
|
dirtyFlags &= ~EffectDirtyFlags.UVOrDimensions;
|
|
}
|
|
|
|
if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
|
|
{
|
|
int shaderIndex = 0;
|
|
|
|
if (normalMapEnabled)
|
|
{
|
|
shaderIndex = 1;
|
|
}
|
|
|
|
shaderIndexParam.SetValue(shaderIndex);
|
|
}
|
|
}
|
|
|
|
private void CacheEffectParameters()
|
|
{
|
|
worldParam = Parameters["World"];
|
|
worldViewProjectionParam = Parameters["WorldViewProjection"];
|
|
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
|
|
|
|
ambientColorParam = Parameters["AmbientColor"];
|
|
|
|
directionalLightDirectionParam = Parameters["DirectionalLightDirection"];
|
|
directionalLightColorParam = Parameters["DirectionalLightColor"];
|
|
|
|
uvOffsetAndDimensionsParam = Parameters["UVOffsetAndDimensions"];
|
|
|
|
shaderIndexParam = Parameters["ShaderIndex"];
|
|
}
|
|
}
|
|
}
|