Show More
Commit Description:
Tweak calculations....
Commit Description:
Tweak calculations.
Prevent a negative number of visitors and separate visitors from donors.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/Effect/Effect.cs
1490 lines | 49.1 KiB | text/x-csharp | CSharpLexer
1490 lines | 49.1 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
r690 | * Copyright 2009-2022 Ethan Lee and the MonoGame Team | |||
r0 | * | |||
* 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 | ||||
{ | ||||
r690 | FNA3D.FNA3D_SetEffectTechnique( | |||
GraphicsDevice.GLDevice, | ||||
glEffect, | ||||
r0 | value.TechniquePointer | |||
); | ||||
INTERNAL_currentTechnique = value; | ||||
} | ||||
} | ||||
public EffectParameterCollection Parameters | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
public EffectTechniqueCollection Techniques | ||||
{ | ||||
get; | ||||
private set; | ||||
} | ||||
#endregion | ||||
r690 | #region Internal FNA3D Variables | |||
r0 | ||||
r690 | internal IntPtr glEffect; | |||
r0 | ||||
#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 | ||||
}; | ||||
r690 | private static readonly MOJOSHADER_textureFilterType[] XNAMag = | |||
new MOJOSHADER_textureFilterType[] | ||||
r0 | { | |||
r690 | 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 | ||||
r0 | }; | |||
r690 | private static readonly MOJOSHADER_textureFilterType[] XNAMin = | |||
new MOJOSHADER_textureFilterType[] | ||||
r0 | { | |||
r690 | 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 | ||||
r0 | }; | |||
r690 | private static readonly MOJOSHADER_textureFilterType[] XNAMip = | |||
new MOJOSHADER_textureFilterType[] | ||||
r0 | { | |||
r690 | 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 | ||||
r0 | }; | |||
#endregion | ||||
#region Public Constructor | ||||
public Effect(GraphicsDevice graphicsDevice, byte[] effectCode) | ||||
{ | ||||
GraphicsDevice = graphicsDevice; | ||||
// Send the blob to the GLDevice to be parsed/compiled | ||||
r690 | IntPtr effectData; | |||
FNA3D.FNA3D_CreateEffect( | ||||
graphicsDevice.GLDevice, | ||||
effectCode, | ||||
effectCode.Length, | ||||
out glEffect, | ||||
out effectData | ||||
); | ||||
r0 | ||||
// This is where it gets ugly... | ||||
r690 | INTERNAL_parseEffectStruct(effectData); | |||
r0 | ||||
// The default technique is the first technique. | ||||
CurrentTechnique = Techniques[0]; | ||||
// Use native memory for changes, .NET loves moving this around | ||||
unsafe | ||||
{ | ||||
stateChangesPtr = Marshal.AllocHGlobal( | ||||
r690 | sizeof(MOJOSHADER_effectStateChanges) | |||
r0 | ); | |||
r690 | MOJOSHADER_effectStateChanges *stateChanges = | |||
(MOJOSHADER_effectStateChanges*) stateChangesPtr; | ||||
r0 | 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 | ||||
r690 | IntPtr effectData; | |||
FNA3D.FNA3D_CloneEffect( | ||||
GraphicsDevice.GLDevice, | ||||
cloneSource.glEffect, | ||||
out glEffect, | ||||
out effectData | ||||
r0 | ); | |||
// Double the ugly, double the fun! | ||||
r690 | INTERNAL_parseEffectStruct(effectData); | |||
r0 | ||||
// 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( | ||||
r690 | sizeof(MOJOSHADER_effectStateChanges) | |||
r0 | ); | |||
r690 | MOJOSHADER_effectStateChanges *stateChanges = | |||
(MOJOSHADER_effectStateChanges*) stateChangesPtr; | ||||
r0 | 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) | ||||
{ | ||||
r690 | if (glEffect != IntPtr.Zero) | |||
r0 | { | |||
r690 | FNA3D.FNA3D_AddDisposeEffect( | |||
GraphicsDevice.GLDevice, | ||||
glEffect | ||||
); | ||||
r0 | } | |||
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) | ||||
{ | ||||
r690 | FNA3D.FNA3D_ApplyEffect( | |||
GraphicsDevice.GLDevice, | ||||
r0 | glEffect, | |||
pass, | ||||
stateChangesPtr | ||||
); | ||||
r690 | MOJOSHADER_effectStateChanges *stateChanges = | |||
(MOJOSHADER_effectStateChanges*) stateChangesPtr; | ||||
r0 | 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; | ||||
r690 | MOJOSHADER_effectState* states = (MOJOSHADER_effectState*) stateChanges->render_state_changes; | |||
r0 | for (int i = 0; i < stateChanges->render_state_change_count; i += 1) | |||
{ | ||||
r690 | MOJOSHADER_renderStateType type = states[i].type; | |||
if ( type == MOJOSHADER_renderStateType.MOJOSHADER_RS_VERTEXSHADER || | ||||
type == MOJOSHADER_renderStateType.MOJOSHADER_RS_PIXELSHADER ) | ||||
r0 | { | |||
// Skip shader states | ||||
continue; | ||||
} | ||||
r690 | if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZENABLE) | |||
r0 | { | |||
r690 | MOJOSHADER_zBufferType* val = (MOJOSHADER_zBufferType*) states[i].value.values; | |||
r0 | pipelineCache.DepthBufferEnable = | |||
r690 | (*val == MOJOSHADER_zBufferType.MOJOSHADER_ZB_TRUE); | |||
r0 | depthStencilStateChanged = true; | |||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_FILLMODE) | |||
r0 | { | |||
r690 | MOJOSHADER_fillMode* val = (MOJOSHADER_fillMode*) states[i].value.values; | |||
if (*val == MOJOSHADER_fillMode.MOJOSHADER_FILL_SOLID) | ||||
r0 | { | |||
pipelineCache.FillMode = FillMode.Solid; | ||||
} | ||||
r690 | else if (*val == MOJOSHADER_fillMode.MOJOSHADER_FILL_WIREFRAME) | |||
r0 | { | |||
pipelineCache.FillMode = FillMode.WireFrame; | ||||
} | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZWRITEENABLE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.DepthBufferWriteEnable = (*val == 1); | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SRCBLEND) | |||
r0 | { | |||
r690 | MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values; | |||
r0 | pipelineCache.ColorSourceBlend = XNABlend[(int) *val]; | |||
if (!pipelineCache.SeparateAlphaBlend) | ||||
{ | ||||
pipelineCache.AlphaSourceBlend = XNABlend[(int) *val]; | ||||
} | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DESTBLEND) | |||
r0 | { | |||
r690 | MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values; | |||
r0 | pipelineCache.ColorDestinationBlend = XNABlend[(int) *val]; | |||
if (!pipelineCache.SeparateAlphaBlend) | ||||
{ | ||||
pipelineCache.AlphaDestinationBlend = XNABlend[(int) *val]; | ||||
} | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CULLMODE) | |||
r0 | { | |||
r690 | MOJOSHADER_cullMode* val = (MOJOSHADER_cullMode*) states[i].value.values; | |||
if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_NONE) | ||||
r0 | { | |||
pipelineCache.CullMode = CullMode.None; | ||||
} | ||||
r690 | else if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_CW) | |||
r0 | { | |||
pipelineCache.CullMode = CullMode.CullClockwiseFace; | ||||
} | ||||
r690 | else if (*val == MOJOSHADER_cullMode.MOJOSHADER_CULL_CCW) | |||
r0 | { | |||
pipelineCache.CullMode = CullMode.CullCounterClockwiseFace; | ||||
} | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ZFUNC) | |||
r0 | { | |||
r690 | MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values; | |||
r0 | pipelineCache.DepthBufferFunction = XNACompare[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_ALPHABLENDENABLE) | |||
r0 | { | |||
// 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; | ||||
} | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILENABLE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.StencilEnable = (*val == 1); | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILFAIL) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.StencilFail = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILZFAIL) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.StencilDepthBufferFail = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILPASS) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.StencilPass = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILFUNC) | |||
r0 | { | |||
r690 | MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values; | |||
r0 | pipelineCache.StencilFunction = XNACompare[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILREF) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ReferenceStencil = *val; | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILMASK) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.StencilMask = *val; | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_STENCILWRITEMASK) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.StencilWriteMask = *val; | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_MULTISAMPLEANTIALIAS) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.MultiSampleAntiAlias = (*val == 1); | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_MULTISAMPLEMASK) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.MultiSampleMask = *val; | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ColorWriteChannels = (ColorWriteChannels) (*val); | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDOP) | |||
r0 | { | |||
r690 | MOJOSHADER_blendOp* val = (MOJOSHADER_blendOp*) states[i].value.values; | |||
r0 | pipelineCache.ColorBlendFunction = XNABlendOp[(int) *val]; | |||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SCISSORTESTENABLE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ScissorTestEnable = (*val == 1); | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SLOPESCALEDEPTHBIAS) | |||
r0 | { | |||
float* val = (float*) states[i].value.values; | ||||
pipelineCache.SlopeScaleDepthBias = *val; | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_TWOSIDEDSTENCILMODE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.TwoSidedStencilMode = (*val == 1); | ||||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILFAIL) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.CCWStencilFail = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILZFAIL) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.CCWStencilDepthBufferFail = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILPASS) | |||
r0 | { | |||
r690 | MOJOSHADER_stencilOp* val = (MOJOSHADER_stencilOp*) states[i].value.values; | |||
r0 | pipelineCache.CCWStencilPass = XNAStencilOp[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_CCW_STENCILFUNC) | |||
r0 | { | |||
r690 | MOJOSHADER_compareFunc* val = (MOJOSHADER_compareFunc*) states[i].value.values; | |||
r0 | pipelineCache.CCWStencilFunction = XNACompare[(int) *val]; | |||
depthStencilStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE1) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ColorWriteChannels1 = (ColorWriteChannels) (*val); | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE2) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ColorWriteChannels2 = (ColorWriteChannels) (*val); | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_COLORWRITEENABLE3) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.ColorWriteChannels3 = (ColorWriteChannels) (*val); | ||||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDFACTOR) | |||
r0 | { | |||
// 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; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DEPTHBIAS) | |||
r0 | { | |||
float* val = (float*) states[i].value.values; | ||||
pipelineCache.DepthBias = *val; | ||||
rasterizerStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SEPARATEALPHABLENDENABLE) | |||
r0 | { | |||
int* val = (int*) states[i].value.values; | ||||
pipelineCache.SeparateAlphaBlend = (*val == 1); | ||||
// FIXME: Do we want to update the state for this...? -flibit | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_SRCBLENDALPHA) | |||
r0 | { | |||
r690 | MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values; | |||
r0 | pipelineCache.AlphaSourceBlend = XNABlend[(int) *val]; | |||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_DESTBLENDALPHA) | |||
r0 | { | |||
r690 | MOJOSHADER_blendMode* val = (MOJOSHADER_blendMode*) states[i].value.values; | |||
r0 | pipelineCache.AlphaDestinationBlend = XNABlend[(int) *val]; | |||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_renderStateType.MOJOSHADER_RS_BLENDOPALPHA) | |||
r0 | { | |||
r690 | MOJOSHADER_blendOp* val = (MOJOSHADER_blendOp*) states[i].value.values; | |||
r0 | pipelineCache.AlphaBlendFunction = XNABlendOp[(int) *val]; | |||
blendStateChanged = true; | ||||
} | ||||
r690 | else if (type == (MOJOSHADER_renderStateType) 178) | |||
r0 | { | |||
/* 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, | ||||
r690 | (MOJOSHADER_samplerStateRegister*) stateChanges->sampler_state_changes, | |||
r0 | GraphicsDevice.Textures, | |||
GraphicsDevice.SamplerStates | ||||
); | ||||
} | ||||
if (stateChanges->vertex_sampler_state_change_count > 0) | ||||
{ | ||||
INTERNAL_updateSamplers( | ||||
stateChanges->vertex_sampler_state_change_count, | ||||
r690 | (MOJOSHADER_samplerStateRegister*) stateChanges->vertex_sampler_state_changes, | |||
r0 | GraphicsDevice.VertexTextures, | |||
GraphicsDevice.VertexSamplerStates | ||||
); | ||||
} | ||||
} | ||||
private unsafe void INTERNAL_updateSamplers( | ||||
uint changeCount, | ||||
r690 | MOJOSHADER_samplerStateRegister* registers, | |||
r0 | 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; | ||||
r690 | MOJOSHADER_textureFilterType magFilter = XNAMag[(int) filter]; | |||
MOJOSHADER_textureFilterType minFilter = XNAMin[(int) filter]; | ||||
MOJOSHADER_textureFilterType mipFilter = XNAMip[(int) filter]; | ||||
r0 | ||||
r690 | MOJOSHADER_effectSamplerState* states = (MOJOSHADER_effectSamplerState*) registers[i].sampler_states; | |||
r0 | for (int j = 0; j < registers[i].sampler_state_count; j += 1) | |||
{ | ||||
r690 | MOJOSHADER_samplerStateType type = states[j].type; | |||
if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_TEXTURE) | ||||
r0 | { | |||
EffectParameter texParam; | ||||
if (samplerMap.TryGetValue(registers[i].sampler_name, out texParam)) | ||||
{ | ||||
Texture texture = texParam.texture; | ||||
if (texture != null) | ||||
{ | ||||
textures[register] = texture; | ||||
} | ||||
} | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSU) | |||
r0 | { | |||
r690 | MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values; | |||
r0 | pipelineCache.AddressU = XNAAddress[(int) *val]; | |||
samplerChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSV) | |||
r0 | { | |||
r690 | MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values; | |||
r0 | pipelineCache.AddressV = XNAAddress[(int) *val]; | |||
samplerChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_ADDRESSW) | |||
r0 | { | |||
r690 | MOJOSHADER_textureAddress* val = (MOJOSHADER_textureAddress*) states[j].value.values; | |||
r0 | pipelineCache.AddressW = XNAAddress[(int) *val]; | |||
samplerChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAGFILTER) | |||
r0 | { | |||
r690 | MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values; | |||
r0 | magFilter = *val; | |||
filterChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MINFILTER) | |||
r0 | { | |||
r690 | MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values; | |||
r0 | minFilter = *val; | |||
filterChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPFILTER) | |||
r0 | { | |||
r690 | MOJOSHADER_textureFilterType* val = (MOJOSHADER_textureFilterType*) states[j].value.values; | |||
r0 | mipFilter = *val; | |||
filterChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MIPMAPLODBIAS) | |||
r0 | { | |||
float* val = (float*) states[j].value.values; | ||||
pipelineCache.MipMapLODBias = *val; | ||||
samplerChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXMIPLEVEL) | |||
r0 | { | |||
int* val = (int*) states[j].value.values; | ||||
pipelineCache.MaxMipLevel = *val; | ||||
samplerChanged = true; | ||||
} | ||||
r690 | else if (type == MOJOSHADER_samplerStateType.MOJOSHADER_SAMP_MAXANISOTROPY) | |||
r0 | { | |||
int* val = (int*) states[j].value.values; | ||||
pipelineCache.MaxAnisotropy = *val; | ||||
samplerChanged = true; | ||||
} | ||||
else | ||||
{ | ||||
throw new NotImplementedException("Unhandled sampler state! " + type); | ||||
} | ||||
} | ||||
if (filterChanged) | ||||
{ | ||||
r690 | if (magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT) | |||
r0 | { | |||
r690 | if (minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT) | |||
r0 | { | |||
r690 | if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.Point; | ||||
} | ||||
r690 | else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.PointMipLinear; | ||||
} | ||||
else | ||||
{ | ||||
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter); | ||||
} | ||||
} | ||||
r690 | else if ( minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
r690 | if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.MinLinearMagPointMipPoint; | ||||
} | ||||
r690 | else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.MinLinearMagPointMipLinear; | ||||
} | ||||
else | ||||
{ | ||||
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter); | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
throw new NotImplementedException("Unhandled minfilter type! " + minFilter); | ||||
} | ||||
} | ||||
r690 | else if ( magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
magFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
r690 | if (minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT) | |||
r0 | { | |||
r690 | if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.MinPointMagLinearMipPoint; | ||||
} | ||||
r690 | else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.MinPointMagLinearMipLinear; | ||||
} | ||||
else | ||||
{ | ||||
throw new NotImplementedException("Unhandled mipfilter type! " + mipFilter); | ||||
} | ||||
} | ||||
r690 | else if ( minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
minFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
r690 | if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_NONE || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_POINT ) | ||||
r0 | { | |||
pipelineCache.Filter = TextureFilter.LinearMipPoint; | ||||
} | ||||
r690 | else if ( mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_LINEAR || | |||
mipFilter == MOJOSHADER_textureFilterType.MOJOSHADER_TEXTUREFILTER_ANISOTROPIC ) | ||||
r0 | { | |||
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 | ||||
r690 | private unsafe void INTERNAL_parseEffectStruct(IntPtr effectData) | |||
r0 | { | |||
r690 | MOJOSHADER_effect* effectPtr = (MOJOSHADER_effect*) effectData; | |||
r0 | ||||
// Set up Parameters | ||||
r690 | MOJOSHADER_effectParam* paramPtr = (MOJOSHADER_effectParam*) effectPtr->parameters; | |||
r0 | List<EffectParameter> parameters = new List<EffectParameter>(); | |||
for (int i = 0; i < effectPtr->param_count; i += 1) | ||||
{ | ||||
r690 | 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 ) | ||||
r0 | { | |||
// Skip shader objects... | ||||
continue; | ||||
} | ||||
r690 | else if ( param.value.type.parameter_type >= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_SAMPLER && | |||
param.value.type.parameter_type <= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_SAMPLERCUBE ) | ||||
r0 | { | |||
string textureName = String.Empty; | ||||
r690 | MOJOSHADER_effectSamplerState* states = (MOJOSHADER_effectSamplerState*) param.value.values; | |||
r0 | for (int j = 0; j < param.value.value_count; j += 1) | |||
{ | ||||
r690 | if ( states[j].value.type.parameter_type >= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_TEXTURE && | |||
states[j].value.type.parameter_type <= MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_TEXTURECUBE ) | ||||
r0 | { | |||
r690 | MOJOSHADER_effectObject *objectPtr = (MOJOSHADER_effectObject*) effectPtr->objects; | |||
r0 | 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 | ||||
{ | ||||
r690 | MOJOSHADER_symbolStructMember* mem = (MOJOSHADER_symbolStructMember*) param.value.type.members; | |||
r0 | 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 | ||||
r690 | MOJOSHADER_effectTechnique* techPtr = (MOJOSHADER_effectTechnique*) effectPtr->techniques; | |||
r0 | List<EffectTechnique> techniques = new List<EffectTechnique>(effectPtr->technique_count); | |||
for (int i = 0; i < techniques.Capacity; i += 1, techPtr += 1) | ||||
{ | ||||
// Set up Passes | ||||
r690 | MOJOSHADER_effectPass* passPtr = (MOJOSHADER_effectPass*) techPtr->passes; | |||
r0 | List<EffectPass> passes = new List<EffectPass>((int) techPtr->pass_count); | |||
for (int j = 0; j < passes.Capacity; j += 1) | ||||
{ | ||||
r690 | MOJOSHADER_effectPass pass = passPtr[j]; | |||
r0 | 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 | ||||
) { | ||||
r690 | MOJOSHADER_effectAnnotation* annoPtr = (MOJOSHADER_effectAnnotation*) rawAnnotations; | |||
r0 | List<EffectAnnotation> annotations = new List<EffectAnnotation>((int) numAnnotations); | |||
for (int i = 0; i < numAnnotations; i += 1) | ||||
{ | ||||
r690 | MOJOSHADER_effectAnnotation anno = annoPtr[i]; | |||
r0 | 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 | ||||
r690 | ||||
#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 | ||||
r0 | } | |||
} | ||||