Commit Description:
Fix issue with simulation....
Commit Description:
Fix issue with simulation. Previously, if there was more than one tick being advanced at once, it would overshoot how many ticks it covered. So if it was covering 5 ticks and each tick happens every 100 units, rather than recording that it had simulated through t= 500, it would increase the cumulative time for each tick, recording that it had simulated through t=2500. Add error message, too.
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Effect/Effect.cs
1490 lines | 49.1 KiB | text/x-csharp | CSharpLexer
#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
* Copyright 2009-2022 Ethan Lee and the MonoGame Team
*
* Released under the Microsoft Public License.
* See LICENSE for details.
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
#endregion
namespace Microsoft.Xna.Framework.Graphics
{
public class Effect : GraphicsResource
{
#region Public Properties
private EffectTechnique INTERNAL_currentTechnique;
public EffectTechnique CurrentTechnique
{
get
{
return INTERNAL_currentTechnique;
}
set
{
FNA3D.FNA3D_SetEffectTechnique(
GraphicsDevice.GLDevice,
glEffect,
value.TechniquePointer
);
INTERNAL_currentTechnique = value;
}
}
public EffectParameterCollection Parameters
{
get;
private set;
}
public EffectTechniqueCollection Techniques
{
get;
private set;
}
#endregion
#region Internal FNA3D Variables
internal IntPtr glEffect;
#endregion
#region Private Variables
private Dictionary<IntPtr, EffectParameter> samplerMap = new Dictionary<IntPtr, EffectParameter>(new IntPtrBoxlessComparer());
private class IntPtrBoxlessComparer : IEqualityComparer<IntPtr>
{
public bool Equals(IntPtr x, IntPtr y)
{
return x == y;
}
public int GetHashCode(IntPtr obj)
{
return obj.GetHashCode();
}
}
private IntPtr stateChangesPtr;
#endregion
#region Private Static Variables
private static readonly EffectParameterType[] XNAType = new EffectParameterType[]
{
EffectParameterType.Void, // MOJOSHADER_SYMTYPE_VOID
EffectParameterType.Bool, // MOJOSHADER_SYMTYPE_BOOL
EffectParameterType.Int32, // MOJOSHADER_SYMTYPE_INT
EffectParameterType.Single, // MOJOSHADER_SYMTYPE_FLOAT
EffectParameterType.String, // MOJOSHADER_SYMTYPE_STRING
EffectParameterType.Texture, // MOJOSHADER_SYMTYPE_TEXTURE
EffectParameterType.Texture1D, // MOJOSHADER_SYMTYPE_TEXTURE1D
EffectParameterType.Texture2D, // MOJOSHADER_SYMTYPE_TEXTURE2D
EffectParameterType.Texture3D, // MOJOSHADER_SYMTYPE_TEXTURE3D
EffectParameterType.TextureCube // MOJOSHADER_SYMTYPE_TEXTURECUBE
};
private static readonly EffectParameterClass[] XNAClass = new EffectParameterClass[]
{
EffectParameterClass.Scalar, // MOJOSHADER_SYMCLASS_SCALAR
EffectParameterClass.Vector, // MOJOSHADER_SYMCLASS_VECTOR
EffectParameterClass.Matrix, // MOJOSHADER_SYMCLASS_MATRIX_ROWS
EffectParameterClass.Matrix, // MOJOSHADER_SYMCLASS_MATRIX_COLUMNS
EffectParameterClass.Object, // MOJOSHADER_SYMCLASS_OBJECT
EffectParameterClass.Struct // MOJOSHADER_SYMCLASS_STRUCT
};
private static readonly Blend[] XNABlend = new Blend[]
{
(Blend) (-1), // NOPE
Blend.Zero, // MOJOSHADER_BLEND_ZERO
Blend.One, // MOJOSHADER_BLEND_ONE
Blend.SourceColor, // MOJOSHADER_BLEND_SRCCOLOR
Blend.InverseSourceColor, // MOJOSHADER_BLEND_INVSRCCOLOR
Blend.SourceAlpha, // MOJOSHADER_BLEND_SRCALPHA
Blend.InverseSourceAlpha, // MOJOSHADER_BLEND_INVSRCALPHA
Blend.DestinationAlpha, // MOJOSHADER_BLEND_DESTALPHA
Blend.InverseDestinationAlpha, // MOJOSHADER_BLEND_INVDESTALPHA
Blend.DestinationColor, // MOJOSHADER_BLEND_DESTCOLOR
Blend.InverseDestinationColor, // MOJOSHADER_BLEND_INVDESTCOLOR
Blend.SourceAlphaSaturation, // MOJOSHADER_BLEND_SRCALPHASAT
(Blend) (-1), // NOPE
(Blend) (-1), // NOPE
Blend.BlendFactor, // MOJOSHADER_BLEND_BLENDFACTOR
Blend.InverseBlendFactor // MOJOSHADER_BLEND_INVBLENDFACTOR
};
private static readonly BlendFunction[] XNABlendOp = new BlendFunction[]
{
(BlendFunction) (-1), // NOPE
BlendFunction.Add, // MOJOSHADER_BLENDOP_ADD
BlendFunction.Subtract, // MOJOSHADER_BLENDOP_SUBTRACT
BlendFunction.ReverseSubtract, // MOJOSHADER_BLENDOP_REVSUBTRACT
BlendFunction.Min, // MOJOSHADER_BLENDOP_MIN
BlendFunction.Max // MOJOSHADER_BLENDOP_MAX
};
private static readonly CompareFunction[] XNACompare = new CompareFunction[]
{
(CompareFunction) (-1), // NOPE
CompareFunction.Never, // MOJOSHADER_CMP_NEVER
CompareFunction.Less, // MOJOSHADER_CMP_LESS
CompareFunction.Equal, // MOJOSHADER_CMP_EQUAL
CompareFunction.LessEqual, // MOJOSHADER_CMP_LESSEQUAL
CompareFunction.Greater, // MOJOSHADER_CMP_GREATER
CompareFunction.NotEqual, // MOJOSHADER_CMP_NOTEQUAL
CompareFunction.GreaterEqual, // MOJOSHADER_CMP_GREATEREQUAL
CompareFunction.Always // MOJOSHADER_CMP_ALWAYS
};
private static readonly StencilOperation[] XNAStencilOp = new StencilOperation[]
{
(StencilOperation) (-1), // NOPE
StencilOperation.Keep, // MOJOSHADER_STENCILOP_KEEP
StencilOperation.Zero, // MOJOSHADER_STENCILOP_ZERO
StencilOperation.Replace, // MOJOSHADER_STENCILOP_REPLACE
StencilOperation.IncrementSaturation, // MOJOSHADER_STENCILOP_INCRSAT
StencilOperation.DecrementSaturation, // MOJOSHADER_STENCILOP_DECRSAT
StencilOperation.Invert, // MOJOSHADER_STENCILOP_INVERT
StencilOperation.Increment, // MOJOSHADER_STENCILOP_INCR
StencilOperation.Decrement // MOJOSHADER_STENCILOP_DECR
};
private static readonly TextureAddressMode[] XNAAddress = new TextureAddressMode[]
{
(TextureAddressMode) (-1), // NOPE
TextureAddressMode.Wrap, // MOJOSHADER_TADDRESS_WRAP
TextureAddressMode.Mirror, // MOJOSHADER_TADDRESS_MIRROR
TextureAddressMode.Clamp // MOJOSHADER_TADDRESS_CLAMP
};
private static readonly MOJOSHADER_textureFilterType[] XNAMag =
new MOJOSHADER_textureFilterType[]
{
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.Linear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.Point
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC, // TextureFilter.Anisotropic
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.LinearMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.PointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.MinLinearMagPointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.MinLinearMagPointMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.MinPointMagLinearMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR // TextureFilter.MinPointMagLinearMipPoint
};
private static readonly MOJOSHADER_textureFilterType[] XNAMin =
new MOJOSHADER_textureFilterType[]
{
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.Linear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.Point
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC, // TextureFilter.Anisotropic
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.LinearMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.PointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.MinLinearMagPointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.MinLinearMagPointMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.MinPointMagLinearMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT // TextureFilter.MinPointMagLinearMipPoint
};
private static readonly MOJOSHADER_textureFilterType[] XNAMip =
new MOJOSHADER_textureFilterType[]
{
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.Linear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.Point
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC, // TextureFilter.Anisotropic
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.LinearMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.PointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.MinLinearMagPointMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT, // TextureFilter.MinLinearMagPointMipPoint
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR, // TextureFilter.MinPointMagLinearMipLinear
MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT // TextureFilter.MinPointMagLinearMipPoint
};
#endregion
#region Public Constructor
public Effect(GraphicsDevice graphicsDevice, byte[] effectCode)
{
GraphicsDevice = graphicsDevice;
// Send the blob to the GLDevice to be parsed/compiled
IntPtr effectData;
FNA3D.FNA3D_CreateEffect(
graphicsDevice.GLDevice,
effectCode,
effectCode.Length,
out glEffect,
out effectData
);
// This is where it gets ugly...
INTERNAL_parseEffectStruct(effectData);
// The default technique is the first technique.
CurrentTechnique = Techniques[0];
// Use native memory for changes, .NET loves moving this around
unsafe
{
stateChangesPtr = Marshal.AllocHGlobal(
sizeof(MOJOSHADER_effectStateChanges)
);
MOJOSHADER_effectStateChanges *stateChanges =
(MOJOSHADER_effectStateChanges*) stateChangesPtr;
stateChanges->render_state_change_count = 0;
stateChanges->sampler_state_change_count = 0;
stateChanges->vertex_sampler_state_change_count = 0;
}
}
#endregion
#region Protected Constructor
protected Effect(Effect cloneSource)
{
GraphicsDevice = cloneSource.GraphicsDevice;
// Send the parsed data to be cloned and recompiled by MojoShader
IntPtr effectData;
FNA3D.FNA3D_CloneEffect(
GraphicsDevice.GLDevice,
cloneSource.glEffect,
out glEffect,
out effectData
);
// Double the ugly, double the fun!
INTERNAL_parseEffectStruct(effectData);
// Copy texture parameters, if applicable
for (int i = 0; i < cloneSource.Parameters.Count; i += 1)
{
Parameters[i].texture = cloneSource.Parameters[i].texture;
}
// The default technique is whatever the current technique was.
for (int i = 0; i < cloneSource.Techniques.Count; i += 1)
{
if (cloneSource.Techniques[i] == cloneSource.CurrentTechnique)
{
CurrentTechnique = Techniques[i];
}
}
// Use native memory for changes, .NET loves moving this around
unsafe
{
stateChangesPtr = Marshal.AllocHGlobal(
sizeof(MOJOSHADER_effectStateChanges)
);
MOJOSHADER_effectStateChanges *stateChanges =
(MOJOSHADER_effectStateChanges*) stateChangesPtr;
stateChanges->render_state_change_count = 0;
stateChanges->sampler_state_change_count = 0;
stateChanges->vertex_sampler_state_change_count = 0;
}
}
#endregion
#region Public Methods
public virtual Effect Clone()
{
return new Effect(this);
}
#endregion
#region Protected Methods
protected override void Dispose(bool disposing)
{
if (!IsDisposed)
{
if (glEffect != IntPtr.Zero)
{
FNA3D.FNA3D_AddDisposeEffect(
GraphicsDevice.GLDevice,
glEffect
);
}
if (stateChangesPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(stateChangesPtr);
stateChangesPtr = IntPtr.Zero;
}
}
base.Dispose(disposing);
}
protected internal virtual void OnApply()
{
}
#endregion
#region Internal Methods
internal unsafe void INTERNAL_applyEffect(uint pass)
{
FNA3D.FNA3D_ApplyEffect(
GraphicsDevice.GLDevice,
glEffect,
pass,
stateChangesPtr
);
MOJOSHADER_effectStateChanges *stateChanges =
(MOJOSHADER_effectStateChanges*) stateChangesPtr;
if (stateChanges->render_state_change_count > 0)
{
PipelineCache pipelineCache = GraphicsDevice.PipelineCache;
pipelineCache.BeginApplyBlend();
pipelineCache.BeginApplyDepthStencil();
pipelineCache.BeginApplyRasterizer();
// Used to avoid redundant device state application
bool blendStateChanged = false;
bool depthStencilStateChanged = false;
bool rasterizerStateChanged = false;
MOJOSHADER_effectState* states = (MOJOSHADER_effectState*) stateChanges->render_state_changes;
for (int i = 0; i < stateChanges->render_state_change_count; i += 1)
{
MOJOSHADER_renderStateType type = states[i].type;
if ( type == MOJOSHADER_renderStateType.MOJOSHADER_RS_VERTEXSHADER ||
type == MOJOSHADER_renderStateType.MOJOSHADER_RS_PIXELSHADER )
{
// Skip shader states
continue;
}
if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZENABLE)
{
MOJOSHADER_zBufferType* val = (MOJOSHADER_zBufferType*) states[i].value.values;
pipelineCache.DepthBufferEnable =
(*val == MOJOSHADER_zBufferType.MOJOSHADER_ZB_TRUE);
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_FILLMODE)
{
MOJOSHADER_fillMode* val = (MOJOSHADER_fillMode*) states[i].value.values;
if (*val == MOJOSHADER_fillMode.MOJOSHADER_FILL_SOLID)
{
pipelineCache.FillMode = FillMode.Solid;
}
else if (*val == MOJOSHADER_fillMode.MOJOSHADER_FILL_WIREFRAME)
{
pipelineCache.FillMode = FillMode.WireFrame;
}
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZWRITEENABLE)
{
int* val = (int*) states[i].value.values;
pipelineCache.DepthBufferWriteEnable = (*val == 1);
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SRCBLEND)
{
MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values;
pipelineCache.ColorSourceBlend = XNABlend[(int) *val];
if (!pipelineCache.SeparateAlphaBlend)
{
pipelineCache.AlphaSourceBlend = XNABlend[(int) *val];
}
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DESTBLEND)
{
MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values;
pipelineCache.ColorDestinationBlend = XNABlend[(int) *val];
if (!pipelineCache.SeparateAlphaBlend)
{
pipelineCache.AlphaDestinationBlend = XNABlend[(int) *val];
}
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CULLMODE)
{
MOJOSHADER_cullMode* val = (MOJOSHADER_cullMode*) states[i].value.values;
if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_NONE)
{
pipelineCache.CullMode = CullMode.None;
}
else if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_CW)
{
pipelineCache.CullMode = CullMode.CullClockwiseFace;
}
else if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_CCW)
{
pipelineCache.CullMode = CullMode.CullCounterClockwiseFace;
}
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZFUNC)
{
MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values;
pipelineCache.DepthBufferFunction = XNACompare[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ALPHABLENDENABLE)
{
// FIXME: Assuming no other blend calls are made in the effect! -flibit
int* val = (int*) states[i].value.values;
if (*val == 0)
{
pipelineCache.ColorSourceBlend = Blend.One;
pipelineCache.ColorDestinationBlend = Blend.Zero;
pipelineCache.AlphaSourceBlend = Blend.One;
pipelineCache.AlphaDestinationBlend = Blend.Zero;
blendStateChanged = true;
}
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILENABLE)
{
int* val = (int*) states[i].value.values;
pipelineCache.StencilEnable = (*val == 1);
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILFAIL)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.StencilFail = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILZFAIL)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.StencilDepthBufferFail = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILPASS)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.StencilPass = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILFUNC)
{
MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values;
pipelineCache.StencilFunction = XNACompare[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILREF)
{
int* val = (int*) states[i].value.values;
pipelineCache.ReferenceStencil = *val;
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILMASK)
{
int* val = (int*) states[i].value.values;
pipelineCache.StencilMask = *val;
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILWRITEMASK)
{
int* val = (int*) states[i].value.values;
pipelineCache.StencilWriteMask = *val;
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_MULTISAMPLEANTIALIAS)
{
int* val = (int*) states[i].value.values;
pipelineCache.MultiSampleAntiAlias = (*val == 1);
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_MULTISAMPLEMASK)
{
int* val = (int*) states[i].value.values;
pipelineCache.MultiSampleMask = *val;
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE)
{
int* val = (int*) states[i].value.values;
pipelineCache.ColorWriteChannels = (ColorWriteChannels) (*val);
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDOP)
{
MOJOSHADER_blendOp* val = (MOJOSHADER_blendOp*) states[i].value.values;
pipelineCache.ColorBlendFunction = XNABlendOp[(int) *val];
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SCISSORTESTENABLE)
{
int* val = (int*) states[i].value.values;
pipelineCache.ScissorTestEnable = (*val == 1);
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SLOPESCALEDEPTHBIAS)
{
float* val = (float*) states[i].value.values;
pipelineCache.SlopeScaleDepthBias = *val;
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_TWOSIDEDSTENCILMODE)
{
int* val = (int*) states[i].value.values;
pipelineCache.TwoSidedStencilMode = (*val == 1);
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILFAIL)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.CCWStencilFail = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILZFAIL)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.CCWStencilDepthBufferFail = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILPASS)
{
MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values;
pipelineCache.CCWStencilPass = XNAStencilOp[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILFUNC)
{
MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values;
pipelineCache.CCWStencilFunction = XNACompare[(int) *val];
depthStencilStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE1)
{
int* val = (int*) states[i].value.values;
pipelineCache.ColorWriteChannels1 = (ColorWriteChannels) (*val);
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE2)
{
int* val = (int*) states[i].value.values;
pipelineCache.ColorWriteChannels2 = (ColorWriteChannels) (*val);
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE3)
{
int* val = (int*) states[i].value.values;
pipelineCache.ColorWriteChannels3 = (ColorWriteChannels) (*val);
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDFACTOR)
{
// FIXME: RGBA? -flibit
int* val = (int*) states[i].value.values;
pipelineCache.BlendFactor = new Color(
(*val >> 24) & 0xFF,
(*val >> 16) & 0xFF,
(*val >> 8) & 0xFF,
*val & 0xFF
);
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DEPTHBIAS)
{
float* val = (float*) states[i].value.values;
pipelineCache.DepthBias = *val;
rasterizerStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SEPARATEALPHABLENDENABLE)
{
int* val = (int*) states[i].value.values;
pipelineCache.SeparateAlphaBlend = (*val == 1);
// FIXME: Do we want to update the state for this...? -flibit
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SRCBLENDALPHA)
{
MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values;
pipelineCache.AlphaSourceBlend = XNABlend[(int) *val];
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DESTBLENDALPHA)
{
MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values;
pipelineCache.AlphaDestinationBlend = XNABlend[(int) *val];
blendStateChanged = true;
}
else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDOPALPHA)
{
MOJOSHADER_blendOp* val = (MOJOSHADER_blendOp*) states[i].value.values;
pipelineCache.AlphaBlendFunction = XNABlendOp[(int) *val];
blendStateChanged = true;
}
else if (type == (MOJOSHADER_renderStateType) 178)
{
/* Apparently this is "SetSampler"? */
}
else
{
throw new NotImplementedException("Unhandled render state! " + type);
}
}
if (blendStateChanged)
{
pipelineCache.EndApplyBlend();
}
if (depthStencilStateChanged)
{
pipelineCache.EndApplyDepthStencil();
}
if (rasterizerStateChanged)
{
pipelineCache.EndApplyRasterizer();
}
}
if (stateChanges->sampler_state_change_count > 0)
{
INTERNAL_updateSamplers(
stateChanges->sampler_state_change_count,
(MOJOSHADER_samplerStateRegister*) stateChanges->sampler_state_changes,
GraphicsDevice.Textures,
GraphicsDevice.SamplerStates
);
}
if (stateChanges->vertex_sampler_state_change_count > 0)
{
INTERNAL_updateSamplers(
stateChanges->vertex_sampler_state_change_count,
(MOJOSHADER_samplerStateRegister*) stateChanges->vertex_sampler_state_changes,
GraphicsDevice.VertexTextures,
GraphicsDevice.VertexSamplerStates
);
}
}
private unsafe void INTERNAL_updateSamplers(
uint changeCount,
MOJOSHADER_samplerStateRegister* registers,
TextureCollection textures,
SamplerStateCollection samplers
) {
for (int i = 0; i < changeCount; i += 1)
{
if (registers[i].sampler_state_count == 0)
{
// Nothing to do
continue;
}
int register = (int) registers[i].sampler_register;
PipelineCache pipelineCache = GraphicsDevice.PipelineCache;
pipelineCache.BeginApplySampler(samplers, register);
// Used to prevent redundant sampler changes
bool samplerChanged = false;
bool filterChanged = false;
// Current sampler filter
TextureFilter filter = pipelineCache.Filter;
MOJOSHADER_textureFilterType magFilter = XNAMag[(int) filter];
MOJOSHADER_textureFilterType minFilter = XNAMin[(int) filter];
MOJOSHADER_textureFilterType mipFilter = XNAMip[(int) filter];
MOJOSHADER_effectSamplerState* states = (MOJOSHADER_effectSamplerState*) registers[i].sampler_states;
for (int j = 0; j < registers[i].sampler_state_count; j += 1)
{
MOJOSHADER_samplerStateType type = states[j].type;
if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_TEXTURE)
{
EffectParameter texParam;
if (samplerMap.TryGetValue(registers[i].sampler_name, out texParam))
{
Texture texture = texParam.texture;
if (texture != null)
{
textures[register] = texture;
}
}
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSU)
{
MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values;
pipelineCache.AddressU = XNAAddress[(int) *val];
samplerChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSV)
{
MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values;
pipelineCache.AddressV = XNAAddress[(int) *val];
samplerChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSW)
{
MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values;
pipelineCache.AddressW = XNAAddress[(int) *val];
samplerChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAGFILTER)
{
MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values;
magFilter = *val;
filterChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MINFILTER)
{
MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values;
minFilter = *val;
filterChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPFILTER)
{
MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values;
mipFilter = *val;
filterChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPMAPLODBIAS)
{
float* val = (float*) states[j].value.values;
pipelineCache.MipMapLODBias = *val;
samplerChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXMIPLEVEL)
{
int* val = (int*) states[j].value.values;
pipelineCache.MaxMipLevel = *val;
samplerChanged = true;
}
else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXANISOTROPY)
{
int* val = (int*) states[j].value.values;
pipelineCache.MaxAnisotropy = *val;
samplerChanged = true;
}
else
{
throw new NotImplementedException("Unhandled sampler state! " + type);
}
}
if (filterChanged)
{
if (magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
{
if (minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
{
if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT )
{
pipelineCache.Filter = TextureFilter.Point;
}
else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
pipelineCache.Filter = TextureFilter.PointMipLinear;
}
else
{
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter);
}
}
else if ( minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT )
{
pipelineCache.Filter = TextureFilter.MinLinearMagPointMipPoint;
}
else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
pipelineCache.Filter = TextureFilter.MinLinearMagPointMipLinear;
}
else
{
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter);
}
}
else
{
throw new NotImplementedException("Unhandled minfilter type! " + minFilter);
}
}
else if ( magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
if (minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT)
{
if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT )
{
pipelineCache.Filter = TextureFilter.MinPointMagLinearMipPoint;
}
else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
pipelineCache.Filter = TextureFilter.MinPointMagLinearMipLinear;
}
else
{
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter);
}
}
else if ( minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT )
{
pipelineCache.Filter = TextureFilter.LinearMipPoint;
}
else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR ||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC )
{
pipelineCache.Filter = TextureFilter.Linear;
}
else
{
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter);
}
}
else
{
throw new NotImplementedException("Unhandled minfilter type! " + minFilter);
}
}
else
{
throw new NotImplementedException("Unhandled magfilter type! " + magFilter);
}
samplerChanged = true;
}
if (samplerChanged)
{
pipelineCache.EndApplySampler(samplers, register);
}
}
}
#endregion
#region Private Methods
private unsafe void INTERNAL_parseEffectStruct(IntPtr effectData)
{
MOJOSHADER_effect* effectPtr = (MOJOSHADER_effect*) effectData;
// Set up Parameters
MOJOSHADER_effectParam* paramPtr = (MOJOSHADER_effectParam*) effectPtr->parameters;
List<EffectParameter> parameters = new List<EffectParameter>();
for (int i = 0; i < effectPtr->param_count; i += 1)
{
MOJOSHADER_effectParam param = paramPtr[i];
if ( param.value.type.parameter_type == MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_VERTEXSHADER ||
param.value.type.parameter_type == MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_PIXELSHADER )
{
// Skip shader objects...
continue;
}
else if ( param.value.type.parameter_type >= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_SAMPLER &&
param.value.type.parameter_type <= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_SAMPLERCUBE )
{
string textureName = String.Empty;
MOJOSHADER_effectSamplerState* states = (MOJOSHADER_effectSamplerState*) param.value.values;
for (int j = 0; j < param.value.value_count; j += 1)
{
if ( states[j].value.type.parameter_type >= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_TEXTURE &&
states[j].value.type.parameter_type <= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_TEXTURECUBE )
{
MOJOSHADER_effectObject *objectPtr = (MOJOSHADER_effectObject*) effectPtr->objects;
int* index = (int*) states[j].value.values;
textureName = Marshal.PtrToStringAnsi(objectPtr[*index].mapping.name);
break;
}
}
/* Because textures have to be declared before the sampler,
* we can assume that it will always be in the list by the
* time we get to this point.
* -flibit
*/
for (int j = 0; j < parameters.Count; j += 1)
{
if (textureName.Equals(parameters[j].Name))
{
samplerMap[param.value.name] = parameters[j];
break;
}
}
continue;
}
EffectParameterCollection structMembers = null;
if (param.value.type.member_count > 0)
{
List<EffectParameter> memList = new List<EffectParameter>();
unsafe
{
MOJOSHADER_symbolStructMember* mem = (MOJOSHADER_symbolStructMember*) param.value.type.members;
IntPtr curOffset = IntPtr.Zero;
for (int j = 0; j < param.value.type.member_count; j += 1)
{
uint memSize = mem[j].info.rows * mem[j].info.columns;
if (mem[j].info.elements > 0)
{
memSize *= mem[j].info.elements;
}
memList.Add(new EffectParameter(
Marshal.PtrToStringAnsi(mem[j].name),
null,
(int) mem[j].info.rows,
(int) mem[j].info.columns,
(int) mem[j].info.elements,
XNAClass[(int) mem[j].info.parameter_class],
XNAType[(int) mem[j].info.parameter_type],
null, // FIXME: Nested structs! -flibit
null,
param.value.values + curOffset.ToInt32(),
memSize * 4
));
curOffset += (int) memSize * 4;
}
}
structMembers = new EffectParameterCollection(memList);
}
parameters.Add(new EffectParameter(
Marshal.PtrToStringAnsi(param.value.name),
Marshal.PtrToStringAnsi(param.value.semantic),
(int) param.value.type.rows,
(int) param.value.type.columns,
(int) param.value.type.elements,
XNAClass[(int) param.value.type.parameter_class],
XNAType[(int) param.value.type.parameter_type],
structMembers,
INTERNAL_readAnnotations(
param.annotations,
param.annotation_count
),
param.value.values,
param.value.value_count * sizeof(float)
));
}
Parameters = new EffectParameterCollection(parameters);
// Set up Techniques
MOJOSHADER_effectTechnique* techPtr = (MOJOSHADER_effectTechnique*) effectPtr->techniques;
List<EffectTechnique> techniques = new List<EffectTechnique>(effectPtr->technique_count);
for (int i = 0; i < techniques.Capacity; i += 1, techPtr += 1)
{
// Set up Passes
MOJOSHADER_effectPass* passPtr = (MOJOSHADER_effectPass*) techPtr->passes;
List<EffectPass> passes = new List<EffectPass>((int) techPtr->pass_count);
for (int j = 0; j < passes.Capacity; j += 1)
{
MOJOSHADER_effectPass pass = passPtr[j];
passes.Add(new EffectPass(
Marshal.PtrToStringAnsi(pass.name),
INTERNAL_readAnnotations(
pass.annotations,
pass.annotation_count
),
this,
(IntPtr) techPtr,
(uint) j
));
}
techniques.Add(new EffectTechnique(
Marshal.PtrToStringAnsi(techPtr->name),
(IntPtr) techPtr,
new EffectPassCollection(passes),
INTERNAL_readAnnotations(
techPtr->annotations,
techPtr->annotation_count
)
));
}
Techniques = new EffectTechniqueCollection(techniques);
}
private unsafe EffectAnnotationCollection INTERNAL_readAnnotations(
IntPtr rawAnnotations,
uint numAnnotations
) {
MOJOSHADER_effectAnnotation* annoPtr = (MOJOSHADER_effectAnnotation*) rawAnnotations;
List<EffectAnnotation> annotations = new List<EffectAnnotation>((int) numAnnotations);
for (int i = 0; i < numAnnotations; i += 1)
{
MOJOSHADER_effectAnnotation anno = annoPtr[i];
annotations.Add(new EffectAnnotation(
Marshal.PtrToStringAnsi(anno.name),
Marshal.PtrToStringAnsi(anno.semantic),
(int) anno.type.rows,
(int) anno.type.columns,
XNAClass[(int) anno.type.parameter_class],
XNAType[(int) anno.type.parameter_type],
anno.values
));
}
return new EffectAnnotationCollection(annotations);
}
#endregion
#region MojoShader Interop
/* Shader Parse Interface */
private enum MOJOSHADER_symbolClass
{
MOJOSHADER_SYMCLASS_SCALAR = 0,
MOJOSHADER_SYMCLASS_VECTOR,
MOJOSHADER_SYMCLASS_MATRIX_ROWS,
MOJOSHADER_SYMCLASS_MATRIX_COLUMNS,
MOJOSHADER_SYMCLASS_OBJECT,
MOJOSHADER_SYMCLASS_STRUCT,
MOJOSHADER_SYMCLASS_TOTAL
}
private enum MOJOSHADER_symbolType
{
MOJOSHADER_SYMTYPE_VOID = 0,
MOJOSHADER_SYMTYPE_BOOL,
MOJOSHADER_SYMTYPE_INT,
MOJOSHADER_SYMTYPE_FLOAT,
MOJOSHADER_SYMTYPE_STRING,
MOJOSHADER_SYMTYPE_TEXTURE,
MOJOSHADER_SYMTYPE_TEXTURE1D,
MOJOSHADER_SYMTYPE_TEXTURE2D,
MOJOSHADER_SYMTYPE_TEXTURE3D,
MOJOSHADER_SYMTYPE_TEXTURECUBE,
MOJOSHADER_SYMTYPE_SAMPLER,
MOJOSHADER_SYMTYPE_SAMPLER1D,
MOJOSHADER_SYMTYPE_SAMPLER2D,
MOJOSHADER_SYMTYPE_SAMPLER3D,
MOJOSHADER_SYMTYPE_SAMPLERCUBE,
MOJOSHADER_SYMTYPE_PIXELSHADER,
MOJOSHADER_SYMTYPE_VERTEXSHADER,
MOJOSHADER_SYMTYPE_PIXELFRAGMENT,
MOJOSHADER_SYMTYPE_VERTEXFRAGMENT,
MOJOSHADER_SYMTYPE_UNSUPPORTED,
MOJOSHADER_SYMTYPE_TOTAL
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_symbolTypeInfo
{
public MOJOSHADER_symbolClass parameter_class;
public MOJOSHADER_symbolType parameter_type;
public uint rows;
public uint columns;
public uint elements;
public uint member_count;
public IntPtr members; // MOJOSHADER_symbolStructMember*
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_symbolStructMember
{
public IntPtr name; //const char*
public MOJOSHADER_symbolTypeInfo info;
}
/* MOJOSHADER_effectState types... */
private enum MOJOSHADER_renderStateType
{
MOJOSHADER_RS_ZENABLE,
MOJOSHADER_RS_FILLMODE,
MOJOSHADER_RS_SHADEMODE,
MOJOSHADER_RS_ZWRITEENABLE,
MOJOSHADER_RS_ALPHATESTENABLE,
MOJOSHADER_RS_LASTPIXEL,
MOJOSHADER_RS_SRCBLEND,
MOJOSHADER_RS_DESTBLEND,
MOJOSHADER_RS_CULLMODE,
MOJOSHADER_RS_ZFUNC,
MOJOSHADER_RS_ALPHAREF,
MOJOSHADER_RS_ALPHAFUNC,
MOJOSHADER_RS_DITHERENABLE,
MOJOSHADER_RS_ALPHABLENDENABLE,
MOJOSHADER_RS_FOGENABLE,
MOJOSHADER_RS_SPECULARENABLE,
MOJOSHADER_RS_FOGCOLOR,
MOJOSHADER_RS_FOGTABLEMODE,
MOJOSHADER_RS_FOGSTART,
MOJOSHADER_RS_FOGEND,
MOJOSHADER_RS_FOGDENSITY,
MOJOSHADER_RS_RANGEFOGENABLE,
MOJOSHADER_RS_STENCILENABLE,
MOJOSHADER_RS_STENCILFAIL,
MOJOSHADER_RS_STENCILZFAIL,
MOJOSHADER_RS_STENCILPASS,
MOJOSHADER_RS_STENCILFUNC,
MOJOSHADER_RS_STENCILREF,
MOJOSHADER_RS_STENCILMASK,
MOJOSHADER_RS_STENCILWRITEMASK,
MOJOSHADER_RS_TEXTUREFACTOR,
MOJOSHADER_RS_WRAP0,
MOJOSHADER_RS_WRAP1,
MOJOSHADER_RS_WRAP2,
MOJOSHADER_RS_WRAP3,
MOJOSHADER_RS_WRAP4,
MOJOSHADER_RS_WRAP5,
MOJOSHADER_RS_WRAP6,
MOJOSHADER_RS_WRAP7,
MOJOSHADER_RS_WRAP8,
MOJOSHADER_RS_WRAP9,
MOJOSHADER_RS_WRAP10,
MOJOSHADER_RS_WRAP11,
MOJOSHADER_RS_WRAP12,
MOJOSHADER_RS_WRAP13,
MOJOSHADER_RS_WRAP14,
MOJOSHADER_RS_WRAP15,
MOJOSHADER_RS_CLIPPING,
MOJOSHADER_RS_LIGHTING,
MOJOSHADER_RS_AMBIENT,
MOJOSHADER_RS_FOGVERTEXMODE,
MOJOSHADER_RS_COLORVERTEX,
MOJOSHADER_RS_LOCALVIEWER,
MOJOSHADER_RS_NORMALIZENORMALS,
MOJOSHADER_RS_DIFFUSEMATERIALSOURCE,
MOJOSHADER_RS_SPECULARMATERIALSOURCE,
MOJOSHADER_RS_AMBIENTMATERIALSOURCE,
MOJOSHADER_RS_EMISSIVEMATERIALSOURCE,
MOJOSHADER_RS_VERTEXBLEND,
MOJOSHADER_RS_CLIPPLANEENABLE,
MOJOSHADER_RS_POINTSIZE,
MOJOSHADER_RS_POINTSIZE_MIN,
MOJOSHADER_RS_POINTSPRITEENABLE,
MOJOSHADER_RS_POINTSCALEENABLE,
MOJOSHADER_RS_POINTSCALE_A,
MOJOSHADER_RS_POINTSCALE_B,
MOJOSHADER_RS_POINTSCALE_C,
MOJOSHADER_RS_MULTISAMPLEANTIALIAS,
MOJOSHADER_RS_MULTISAMPLEMASK,
MOJOSHADER_RS_PATCHEDGESTYLE,
MOJOSHADER_RS_DEBUGMONITORTOKEN,
MOJOSHADER_RS_POINTSIZE_MAX,
MOJOSHADER_RS_INDEXEDVERTEXBLENDENABLE,
MOJOSHADER_RS_COLORWRITEENABLE,
MOJOSHADER_RS_TWEENFACTOR,
MOJOSHADER_RS_BLENDOP,
MOJOSHADER_RS_POSITIONDEGREE,
MOJOSHADER_RS_NORMALDEGREE,
MOJOSHADER_RS_SCISSORTESTENABLE,
MOJOSHADER_RS_SLOPESCALEDEPTHBIAS,
MOJOSHADER_RS_ANTIALIASEDLINEENABLE,
MOJOSHADER_RS_MINTESSELLATIONLEVEL,
MOJOSHADER_RS_MAXTESSELLATIONLEVEL,
MOJOSHADER_RS_ADAPTIVETESS_X,
MOJOSHADER_RS_ADAPTIVETESS_Y,
MOJOSHADER_RS_ADAPTIVETESS_Z,
MOJOSHADER_RS_ADAPTIVETESS_W,
MOJOSHADER_RS_ENABLEADAPTIVETESSELLATION,
MOJOSHADER_RS_TWOSIDEDSTENCILMODE,
MOJOSHADER_RS_CCW_STENCILFAIL,
MOJOSHADER_RS_CCW_STENCILZFAIL,
MOJOSHADER_RS_CCW_STENCILPASS,
MOJOSHADER_RS_CCW_STENCILFUNC,
MOJOSHADER_RS_COLORWRITEENABLE1,
MOJOSHADER_RS_COLORWRITEENABLE2,
MOJOSHADER_RS_COLORWRITEENABLE3,
MOJOSHADER_RS_BLENDFACTOR,
MOJOSHADER_RS_SRGBWRITEENABLE,
MOJOSHADER_RS_DEPTHBIAS,
MOJOSHADER_RS_SEPARATEALPHABLENDENABLE,
MOJOSHADER_RS_SRCBLENDALPHA,
MOJOSHADER_RS_DESTBLENDALPHA,
MOJOSHADER_RS_BLENDOPALPHA,
MOJOSHADER_RS_VERTEXSHADER = 146,
MOJOSHADER_RS_PIXELSHADER = 147
}
private enum MOJOSHADER_zBufferType
{
MOJOSHADER_ZB_FALSE,
MOJOSHADER_ZB_TRUE,
MOJOSHADER_ZB_USEW
}
private enum MOJOSHADER_fillMode
{
MOJOSHADER_FILL_POINT = 1,
MOJOSHADER_FILL_WIREFRAME = 2,
MOJOSHADER_FILL_SOLID = 3
}
private enum MOJOSHADER_blendMode
{
MOJOSHADER_BLEND_ZERO = 1,
MOJOSHADER_BLEND_ONE = 2,
MOJOSHADER_BLEND_SRCCOLOR = 3,
MOJOSHADER_BLEND_INVSRCCOLOR = 4,
MOJOSHADER_BLEND_SRCALPHA = 5,
MOJOSHADER_BLEND_INVSRCALPHA = 6,
MOJOSHADER_BLEND_DESTALPHA = 7,
MOJOSHADER_BLEND_INVDESTALPHA = 8,
MOJOSHADER_BLEND_DESTCOLOR = 9,
MOJOSHADER_BLEND_INVDESTCOLOR = 10,
MOJOSHADER_BLEND_SRCALPHASAT = 11,
MOJOSHADER_BLEND_BOTHSRCALPHA = 12,
MOJOSHADER_BLEND_BOTHINVSRCALPHA = 13,
MOJOSHADER_BLEND_BLENDFACTOR = 14,
MOJOSHADER_BLEND_INVBLENDFACTOR = 15,
MOJOSHADER_BLEND_SRCCOLOR2 = 16,
MOJOSHADER_BLEND_INVSRCCOLOR2 = 17
}
private enum MOJOSHADER_cullMode
{
MOJOSHADER_CULL_NONE = 1,
MOJOSHADER_CULL_CW = 2,
MOJOSHADER_CULL_CCW = 3
}
private enum MOJOSHADER_compareFunc
{
MOJOSHADER_CMP_NEVER = 1,
MOJOSHADER_CMP_LESS = 2,
MOJOSHADER_CMP_EQUAL = 3,
MOJOSHADER_CMP_LESSEQUAL = 4,
MOJOSHADER_CMP_GREATER = 5,
MOJOSHADER_CMP_NOTEQUAL = 6,
MOJOSHADER_CMP_GREATEREQUAL = 7,
MOJOSHADER_CMP_ALWAYS = 8
}
private enum MOJOSHADER_stencilOp
{
MOJOSHADER_STENCILOP_KEEP = 1,
MOJOSHADER_STENCILOP_ZERO = 2,
MOJOSHADER_STENCILOP_REPLACE = 3,
MOJOSHADER_STENCILOP_INCRSAT = 4,
MOJOSHADER_STENCILOP_DECRSAT = 5,
MOJOSHADER_STENCILOP_INVERT = 6,
MOJOSHADER_STENCILOP_INCR = 7,
MOJOSHADER_STENCILOP_DECR = 8
}
private enum MOJOSHADER_blendOp
{
MOJOSHADER_BLENDOP_ADD = 1,
MOJOSHADER_BLENDOP_SUBTRACT = 2,
MOJOSHADER_BLENDOP_REVSUBTRACT = 3,
MOJOSHADER_BLENDOP_MIN = 4,
MOJOSHADER_BLENDOP_MAX = 5
}
/* MOJOSHADER_effectSamplerState types... */
private enum MOJOSHADER_samplerStateType
{
MOJOSHADER_SAMP_UNKNOWN0 = 0,
MOJOSHADER_SAMP_UNKNOWN1 = 1,
MOJOSHADER_SAMP_UNKNOWN2 = 2,
MOJOSHADER_SAMP_UNKNOWN3 = 3,
MOJOSHADER_SAMP_TEXTURE = 4,
MOJOSHADER_SAMP_ADDRESSU = 5,
MOJOSHADER_SAMP_ADDRESSV = 6,
MOJOSHADER_SAMP_ADDRESSW = 7,
MOJOSHADER_SAMP_BORDERCOLOR = 8,
MOJOSHADER_SAMP_MAGFILTER = 9,
MOJOSHADER_SAMP_MINFILTER = 10,
MOJOSHADER_SAMP_MIPFILTER = 11,
MOJOSHADER_SAMP_MIPMAPLODBIAS = 12,
MOJOSHADER_SAMP_MAXMIPLEVEL = 13,
MOJOSHADER_SAMP_MAXANISOTROPY = 14,
MOJOSHADER_SAMP_SRGBTEXTURE = 15,
MOJOSHADER_SAMP_ELEMENTINDEX = 16,
MOJOSHADER_SAMP_DMAPOFFSET = 17
}
private enum MOJOSHADER_textureAddress
{
MOJOSHADER_TADDRESS_WRAP = 1,
MOJOSHADER_TADDRESS_MIRROR = 2,
MOJOSHADER_TADDRESS_CLAMP = 3,
MOJOSHADER_TADDRESS_BORDER = 4,
MOJOSHADER_TADDRESS_MIRRORONCE = 5
}
private enum MOJOSHADER_textureFilterType
{
MOJOSHADER_TEXTUREFILTER_NONE,
MOJOSHADER_TEXTUREFILTER_POINT,
MOJOSHADER_TEXTUREFILTER_LINEAR,
MOJOSHADER_TEXTUREFILTER_ANISOTROPIC,
MOJOSHADER_TEXTUREFILTER_PYRAMIDALQUAD,
MOJOSHADER_TEXTUREFILTER_GAUSSIANQUAD,
MOJOSHADER_TEXTUREFILTER_CONVOLUTIONMONO
}
/* Effect value types... */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectValue
{
public IntPtr name; // const char*
public IntPtr semantic; // const char*
public MOJOSHADER_symbolTypeInfo type;
public uint value_count;
public IntPtr values; // You know what, just look at the C header...
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectState
{
public MOJOSHADER_renderStateType type;
public MOJOSHADER_effectValue value;
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectSamplerState
{
public MOJOSHADER_samplerStateType type;
public MOJOSHADER_effectValue value;
}
/* typedef MOJOSHADER_effectValue MOJOSHADER_effectAnnotation; */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectAnnotation
{
public IntPtr name; // const char*
public IntPtr semantic; // const char*
public MOJOSHADER_symbolTypeInfo type;
public uint value_count;
public IntPtr values; // You know what, just look at the C header...
}
/* Effect interface structures... */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectParam
{
public MOJOSHADER_effectValue value;
public uint annotation_count;
public IntPtr annotations; // MOJOSHADER_effectAnnotations*
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectPass
{
public IntPtr name; // const char*
public uint state_count;
public IntPtr states; // MOJOSHADER_effectState*
public uint annotation_count;
public IntPtr annotations; // MOJOSHADER_effectAnnotations*
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectTechnique
{
public IntPtr name; // const char*
public uint pass_count;
public IntPtr passes; // MOJOSHADER_effectPass*
public uint annotation_count;
public IntPtr annotations; // MOJOSHADER_effectAnnotations*
}
/* Effect "objects"... */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectShader
{
public MOJOSHADER_symbolType type;
public uint technique;
public uint pass;
public uint is_preshader;
public uint preshader_param_count;
public IntPtr preshader_params; // unsigned int*
public uint param_count;
public IntPtr parameters; // unsigned int*
public uint sampler_count;
public IntPtr samplers; // MOJOSHADER_samplerStateRegister*
public IntPtr shader; // *shader/*preshader union
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectSamplerMap
{
public MOJOSHADER_symbolType type;
public IntPtr name; // const char*
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectString
{
public MOJOSHADER_symbolType type;
public IntPtr stringvalue; // const char*
}
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effectTexture
{
public MOJOSHADER_symbolType type;
}
[StructLayout(LayoutKind.Explicit)]
private struct MOJOSHADER_effectObject
{
[FieldOffset(0)]
public MOJOSHADER_symbolType type;
[FieldOffset(0)]
public MOJOSHADER_effectShader shader;
[FieldOffset(0)]
public MOJOSHADER_effectSamplerMap mapping;
[FieldOffset(0)]
public MOJOSHADER_effectString stringvalue;
[FieldOffset(0)]
public MOJOSHADER_effectTexture texture;
}
/* Effect state change types... */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_samplerStateRegister
{
public IntPtr sampler_name; // const char*
public uint sampler_register;
public uint sampler_state_count;
public IntPtr sampler_states; // const MOJOSHADER_effectSamplerState*
}
// Needed by VideoPlayer...
[StructLayout(LayoutKind.Sequential)]
internal struct MOJOSHADER_effectStateChanges
{
public uint render_state_change_count;
public IntPtr render_state_changes; // const MOJOSHADER_effectState*
public uint sampler_state_change_count;
public IntPtr sampler_state_changes; // const MOJOSHADER_samplerStateRegister*
public uint vertex_sampler_state_change_count;
public IntPtr vertex_sampler_state_changes; // const MOJOSHADER_samplerStateRegister*
}
/* Effect parsing interface... this is a partial struct! */
[StructLayout(LayoutKind.Sequential)]
private struct MOJOSHADER_effect
{
public int error_count;
public IntPtr errors; // MOJOSHADER_error*
public int param_count;
public IntPtr parameters; // MOJOSHADER_effectParam* params, lolC#
public int technique_count;
public IntPtr techniques; // MOJOSHADER_effectTechnique*
public int object_count;
public IntPtr objects; // MOJOSHADER_effectObject*
}
#endregion
}
}