(ded4a3e0a) v0.9.0.7

This commit is contained in:
Joonas Rikkonen
2019-06-25 16:00:44 +03:00
parent e5ae622c77
commit 4a51db77b5
1777 changed files with 421528 additions and 917 deletions
@@ -0,0 +1,272 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{46474D32-2E58-6957-6E64-6F7773324D47}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>TwoMGFX</RootNamespace>
<AssemblyName>2MGFX</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>1591,0436</NoWarn>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<LangVersion>Default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
<EnableUnmanagedDebugging>true</EnableUnmanagedDebugging>
<OutputPath>bin\Windows\AnyCPU\Debug</OutputPath>
<IntermediateOutputPath>obj\Windows\AnyCPU\Debug</IntermediateOutputPath>
<DocumentationFile>bin\Windows\AnyCPU\Debug\2MGFX.xml</DocumentationFile>
<DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<DebugType>none</DebugType>
<OutputPath>bin\Windows\AnyCPU\Release</OutputPath>
<IntermediateOutputPath>obj\Windows\AnyCPU\Release</IntermediateOutputPath>
<DocumentationFile>bin\Windows\AnyCPU\Release\2MGFX.xml</DocumentationFile>
<DefineConstants>TRACE;WINDOWS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
<Reference Include="SharpDX">
<HintPath>..\..\ThirdParty\Dependencies\SharpDX\net40\SharpDX.dll</HintPath>
</Reference>
<Reference Include="SharpDX.D3DCompiler">
<HintPath>..\..\ThirdParty\Dependencies\SharpDX\SharpDX.D3DCompiler.dll</HintPath>
</Reference>
<Reference Include="CppNet">
<HintPath>..\..\ThirdParty\Dependencies\CppNet\CppNet.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="CommandLineParser.cs" />
<Compile Include="Options.cs" />
<Compile Include="..\..\MonoGame.Framework\BoundingBox.cs">
<Link>MonoGame.Framework\BoundingBox.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\BoundingFrustum.cs">
<Link>MonoGame.Framework\BoundingFrustum.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\BoundingSphere.cs">
<Link>MonoGame.Framework\BoundingSphere.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Color.cs">
<Link>MonoGame.Framework\Color.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\ContainmentType.cs">
<Link>MonoGame.Framework\ContainmentType.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\EventHelpers.cs">
<Link>MonoGame.Framework\EventHelpers.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\ColorWriteChannels.cs">
<Link>MonoGame.Framework\ColorWriteChannels.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\Effect\EffectParameterClass.cs">
<Link>MonoGame.Framework\EffectParameterClass.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\Effect\EffectParameterType.cs">
<Link>MonoGame.Framework\EffectParameterType.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\GraphicsResource.cs">
<Link>MonoGame.Framework\GraphicsResource.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\Blend.cs">
<Link>MonoGame.Framework\Blend.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\BlendFunction.cs">
<Link>MonoGame.Framework\BlendFunction.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\BlendState.cs">
<Link>MonoGame.Framework\BlendState.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\CompareFunction.cs">
<Link>MonoGame.Framework\CompareFunction.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\CullMode.cs">
<Link>MonoGame.Framework\CullMode.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\DepthStencilState.cs">
<Link>MonoGame.Framework\DepthStencilState.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\FillMode.cs">
<Link>MonoGame.Framework\FillMode.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\RasterizerState.cs">
<Link>MonoGame.Framework\RasterizerState.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\SamplerState.cs">
<Link>MonoGame.Framework\SamplerState.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\StencilOperation.cs">
<Link>MonoGame.Framework\StencilOperation.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\TargetBlendState.cs">
<Link>MonoGame.Framework\TargetBlendState.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\TextureAddressMode.cs">
<Link>MonoGame.Framework\TextureAddressMode.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\TextureFilter.cs">
<Link>MonoGame.Framework\TextureFilter.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\States\TextureFilterMode.cs">
<Link>MonoGame.Framework\TextureFilterMode.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\Vertices\VertexElementUsage.cs">
<Link>MonoGame.Framework\VertexElementUsage.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\MathHelper.cs">
<Link>MonoGame.Framework\MathHelper.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Matrix.cs">
<Link>MonoGame.Framework\Matrix.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Plane.cs">
<Link>MonoGame.Framework\Plane.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Point.cs">
<Link>MonoGame.Framework\Point.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\PlaneIntersectionType.cs">
<Link>MonoGame.Framework\PlaneIntersectionType.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Quaternion.cs">
<Link>MonoGame.Framework\Quaternion.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Ray.cs">
<Link>MonoGame.Framework\Ray.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Rectangle.cs">
<Link>MonoGame.Framework\Rectangle.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Vector2.cs">
<Link>MonoGame.Framework\Vector2.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Vector3.cs">
<Link>MonoGame.Framework\Vector3.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Vector4.cs">
<Link>MonoGame.Framework\Vector4.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Design\Vector2TypeConverter.cs">
<Link>MonoGame.Framework\Design\Vector2TypeConverter.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Design\Vector3TypeConverter.cs">
<Link>MonoGame.Framework\Design\Vector3TypeConverter.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Design\Vector4TypeConverter.cs">
<Link>MonoGame.Framework\Design\Vector4TypeConverter.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Design\VectorConversion.cs">
<Link>MonoGame.Framework\Design\VectorConversion.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Graphics\PackedVector\IPackedVector.cs">
<Link>MonoGame.Framework\Graphics\PackedVector\IPackedVector.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Utilities\Hash.cs">
<Link>MonoGame.Framework\Utilities\Hash.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework\Utilities\CurrentPlatform.cs" />
<Compile Include="..\..\MonoGame.Framework.Content.Pipeline\ExternalTool.cs">
<Link>MonoGame.Framework.Content.Pipeline\ExternalTool.cs</Link>
</Compile>
<Compile Include="..\..\MonoGame.Framework.Content.Pipeline\LoadedTypeCollection.cs">
<Link>MonoGame.Framework.Content.Pipeline\LoadedTypeCollection.c</Link>
</Compile>
<Compile Include="MonoGame.Framework\GraphicsDevice.cs" />
<Compile Include="ConstantBufferData.cs" />
<Compile Include="ConstantBufferData.mojo.cs" />
<Compile Include="ConstantBufferData.sharpdx.cs" />
<Compile Include="ConstantBufferData.writer.cs" />
<Compile Include="EffectObject.cs" />
<Compile Include="EffectObject.hlsl.cs" />
<Compile Include="EffectObject.pssl.cs" />
<Compile Include="EffectObject.writer.cs" />
<Compile Include="IEffectCompilerOutput.cs" />
<Compile Include="ShaderCompilerException.cs" />
<Compile Include="ShaderData.cs" />
<Compile Include="ShaderData.mojo.cs" />
<Compile Include="ShaderData.pssl.cs" />
<Compile Include="ShaderData.sharpdx.cs" />
<Compile Include="ShaderData.writer.cs" />
<Compile Include="ShaderProfile.cs" />
<Compile Include="ShaderProfile.OpenGL.cs" />
<Compile Include="ShaderProfile.DirectX.cs" />
<Compile Include="ShaderResult.cs" />
<Compile Include="TextureFilterType.cs" />
<Compile Include="MarshalHelper.cs" />
<Compile Include="MojoShader.cs" />
<Compile Include="TPGParser\Parser.cs" />
<Compile Include="TPGParser\ParseTree.cs" />
<Compile Include="TPGParser\Scanner.cs" />
<Compile Include="TPGParser\ParseTreeTools.cs" />
<Compile Include="TPGParser\PassInfo.cs" />
<Compile Include="TPGParser\SamplerStateInfo.cs" />
<Compile Include="TPGParser\ShaderInfo.cs" />
<Compile Include="TPGParser\TechniqueInfo.cs" />
<Compile Include="Preprocessor.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="TPGParser\MGFX.tpg" />
</ItemGroup>
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup />
<ItemGroup>
<None Include="..\..\ThirdParty\Dependencies\MojoShader\Windows\libmojoshader_64.dll">
<Link>libmojoshader_64.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<NativeBinary>True</NativeBinary>
</None>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<_PostBuildHookTimestamp>@(IntermediateAssembly-&gt;'%(FullPath).timestamp')</_PostBuildHookTimestamp>
<_PostBuildHookHostPlatform>$(Platform)</_PostBuildHookHostPlatform>
</PropertyGroup>
<Target Name="PostBuildHooks" Inputs="@(IntermediateAssembly);@(ReferencePath)" Outputs="@(IntermediateAssembly);$(_PostBuildHookTimestamp)" AfterTargets="CoreCompile" BeforeTargets="AfterCompile">
<Touch Files="$(_PostBuildHookTimestamp)" AlwaysCreate="True" />
</Target>
<ItemGroup />
<ProjectExtensions>
<MonoDevelop>
<Properties><Policies>
<TextStylePolicy inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
<CSharpFormattingPolicy IndentSwitchSection="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="True" NewLineForMembersInAnonymousTypes="True" NewLineForClausesInQuery="True" SpacingAfterMethodDeclarationName="False" SpaceAfterMethodCallName="False" SpaceBeforeOpenSquareBracket="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
</Policies>
</Properties>
</MonoDevelop>
</ProjectExtensions>
</Project>
@@ -0,0 +1,280 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.ComponentModel;
namespace TwoMGFX
{
// Reusable, reflection based helper for parsing commandline options.
//
// From Shawn Hargreaves Blog:
// http://blogs.msdn.com/b/shawnhar/archive/2012/04/20/a-reusable-reflection-based-command-line-parser.aspx
//
public class CommandLineParser
{
object _optionsObject;
Queue<FieldInfo> _requiredOptions = new Queue<FieldInfo>();
Dictionary<string, FieldInfo> _optionalOptions = new Dictionary<string, FieldInfo>();
List<string> _requiredUsageHelp = new List<string>();
List<string> _optionalUsageHelp = new List<string>();
// Constructor.
public CommandLineParser(object optionsObject)
{
this._optionsObject = optionsObject;
// Reflect to find what commandline options are available.
foreach (var field in optionsObject.GetType().GetFields())
{
String description;
var fieldName = GetOptionNameAndDescription(field, out description);
if (GetAttribute<RequiredAttribute>(field) != null)
{
// Record a required option.
_requiredOptions.Enqueue(field);
_requiredUsageHelp.Add(string.Format("<{0}> {1}", fieldName, description));
}
else
{
// Record an optional option.
_optionalOptions.Add(fieldName.ToLowerInvariant(), field);
if (field.FieldType == typeof(bool))
_optionalUsageHelp.Add(string.Format("/{0} {1}", fieldName, description));
else
_optionalUsageHelp.Add(string.Format("/{0}:value {1}", fieldName, description));
}
}
}
public bool ParseCommandLine(string[] args)
{
// Parse each argument in turn.
foreach (var arg in args)
{
if (!ParseArgument(arg.Trim()))
return false;
}
// Make sure we got all the required options.
var missingRequiredOption = _requiredOptions.FirstOrDefault(field => !IsList(field) || GetList(field).Count == 0);
if (missingRequiredOption != null)
{
ShowError("Missing argument '{0}'", GetOptionName(missingRequiredOption));
return false;
}
return true;
}
bool ParseArgument(string arg)
{
if (arg.StartsWith("/"))
{
// After the first escaped argument we can no
// longer read non-escaped arguments.
_requiredOptions.Clear();
// Parse an optional argument.
char[] separators = { ':' };
var split = arg.Substring(1).Split(separators, 2, StringSplitOptions.None);
var name = split[0];
var value = (split.Length > 1) ? split[1] : "true";
FieldInfo field;
if (!_optionalOptions.TryGetValue(name.ToLowerInvariant(), out field))
{
ShowError("Unknown option '{0}'", name);
return false;
}
return SetOption(field, value);
}
else if ( _requiredOptions.Count > 0 )
{
// Parse the next non escaped argument.
var field = _requiredOptions.Peek();
if (!IsList(field))
_requiredOptions.Dequeue();
return SetOption(field, arg);
}
else
{
ShowError("Too many arguments");
return false;
}
}
bool SetOption(FieldInfo field, string value)
{
try
{
if (IsList(field))
{
// Append this value to a list of options.
GetList(field).Add(ChangeType(value, ListElementType(field)));
}
else
{
// Set the value of a single option.
field.SetValue(_optionsObject, ChangeType(value, field.FieldType));
}
return true;
}
catch
{
ShowError("Invalid value '{0}' for option '{1}'", value, GetOptionName(field));
return false;
}
}
static object ChangeType(string value, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
return converter.ConvertFromInvariantString(value);
}
static bool IsList(FieldInfo field)
{
return typeof(IList).IsAssignableFrom(field.FieldType);
}
IList GetList(FieldInfo field)
{
return (IList)field.GetValue(_optionsObject);
}
static Type ListElementType(FieldInfo field)
{
var interfaces = from i in field.FieldType.GetInterfaces()
where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>)
select i;
return interfaces.First().GetGenericArguments()[0];
}
static string GetOptionName(FieldInfo field)
{
var nameAttribute = GetAttribute<NameAttribute>(field);
if (nameAttribute != null)
return nameAttribute.Name;
else
return field.Name;
}
static string GetOptionNameAndDescription(FieldInfo field, out String description)
{
var nameAttribute = GetAttribute<NameAttribute>(field);
if (nameAttribute != null)
{
description = nameAttribute.Description;
return nameAttribute.Name;
}
else
{
description = null;
return field.Name;
}
}
public string Title { get; set; }
void ShowError(string message, params object[] args)
{
var name = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName);
if (!string.IsNullOrEmpty(Title))
{
Console.Error.WriteLine(Title);
Console.Error.WriteLine();
}
Console.Error.WriteLine(message, args);
Console.Error.WriteLine();
Console.Error.WriteLine("Usage: {0} {1}", name, string.Join(" ", _requiredUsageHelp));
if (_optionalUsageHelp.Count > 0)
{
Console.Error.WriteLine();
Console.Error.WriteLine("Options:");
foreach (string optional in _optionalUsageHelp)
Console.Error.WriteLine(" {0}", optional);
}
}
static T GetAttribute<T>(ICustomAttributeProvider provider) where T : Attribute
{
return provider.GetCustomAttributes(typeof(T), false).OfType<T>().FirstOrDefault();
}
// Used on optionsObject fields to indicate which options are required.
[AttributeUsage(AttributeTargets.Field)]
public sealed class RequiredAttribute : Attribute
{
}
// Used on an optionsObject field to rename the corresponding commandline option.
[AttributeUsage(AttributeTargets.Field)]
public class NameAttribute : Attribute
{
public NameAttribute(string name)
{
Name = name;
Description = null;
}
public NameAttribute(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; private set; }
public string Description { get; protected set; }
}
[AttributeUsage(AttributeTargets.Field)]
public sealed class ProfileNameAttribute : NameAttribute
{
public ProfileNameAttribute()
: base("Profile")
{
var names = ShaderProfile.All.Select(p => p.Name);
Description = "\t - Must be one of the following: " + string.Join(", ", names);
}
}
}
}
@@ -0,0 +1,61 @@
using System.Collections.Generic;
namespace TwoMGFX
{
internal partial class ConstantBufferData
{
public string Name { get; private set; }
public int Size { get; private set; }
public List<int> ParameterIndex { get; private set; }
public List<int> ParameterOffset { get; private set; }
public List<EffectObject.d3dx_parameter> Parameters { get; private set; }
public ConstantBufferData(string name)
{
Name = name;
ParameterIndex = new List<int>();
ParameterOffset = new List<int>();
Parameters = new List<EffectObject.d3dx_parameter>();
Size = 0;
}
public bool SameAs(ConstantBufferData other)
{
// If the names of the constant buffers don't
// match then consider them different right off
// the bat... even if their parameters are the same.
if (Name != other.Name)
return false;
// Do we have the same count of parameters and size?
if ( Size != other.Size ||
Parameters.Count != other.Parameters.Count)
return false;
// Compare the parameters themselves.
for (var i = 0; i < Parameters.Count; i++)
{
var p1 = Parameters[i];
var p2 = other.Parameters[i];
// Check the importaint bits.
if ( p1.name != p2.name ||
p1.rows != p2.rows ||
p1.columns != p2.columns ||
p1.class_ != p2.class_ ||
p1.type != p2.type ||
p1.bufferOffset != p2.bufferOffset)
return false;
}
// These are equal.
return true;
}
}
}
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
namespace TwoMGFX
{
internal partial class ConstantBufferData
{
public ConstantBufferData (string name,
MojoShader.MOJOSHADER_symbolRegisterSet set,
MojoShader.MOJOSHADER_symbol[] symbols)
{
Name = name ?? string.Empty;
ParameterIndex = new List<int> ();
ParameterOffset = new List<int> ();
Parameters = new List<EffectObject.d3dx_parameter> ();
int minRegister = short.MaxValue;
int maxRegister = 0;
var registerSize = (set == MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL ? 1 : 4) * 4;
foreach (var symbol in symbols) {
if (symbol.register_set != set)
continue;
// Create the parameter.
var parm = GetParameterFromSymbol (symbol);
var offset = (int)symbol.register_index * registerSize;
parm.bufferOffset = offset;
Parameters.Add (parm);
ParameterOffset.Add(offset);
minRegister = Math.Min(minRegister, (int)symbol.register_index);
maxRegister = Math.Max(maxRegister, (int)(symbol.register_index + symbol.register_count));
}
Size = Math.Max(maxRegister - minRegister, 0) * registerSize;
}
private static EffectObject.d3dx_parameter GetParameterFromSymbol(MojoShader.MOJOSHADER_symbol symbol)
{
var param = new EffectObject.d3dx_parameter();
param.rows = symbol.info.rows;
param.columns = symbol.info.columns;
param.name = symbol.name ?? string.Empty;
param.semantic = string.Empty; // TODO: How do i do this with only MojoShader?
var registerSize = (symbol.register_set == MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL ? 1 : 4) * 4;
var offset = (int)symbol.register_index * registerSize;
param.bufferOffset = offset;
switch (symbol.info.parameter_class)
{
case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_SCALAR:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.SCALAR;
break;
case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_VECTOR:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.VECTOR;
break;
case MojoShader.MOJOSHADER_symbolClass.MOJOSHADER_SYMCLASS_MATRIX_COLUMNS:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.MATRIX_COLUMNS;
break;
default:
throw new Exception("Unsupported parameter class!");
}
switch (symbol.info.parameter_type)
{
case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_BOOL:
param.type = EffectObject.D3DXPARAMETER_TYPE.BOOL;
break;
case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_FLOAT:
param.type = EffectObject.D3DXPARAMETER_TYPE.FLOAT;
break;
case MojoShader.MOJOSHADER_symbolType.MOJOSHADER_SYMTYPE_INT:
param.type = EffectObject.D3DXPARAMETER_TYPE.INT;
break;
default:
throw new Exception("Unsupported parameter type!");
}
// HACK: We don't have real default parameters from mojoshader!
param.data = new byte[param.rows * param.columns * 4];
param.member_count = symbol.info.member_count;
param.element_count = symbol.info.elements > 1 ? symbol.info.elements : 0;
if (param.member_count > 0)
{
param.member_handles = new EffectObject.d3dx_parameter[param.member_count];
var members = MarshalHelper.UnmarshalArray<MojoShader.MOJOSHADER_symbol>(
symbol.info.members, (int)symbol.info.member_count);
for (var i = 0; i < param.member_count; i++)
{
var mparam = GetParameterFromSymbol(members[i]);
param.member_handles[i] = mparam;
}
}
else
{
param.member_handles = new EffectObject.d3dx_parameter[param.element_count];
for (var i = 0; i < param.element_count; i++)
{
var mparam = new EffectObject.d3dx_parameter();
mparam.name = string.Empty;
mparam.semantic = string.Empty;
mparam.type = param.type;
mparam.class_ = param.class_;
mparam.rows = param.rows;
mparam.columns = param.columns;
mparam.data = new byte[param.columns * param.rows * 4];
param.member_handles[i] = mparam;
}
}
return param;
}
}
}
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace TwoMGFX
{
internal partial class ConstantBufferData
{
public ConstantBufferData(SharpDX.D3DCompiler.ConstantBuffer cb)
{
Name = string.Empty;
Size = cb.Description.Size;
ParameterIndex = new List<int>();
var parameters = new List<EffectObject.d3dx_parameter>();
// Gather all the parameters.
for (var i = 0; i < cb.Description.VariableCount; i++)
{
var vdesc = cb.GetVariable(i);
var param = GetParameterFromType(vdesc.GetVariableType());
param.name = vdesc.Description.Name;
param.semantic = string.Empty;
param.bufferOffset = vdesc.Description.StartOffset;
var size = param.columns * param.rows * 4;
var data = new byte[size];
if (vdesc.Description.DefaultValue != IntPtr.Zero)
Marshal.Copy(vdesc.Description.DefaultValue, data, 0, (int)size);
param.data = data;
parameters.Add(param);
}
// Sort them by the offset for some consistent results.
Parameters = parameters.OrderBy(e => e.bufferOffset).ToList();
// Store the parameter offsets.
ParameterOffset = new List<int>();
foreach (var param in Parameters)
ParameterOffset.Add(param.bufferOffset);
}
private static EffectObject.d3dx_parameter GetParameterFromType(SharpDX.D3DCompiler.ShaderReflectionType type)
{
var param = new EffectObject.d3dx_parameter();
param.rows = (uint)type.Description.RowCount;
param.columns = (uint)type.Description.ColumnCount;
param.name = type.Description.Name ?? string.Empty;
param.semantic = string.Empty;
param.bufferOffset = type.Description.Offset;
switch (type.Description.Class)
{
case SharpDX.D3DCompiler.ShaderVariableClass.Scalar:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.SCALAR;
break;
case SharpDX.D3DCompiler.ShaderVariableClass.Vector:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.VECTOR;
break;
case SharpDX.D3DCompiler.ShaderVariableClass.MatrixColumns:
param.class_ = EffectObject.D3DXPARAMETER_CLASS.MATRIX_COLUMNS;
break;
default:
throw new Exception("Unsupported parameter class!");
}
switch (type.Description.Type)
{
case SharpDX.D3DCompiler.ShaderVariableType.Bool:
param.type = EffectObject.D3DXPARAMETER_TYPE.BOOL;
break;
case SharpDX.D3DCompiler.ShaderVariableType.Float:
param.type = EffectObject.D3DXPARAMETER_TYPE.FLOAT;
break;
case SharpDX.D3DCompiler.ShaderVariableType.Int:
param.type = EffectObject.D3DXPARAMETER_TYPE.INT;
break;
default:
throw new Exception("Unsupported parameter type!");
}
param.member_count = (uint)type.Description.MemberCount;
param.element_count = (uint)type.Description.ElementCount;
if (param.member_count > 0)
{
param.member_handles = new EffectObject.d3dx_parameter[param.member_count];
for (var i = 0; i < param.member_count; i++)
{
var mparam = GetParameterFromType(type.GetMemberType(i));
mparam.name = type.GetMemberTypeName(i) ?? string.Empty;
param.member_handles[i] = mparam;
}
}
else
{
param.member_handles = new EffectObject.d3dx_parameter[param.element_count];
for (var i = 0; i < param.element_count; i++)
{
var mparam = new EffectObject.d3dx_parameter();
mparam.name = string.Empty;
mparam.semantic = string.Empty;
mparam.type = param.type;
mparam.class_ = param.class_;
mparam.rows = param.rows;
mparam.columns = param.columns;
mparam.data = new byte[param.columns * param.rows * 4];
param.member_handles[i] = mparam;
}
}
return param;
}
}
}
@@ -0,0 +1,21 @@
using System.IO;
namespace TwoMGFX
{
internal partial class ConstantBufferData
{
public void Write(BinaryWriter writer, Options options)
{
writer.Write(Name);
writer.Write((ushort)Size);
writer.Write((byte)ParameterIndex.Count);
for (var i=0; i < ParameterIndex.Count; i++)
{
writer.Write((byte)ParameterIndex[i]);
writer.Write((ushort)ParameterOffset[i]);
}
}
}
}
@@ -0,0 +1,846 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework.Graphics;
namespace TwoMGFX
{
internal partial class EffectObject
{
private EffectObject()
{
}
public enum D3DRENDERSTATETYPE
{
ZENABLE = 7,
FILLMODE = 8,
SHADEMODE = 9,
ZWRITEENABLE = 14,
ALPHATESTENABLE = 15,
LASTPIXEL = 16,
SRCBLEND = 19,
DESTBLEND = 20,
CULLMODE = 22,
ZFUNC = 23,
ALPHAREF = 24,
ALPHAFUNC = 25,
DITHERENABLE = 26,
ALPHABLENDENABLE = 27,
FOGENABLE = 28,
SPECULARENABLE = 29,
FOGCOLOR = 34,
FOGTABLEMODE = 35,
FOGSTART = 36,
FOGEND = 37,
FOGDENSITY = 38,
RANGEFOGENABLE = 48,
STENCILENABLE = 52,
STENCILFAIL = 53,
STENCILZFAIL = 54,
STENCILPASS = 55,
STENCILFUNC = 56,
STENCILREF = 57,
STENCILMASK = 58,
STENCILWRITEMASK = 59,
TEXTUREFACTOR = 60,
WRAP0 = 128,
WRAP1 = 129,
WRAP2 = 130,
WRAP3 = 131,
WRAP4 = 132,
WRAP5 = 133,
WRAP6 = 134,
WRAP7 = 135,
CLIPPING = 136,
LIGHTING = 137,
AMBIENT = 139,
FOGVERTEXMODE = 140,
COLORVERTEX = 141,
LOCALVIEWER = 142,
NORMALIZENORMALS = 143,
DIFFUSEMATERIALSOURCE = 145,
SPECULARMATERIALSOURCE = 146,
AMBIENTMATERIALSOURCE = 147,
EMISSIVEMATERIALSOURCE = 148,
VERTEXBLEND = 151,
CLIPPLANEENABLE = 152,
POINTSIZE = 154,
POINTSIZE_MIN = 155,
POINTSPRITEENABLE = 156,
POINTSCALEENABLE = 157,
POINTSCALE_A = 158,
POINTSCALE_B = 159,
POINTSCALE_C = 160,
MULTISAMPLEANTIALIAS = 161,
MULTISAMPLEMASK = 162,
PATCHEDGESTYLE = 163,
DEBUGMONITORTOKEN = 165,
POINTSIZE_MAX = 166,
INDEXEDVERTEXBLENDENABLE = 167,
COLORWRITEENABLE = 168,
TWEENFACTOR = 170,
BLENDOP = 171,
POSITIONDEGREE = 172,
NORMALDEGREE = 173,
SCISSORTESTENABLE = 174,
SLOPESCALEDEPTHBIAS = 175,
ANTIALIASEDLINEENABLE = 176,
MINTESSELLATIONLEVEL = 178,
MAXTESSELLATIONLEVEL = 179,
ADAPTIVETESS_X = 180,
ADAPTIVETESS_Y = 181,
ADAPTIVETESS_Z = 182,
ADAPTIVETESS_W = 183,
ENABLEADAPTIVETESSELLATION= 184,
TWOSIDEDSTENCILMODE = 185,
CCW_STENCILFAIL = 186,
CCW_STENCILZFAIL = 187,
CCW_STENCILPASS = 188,
CCW_STENCILFUNC = 189,
COLORWRITEENABLE1 = 190,
COLORWRITEENABLE2 = 191,
COLORWRITEENABLE3 = 192,
BLENDFACTOR = 193,
SRGBWRITEENABLE = 194,
DEPTHBIAS = 195,
WRAP8 = 198,
WRAP9 = 199,
WRAP10 = 200,
WRAP11 = 201,
WRAP12 = 202,
WRAP13 = 203,
WRAP14 = 204,
WRAP15 = 205,
SEPARATEALPHABLENDENABLE = 206,
SRCBLENDALPHA = 207,
DESTBLENDALPHA = 208,
BLENDOPALPHA = 209,
FORCE_DWORD = 0x7fffffff
}
public enum D3DTEXTURESTAGESTATETYPE
{
COLOROP = 1,
COLORARG1 = 2,
COLORARG2 = 3,
ALPHAOP = 4,
ALPHAARG1 = 5,
ALPHAARG2 = 6,
BUMPENVMAT00 = 7,
BUMPENVMAT01 = 8,
BUMPENVMAT10 = 9,
BUMPENVMAT11 = 10,
TEXCOORDINDEX = 11,
BUMPENVLSCALE = 22,
BUMPENVLOFFSET = 23,
TEXTURETRANSFORMFLAGS = 24,
COLORARG0 = 26,
ALPHAARG0 = 27,
RESULTARG = 28,
CONSTANT = 32,
FORCE_DWORD = 0x7fffffff
}
public enum D3DTRANSFORMSTATETYPE
{
VIEW = 2,
PROJECTION = 3,
TEXTURE0 = 16,
TEXTURE1 = 17,
TEXTURE2 = 18,
TEXTURE3 = 19,
TEXTURE4 = 20,
TEXTURE5 = 21,
TEXTURE6 = 22,
TEXTURE7 = 23,
WORLD = 256,
FORCE_DWORD = 0x7fffffff
}
public const int D3DX_PARAMETER_SHARED = 1;
public const int D3DX_PARAMETER_LITERAL = 2;
public const int D3DX_PARAMETER_ANNOTATION = 4;
public enum D3DXPARAMETER_CLASS
{
SCALAR,
VECTOR,
MATRIX_ROWS,
MATRIX_COLUMNS,
OBJECT,
STRUCT,
FORCE_DWORD = 0x7fffffff,
}
public enum D3DXPARAMETER_TYPE
{
VOID,
BOOL,
INT,
FLOAT,
STRING,
TEXTURE,
TEXTURE1D,
TEXTURE2D,
TEXTURE3D,
TEXTURECUBE,
SAMPLER,
SAMPLER1D,
SAMPLER2D,
SAMPLER3D,
SAMPLERCUBE,
PIXELSHADER,
VERTEXSHADER,
PIXELFRAGMENT,
VERTEXFRAGMENT,
UNSUPPORTED,
FORCE_DWORD = 0x7fffffff,
}
enum D3DSAMPLERSTATETYPE
{
ADDRESSU = 1,
ADDRESSV = 2,
ADDRESSW = 3,
BORDERCOLOR = 4,
MAGFILTER = 5,
MINFILTER = 6,
MIPFILTER = 7,
MIPMAPLODBIAS = 8,
MAXMIPLEVEL = 9,
MAXANISOTROPY = 10,
SRGBTEXTURE = 11,
ELEMENTINDEX = 12,
DMAPOFFSET = 13,
FORCE_DWORD = 0x7fffffff,
};
public enum STATE_CLASS
{
LIGHTENABLE,
FVF,
LIGHT,
MATERIAL,
NPATCHMODE,
PIXELSHADER,
RENDERSTATE,
SETSAMPLER,
SAMPLERSTATE,
TEXTURE,
TEXTURESTAGE,
TRANSFORM,
VERTEXSHADER,
SHADERCONST,
UNKNOWN,
};
public enum MATERIAL_TYPE
{
DIFFUSE,
AMBIENT,
SPECULAR,
EMISSIVE,
POWER,
};
public enum LIGHT_TYPE
{
TYPE,
DIFFUSE,
SPECULAR,
AMBIENT,
POSITION,
DIRECTION,
RANGE,
FALLOFF,
ATTENUATION0,
ATTENUATION1,
ATTENUATION2,
THETA,
PHI,
};
public enum SHADER_CONSTANT_TYPE
{
VSFLOAT,
VSBOOL,
VSINT,
PSFLOAT,
PSBOOL,
PSINT,
}
public enum STATE_TYPE
{
CONSTANT,
PARAMETER,
EXPRESSION,
EXPRESSIONINDEX,
}
public class d3dx_parameter
{
public string name;
public string semantic;
public object data;
public D3DXPARAMETER_CLASS class_;
public D3DXPARAMETER_TYPE type;
public uint rows;
public uint columns;
public uint element_count;
public uint annotation_count = 0;
public uint member_count;
public uint flags = 0;
public uint bytes = 0;
public int bufferIndex = -1;
public int bufferOffset = -1;
public d3dx_parameter[] annotation_handles = null;
public d3dx_parameter[] member_handles;
public override string ToString()
{
if (rows > 0 || columns > 0)
return string.Format("{0} {1}{2}x{3} {4} : cb{5},{6}", class_, type, rows, columns, name, bufferIndex, bufferOffset);
else
return string.Format("{0} {1} {2}", class_, type, name);
}
}
public class d3dx_state
{
public uint operation;
public uint index;
public STATE_TYPE type;
public d3dx_parameter parameter;
}
public class d3dx_sampler
{
public uint state_count = 0;
public d3dx_state[] states = null;
}
public class d3dx_pass
{
public string name;
public uint state_count;
public uint annotation_count = 0;
public BlendState blendState;
public DepthStencilState depthStencilState;
public RasterizerState rasterizerState;
public d3dx_state[] states;
public d3dx_parameter[] annotation_handles = null;
}
public class d3dx_technique
{
public string name;
public uint pass_count;
public uint annotation_count = 0;
public d3dx_parameter[] annotation_handles = null;
public d3dx_pass[] pass_handles;
}
public class state_info
{
public STATE_CLASS class_ { get; private set; }
public uint op { get; private set; }
public string name { get; private set; }
public state_info(STATE_CLASS class_, uint op, string name)
{
this.class_ = class_;
this.op = op;
this.name = name;
}
}
/// <summary>
/// The shared state definition table.
/// </summary>
public static readonly state_info[] state_table =
{
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ZENABLE, "ZENABLE"), /* 0x0 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FILLMODE, "FILLMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SHADEMODE, "SHADEMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ZWRITEENABLE, "ZWRITEENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ALPHATESTENABLE, "ALPHATESTENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.LASTPIXEL, "LASTPIXEL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SRCBLEND, "SRCBLEND"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DESTBLEND, "DESTBLEND"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CULLMODE, "CULLMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ZFUNC, "ZFUNC"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ALPHAREF, "ALPHAREF"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ALPHAFUNC, "ALPHAFUNC"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DITHERENABLE, "DITHERENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ALPHABLENDENABLE, "ALPHABLENDENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGENABLE, "FOGENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SPECULARENABLE, "SPECULARENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGCOLOR, "FOGCOLOR"), /* 0x10 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGTABLEMODE, "FOGTABLEMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGSTART, "FOGSTART"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGEND, "FOGEND"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGDENSITY, "FOGDENSITY"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.RANGEFOGENABLE, "RANGEFOGENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILENABLE, "STENCILENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILFAIL, "STENCILFAIL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILZFAIL, "STENCILZFAIL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILPASS, "STENCILPASS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILFUNC, "STENCILFUNC"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILREF, "STENCILREF"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILMASK, "STENCILMASK"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.STENCILWRITEMASK, "STENCILWRITEMASK"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.TEXTUREFACTOR, "TEXTUREFACTOR"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP0, "WRAP0"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP1, "WRAP1"), /* 0x20 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP2, "WRAP2"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP3, "WRAP3"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP4, "WRAP4"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP5, "WRAP5"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP6, "WRAP6"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP7, "WRAP7"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP8, "WRAP8"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP9, "WRAP9"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP10, "WRAP10"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP11, "WRAP11"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP12, "WRAP12"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP13, "WRAP13"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP14, "WRAP14"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.WRAP15, "WRAP15"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CLIPPING, "CLIPPING"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.LIGHTING, "LIGHTING"), /* 0x30 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.AMBIENT, "AMBIENT"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.FOGVERTEXMODE, "FOGVERTEXMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.COLORVERTEX, "COLORVERTEX"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.LOCALVIEWER, "LOCALVIEWER"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.NORMALIZENORMALS, "NORMALIZENORMALS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DIFFUSEMATERIALSOURCE, "DIFFUSEMATERIALSOURCE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SPECULARMATERIALSOURCE, "SPECULARMATERIALSOURCE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.AMBIENTMATERIALSOURCE, "AMBIENTMATERIALSOURCE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.EMISSIVEMATERIALSOURCE, "EMISSIVEMATERIALSOURCE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.VERTEXBLEND, "VERTEXBLEND"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CLIPPLANEENABLE, "CLIPPLANEENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSIZE, "POINTSIZE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSIZE_MIN, "POINTSIZE_MIN"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSIZE_MAX, "POINTSIZE_MAX"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSPRITEENABLE, "POINTSPRITEENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSCALEENABLE, "POINTSCALEENABLE"), /* 0x40 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSCALE_A, "POINTSCALE_A"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSCALE_B, "POINTSCALE_B"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POINTSCALE_C, "POINTSCALE_C"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.MULTISAMPLEANTIALIAS, "MULTISAMPLEANTIALIAS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.MULTISAMPLEMASK, "MULTISAMPLEMASK"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.PATCHEDGESTYLE, "PATCHEDGESTYLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DEBUGMONITORTOKEN, "DEBUGMONITORTOKEN"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.INDEXEDVERTEXBLENDENABLE, "INDEXEDVERTEXBLENDENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.COLORWRITEENABLE, "COLORWRITEENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.TWEENFACTOR, "TWEENFACTOR"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.BLENDOP, "BLENDOP"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.POSITIONDEGREE, "POSITIONDEGREE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.NORMALDEGREE, "NORMALDEGREE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SCISSORTESTENABLE, "SCISSORTESTENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SLOPESCALEDEPTHBIAS, "SLOPESCALEDEPTHBIAS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ANTIALIASEDLINEENABLE, "ANTIALIASEDLINEENABLE"), /* 0x50 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.MINTESSELLATIONLEVEL, "MINTESSELLATIONLEVEL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.MAXTESSELLATIONLEVEL, "MAXTESSELLATIONLEVEL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ADAPTIVETESS_X, "ADAPTIVETESS_X"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ADAPTIVETESS_Y, "ADAPTIVETESS_Y"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ADAPTIVETESS_Z, "ADAPTIVETESS_Z"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ADAPTIVETESS_W, "ADAPTIVETESS_W"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.ENABLEADAPTIVETESSELLATION, "ENABLEADAPTIVETESSELLATION"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.TWOSIDEDSTENCILMODE, "TWOSIDEDSTENCILMODE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CCW_STENCILFAIL, "CCW_STENCILFAIL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CCW_STENCILZFAIL, "CCW_STENCILZFAIL"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CCW_STENCILPASS, "CCW_STENCILPASS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.CCW_STENCILFUNC, "CCW_STENCILFUNC"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.COLORWRITEENABLE1, "COLORWRITEENABLE1"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.COLORWRITEENABLE2, "COLORWRITEENABLE2"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.COLORWRITEENABLE3, "COLORWRITEENABLE3"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.BLENDFACTOR, "BLENDFACTOR"), /* 0x60 */
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SRGBWRITEENABLE, "SRGBWRITEENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DEPTHBIAS, "DEPTHBIAS"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SEPARATEALPHABLENDENABLE, "SEPARATEALPHABLENDENABLE"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.SRCBLENDALPHA, "SRCBLENDALPHA"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.DESTBLENDALPHA, "DESTBLENDALPHA"),
new state_info(STATE_CLASS.RENDERSTATE, (uint)D3DRENDERSTATETYPE.BLENDOPALPHA, "BLENDOPALPHA"),
/* Texture stages */
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.COLOROP, "COLOROP"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.COLORARG0, "COLORARG0"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.COLORARG1, "COLORARG1"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.COLORARG2, "COLORARG2"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.ALPHAOP, "ALPHAOP"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.ALPHAARG0, "ALPHAARG0"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.ALPHAARG1, "ALPHAARG1"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.ALPHAARG2, "ALPHAARG2"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.RESULTARG, "RESULTARG"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVMAT00, "BUMPENVMAT00"), /* 0x70 */
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVMAT01, "BUMPENVMAT01"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVMAT10, "BUMPENVMAT10"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVMAT11, "BUMPENVMAT11"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.TEXCOORDINDEX, "TEXCOORDINDEX"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVLSCALE, "BUMPENVLSCALE"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.BUMPENVLOFFSET, "BUMPENVLOFFSET"),
new state_info(STATE_CLASS.TEXTURESTAGE, (uint)D3DTEXTURESTAGESTATETYPE.TEXTURETRANSFORMFLAGS, "TEXTURETRANSFORMFLAGS"),
/* */
new state_info(STATE_CLASS.UNKNOWN, 0, "UNKNOWN"),
/* NPatchMode */
new state_info(STATE_CLASS.NPATCHMODE, 0, "NPatchMode"),
/* */
new state_info(STATE_CLASS.UNKNOWN, 0, "UNKNOWN"),
/* Transform */
new state_info(STATE_CLASS.TRANSFORM, (uint)D3DTRANSFORMSTATETYPE.PROJECTION, "PROJECTION"),
new state_info(STATE_CLASS.TRANSFORM, (uint)D3DTRANSFORMSTATETYPE.VIEW, "VIEW"),
new state_info(STATE_CLASS.TRANSFORM, (uint)D3DTRANSFORMSTATETYPE.WORLD, "WORLD"),
new state_info(STATE_CLASS.TRANSFORM, (uint)D3DTRANSFORMSTATETYPE.TEXTURE0, "TEXTURE0"),
/* Material */
new state_info(STATE_CLASS.MATERIAL, (uint)MATERIAL_TYPE.DIFFUSE, "MaterialDiffuse"),
new state_info(STATE_CLASS.MATERIAL, (uint)MATERIAL_TYPE.AMBIENT, "MaterialAmbient"), /* 0x80 */
new state_info(STATE_CLASS.MATERIAL, (uint)MATERIAL_TYPE.SPECULAR, "MaterialSpecular"),
new state_info(STATE_CLASS.MATERIAL, (uint)MATERIAL_TYPE.EMISSIVE, "MaterialEmissive"),
new state_info(STATE_CLASS.MATERIAL, (uint)MATERIAL_TYPE.POWER, "MaterialPower"),
/* Light */
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.TYPE, "LightType"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.DIFFUSE, "LightDiffuse"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.SPECULAR, "LightSpecular"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.AMBIENT, "LightAmbient"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.POSITION, "LightPosition"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.DIRECTION, "LightDirection"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.RANGE, "LightRange"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.FALLOFF, "LightFallOff"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.ATTENUATION0, "LightAttenuation0"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.ATTENUATION1, "LightAttenuation1"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.ATTENUATION2, "LightAttenuation2"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.THETA, "LightTheta"),
new state_info(STATE_CLASS.LIGHT, (uint)LIGHT_TYPE.PHI, "LightPhi"), /* 0x90 */
/* Ligthenable */
new state_info(STATE_CLASS.LIGHTENABLE, 0, "LightEnable"),
/* Vertexshader */
new state_info(STATE_CLASS.VERTEXSHADER, 0, "Vertexshader"),
/* Pixelshader */
new state_info(STATE_CLASS.PIXELSHADER, 0, "Pixelshader"),
/* Shader constants */
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstantF"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSBOOL, "VertexShaderConstantB"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSINT, "VertexShaderConstantI"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstant"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstant1"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstant2"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstant3"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.VSFLOAT, "VertexShaderConstant4"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstantF"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSBOOL, "PixelShaderConstantB"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSINT, "PixelShaderConstantI"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstant"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstant1"), /* 0xa0 */
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstant2"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstant3"),
new state_info(STATE_CLASS.SHADERCONST, (uint)SHADER_CONSTANT_TYPE.PSFLOAT, "PixelShaderConstant4"),
/* Texture */
new state_info(STATE_CLASS.TEXTURE, 0, "Texture"),
/* Sampler states */
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.ADDRESSU, "AddressU"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.ADDRESSV, "AddressV"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.ADDRESSW, "AddressW"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.BORDERCOLOR, "BorderColor"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MAGFILTER, "MagFilter"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MINFILTER, "MinFilter"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MIPFILTER, "MipFilter"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MIPMAPLODBIAS, "MipMapLodBias"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MAXMIPLEVEL, "MaxMipLevel"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.MAXANISOTROPY, "MaxAnisotropy"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.SRGBTEXTURE, "SRGBTexture"),
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.ELEMENTINDEX, "ElementIndex"), /* 0xb0 */
new state_info(STATE_CLASS.SAMPLERSTATE, (uint)D3DSAMPLERSTATETYPE.DMAPOFFSET, "DMAPOffset"),
/* Set sampler */
new state_info(STATE_CLASS.SETSAMPLER, 0, "Sampler"),
};
static public EffectParameterClass ToXNAParameterClass( D3DXPARAMETER_CLASS class_ )
{
switch (class_)
{
case D3DXPARAMETER_CLASS.SCALAR:
return EffectParameterClass.Scalar;
case D3DXPARAMETER_CLASS.VECTOR:
return EffectParameterClass.Vector;
case D3DXPARAMETER_CLASS.MATRIX_ROWS:
case D3DXPARAMETER_CLASS.MATRIX_COLUMNS:
return EffectParameterClass.Matrix;
case D3DXPARAMETER_CLASS.OBJECT:
return EffectParameterClass.Object;
case D3DXPARAMETER_CLASS.STRUCT:
return EffectParameterClass.Struct;
default:
throw new NotImplementedException();
}
}
static public EffectParameterType ToXNAParameterType(D3DXPARAMETER_TYPE type)
{
switch (type)
{
case D3DXPARAMETER_TYPE.BOOL:
return EffectParameterType.Bool;
case D3DXPARAMETER_TYPE.INT:
return EffectParameterType.Int32;
case D3DXPARAMETER_TYPE.FLOAT:
return EffectParameterType.Single;
case D3DXPARAMETER_TYPE.STRING:
return EffectParameterType.String;
case D3DXPARAMETER_TYPE.TEXTURE:
return EffectParameterType.Texture;
case D3DXPARAMETER_TYPE.TEXTURE1D:
return EffectParameterType.Texture1D;
case D3DXPARAMETER_TYPE.TEXTURE2D:
return EffectParameterType.Texture2D;
case D3DXPARAMETER_TYPE.TEXTURE3D:
return EffectParameterType.Texture3D;
case D3DXPARAMETER_TYPE.TEXTURECUBE:
return EffectParameterType.TextureCube;
default:
throw new NotImplementedException();
}
}
static internal VertexElementUsage ToXNAVertexElementUsage(MojoShader.MOJOSHADER_usage usage)
{
switch (usage)
{
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_POSITION:
return VertexElementUsage.Position;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BLENDWEIGHT:
return VertexElementUsage.BlendWeight;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BLENDINDICES:
return VertexElementUsage.BlendIndices;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_NORMAL:
return VertexElementUsage.Normal;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_POINTSIZE:
return VertexElementUsage.PointSize;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TEXCOORD:
return VertexElementUsage.TextureCoordinate;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TANGENT:
return VertexElementUsage.Tangent;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_BINORMAL:
return VertexElementUsage.Binormal;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_TESSFACTOR:
return VertexElementUsage.TessellateFactor;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_COLOR:
return VertexElementUsage.Color;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_FOG:
return VertexElementUsage.Fog;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_DEPTH:
return VertexElementUsage.Depth;
case MojoShader.MOJOSHADER_usage.MOJOSHADER_USAGE_SAMPLE:
return VertexElementUsage.Sample;
default:
throw new NotImplementedException();
}
}
static public EffectObject CompileEffect(ShaderResult shaderResult, out string errorsAndWarnings)
{
var effect = new EffectObject();
errorsAndWarnings = string.Empty;
// These are filled out as we process stuff.
effect.ConstantBuffers = new List<ConstantBufferData>();
effect.Shaders = new List<ShaderData>();
// Go thru the techniques and that will find all the
// shaders and constant buffers.
var shaderInfo = shaderResult.ShaderInfo;
effect.Techniques = new d3dx_technique[shaderInfo.Techniques.Count];
for (var t = 0; t < shaderInfo.Techniques.Count; t++)
{
var tinfo = shaderInfo.Techniques[t]; ;
var technique = new d3dx_technique();
technique.name = tinfo.name;
technique.pass_count = (uint)tinfo.Passes.Count;
technique.pass_handles = new d3dx_pass[tinfo.Passes.Count];
for (var p = 0; p < tinfo.Passes.Count; p++)
{
var pinfo = tinfo.Passes[p];
var pass = new d3dx_pass();
pass.name = pinfo.name ?? string.Empty;
pass.blendState = pinfo.blendState;
pass.depthStencilState = pinfo.depthStencilState;
pass.rasterizerState = pinfo.rasterizerState;
pass.state_count = 0;
var tempstate = new d3dx_state[2];
shaderResult.Profile.ValidateShaderModels(pinfo);
if (!string.IsNullOrEmpty(pinfo.psFunction))
{
pass.state_count += 1;
tempstate[pass.state_count - 1] = effect.CreateShader(shaderResult, pinfo.psFunction, pinfo.psModel, false, ref errorsAndWarnings);
}
if (!string.IsNullOrEmpty(pinfo.vsFunction))
{
pass.state_count += 1;
tempstate[pass.state_count - 1] = effect.CreateShader(shaderResult, pinfo.vsFunction, pinfo.vsModel, true, ref errorsAndWarnings);
}
pass.states = new d3dx_state[pass.state_count];
for (var s = 0; s < pass.state_count; s++)
pass.states[s] = tempstate[s];
technique.pass_handles[p] = pass;
}
effect.Techniques[t] = technique;
}
// Make the list of parameters by combining all the
// constant buffers ignoring the buffer offsets.
var parameters = new List<d3dx_parameter>();
for (var c = 0; c < effect.ConstantBuffers.Count; c++)
{
var cb = effect.ConstantBuffers[c];
for (var i = 0; i < cb.Parameters.Count; i++)
{
var param = cb.Parameters[i];
var match = parameters.FindIndex(e => e.name == param.name);
if (match == -1)
{
cb.ParameterIndex.Add(parameters.Count);
parameters.Add(param);
}
else
{
// TODO: Make sure the type and size of
// the parameter match up!
cb.ParameterIndex.Add(match);
}
}
}
// Add the texture parameters from the samplers.
foreach (var shader in effect.Shaders)
{
for (var s = 0; s < shader._samplers.Length; s++)
{
var sampler = shader._samplers[s];
var match = parameters.FindIndex(e => e.name == sampler.parameterName);
if (match == -1)
{
// Store the index for runtime lookup.
shader._samplers[s].parameter = parameters.Count;
var param = new d3dx_parameter();
param.class_ = D3DXPARAMETER_CLASS.OBJECT;
param.name = sampler.parameterName;
param.semantic = string.Empty;
switch (sampler.type)
{
case MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_1D:
param.type = D3DXPARAMETER_TYPE.TEXTURE1D;
break;
case MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_2D:
param.type = D3DXPARAMETER_TYPE.TEXTURE2D;
break;
case MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_VOLUME:
param.type = D3DXPARAMETER_TYPE.TEXTURE3D;
break;
case MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_CUBE:
param.type = D3DXPARAMETER_TYPE.TEXTURECUBE;
break;
}
parameters.Add(param);
}
else
{
// TODO: Make sure the type and size of
// the parameter match up!
shader._samplers[s].parameter = match;
}
}
}
// TODO: Annotations are part of the .FX format and
// not a part of shaders... we need to implement them
// in our mgfx parser if we want them back.
effect.Parameters = parameters.ToArray();
return effect;
}
private d3dx_state CreateShader(ShaderResult shaderResult, string shaderFunction, string shaderProfile, bool isVertexShader, ref string errorsAndWarnings)
{
// Compile and create the shader.
var shaderData = shaderResult.Profile.CreateShader(shaderResult, shaderFunction, shaderProfile, isVertexShader, this, ref errorsAndWarnings);
var state = new d3dx_state();
state.index = 0;
state.type = STATE_TYPE.CONSTANT;
state.operation = isVertexShader ? (uint)146 : (uint)147;
state.parameter = new d3dx_parameter();
state.parameter.name = string.Empty;
state.parameter.semantic = string.Empty;
state.parameter.class_ = D3DXPARAMETER_CLASS.OBJECT;
state.parameter.type = isVertexShader ? D3DXPARAMETER_TYPE.VERTEXSHADER : D3DXPARAMETER_TYPE.PIXELSHADER;
state.parameter.rows = 0;
state.parameter.columns = 0;
state.parameter.data = shaderData.SharedIndex;
return state;
}
internal static int GetShaderIndex(STATE_CLASS type, d3dx_state[] states)
{
foreach (var state in states)
{
var operation = state_table[state.operation];
if (operation.class_ != type)
continue;
if (state.type != STATE_TYPE.CONSTANT)
throw new NotSupportedException("We do not support shader expressions!");
return (int)state.parameter.data;
}
return -1;
}
public d3dx_parameter[] Objects { get; private set; }
public d3dx_parameter[] Parameters { get; private set; }
public d3dx_technique[] Techniques { get; private set; }
public List<ShaderData> Shaders { get; private set; }
public List<ConstantBufferData> ConstantBuffers { get; private set; }
}
}
@@ -0,0 +1,63 @@
using System;
using System.Linq;
namespace TwoMGFX
{
partial class EffectObject
{
public static byte[] CompileHLSL(ShaderResult shaderResult, string shaderFunction, string shaderProfile, ref string errorsAndWarnings)
{
SharpDX.D3DCompiler.ShaderBytecode shaderByteCode;
try
{
SharpDX.D3DCompiler.ShaderFlags shaderFlags = 0;
// While we never allow preshaders, this flag is invalid for
// the DX11 shader compiler which doesn't allow preshaders
// in the first place.
//shaderFlags |= SharpDX.D3DCompiler.ShaderFlags.NoPreshader;
if (shaderResult.Profile == ShaderProfile.DirectX_11)
shaderFlags |= SharpDX.D3DCompiler.ShaderFlags.EnableBackwardsCompatibility;
if (shaderResult.Debug)
{
shaderFlags |= SharpDX.D3DCompiler.ShaderFlags.SkipOptimization;
shaderFlags |= SharpDX.D3DCompiler.ShaderFlags.Debug;
}
else
{
shaderFlags |= SharpDX.D3DCompiler.ShaderFlags.OptimizationLevel3;
}
// Compile the shader into bytecode.
var result = SharpDX.D3DCompiler.ShaderBytecode.Compile(
shaderResult.FileContent,
shaderFunction,
shaderProfile,
shaderFlags,
0,
null,
null,
shaderResult.FilePath);
// Store all the errors and warnings to log out later.
errorsAndWarnings += result.Message;
if (result.Bytecode == null)
throw new ShaderCompilerException();
shaderByteCode = result.Bytecode;
//var source = shaderByteCode.Disassemble();
}
catch (SharpDX.CompilationException ex)
{
errorsAndWarnings += ex.Message;
throw new ShaderCompilerException();
}
// Return a copy of the shader bytecode.
return shaderByteCode.Data.ToArray();
}
}
}
@@ -0,0 +1,13 @@
using System;
namespace TwoMGFX
{
partial class EffectObject
{
private static byte[] CompilePSSL(ShaderResult shaderResult, string shaderFunction, string shaderProfile, ref string errorsAndWarnings)
{
// This is only part of the private PS4 repository.
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,188 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace TwoMGFX
{
internal partial class EffectObject
{
private const string Header = "MGFX";
private const int Version = 8;
/// <summary>
/// Writes the effect for loading later.
/// </summary>
public void Write(BinaryWriter writer, Options options)
{
// Write a very simple header for identification and versioning.
writer.Write(Header.ToCharArray());
writer.Write((byte)Version);
// Write an simple identifier for DX11 vs GLSL
// so we can easily detect the correct shader type.
var profile = (byte)options.Profile.FormatId;
writer.Write(profile);
// Write the rest to a memory stream.
using(MemoryStream memStream = new MemoryStream())
using(BinaryWriter memWriter = new BinaryWriter(memStream))
{
// Write all the constant buffers.
memWriter.Write((byte)ConstantBuffers.Count);
foreach (var cbuffer in ConstantBuffers)
cbuffer.Write(memWriter, options);
// Write all the shaders.
memWriter.Write((byte)Shaders.Count);
foreach (var shader in Shaders)
shader.Write(memWriter, options);
// Write the parameters.
WriteParameters(memWriter, Parameters, Parameters.Length);
// Write the techniques.
memWriter.Write((byte)Techniques.Length);
foreach (var technique in Techniques)
{
memWriter.Write(technique.name);
WriteAnnotations(memWriter, technique.annotation_handles);
// Write the passes.
memWriter.Write((byte)technique.pass_count);
for (var p = 0; p < technique.pass_count; p++)
{
var pass = technique.pass_handles[p];
memWriter.Write(pass.name);
WriteAnnotations(memWriter, pass.annotation_handles);
// Write the index for the vertex and pixel shaders.
var vertexShader = GetShaderIndex(STATE_CLASS.VERTEXSHADER, pass.states);
var pixelShader = GetShaderIndex(STATE_CLASS.PIXELSHADER, pass.states);
memWriter.Write((byte)vertexShader);
memWriter.Write((byte)pixelShader);
// Write the state objects too!
if (pass.blendState != null)
{
memWriter.Write(true);
memWriter.Write((byte)pass.blendState.AlphaBlendFunction);
memWriter.Write((byte)pass.blendState.AlphaDestinationBlend);
memWriter.Write((byte)pass.blendState.AlphaSourceBlend);
memWriter.Write(pass.blendState.BlendFactor.R);
memWriter.Write(pass.blendState.BlendFactor.G);
memWriter.Write(pass.blendState.BlendFactor.B);
memWriter.Write(pass.blendState.BlendFactor.A);
memWriter.Write((byte)pass.blendState.ColorBlendFunction);
memWriter.Write((byte)pass.blendState.ColorDestinationBlend);
memWriter.Write((byte)pass.blendState.ColorSourceBlend);
memWriter.Write((byte)pass.blendState.ColorWriteChannels);
memWriter.Write((byte)pass.blendState.ColorWriteChannels1);
memWriter.Write((byte)pass.blendState.ColorWriteChannels2);
memWriter.Write((byte)pass.blendState.ColorWriteChannels3);
memWriter.Write(pass.blendState.MultiSampleMask);
}
else
memWriter.Write(false);
if (pass.depthStencilState != null)
{
memWriter.Write(true);
memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilDepthBufferFail);
memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilFail);
memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilFunction);
memWriter.Write((byte)pass.depthStencilState.CounterClockwiseStencilPass);
memWriter.Write(pass.depthStencilState.DepthBufferEnable);
memWriter.Write((byte)pass.depthStencilState.DepthBufferFunction);
memWriter.Write(pass.depthStencilState.DepthBufferWriteEnable);
memWriter.Write(pass.depthStencilState.ReferenceStencil);
memWriter.Write((byte)pass.depthStencilState.StencilDepthBufferFail);
memWriter.Write(pass.depthStencilState.StencilEnable);
memWriter.Write((byte)pass.depthStencilState.StencilFail);
memWriter.Write((byte)pass.depthStencilState.StencilFunction);
memWriter.Write(pass.depthStencilState.StencilMask);
memWriter.Write((byte)pass.depthStencilState.StencilPass);
memWriter.Write(pass.depthStencilState.StencilWriteMask);
memWriter.Write(pass.depthStencilState.TwoSidedStencilMode);
}
else
memWriter.Write(false);
if (pass.rasterizerState != null)
{
memWriter.Write(true);
memWriter.Write((byte)pass.rasterizerState.CullMode);
memWriter.Write(pass.rasterizerState.DepthBias);
memWriter.Write((byte)pass.rasterizerState.FillMode);
memWriter.Write(pass.rasterizerState.MultiSampleAntiAlias);
memWriter.Write(pass.rasterizerState.ScissorTestEnable);
memWriter.Write(pass.rasterizerState.SlopeScaleDepthBias);
}
else
memWriter.Write(false);
}
}
// Calculate a hash code from memory stream
// and write it to the header.
var effectKey = MonoGame.Utilities.Hash.ComputeHash(memStream);
writer.Write((Int32)effectKey);
//write content from memory stream to final stream.
memStream.WriteTo(writer.BaseStream);
}
}
private static void WriteParameters(BinaryWriter writer, d3dx_parameter[] parameters, int count)
{
writer.Write((byte)count);
for (var i = 0; i < count; i++)
WriteParameter(writer, parameters[i]);
}
private static void WriteParameter(BinaryWriter writer, d3dx_parameter param)
{
var class_ = ToXNAParameterClass(param.class_);
var type = ToXNAParameterType(param.type);
writer.Write((byte)class_);
writer.Write((byte)type);
writer.Write(param.name);
writer.Write(param.semantic);
WriteAnnotations(writer, param.annotation_handles);
writer.Write((byte)param.rows);
writer.Write((byte)param.columns);
// Write the elements or struct members.
WriteParameters(writer, param.member_handles, (int)param.element_count);
WriteParameters(writer, param.member_handles, (int)param.member_count);
if (param.element_count == 0 && param.member_count == 0)
{
switch (type)
{
case EffectParameterType.Bool:
case EffectParameterType.Int32:
case EffectParameterType.Single:
writer.Write((byte[])param.data);
break;
}
}
}
private static void WriteAnnotations(BinaryWriter writer, d3dx_parameter[] annotations)
{
var count = annotations == null ? 0 : annotations.Length;
writer.Write((byte)count);
for (var i = 0; i < count; i++)
WriteParameter(writer, annotations[i]);
}
}
}
@@ -0,0 +1,8 @@
namespace TwoMGFX
{
public interface IEffectCompilerOutput
{
void WriteWarning(string file, int line, int column, string message);
void WriteError(string file, int line, int column, string message);
}
}
@@ -0,0 +1,39 @@
using System;
using System.Runtime.InteropServices;
namespace TwoMGFX
{
internal class MarshalHelper
{
public static T Unmarshal<T>(IntPtr ptr)
{
var type = typeof(T);
var result = (T)Marshal.PtrToStructure(ptr, type);
return result;
}
public static T[] UnmarshalArray<T>(IntPtr ptr, int count)
{
var type = typeof(T);
var size = Marshal.SizeOf(type);
var ret = new T[count];
for (int i = 0; i < count; i++)
{
var offset = i * size;
var structPtr = new IntPtr(ptr.ToInt64() + offset);
ret[i] = (T)Marshal.PtrToStructure(structPtr, type);
}
return ret;
}
public static byte[] UnmarshalArray(IntPtr ptr, int count)
{
var result = new byte[count];
Marshal.Copy(ptr, result, 0, count);
return result;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
using System;
namespace Microsoft.Xna.Framework.Graphics
{
// Dummy class for 2MGFX to compile.
public class GraphicsDevice
{
internal void AddResourceReference(WeakReference resourceReference)
{
}
internal void RemoveResourceReference(WeakReference resourceReference)
{
}
}
}
@@ -0,0 +1,24 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
namespace TwoMGFX
{
public class Options
{
[CommandLineParser.Required]
public string SourceFile;
[CommandLineParser.Required]
public string OutputFile = string.Empty;
[CommandLineParser.ProfileName]
public ShaderProfile Profile = ShaderProfile.OpenGL;
[CommandLineParser.Name("Debug", "\t\t - Include extra debug information in the compiled effect.")]
public bool Debug;
[CommandLineParser.Name("Defines", "\t - Semicolon-delimited define assignments")]
public string Defines;
}
}
@@ -0,0 +1,185 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using CppNet;
namespace TwoMGFX
{
public static class Preprocessor
{
public static string Preprocess(
string effectCode, string filePath, IDictionary<string, string> defines, List<string> dependencies,
IEffectCompilerOutput output)
{
var fullPath = Path.GetFullPath(filePath);
var pp = new CppNet.Preprocessor();
pp.EmitExtraLineInfo = false;
pp.addFeature(Feature.LINEMARKERS);
pp.setListener(new MGErrorListener(output));
pp.setFileSystem(new MGFileSystem(dependencies));
pp.setQuoteIncludePath(new List<string> { Path.GetDirectoryName(fullPath) });
foreach (var define in defines)
pp.addMacro(define.Key, define.Value);
effectCode = effectCode.Replace("#line", "//--WORKAROUND#line");
pp.addInput(new MGStringLexerSource(effectCode, true, fullPath));
var result = new StringBuilder();
var endOfStream = false;
while (!endOfStream)
{
var token = pp.token();
switch (token.getType())
{
case CppNet.Token.EOF:
endOfStream = true;
break;
case CppNet.Token.CPPCOMMENT:
if (token.getText().StartsWith("//--WORKAROUND#line"))
{
result.Append(token.getText().Replace("//--WORKAROUND#line", "#line"));
}
break;
case CppNet.Token.CCOMMENT:
{
var tokenText = token.getText();
if (tokenText != null)
{
// Need to preserve line breaks so that line numbers are correct.
foreach (var c in tokenText)
if (c == '\n')
result.Append(c);
}
break;
}
default:
{
var tokenText = token.getText();
if (tokenText != null)
result.Append(tokenText);
break;
}
}
}
return result.ToString();
}
private class MGFileSystem : VirtualFileSystem
{
private readonly List<string> _dependencies;
public MGFileSystem(List<string> dependencies)
{
_dependencies = dependencies;
}
public VirtualFile getFile(string path)
{
return new MGFile(path, _dependencies);
}
public VirtualFile getFile(string dir, string name)
{
return new MGFile(Path.Combine(dir, name), _dependencies);
}
}
private class MGFile : VirtualFile
{
private readonly List<string> _dependencies;
private readonly string _path;
public MGFile(string path, List<string> dependencies)
{
_dependencies = dependencies;
_path = Path.GetFullPath(path);
}
public bool isFile()
{
return File.Exists(_path) && !File.GetAttributes(_path).HasFlag(FileAttributes.Directory);
}
public string getPath()
{
return _path;
}
public string getName()
{
return Path.GetFileName(_path);
}
public VirtualFile getParentFile()
{
return new MGFile(Path.GetDirectoryName(_path), _dependencies);
}
public VirtualFile getChildFile(string name)
{
return new MGFile(Path.Combine(_path, name), _dependencies);
}
public Source getSource()
{
if (!_dependencies.Contains(_path))
_dependencies.Add(_path);
return new MGStringLexerSource(AppendNewlineIfNonePresent(File.ReadAllText(_path)), true, _path);
}
private static string AppendNewlineIfNonePresent(string text)
{
if (!text.EndsWith("\n"))
return text + "\n";
return text;
}
}
private class MGStringLexerSource : StringLexerSource
{
public string Path { get; private set; }
public MGStringLexerSource(string str, bool ppvalid, string fileName)
: base(str.Replace("\r\n", "\n"), ppvalid, fileName)
{
Path = fileName;
}
}
private class MGErrorListener : PreprocessorListener
{
private readonly IEffectCompilerOutput _output;
public MGErrorListener(IEffectCompilerOutput output)
{
_output = output;
}
public void handleWarning(Source source, int line, int column, string msg)
{
_output.WriteWarning(GetPath(source), line, column, msg);
}
public void handleError(Source source, int line, int column, string msg)
{
_output.WriteError(GetPath(source), line, column, msg);
}
private string GetPath(Source source)
{
return ((MGStringLexerSource) source).Path;
}
public void handleSourceChange(Source source, string ev)
{
}
}
}
}
@@ -0,0 +1,120 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.IO;
namespace TwoMGFX
{
public static class Program
{
public static int Main(string[] args)
{
if (!Environment.Is64BitProcess && Environment.OSVersion.Platform != PlatformID.Unix)
{
Console.Error.WriteLine("The MonoGame content tools only work on a 64bit OS.");
return -1;
}
var options = new Options();
var parser = new CommandLineParser(options);
parser.Title = "2MGFX - The MonoGame Effect compiler.";
if (!parser.ParseCommandLine(args))
return 1;
// Validate the input file exits.
if (!File.Exists(options.SourceFile))
{
Console.Error.WriteLine("The input file '{0}' was not found!", options.SourceFile);
return 1;
}
// TODO: This would be where we would decide the user
// is trying to convert an FX file to a MGFX glsl file.
//
// For now we assume we're going right to a compiled MGFXO file.
// Parse the MGFX file expanding includes, macros, and returning the techniques.
ShaderResult shaderResult;
try
{
shaderResult = ShaderResult.FromFile(options.SourceFile, options, new ConsoleEffectCompilerOutput());
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
Console.Error.WriteLine("Failed to parse '{0}'!", options.SourceFile);
return 1;
}
// Create the effect object.
EffectObject effect;
var shaderErrorsAndWarnings = string.Empty;
try
{
effect = EffectObject.CompileEffect(shaderResult, out shaderErrorsAndWarnings);
if (!string.IsNullOrEmpty(shaderErrorsAndWarnings))
Console.Error.WriteLine(shaderErrorsAndWarnings);
}
catch (ShaderCompilerException)
{
// Write the compiler errors and warnings and let the user know what happened.
Console.Error.WriteLine(shaderErrorsAndWarnings);
Console.Error.WriteLine("Failed to compile '{0}'!", options.SourceFile);
return 1;
}
catch (Exception ex)
{
// First write all the compiler errors and warnings.
if (!string.IsNullOrEmpty(shaderErrorsAndWarnings))
Console.Error.WriteLine(shaderErrorsAndWarnings);
// If we have an exception message then write that.
if (!string.IsNullOrEmpty(ex.Message))
Console.Error.WriteLine(ex.Message);
// Let the user know what happened.
Console.Error.WriteLine("Unexpected error compiling '{0}'!", options.SourceFile);
return 1;
}
// Get the output file path.
if (options.OutputFile == string.Empty)
options.OutputFile = Path.GetFileNameWithoutExtension(options.SourceFile) + ".mgfxo";
// Write out the effect to a runtime format.
try
{
using (var stream = new FileStream(options.OutputFile, FileMode.Create, FileAccess.Write))
using (var writer = new BinaryWriter(stream))
effect.Write(writer, options);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
Console.Error.WriteLine("Failed to write '{0}'!", options.OutputFile);
return 1;
}
// We finished succesfully.
Console.WriteLine("Compiled '{0}' to '{1}'.", options.SourceFile, options.OutputFile);
return 0;
}
private class ConsoleEffectCompilerOutput : IEffectCompilerOutput
{
public void WriteWarning(string file, int line, int column, string message)
{
Console.WriteLine("Warning: {0}({1},{2}): {3}" , file, line, column, message);
}
public void WriteError(string file, int line, int column, string message)
{
throw new Exception(string.Format("Error: {0}({1},{2}): {3}", file, line, column, message));
}
}
}
}
@@ -0,0 +1,40 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("2MGFX")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("The MonoGame Team")]
[assembly: AssemblyProduct("2MGFX")]
[assembly: AssemblyCopyright("Copyright (C) The MonoGame Team")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Mark the assembly as CLS compliant so it can be safely used in other .NET languages
[assembly: CLSCompliant(true)]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("91c6a368-4017-4be4-babb-39cca4870312")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
namespace TwoMGFX
{
public class ShaderCompilerException : Exception
{
public ShaderCompilerException()
: base("A shader failed to compile!")
{
}
}
}
@@ -0,0 +1,61 @@
using Microsoft.Xna.Framework.Graphics;
namespace TwoMGFX
{
internal partial class ShaderData
{
public ShaderData(bool isVertexShader, int sharedIndex, byte[] bytecode)
{
IsVertexShader = isVertexShader;
SharedIndex = sharedIndex;
Bytecode = (byte[])bytecode.Clone();
}
public bool IsVertexShader { get; private set; }
public struct Sampler
{
public MojoShader.MOJOSHADER_samplerType type;
public int textureSlot;
public int samplerSlot;
public string samplerName;
public string parameterName;
public int parameter;
public SamplerState state;
}
public struct Attribute
{
public string name;
public VertexElementUsage usage;
public int index;
#pragma warning disable 649
public int location;
#pragma warning restore 649
}
/// <summary>
/// The index to the constant buffers which are
/// required by this shader at runtime.
/// </summary>
public int[] _cbuffers;
public Sampler[] _samplers;
public Attribute[] _attributes;
public byte[] ShaderCode { get; set; }
#region Non-Serialized Stuff
public byte[] Bytecode { get; private set; }
// The index of the shader in the shared list.
public int SharedIndex { get; private set; }
#endregion // Non-Serialized Stuff
}
}
@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
internal partial class ShaderData
{
public static ShaderData CreateGLSL(byte[] byteCode, bool isVertexShader, List<ConstantBufferData> cbuffers, int sharedIndex, Dictionary<string, SamplerStateInfo> samplerStates, bool debug)
{
var dxshader = new ShaderData(isVertexShader, sharedIndex, byteCode);
// Use MojoShader to convert the HLSL bytecode to GLSL.
var parseDataPtr = MojoShader.NativeMethods.MOJOSHADER_parse (
"glsl",
byteCode,
byteCode.Length,
IntPtr.Zero,
0,
IntPtr.Zero,
0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
var parseData = MarshalHelper.Unmarshal<MojoShader.MOJOSHADER_parseData> (parseDataPtr);
if (parseData.error_count > 0) {
var errors = MarshalHelper.UnmarshalArray<MojoShader.MOJOSHADER_error> (
parseData.errors,
parseData.error_count
);
throw new Exception (errors [0].error);
}
// Conver the attributes.
//
// TODO: Could this be done using DX shader reflection?
//
{
var attributes = MarshalHelper.UnmarshalArray<MojoShader.MOJOSHADER_attribute> (
parseData.attributes, parseData.attribute_count);
dxshader._attributes = new Attribute[attributes.Length];
for (var i = 0; i < attributes.Length; i++) {
dxshader._attributes [i].name = attributes [i].name;
dxshader._attributes [i].index = attributes [i].index;
dxshader._attributes [i].usage = EffectObject.ToXNAVertexElementUsage (attributes [i].usage);
}
}
var symbols = MarshalHelper.UnmarshalArray<MojoShader.MOJOSHADER_symbol> (
parseData.symbols, parseData.symbol_count);
//try to put the symbols in the order they are eventually packed into the uniform arrays
//this /should/ be done by pulling the info from mojoshader
Array.Sort (symbols, delegate(MojoShader.MOJOSHADER_symbol a, MojoShader.MOJOSHADER_symbol b) {
uint va = a.register_index;
if (a.info.elements == 1)
va += 1024; //hax. mojoshader puts array objects first
uint vb = b.register_index;
if (b.info.elements == 1)
vb += 1024;
return va.CompareTo (vb);
}
);//(a, b) => ((int)(a.info.elements > 1))a.register_index.CompareTo(b.register_index));
// NOTE: It seems the latest versions of MojoShader only
// output vec4 register sets. We leave the code below, but
// the runtime has been optimized for this case.
// For whatever reason the register indexing is
// incorrect from MojoShader.
{
uint bool_index = 0;
uint float4_index = 0;
uint int4_index = 0;
for (var i = 0; i < symbols.Length; i++) {
switch (symbols [i].register_set) {
case MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL:
symbols [i].register_index = bool_index;
bool_index += symbols [i].register_count;
break;
case MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_FLOAT4:
symbols [i].register_index = float4_index;
float4_index += symbols[i].register_count;
break;
case MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_INT4:
symbols [i].register_index = int4_index;
int4_index += symbols [i].register_count;
break;
}
}
}
// Get the samplers.
var samplers = MarshalHelper.UnmarshalArray<MojoShader.MOJOSHADER_sampler> (
parseData.samplers, parseData.sampler_count);
dxshader._samplers = new Sampler[samplers.Length];
for (var i = 0; i < samplers.Length; i++)
{
// We need the original sampler name... look for that in the symbols.
var originalSamplerName =
symbols.First(e => e.register_set == MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_SAMPLER &&
e.register_index == samplers[i].index
).name;
var sampler = new Sampler
{
//sampler mapping to parameter is unknown atm
parameter = -1,
// GLSL needs the MojoShader mangled sampler name.
samplerName = samplers[i].name,
// By default use the original sampler name for the parameter name.
parameterName = originalSamplerName,
textureSlot = samplers[i].index,
samplerSlot = samplers[i].index,
type = samplers[i].type,
};
SamplerStateInfo state;
if (samplerStates.TryGetValue(originalSamplerName, out state))
{
sampler.state = state.State;
sampler.parameterName = state.TextureName ?? originalSamplerName;
}
// Store the sampler.
dxshader._samplers[i] = sampler;
}
// Gather all the parameters used by this shader.
var symbol_types = new [] {
new { name = dxshader.IsVertexShader ? "vs_uniforms_bool" : "ps_uniforms_bool", set = MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_BOOL, },
new { name = dxshader.IsVertexShader ? "vs_uniforms_ivec4" : "ps_uniforms_ivec4", set = MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_INT4, },
new { name = dxshader.IsVertexShader ? "vs_uniforms_vec4" : "ps_uniforms_vec4", set = MojoShader.MOJOSHADER_symbolRegisterSet.MOJOSHADER_SYMREGSET_FLOAT4, },
};
var cbuffer_index = new List<int> ();
for (var i = 0; i < symbol_types.Length; i++) {
var cbuffer = new ConstantBufferData (symbol_types [i].name,
symbol_types [i].set,
symbols);
if (cbuffer.Size == 0)
continue;
var match = cbuffers.FindIndex (e => e.SameAs (cbuffer));
if (match == -1) {
cbuffer_index.Add (cbuffers.Count);
cbuffers.Add (cbuffer);
} else
cbuffer_index.Add (match);
}
dxshader._cbuffers = cbuffer_index.ToArray ();
var glslCode = parseData.output;
// TODO: This sort of sucks... why does MojoShader not produce
// code valid for GLES out of the box?
// GLES platforms do not like this.
glslCode = glslCode.Replace ("#version 110", "");
// Add the required precision specifiers for GLES.
var floatPrecision = dxshader.IsVertexShader ? "precision highp float;\r\n" : "precision mediump float;\r\n";
glslCode = "#ifdef GL_ES\r\n" +
floatPrecision +
"precision mediump int;\r\n" +
"#endif\r\n" +
glslCode;
// Enable standard derivatives extension as necessary
if ((glslCode.IndexOf("dFdx", StringComparison.InvariantCulture) >= 0)
|| (glslCode.IndexOf("dFdy", StringComparison.InvariantCulture) >= 0))
{
glslCode = "#extension GL_OES_standard_derivatives : enable\r\n" + glslCode;
}
// Store the code for serialization.
dxshader.ShaderCode = Encoding.ASCII.GetBytes (glslCode);
return dxshader;
}
}
}
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
internal partial class ShaderData
{
public static ShaderData CreatePSSL(byte[] byteCode, bool isVertexShader, List<ConstantBufferData> cbuffers, int sharedIndex, Dictionary<string, SamplerStateInfo> samplerStates, bool debug)
{
// This is only part of the private PS4 repository.
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,156 @@
using System.Collections.Generic;
using SharpDX.Direct3D;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
internal partial class ShaderData
{
public static ShaderData CreateHLSL(byte[] byteCode, bool isVertexShader, List<ConstantBufferData> cbuffers, int sharedIndex, Dictionary<string, SamplerStateInfo> samplerStates, bool debug)
{
var dxshader = new ShaderData(isVertexShader, sharedIndex, byteCode);
dxshader._attributes = new Attribute[0];
// Strip the bytecode we're gonna save!
var stripFlags = SharpDX.D3DCompiler.StripFlags.CompilerStripReflectionData |
SharpDX.D3DCompiler.StripFlags.CompilerStripTestBlobs;
if (!debug)
stripFlags |= SharpDX.D3DCompiler.StripFlags.CompilerStripDebugInformation;
using (var original = new SharpDX.D3DCompiler.ShaderBytecode(byteCode))
{
// Strip the bytecode for saving to disk.
var stripped = original.Strip(stripFlags);
{
// Only SM4 and above works with strip... so this can return null!
if (stripped != null)
{
dxshader.ShaderCode = stripped;
}
else
{
// TODO: There is a way to strip SM3 and below
// but we have to write the method ourselves.
//
// If we need to support it then consider porting
// this code over...
//
// http://entland.homelinux.com/blog/2009/01/15/stripping-comments-from-shader-bytecodes/
//
dxshader.ShaderCode = (byte[])dxshader.Bytecode.Clone();
}
}
// Use reflection to get details of the shader.
using (var refelect = new SharpDX.D3DCompiler.ShaderReflection(byteCode))
{
// Get the samplers.
var samplers = new List<Sampler>();
for (var i = 0; i < refelect.Description.BoundResources; i++)
{
var rdesc = refelect.GetResourceBindingDescription(i);
if (rdesc.Type == SharpDX.D3DCompiler.ShaderInputType.Texture)
{
var samplerName = rdesc.Name;
var sampler = new Sampler
{
samplerName = string.Empty,
textureSlot = rdesc.BindPoint,
samplerSlot = rdesc.BindPoint,
parameterName = samplerName
};
SamplerStateInfo state;
if (samplerStates.TryGetValue(samplerName, out state))
{
sampler.parameterName = state.TextureName ?? samplerName;
sampler.state = state.State;
}
else
{
foreach (var s in samplerStates.Values)
{
if (samplerName == s.TextureName)
{
sampler.state = s.State;
samplerName = s.Name;
break;
}
}
}
// Find sampler slot, which can be different from the texture slot.
for (int j = 0; j < refelect.Description.BoundResources; j++)
{
var samplerrdesc = refelect.GetResourceBindingDescription(j);
if (samplerrdesc.Type == SharpDX.D3DCompiler.ShaderInputType.Sampler &&
samplerrdesc.Name == samplerName)
{
sampler.samplerSlot = samplerrdesc.BindPoint;
break;
}
}
switch (rdesc.Dimension)
{
case ShaderResourceViewDimension.Texture1D:
case ShaderResourceViewDimension.Texture1DArray:
sampler.type = MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_1D;
break;
case ShaderResourceViewDimension.Texture2D:
case ShaderResourceViewDimension.Texture2DArray:
case ShaderResourceViewDimension.Texture2DMultisampled:
case ShaderResourceViewDimension.Texture2DMultisampledArray:
sampler.type = MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_2D;
break;
case ShaderResourceViewDimension.Texture3D:
sampler.type = MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_VOLUME;
break;
case ShaderResourceViewDimension.TextureCube:
case ShaderResourceViewDimension.TextureCubeArray:
sampler.type = MojoShader.MOJOSHADER_samplerType.MOJOSHADER_SAMPLER_CUBE;
break;
}
samplers.Add(sampler);
}
}
dxshader._samplers = samplers.ToArray();
// Gather all the constant buffers used by this shader.
dxshader._cbuffers = new int[refelect.Description.ConstantBuffers];
for (var i = 0; i < refelect.Description.ConstantBuffers; i++)
{
var cb = new ConstantBufferData(refelect.GetConstantBuffer(i));
// Look for a duplicate cbuffer in the list.
for (var c = 0; c < cbuffers.Count; c++)
{
if (cb.SameAs(cbuffers[c]))
{
cb = null;
dxshader._cbuffers[i] = c;
break;
}
}
// Add a new cbuffer.
if (cb != null)
{
dxshader._cbuffers[i] = cbuffers.Count;
cbuffers.Add(cb);
}
}
}
}
return dxshader;
}
}
}
@@ -0,0 +1,58 @@
using System.IO;
namespace TwoMGFX
{
internal partial class ShaderData
{
public void Write(BinaryWriter writer, Options options)
{
writer.Write(IsVertexShader);
writer.Write(ShaderCode.Length);
writer.Write(ShaderCode);
writer.Write((byte)_samplers.Length);
foreach (var sampler in _samplers)
{
writer.Write((byte)sampler.type);
writer.Write((byte)sampler.textureSlot);
writer.Write((byte)sampler.samplerSlot);
if (sampler.state != null)
{
writer.Write(true);
writer.Write((byte)sampler.state.AddressU);
writer.Write((byte)sampler.state.AddressV);
writer.Write((byte)sampler.state.AddressW);
writer.Write(sampler.state.BorderColor.R);
writer.Write(sampler.state.BorderColor.G);
writer.Write(sampler.state.BorderColor.B);
writer.Write(sampler.state.BorderColor.A);
writer.Write((byte)sampler.state.Filter);
writer.Write(sampler.state.MaxAnisotropy);
writer.Write(sampler.state.MaxMipLevel);
writer.Write(sampler.state.MipMapLevelOfDetailBias);
}
else
writer.Write(false);
writer.Write(sampler.samplerName);
writer.Write((byte)sampler.parameter);
}
writer.Write((byte)_cbuffers.Length);
foreach (var cb in _cbuffers)
writer.Write((byte)cb);
writer.Write((byte)_attributes.Length);
foreach (var attrib in _attributes)
{
writer.Write(attrib.name);
writer.Write((byte)attrib.usage);
writer.Write((byte)attrib.index);
writer.Write((short)attrib.location);
}
}
}
}
@@ -0,0 +1,75 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
class DirectX11ShaderProfile : ShaderProfile
{
private static readonly Regex HlslPixelShaderRegex = new Regex(@"^ps_(?<major>1|2|3|4|5)_(?<minor>0|1|)(_level_(9_1|9_2|9_3))?$", RegexOptions.Compiled);
private static readonly Regex HlslVertexShaderRegex = new Regex(@"^vs_(?<major>1|2|3|4|5)_(?<minor>0|1|)(_level_(9_1|9_2|9_3))?$", RegexOptions.Compiled);
public DirectX11ShaderProfile()
: base("DirectX_11", 1)
{
}
internal override void AddMacros(Dictionary<string, string> macros)
{
macros.Add("HLSL", "1");
macros.Add("SM4", "1");
}
internal override void ValidateShaderModels(PassInfo pass)
{
int major, minor;
if (!string.IsNullOrEmpty(pass.vsFunction))
{
ParseShaderModel(pass.vsModel, HlslVertexShaderRegex, out major, out minor);
if (major <= 3)
throw new Exception(String.Format("Invalid profile '{0}'. Vertex shader '{1}' must be SM 4.0 level 9.1 or higher!", pass.vsModel, pass.vsFunction));
}
if (!string.IsNullOrEmpty(pass.psFunction))
{
ParseShaderModel(pass.psModel, HlslPixelShaderRegex, out major, out minor);
if (major <= 3)
throw new Exception(String.Format("Invalid profile '{0}'. Pixel shader '{1}' must be SM 4.0 level 9.1 or higher!", pass.vsModel, pass.psFunction));
}
}
internal override ShaderData CreateShader(ShaderResult shaderResult, string shaderFunction, string shaderProfile, bool isVertexShader, EffectObject effect, ref string errorsAndWarnings)
{
var bytecode = EffectObject.CompileHLSL(shaderResult, shaderFunction, shaderProfile, ref errorsAndWarnings);
// First look to see if we already created this same shader.
foreach (var shader in effect.Shaders)
{
if (bytecode.SequenceEqual(shader.Bytecode))
return shader;
}
var shaderInfo = shaderResult.ShaderInfo;
var shaderData = ShaderData.CreateHLSL(bytecode, isVertexShader, effect.ConstantBuffers, effect.Shaders.Count, shaderInfo.SamplerStates, shaderResult.Debug);
effect.Shaders.Add(shaderData);
return shaderData;
}
internal override bool Supports(string platform)
{
if (platform == "Windows" ||
platform == "WindowsPhone8" ||
platform == "WindowsStoreApp")
return true;
return false;
}
}
}
@@ -0,0 +1,80 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
class OpenGLShaderProfile : ShaderProfile
{
private static readonly Regex GlslPixelShaderRegex = new Regex(@"^ps_(?<major>1|2|3|4|5)_(?<minor>0|1|)$", RegexOptions.Compiled);
private static readonly Regex GlslVertexShaderRegex = new Regex(@"^vs_(?<major>1|2|3|4|5)_(?<minor>0|1|)$", RegexOptions.Compiled);
public OpenGLShaderProfile()
: base("OpenGL", 0)
{
}
internal override void AddMacros(Dictionary<string, string> macros)
{
macros.Add("GLSL", "1");
macros.Add("OPENGL", "1");
}
internal override void ValidateShaderModels(PassInfo pass)
{
int major, minor;
if (!string.IsNullOrEmpty(pass.vsFunction))
{
ParseShaderModel(pass.vsModel, GlslVertexShaderRegex, out major, out minor);
if (major > 3)
throw new Exception(String.Format("Invalid profile '{0}'. Vertex shader '{1}' must be SM 3.0 or lower!", pass.vsModel, pass.vsFunction));
}
if (!string.IsNullOrEmpty(pass.psFunction))
{
ParseShaderModel(pass.psModel, GlslPixelShaderRegex, out major, out minor);
if (major > 3)
throw new Exception(String.Format("Invalid profile '{0}'. Pixel shader '{1}' must be SM 3.0 or lower!", pass.vsModel, pass.psFunction));
}
}
internal override ShaderData CreateShader(ShaderResult shaderResult, string shaderFunction, string shaderProfile, bool isVertexShader, EffectObject effect, ref string errorsAndWarnings)
{
// For now GLSL is only supported via translation
// using MojoShader which works from HLSL bytecode.
var bytecode = EffectObject.CompileHLSL(shaderResult, shaderFunction, shaderProfile, ref errorsAndWarnings);
// First look to see if we already created this same shader.
foreach (var shader in effect.Shaders)
{
if (bytecode.SequenceEqual(shader.Bytecode))
return shader;
}
var shaderInfo = shaderResult.ShaderInfo;
var shaderData = ShaderData.CreateGLSL(bytecode, isVertexShader, effect.ConstantBuffers, effect.Shaders.Count, shaderInfo.SamplerStates, shaderResult.Debug);
effect.Shaders.Add(shaderData);
return shaderData;
}
internal override bool Supports(string platform)
{
if (platform == "iOS" ||
platform == "Android" ||
platform == "DesktopGL" ||
platform == "MacOSX" ||
platform == "RaspberryPi")
return true;
return false;
}
}
}
@@ -0,0 +1,107 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Xna.Framework.Content.Pipeline;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
[TypeConverter(typeof(StringConverter))]
public abstract class ShaderProfile
{
private static readonly LoadedTypeCollection<ShaderProfile> _profiles = new LoadedTypeCollection<ShaderProfile>();
protected ShaderProfile(string name, byte formatId)
{
Name = name;
FormatId = formatId;
}
public static readonly ShaderProfile OpenGL = FromName("OpenGL");
public static readonly ShaderProfile DirectX_11 = FromName("DirectX_11");
/// <summary>
/// Returns all the loaded shader profiles.
/// </summary>
public static IEnumerable<ShaderProfile> All
{
get { return _profiles; }
}
/// <summary>
/// Returns the name of the shader profile.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Returns the format identifier used in the MGFX file format.
/// </summary>
public byte FormatId { get; private set; }
/// <summary>
/// Returns the correct profile for the named platform or
/// null if no supporting profile is found.
/// </summary>
public static ShaderProfile ForPlatform(string platform)
{
return _profiles.FirstOrDefault(p => p.Supports(platform));
}
/// <summary>
/// Returns the profile by name or null if no match is found.
/// </summary>
public static ShaderProfile FromName(string name)
{
return _profiles.FirstOrDefault(p => p.Name == name);
}
internal abstract void AddMacros(Dictionary<string, string> macros);
internal abstract void ValidateShaderModels(PassInfo pass);
internal abstract ShaderData CreateShader(ShaderResult shaderResult, string shaderFunction, string shaderProfile, bool isVertexShader, EffectObject effect, ref string errorsAndWarnings);
internal abstract bool Supports(string platform);
protected static void ParseShaderModel(string text, Regex regex, out int major, out int minor)
{
var match = regex.Match(text);
if (!match.Success)
{
major = 0;
minor = 0;
return;
}
major = int.Parse(match.Groups["major"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture);
minor = int.Parse(match.Groups["minor"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture);
}
private class StringConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string)
{
var name = value as string;
foreach (var e in All)
{
if (e.Name == name)
return e;
}
}
return base.ConvertFrom(context, culture, value);
}
}
}
}
@@ -0,0 +1,160 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.IO;
using TwoMGFX.TPGParser;
namespace TwoMGFX
{
public class ShaderResult
{
public ShaderInfo ShaderInfo { get; private set; }
public string FilePath { get; private set; }
public string FileContent { get; private set; }
public string OutputFilePath { get; private set; }
public List<string> Dependencies { get; private set; }
public List<string> AdditionalOutputFiles { get; private set; }
public ShaderProfile Profile { get; private set; }
public bool Debug { get; private set; }
static public ShaderResult FromFile(string path, Options options, IEffectCompilerOutput output)
{
var effectSource = File.ReadAllText(path);
return FromString(effectSource, path, options, output);
}
static public ShaderResult FromString(string effectSource, string filePath, Options options, IEffectCompilerOutput output)
{
var macros = new Dictionary<string, string>();
macros.Add("MGFX", "1");
options.Profile.AddMacros(macros);
// If we're building shaders for debug set that flag too.
if (options.Debug)
macros.Add("DEBUG", "1");
if (!string.IsNullOrEmpty(options.Defines))
{
var defines = options.Defines.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var define in defines)
{
var name = define;
var value = "1";
if (define.Contains("="))
{
var parts = define.Split('=');
if (parts.Length > 0)
name = parts[0].Trim();
if (parts.Length > 1)
value = parts[1].Trim();
}
macros.Add(name, value);
}
}
// Use the D3DCompiler to pre-process the file resolving
// all #includes and macros.... this even works for GLSL.
string newFile;
var fullPath = Path.GetFullPath(filePath);
var dependencies = new List<string>();
newFile = Preprocessor.Preprocess(effectSource, fullPath, macros, dependencies, output);
// Parse the resulting file for techniques and passes.
var tree = new Parser(new Scanner()).Parse(newFile, fullPath);
if (tree.Errors.Count > 0)
{
var errors = String.Empty;
foreach (var error in tree.Errors)
errors += string.Format("{0}({1},{2}) : {3}\r\n", error.File, error.Line, error.Column, error.Message);
throw new Exception(errors);
}
// Evaluate the results of the parse tree.
var shaderInfo = tree.Eval() as ShaderInfo;
// Remove the samplers and techniques so that the shader compiler
// gets a clean file without any FX file syntax in it.
var cleanFile = newFile;
WhitespaceNodes(TokenType.Technique_Declaration, tree.Nodes, ref cleanFile);
WhitespaceNodes(TokenType.Sampler_Declaration_States, tree.Nodes, ref cleanFile);
// Setup the rest of the shader info.
ShaderResult result = new ShaderResult();
result.ShaderInfo = shaderInfo;
result.Dependencies = dependencies;
result.FilePath = fullPath;
result.FileContent = cleanFile;
if (!string.IsNullOrEmpty(options.OutputFile))
result.OutputFilePath = Path.GetFullPath(options.OutputFile);
result.AdditionalOutputFiles = new List<string>();
// Remove empty techniques.
for (var i = 0; i < shaderInfo.Techniques.Count; i++)
{
var tech = shaderInfo.Techniques[i];
if (tech.Passes.Count <= 0)
{
shaderInfo.Techniques.RemoveAt(i);
i--;
}
}
// We must have at least one technique.
if (shaderInfo.Techniques.Count <= 0)
throw new Exception("The effect must contain at least one technique and pass!");
result.Profile = options.Profile;
result.Debug = options.Debug;
return result;
}
public static void WhitespaceNodes(TokenType type, List<ParseNode> nodes, ref string sourceFile)
{
for (var i = 0; i < nodes.Count; i++)
{
var n = nodes[i];
if (n.Token.Type != type)
{
WhitespaceNodes(type, n.Nodes, ref sourceFile);
continue;
}
// Get the full content of this node.
var start = n.Token.StartPos;
var end = n.Token.EndPos;
var length = end - n.Token.StartPos;
var content = sourceFile.Substring(start, length);
// Replace the content of this node with whitespace.
for (var c = 0; c < length; c++)
{
if (!char.IsWhiteSpace(content[c]))
content = content.Replace(content[c], ' ');
}
// Add the whitespace back to the source file.
var newfile = sourceFile.Substring(0, start);
newfile += content;
newfile += sourceFile.Substring(end);
sourceFile = newfile;
}
}
}
}
@@ -0,0 +1,428 @@
// MonoGame Effect Parser
//
// For use with our fork of the "Tiny Parser Generator"
// https://github.com/SickheadGames/TinyPG
//
<% @TinyPG Namespace="TwoMGFX.TPGParser" Language="C#"%>
[Skip] BlockComment -> @"/\*([^*]|\*[^/])*\*/";
[Skip] Comment -> @"//[^\n\r]*";
[Skip] Whitespace -> @"[ \t\n\r]+";
[FileAndLine] LinePragma -> @"^[ \t]*#line[ \t]*(?<Line>\d*)[ \t]*(\""(?<File>[^\""\\]*(?:\\.[^\""\\]*)*)\"")?\n";
// TOKENS
[IgnoreCase] Pass -> @"pass";
[IgnoreCase] Technique -> @"technique";
[IgnoreCase] Sampler -> @"sampler1D|sampler2D|sampler3D|samplerCUBE|SamplerState|sampler";
[IgnoreCase] SamplerState -> @"sampler_state";
[IgnoreCase] VertexShader -> @"VertexShader";
[IgnoreCase] PixelShader -> @"PixelShader";
[IgnoreCase] Register -> @"register";
[IgnoreCase] Boolean -> @"true|false|0|1";
Number -> @"[+-]? ?[0-9]?\.?[0-9]+[fF]?";
[IgnoreCase] HexColor -> @"0x[0-9a-f]{6}([0-9a-f][0-9a-f])?";
Identifier -> @"[A-Za-z_][A-Za-z0-9_]*";
OpenBracket -> @"{";
CloseBracket -> @"}";
Equals -> @"=";
Colon -> @":";
Comma -> @",";
Semicolon -> @";";
Or -> @"\|";
OpenParenthesis -> @"\(";
CloseParenthesis -> @"\)";
OpenSquareBracket -> @"\[";
CloseSquareBracket -> @"\]";
LessThan -> @"<";
GreaterThan -> @">";
[IgnoreCase] Compile -> @"compile";
ShaderModel -> @"[A-Za-z_][A-Za-z0-9_]*";
Code -> @"[\S]+";
EndOfFile -> @"^$";
// Sampler states
[IgnoreCase] MinFilter -> @"MinFilter";
[IgnoreCase] MagFilter -> @"MagFilter";
[IgnoreCase] MipFilter -> @"MipFilter";
[IgnoreCase] Filter -> @"Filter";
[IgnoreCase] Texture -> @"Texture";
[IgnoreCase] AddressU -> @"AddressU";
[IgnoreCase] AddressV -> @"AddressV";
[IgnoreCase] AddressW -> @"AddressW";
[IgnoreCase] BorderColor -> @"BorderColor";
[IgnoreCase] MaxAnisotropy -> @"MaxAnisotropy";
[IgnoreCase] MaxMipLevel -> @"MaxMipLevel|MaxLod";
[IgnoreCase] MipLodBias -> @"MipLodBias";
// Address Mode
[IgnoreCase] Clamp -> @"Clamp";
[IgnoreCase] Wrap -> @"Wrap";
[IgnoreCase] Mirror -> @"Mirror";
[IgnoreCase] Border -> @"Border";
// Texture Filters
[IgnoreCase] None -> @"None";
[IgnoreCase] Linear -> @"Linear";
[IgnoreCase] Point -> @"Point";
[IgnoreCase] Anisotropic -> @"Anisotropic";
// Render states
[IgnoreCase] AlphaBlendEnable -> @"AlphaBlendEnable";
[IgnoreCase] SrcBlend -> @"SrcBlend";
[IgnoreCase] DestBlend -> @"DestBlend";
[IgnoreCase] BlendOp -> @"BlendOp";
[IgnoreCase] ColorWriteEnable -> @"ColorWriteEnable";
[IgnoreCase] ZEnable -> @"ZEnable";
[IgnoreCase] ZWriteEnable -> @"ZWriteEnable";
[IgnoreCase] ZFunc-> @"ZFunc";
[IgnoreCase] DepthBias -> @"DepthBias";
[IgnoreCase] CullMode -> @"CullMode";
[IgnoreCase] FillMode -> @"FillMode";
[IgnoreCase] MultiSampleAntiAlias -> @"MultiSampleAntiAlias";
[IgnoreCase] ScissorTestEnable -> @"ScissorTestEnable";
[IgnoreCase] SlopeScaleDepthBias -> @"SlopeScaleDepthBias";
[IgnoreCase] StencilEnable -> @"StencilEnable";
[IgnoreCase] StencilFail -> @"StencilFail";
[IgnoreCase] StencilFunc -> @"StencilFunc";
[IgnoreCase] StencilMask -> @"StencilMask";
[IgnoreCase] StencilPass -> @"StencilPass";
[IgnoreCase] StencilRef -> @"StencilRef";
[IgnoreCase] StencilWriteMask -> @"StencilWriteMask";
[IgnoreCase] StencilZFail -> @"StencilZFail";
// Compare function
[IgnoreCase] Never -> @"Never";
[IgnoreCase] Less -> @"Less";
[IgnoreCase] Equal -> @"Equal";
[IgnoreCase] LessEqual -> @"LessEqual";
[IgnoreCase] Greater -> @"Greater";
[IgnoreCase] NotEqual -> @"NotEqual";
[IgnoreCase] GreaterEqual -> @"GreaterEqual";
[IgnoreCase] Always -> @"Always";
// Stencil operation
[IgnoreCase] Keep -> @"Keep";
[IgnoreCase] Zero -> @"Zero";
[IgnoreCase] Replace -> @"Replace";
[IgnoreCase] IncrSat -> @"IncrSat";
[IgnoreCase] DecrSat -> @"DecrSat";
[IgnoreCase] Invert -> @"Invert";
[IgnoreCase] Incr -> @"Incr";
[IgnoreCase] Decr -> @"Decr";
// Colors
[IgnoreCase] Red -> @"Red";
[IgnoreCase] Green -> @"Green";
[IgnoreCase] Blue -> @"Blue";
[IgnoreCase] Alpha -> @"Alpha";
[IgnoreCase] All -> @"All";
// Cull mode
[IgnoreCase] Cw -> @"Cw";
[IgnoreCase] Ccw -> @"Ccw";
// Fill mode
[IgnoreCase] Solid -> @"Solid";
[IgnoreCase] WireFrame -> @"WireFrame";
// Blend function
[IgnoreCase] Add -> @"Add";
[IgnoreCase] Subtract -> @"Subtract";
[IgnoreCase] RevSubtract -> @"RevSubtract";
[IgnoreCase] Min -> @"Min";
[IgnoreCase] Max -> @"Max";
// Blend
[IgnoreCase] Zero -> @"Zero";
[IgnoreCase] One -> @"One";
[IgnoreCase] SrcColor -> @"SrcColor";
[IgnoreCase] InvSrcColor -> @"InvSrcColor";
[IgnoreCase] SrcAlpha -> @"SrcAlpha";
[IgnoreCase] InvSrcAlpha -> @"InvSrcAlpha";
[IgnoreCase] DestAlpha -> @"DestAlpha";
[IgnoreCase] InvDestAlpha -> @"InvDestAlpha";
[IgnoreCase] DestColor -> @"DestColor";
[IgnoreCase] InvDestColor -> @"InvDestColor";
[IgnoreCase] SrcAlphaSat -> @"SrcAlphaSat";
[IgnoreCase] BlendFactor -> @"BlendFactor";
[IgnoreCase] InvBlendFactor -> @"InvBlendFactor";
// Productions
Start -> (Code | Technique_Declaration | Sampler_Declaration)* EndOfFile
{
var shader = new ShaderInfo();
foreach (var node in Nodes)
node.Eval(tree, shader);
return shader;
};
Technique_Declaration -> Technique Identifier? OpenBracket Pass_Declaration+ CloseBracket
{
var technique = new TechniqueInfo();
technique.name = $Identifier as string ?? string.Empty;
technique.startPos = Token.StartPos;
technique.length = Token.Length;
foreach (var node in Nodes)
node.Eval(tree, technique);
// Make sure we have at least one pass.
if (technique.Passes.Count > 0)
{
var shaderInfo = paramlist[0] as ShaderInfo;
shaderInfo.Techniques.Add(technique);
}
return null;
};
FillMode_Solid -> Solid { return FillMode.Solid; };
FillMode_WireFrame -> WireFrame { return FillMode.WireFrame; };
FillModes -> (FillMode_Solid|FillMode_WireFrame)
{
return $FillMode_Solid ?? $FillMode_WireFrame;
};
CullMode_None -> None { return CullMode.None; };
CullMode_Cw -> Cw { return CullMode.CullClockwiseFace; };
CullMode_Ccw -> Ccw { return CullMode.CullCounterClockwiseFace; };
CullModes -> (CullMode_None|CullMode_Cw|CullMode_Ccw)
{
return $CullMode_None ?? $CullMode_Cw ?? $CullMode_Ccw;
};
Colors_None -> None { return ColorWriteChannels.None; };
Colors_Red -> Red { return ColorWriteChannels.Red; };
Colors_Green -> Green { return ColorWriteChannels.Green; };
Colors_Blue -> Blue { return ColorWriteChannels.Blue; };
Colors_Alpha -> Alpha { return ColorWriteChannels.Alpha; };
Colors_All -> All { return ColorWriteChannels.All; };
Colors_Boolean -> Boolean { return ParseTreeTools.ParseBool((string)$Boolean) ? ColorWriteChannels.All : ColorWriteChannels.None; };
Colors -> (Colors_Red|Colors_Green|Colors_Blue|Colors_Alpha|Colors_None|Colors_All|Colors_Boolean)
{
return $Colors_Red ?? $Colors_Green ?? $Colors_Blue ?? $Colors_Alpha ?? $Colors_None ?? $Colors_All ?? $Colors_Boolean;
};
ColorsMasks -> Colors (Or Colors)? (Or Colors)? (Or Colors)?
{
return (ColorWriteChannels)($Colors[0] ?? 0) |
(ColorWriteChannels)($Colors[1] ?? 0) |
(ColorWriteChannels)($Colors[2] ?? 0) |
(ColorWriteChannels)($Colors[3] ?? 0);
};
Blend_Zero -> Zero { return Blend.Zero; };
Blend_One -> One { return Blend.One; };
Blend_SrcColor -> SrcColor { return Blend.SourceColor; };
Blend_InvSrcColor -> InvSrcColor { return Blend.InverseSourceColor; };
Blend_SrcAlpha -> SrcAlpha { return Blend.SourceAlpha; };
Blend_InvSrcAlpha -> InvSrcAlpha { return Blend.InverseSourceAlpha; };
Blend_DestAlpha -> DestAlpha { return Blend.DestinationAlpha; };
Blend_InvDestAlpha -> InvDestAlpha { return Blend.InverseDestinationAlpha; };
Blend_DestColor -> DestColor { return Blend.DestinationColor; };
Blend_InvDestColor -> InvDestColor { return Blend.InverseDestinationColor; };
Blend_SrcAlphaSat -> SrcAlphaSat { return Blend.SourceAlphaSaturation; };
Blend_BlendFactor -> BlendFactor { return Blend.BlendFactor; };
Blend_InvBlendFactor -> InvBlendFactor { return Blend.InverseBlendFactor; };
Blends -> ( Blend_Zero|Blend_One|Blend_SrcColor|Blend_InvSrcColor|Blend_SrcAlpha|Blend_InvSrcAlpha|
Blend_DestAlpha|Blend_InvDestAlpha|Blend_DestColor|Blend_InvDestColor|Blend_SrcAlphaSat|
Blend_BlendFactor|Blend_InvBlendFactor)
{
return $Blend_Zero ?? $Blend_One ?? $Blend_SrcColor ?? $Blend_InvSrcColor ?? $Blend_SrcAlpha ?? $Blend_InvSrcAlpha ??
$Blend_DestAlpha ?? $Blend_InvDestAlpha ?? $Blend_DestColor ?? $Blend_InvDestColor ?? $Blend_SrcAlphaSat ??
$Blend_BlendFactor ?? $Blend_InvBlendFactor;
};
BlendOp_Add -> Add { return BlendFunction.Add; };
BlendOp_Subtract -> Subtract { return BlendFunction.Subtract; };
BlendOp_RevSubtract -> RevSubtract { return BlendFunction.ReverseSubtract; };
BlendOp_Min -> Min { return BlendFunction.Min; };
BlendOp_Max -> Max { return BlendFunction.Max; };
BlendOps -> (BlendOp_Add|BlendOp_Subtract|BlendOp_RevSubtract|BlendOp_Min|BlendOp_Max)
{
return $BlendOp_Add ?? $BlendOp_Subtract ?? $BlendOp_RevSubtract ?? $BlendOp_Min ?? $BlendOp_Max;
};
CmpFunc_Never -> Never { return CompareFunction.Never; };
CmpFunc_Less -> Less { return CompareFunction.Less; };
CmpFunc_Equal -> Equal { return CompareFunction.Equal; };
CmpFunc_LessEqual -> LessEqual { return CompareFunction.LessEqual; };
CmpFunc_Greater -> Greater { return CompareFunction.Greater; };
CmpFunc_NotEqual -> NotEqual { return CompareFunction.NotEqual; };
CmpFunc_GreaterEqual -> GreaterEqual { return CompareFunction.GreaterEqual; };
CmpFunc_Always -> Always { return CompareFunction.Always; };
CmpFunc -> (CmpFunc_Never|CmpFunc_Less|CmpFunc_Equal|CmpFunc_LessEqual|CmpFunc_Greater|CmpFunc_NotEqual|CmpFunc_GreaterEqual|CmpFunc_Always)
{
return $CmpFunc_Never ?? $CmpFunc_Less ?? $CmpFunc_Equal ?? $CmpFunc_LessEqual ?? $CmpFunc_Greater ?? $CmpFunc_NotEqual ?? $CmpFunc_GreaterEqual ?? $CmpFunc_Always;
};
StencilOp_Keep -> Keep { return StencilOperation.Keep; };
StencilOp_Zero -> Zero { return StencilOperation.Zero; };
StencilOp_Replace -> Replace { return StencilOperation.Replace; };
StencilOp_IncrSat -> IncrSat { return StencilOperation.IncrementSaturation; };
StencilOp_DecrSat -> DecrSat { return StencilOperation.DecrementSaturation; };
StencilOp_Invert -> Invert { return StencilOperation.Invert; };
StencilOp_Incr -> Incr { return StencilOperation.Increment; };
StencilOp_Decr -> Decr { return StencilOperation.Decrement; };
StencilOp -> (StencilOp_Keep|StencilOp_Zero|StencilOp_Replace|StencilOp_IncrSat|StencilOp_DecrSat|StencilOp_Invert|StencilOp_Incr|StencilOp_Decr)
{
return $StencilOp_Keep ?? $StencilOp_Zero ?? $StencilOp_Replace ?? $StencilOp_IncrSat ?? $StencilOp_DecrSat ?? $StencilOp_Invert ?? $StencilOp_Incr ?? $StencilOp_Decr;
};
// Render states
Render_State_CullMode -> CullMode Equals CullModes Semicolon { (paramlist[0] as PassInfo).CullMode = (CullMode)$CullModes; return null; };
Render_State_FillMode -> FillMode Equals FillModes Semicolon { (paramlist[0] as PassInfo).FillMode = (FillMode)$FillModes; return null; };
Render_State_AlphaBlendEnable -> AlphaBlendEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).AlphaBlendEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_SrcBlend -> SrcBlend Equals Blends Semicolon { (paramlist[0] as PassInfo).SrcBlend = (Blend)$Blends; return null; };
Render_State_DestBlend -> DestBlend Equals Blends Semicolon { (paramlist[0] as PassInfo).DestBlend = (Blend)$Blends; return null; };
Render_State_BlendOp -> BlendOp Equals BlendOps Semicolon { (paramlist[0] as PassInfo).BlendOp = (BlendFunction)$BlendOps; return null; };
Render_State_ColorWriteEnable -> ColorWriteEnable Equals ColorsMasks Semicolon { (paramlist[0] as PassInfo).ColorWriteEnable = (ColorWriteChannels)$ColorsMasks; return null; };
Render_State_DepthBias -> DepthBias Equals Number Semicolon { (paramlist[0] as PassInfo).DepthBias = ParseTreeTools.ParseFloat((string)$Number); return null; };
Render_State_SlopeScaleDepthBias -> SlopeScaleDepthBias Equals Number Semicolon { (paramlist[0] as PassInfo).SlopeScaleDepthBias = ParseTreeTools.ParseFloat((string)$Number); return null; };
Render_State_ZEnable -> ZEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ZEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_ZWriteEnable -> ZWriteEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ZWriteEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_ZFunc -> ZFunc Equals CmpFunc Semicolon { (paramlist[0] as PassInfo).DepthBufferFunction = (CompareFunction)$CmpFunc; return null; };
Render_State_MultiSampleAntiAlias -> MultiSampleAntiAlias Equals Boolean Semicolon { (paramlist[0] as PassInfo).MultiSampleAntiAlias = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_ScissorTestEnable -> ScissorTestEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).ScissorTestEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_StencilEnable -> StencilEnable Equals Boolean Semicolon { (paramlist[0] as PassInfo).StencilEnable = ParseTreeTools.ParseBool((string)$Boolean); return null; };
Render_State_StencilFail -> StencilFail Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilFail = (StencilOperation)$StencilOp; return null; };
Render_State_StencilFunc -> StencilFunc Equals CmpFunc Semicolon { (paramlist[0] as PassInfo).StencilFunc = (CompareFunction)$CmpFunc; return null; };
Render_State_StencilMask -> StencilMask Equals Number Semicolon { (paramlist[0] as PassInfo).StencilMask = ParseTreeTools.ParseInt((string)$Number); return null; };
Render_State_StencilPass -> StencilPass Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilPass = (StencilOperation)$StencilOp; return null; };
Render_State_StencilRef -> StencilRef Equals Number Semicolon { (paramlist[0] as PassInfo).StencilRef = ParseTreeTools.ParseInt((string)$Number); return null; };
Render_State_StencilWriteMask -> StencilWriteMask Equals Number Semicolon { (paramlist[0] as PassInfo).StencilWriteMask = ParseTreeTools.ParseInt((string)$Number); return null; };
Render_State_StencilZFail -> StencilZFail Equals StencilOp Semicolon { (paramlist[0] as PassInfo).StencilZFail = (StencilOperation)$StencilOp; return null; };
Render_State_Expression ->
Render_State_CullMode |
Render_State_FillMode |
Render_State_AlphaBlendEnable |
Render_State_SrcBlend |
Render_State_DestBlend |
Render_State_BlendOp |
Render_State_ColorWriteEnable |
Render_State_DepthBias |
Render_State_SlopeScaleDepthBias |
Render_State_ZEnable |
Render_State_ZWriteEnable |
Render_State_ZFunc |
Render_State_MultiSampleAntiAlias |
Render_State_ScissorTestEnable |
Render_State_StencilEnable |
Render_State_StencilFail |
Render_State_StencilFunc |
Render_State_StencilMask |
Render_State_StencilPass |
Render_State_StencilRef |
Render_State_StencilWriteMask |
Render_State_StencilZFail;
Pass_Declaration -> Pass Identifier? OpenBracket (VertexShader_Pass_Expression | PixelShader_Pass_Expression | Render_State_Expression)* CloseBracket
{
var pass = new PassInfo();
pass.name = $Identifier as string ?? string.Empty;
foreach (var node in Nodes)
node.Eval(tree, pass);
// We need to have a pixel or vertex shader to keep this pass.
if (!string.IsNullOrEmpty(pass.psFunction) || !string.IsNullOrEmpty(pass.vsFunction))
{
var technique = paramlist[0] as TechniqueInfo;
technique.Passes.Add(pass);
}
return null;
};
VertexShader_Pass_Expression -> VertexShader Equals Compile ShaderModel Identifier OpenParenthesis CloseParenthesis Semicolon
{
var pass = paramlist[0] as PassInfo;
pass.vsModel = $ShaderModel as string;
pass.vsFunction = $Identifier as string;
return null;
};
PixelShader_Pass_Expression -> PixelShader Equals Compile ShaderModel Identifier OpenParenthesis CloseParenthesis Semicolon
{
var pass = paramlist[0] as PassInfo;
pass.psModel = $ShaderModel as string;
pass.psFunction = $Identifier as string;
return null;
};
AddressMode_Clamp -> Clamp { return TextureAddressMode.Clamp; };
AddressMode_Wrap -> Wrap { return TextureAddressMode.Wrap; };
AddressMode_Mirror -> Mirror { return TextureAddressMode.Mirror; };
AddressMode_Border -> Border { return TextureAddressMode.Border; };
AddressMode -> (AddressMode_Clamp|AddressMode_Wrap|AddressMode_Mirror|AddressMode_Border)
{
return $AddressMode_Clamp ?? $AddressMode_Wrap ?? $AddressMode_Mirror ?? $AddressMode_Border;
};
TextureFilter_None -> None { return TextureFilterType.None; };
TextureFilter_Linear -> Linear { return TextureFilterType.Linear; };
TextureFilter_Point -> Point { return TextureFilterType.Point; };
TextureFilter_Anisotropic -> Anisotropic { return TextureFilterType.Anisotropic; };
TextureFilter -> (TextureFilter_None|TextureFilter_Linear|TextureFilter_Point|TextureFilter_Anisotropic)
{
return $TextureFilter_None ?? $TextureFilter_Linear ?? $TextureFilter_Point ?? $TextureFilter_Anisotropic;
};
// Sampler States
Sampler_State_Texture -> Texture Equals (LessThan|OpenParenthesis) Identifier (GreaterThan|CloseParenthesis) Semicolon { (paramlist[0] as SamplerStateInfo).TextureName = (string)$Identifier; return null; };
Sampler_State_MinFilter -> MinFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MinFilter = (TextureFilterType)$TextureFilter; return null; };
Sampler_State_MagFilter -> MagFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MagFilter = (TextureFilterType)$TextureFilter; return null; };
Sampler_State_MipFilter -> MipFilter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).MipFilter = (TextureFilterType)$TextureFilter; return null; };
Sampler_State_Filter -> Filter Equals TextureFilter Semicolon { (paramlist[0] as SamplerStateInfo).Filter = (TextureFilterType)$TextureFilter; return null; };
Sampler_State_AddressU -> AddressU Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressU = (TextureAddressMode)$AddressMode; return null; };
Sampler_State_AddressV -> AddressV Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressV = (TextureAddressMode)$AddressMode; return null; };
Sampler_State_AddressW -> AddressW Equals AddressMode Semicolon { (paramlist[0] as SamplerStateInfo).AddressW = (TextureAddressMode)$AddressMode; return null; };
Sampler_State_BorderColor -> BorderColor Equals HexColor Semicolon { (paramlist[0] as SamplerStateInfo).BorderColor = ParseTreeTools.ParseColor((string)$HexColor); return null; };
Sampler_State_MaxMipLevel -> MaxMipLevel Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MaxMipLevel = ParseTreeTools.ParseInt((string)$Number); return null; };
Sampler_State_MaxAnisotropy -> MaxAnisotropy Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MaxAnisotropy = ParseTreeTools.ParseInt((string)$Number); return null; };
Sampler_State_MipLodBias -> MipLodBias Equals Number Semicolon { (paramlist[0] as SamplerStateInfo).MipMapLevelOfDetailBias = ParseTreeTools.ParseFloat((string)$Number); return null; };
Sampler_State_Expression ->
Sampler_State_Texture |
Sampler_State_MinFilter |
Sampler_State_MagFilter |
Sampler_State_MipFilter |
Sampler_State_Filter |
Sampler_State_AddressU |
Sampler_State_AddressV |
Sampler_State_AddressW |
Sampler_State_BorderColor |
Sampler_State_MaxMipLevel |
Sampler_State_MaxAnisotropy |
Sampler_State_MipLodBias;
Sampler_Register_Expression -> Colon Register OpenParenthesis Identifier (Comma Identifier (OpenSquareBracket Number CloseSquareBracket)?)? CloseParenthesis
{
return null;
};
Sampler_Declaration_States -> (Equals SamplerState)? OpenBracket Sampler_State_Expression* CloseBracket;
Sampler_Declaration -> Sampler Identifier Sampler_Register_Expression* Sampler_Declaration_States? (Semicolon | Comma | CloseParenthesis)
{
// if there is a comma or closing paren at the end this is a sampler as a parameter of a function
if ($Semicolon == null) return null;
var sampler = new SamplerStateInfo();
sampler.Name = $Identifier[0] as string;
foreach (ParseNode node in Nodes)
node.Eval(tree, sampler);
var shaderInfo = paramlist[0] as ShaderInfo;
shaderInfo.SamplerStates.Add(sampler.Name, sampler);
return null;
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.Xna.Framework;
namespace TwoMGFX.TPGParser
{
public static class ParseTreeTools
{
public static float ParseFloat(string value)
{
// Remove all whitespace and trailing F or f.
value = value.Replace(" ", "");
value = value.TrimEnd('f', 'F');
return float.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture);
}
public static int ParseInt(string value)
{
// We read it as a float and cast it down to
// an integer to match Microsoft FX behavior.
return (int)Math.Floor(ParseFloat(value));
}
public static bool ParseBool(string value)
{
if (value.ToLowerInvariant() == "true" || value == "1")
return true;
if (value.ToLowerInvariant() == "false" || value == "0")
return false;
throw new Exception("Invalid boolean value '" + value + "'");
}
public static Color ParseColor(string value)
{
var hexValue = Convert.ToUInt32(value, 16);
byte r, g, b, a;
if (value.Length == 8)
{
r = (byte) ((hexValue >> 16) & 0xFF);
g = (byte) ((hexValue >> 8) & 0xFF);
b = (byte) ((hexValue >> 0) & 0xFF);
a = 255;
}
else if (value.Length == 10)
{
r = (byte) ((hexValue >> 24) & 0xFF);
g = (byte) ((hexValue >> 16) & 0xFF);
b = (byte) ((hexValue >> 8) & 0xFF);
a = (byte) ((hexValue >> 0) & 0xFF);
}
else
{
throw new NotSupportedException();
}
return new Color(r, g, b, a);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,277 @@
using System;
using System.Text.RegularExpressions;
using Microsoft.Xna.Framework.Graphics;
using System.Globalization;
namespace TwoMGFX.TPGParser
{
public class PassInfo
{
public string name;
public string vsModel;
public string vsFunction;
public string psModel;
public string psFunction;
public BlendState blendState;
public RasterizerState rasterizerState;
public DepthStencilState depthStencilState;
private static Blend ToAlphaBlend(Blend blend)
{
switch (blend)
{
case Blend.SourceColor:
return Blend.SourceAlpha;
case Blend.InverseSourceColor:
return Blend.InverseSourceAlpha;
case Blend.DestinationColor:
return Blend.DestinationAlpha;
case Blend.InverseDestinationColor:
return Blend.InverseDestinationAlpha;
}
return blend;
}
public bool AlphaBlendEnable
{
set
{
if (value)
{
if (blendState == null)
{
blendState = new BlendState();
blendState.ColorSourceBlend = Blend.One;
blendState.AlphaSourceBlend = Blend.One;
blendState.ColorDestinationBlend = Blend.InverseSourceAlpha;
blendState.AlphaDestinationBlend = Blend.InverseSourceAlpha;
}
}
else if (!value)
{
if (blendState == null)
blendState = new BlendState();
blendState.ColorSourceBlend = Blend.One;
blendState.AlphaSourceBlend = Blend.One;
blendState.ColorDestinationBlend = Blend.Zero;
blendState.AlphaDestinationBlend = Blend.Zero;
}
}
}
public FillMode FillMode
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.FillMode = value;
}
}
public CullMode CullMode
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.CullMode = value;
}
}
public bool ZEnable
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.DepthBufferEnable = value;
}
}
public bool ZWriteEnable
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.DepthBufferWriteEnable = value;
}
}
public CompareFunction DepthBufferFunction
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.DepthBufferFunction = value;
}
}
public bool MultiSampleAntiAlias
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.MultiSampleAntiAlias = value;
}
}
public bool ScissorTestEnable
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.ScissorTestEnable = value;
}
}
public bool StencilEnable
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilEnable = value;
}
}
public StencilOperation StencilFail
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilFail = value;
}
}
public CompareFunction StencilFunc
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilFunction = value;
}
}
public int StencilMask
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilMask = value;
}
}
public StencilOperation StencilPass
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilPass = value;
}
}
public int StencilRef
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.ReferenceStencil = value;
}
}
public int StencilWriteMask
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilWriteMask = value;
}
}
public StencilOperation StencilZFail
{
set
{
if (depthStencilState == null)
depthStencilState = new DepthStencilState();
depthStencilState.StencilDepthBufferFail = value;
}
}
public Blend SrcBlend
{
set
{
if (blendState == null)
blendState = new BlendState();
blendState.ColorSourceBlend = value;
blendState.AlphaSourceBlend = ToAlphaBlend(value);
}
}
public Blend DestBlend
{
set
{
if (blendState == null)
blendState = new BlendState();
blendState.ColorDestinationBlend = value;
blendState.AlphaDestinationBlend = ToAlphaBlend(value);
}
}
public BlendFunction BlendOp
{
set
{
if (blendState == null)
blendState = new BlendState();
blendState.AlphaBlendFunction = value;
}
}
public ColorWriteChannels ColorWriteEnable
{
set
{
if (blendState == null)
blendState = new BlendState();
blendState.ColorWriteChannels = value;
}
}
public float DepthBias
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.DepthBias = value;
}
}
public float SlopeScaleDepthBias
{
set
{
if (rasterizerState == null)
rasterizerState = new RasterizerState();
rasterizerState.SlopeScaleDepthBias = value;
}
}
}
}
@@ -0,0 +1,210 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace TwoMGFX.TPGParser
{
public class SamplerStateInfo
{
private SamplerState _state;
private bool _dirty;
private TextureFilterType _minFilter;
private TextureFilterType _magFilter;
private TextureFilterType _mipFilter;
private TextureAddressMode _addressU;
private TextureAddressMode _addressV;
private TextureAddressMode _addressW;
private Color _borderColor;
private int _maxAnisotropy;
private int _maxMipLevel;
private float _mipMapLevelOfDetailBias;
public SamplerStateInfo()
{
// NOTE: These match the defaults of SamplerState.
_minFilter = TextureFilterType.Linear;
_magFilter = TextureFilterType.Linear;
_mipFilter = TextureFilterType.Linear;
_addressU = TextureAddressMode.Wrap;
_addressV = TextureAddressMode.Wrap;
_addressW = TextureAddressMode.Wrap;
_borderColor = Color.White;
_maxAnisotropy = 4;
_maxMipLevel = 0;
_mipMapLevelOfDetailBias = 0.0f;
}
public string Name { get; set; }
public string TextureName { get; set; }
public TextureFilterType MinFilter
{
set
{
_minFilter = value;
_dirty = true;
}
}
public TextureFilterType MagFilter
{
set
{
_magFilter = value;
_dirty = true;
}
}
public TextureFilterType MipFilter
{
set
{
_mipFilter = value;
_dirty = true;
}
}
public TextureFilterType Filter
{
set
{
_minFilter = _magFilter = _mipFilter = value;
_dirty = true;
}
}
public TextureAddressMode AddressU
{
set
{
_addressU = value;
_dirty = true;
}
}
public TextureAddressMode AddressV
{
set
{
_addressV = value;
_dirty = true;
}
}
public TextureAddressMode AddressW
{
set
{
_addressW = value;
_dirty = true;
}
}
public Color BorderColor
{
set
{
_borderColor = value;
_dirty = true;
}
}
public int MaxAnisotropy
{
set
{
_maxAnisotropy = value;
_dirty = true;
}
}
public int MaxMipLevel
{
set
{
_maxMipLevel = value;
_dirty = true;
}
}
public float MipMapLevelOfDetailBias
{
set
{
_mipMapLevelOfDetailBias = value;
_dirty = true;
}
}
private void UpdateSamplerState()
{
// Get the existing state or create it.
if (_state == null)
_state = new SamplerState();
_state.AddressU = _addressU;
_state.AddressV = _addressV;
_state.AddressW = _addressW;
_state.BorderColor = _borderColor;
_state.MaxAnisotropy = _maxAnisotropy;
_state.MaxMipLevel = _maxMipLevel;
_state.MipMapLevelOfDetailBias = _mipMapLevelOfDetailBias;
// Figure out what kind of filter to set based on each
// individual min, mag, and mip filter settings.
//
// NOTE: We're treating "None" and "Point" the same here
// and disabling mipmapping further below.
//
if (_minFilter == TextureFilterType.Anisotropic)
_state.Filter = TextureFilter.Anisotropic;
else if (_minFilter == TextureFilterType.Linear && _magFilter == TextureFilterType.Linear && _mipFilter == TextureFilterType.Linear)
_state.Filter = TextureFilter.Linear;
else if (_minFilter == TextureFilterType.Linear && _magFilter == TextureFilterType.Linear && _mipFilter <= TextureFilterType.Point)
_state.Filter = TextureFilter.LinearMipPoint;
else if (_minFilter == TextureFilterType.Linear && _magFilter <= TextureFilterType.Point && _mipFilter == TextureFilterType.Linear)
_state.Filter = TextureFilter.MinLinearMagPointMipLinear;
else if (_minFilter == TextureFilterType.Linear && _magFilter <= TextureFilterType.Point && _mipFilter <= TextureFilterType.Point)
_state.Filter = TextureFilter.MinLinearMagPointMipPoint;
else if (_minFilter <= TextureFilterType.Point && _magFilter == TextureFilterType.Linear && _mipFilter == TextureFilterType.Linear)
_state.Filter = TextureFilter.MinPointMagLinearMipLinear;
else if (_minFilter <= TextureFilterType.Point && _magFilter == TextureFilterType.Linear && _mipFilter <= TextureFilterType.Point)
_state.Filter = TextureFilter.MinPointMagLinearMipPoint;
else if (_minFilter <= TextureFilterType.Point && _magFilter <= TextureFilterType.Point && _mipFilter <= TextureFilterType.Point)
_state.Filter = TextureFilter.Point;
else if (_minFilter <= TextureFilterType.Point && _magFilter <= TextureFilterType.Point && _mipFilter == TextureFilterType.Linear)
_state.Filter = TextureFilter.PointMipLinear;
// Do we need to disable mipmapping?
if (_mipFilter == TextureFilterType.None)
{
// TODO: This is the only option we have right now for
// disabling mipmapping. We should add support for MinLod
// and MaxLod which potentially does a better job at this.
_state.MipMapLevelOfDetailBias = -16.0f;
_state.MaxMipLevel = 0;
}
_dirty = false;
}
public SamplerState State
{
get
{
if (_dirty)
UpdateSamplerState();
return _state;
}
}
}
}
@@ -0,0 +1,986 @@
// Generated by TinyPG v1.3 available at www.codeproject.com
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
namespace TwoMGFX.TPGParser
{
#region Scanner
public partial class Scanner
{
public string Input;
public int StartPos = 0;
public int EndPos = 0;
public string CurrentFile;
public int CurrentLine;
public int CurrentColumn;
public int CurrentPosition;
public List<Token> Skipped; // tokens that were skipped
public Dictionary<TokenType, Regex> Patterns;
private Token LookAheadToken;
private List<TokenType> Tokens;
private List<TokenType> SkipList; // tokens to be skipped
private readonly TokenType FileAndLine;
public Scanner()
{
Regex regex;
Patterns = new Dictionary<TokenType, Regex>();
Tokens = new List<TokenType>();
LookAheadToken = null;
Skipped = new List<Token>();
SkipList = new List<TokenType>();
SkipList.Add(TokenType.BlockComment);
SkipList.Add(TokenType.Comment);
SkipList.Add(TokenType.Whitespace);
SkipList.Add(TokenType.LinePragma);
FileAndLine = TokenType.LinePragma;
regex = new Regex(@"/\*([^*]|\*[^/])*\*/", RegexOptions.Compiled);
Patterns.Add(TokenType.BlockComment, regex);
Tokens.Add(TokenType.BlockComment);
regex = new Regex(@"//[^\n\r]*", RegexOptions.Compiled);
Patterns.Add(TokenType.Comment, regex);
Tokens.Add(TokenType.Comment);
regex = new Regex(@"[ \t\n\r]+", RegexOptions.Compiled);
Patterns.Add(TokenType.Whitespace, regex);
Tokens.Add(TokenType.Whitespace);
regex = new Regex(@"^[ \t]*#line[ \t]*(?<Line>\d*)[ \t]*(\""(?<File>[^\""\\]*(?:\\.[^\""\\]*)*)\"")?\n", RegexOptions.Compiled);
Patterns.Add(TokenType.LinePragma, regex);
Tokens.Add(TokenType.LinePragma);
regex = new Regex(@"pass", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Pass, regex);
Tokens.Add(TokenType.Pass);
regex = new Regex(@"technique", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Technique, regex);
Tokens.Add(TokenType.Technique);
regex = new Regex(@"sampler1D|sampler2D|sampler3D|samplerCUBE|SamplerState|sampler", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Sampler, regex);
Tokens.Add(TokenType.Sampler);
regex = new Regex(@"sampler_state", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SamplerState, regex);
Tokens.Add(TokenType.SamplerState);
regex = new Regex(@"VertexShader", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.VertexShader, regex);
Tokens.Add(TokenType.VertexShader);
regex = new Regex(@"PixelShader", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.PixelShader, regex);
Tokens.Add(TokenType.PixelShader);
regex = new Regex(@"register", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Register, regex);
Tokens.Add(TokenType.Register);
regex = new Regex(@"true|false|0|1", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Boolean, regex);
Tokens.Add(TokenType.Boolean);
regex = new Regex(@"[+-]? ?[0-9]?\.?[0-9]+[fF]?", RegexOptions.Compiled);
Patterns.Add(TokenType.Number, regex);
Tokens.Add(TokenType.Number);
regex = new Regex(@"0x[0-9a-f]{6}([0-9a-f][0-9a-f])?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.HexColor, regex);
Tokens.Add(TokenType.HexColor);
regex = new Regex(@"[A-Za-z_][A-Za-z0-9_]*", RegexOptions.Compiled);
Patterns.Add(TokenType.Identifier, regex);
Tokens.Add(TokenType.Identifier);
regex = new Regex(@"{", RegexOptions.Compiled);
Patterns.Add(TokenType.OpenBracket, regex);
Tokens.Add(TokenType.OpenBracket);
regex = new Regex(@"}", RegexOptions.Compiled);
Patterns.Add(TokenType.CloseBracket, regex);
Tokens.Add(TokenType.CloseBracket);
regex = new Regex(@"=", RegexOptions.Compiled);
Patterns.Add(TokenType.Equals, regex);
Tokens.Add(TokenType.Equals);
regex = new Regex(@":", RegexOptions.Compiled);
Patterns.Add(TokenType.Colon, regex);
Tokens.Add(TokenType.Colon);
regex = new Regex(@",", RegexOptions.Compiled);
Patterns.Add(TokenType.Comma, regex);
Tokens.Add(TokenType.Comma);
regex = new Regex(@";", RegexOptions.Compiled);
Patterns.Add(TokenType.Semicolon, regex);
Tokens.Add(TokenType.Semicolon);
regex = new Regex(@"\|", RegexOptions.Compiled);
Patterns.Add(TokenType.Or, regex);
Tokens.Add(TokenType.Or);
regex = new Regex(@"\(", RegexOptions.Compiled);
Patterns.Add(TokenType.OpenParenthesis, regex);
Tokens.Add(TokenType.OpenParenthesis);
regex = new Regex(@"\)", RegexOptions.Compiled);
Patterns.Add(TokenType.CloseParenthesis, regex);
Tokens.Add(TokenType.CloseParenthesis);
regex = new Regex(@"\[", RegexOptions.Compiled);
Patterns.Add(TokenType.OpenSquareBracket, regex);
Tokens.Add(TokenType.OpenSquareBracket);
regex = new Regex(@"\]", RegexOptions.Compiled);
Patterns.Add(TokenType.CloseSquareBracket, regex);
Tokens.Add(TokenType.CloseSquareBracket);
regex = new Regex(@"<", RegexOptions.Compiled);
Patterns.Add(TokenType.LessThan, regex);
Tokens.Add(TokenType.LessThan);
regex = new Regex(@">", RegexOptions.Compiled);
Patterns.Add(TokenType.GreaterThan, regex);
Tokens.Add(TokenType.GreaterThan);
regex = new Regex(@"compile", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Compile, regex);
Tokens.Add(TokenType.Compile);
regex = new Regex(@"[A-Za-z_][A-Za-z0-9_]*", RegexOptions.Compiled);
Patterns.Add(TokenType.ShaderModel, regex);
Tokens.Add(TokenType.ShaderModel);
regex = new Regex(@"[\S]+", RegexOptions.Compiled);
Patterns.Add(TokenType.Code, regex);
Tokens.Add(TokenType.Code);
regex = new Regex(@"^$", RegexOptions.Compiled);
Patterns.Add(TokenType.EndOfFile, regex);
Tokens.Add(TokenType.EndOfFile);
regex = new Regex(@"MinFilter", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MinFilter, regex);
Tokens.Add(TokenType.MinFilter);
regex = new Regex(@"MagFilter", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MagFilter, regex);
Tokens.Add(TokenType.MagFilter);
regex = new Regex(@"MipFilter", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MipFilter, regex);
Tokens.Add(TokenType.MipFilter);
regex = new Regex(@"Filter", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Filter, regex);
Tokens.Add(TokenType.Filter);
regex = new Regex(@"Texture", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Texture, regex);
Tokens.Add(TokenType.Texture);
regex = new Regex(@"AddressU", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.AddressU, regex);
Tokens.Add(TokenType.AddressU);
regex = new Regex(@"AddressV", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.AddressV, regex);
Tokens.Add(TokenType.AddressV);
regex = new Regex(@"AddressW", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.AddressW, regex);
Tokens.Add(TokenType.AddressW);
regex = new Regex(@"BorderColor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.BorderColor, regex);
Tokens.Add(TokenType.BorderColor);
regex = new Regex(@"MaxAnisotropy", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MaxAnisotropy, regex);
Tokens.Add(TokenType.MaxAnisotropy);
regex = new Regex(@"MaxMipLevel|MaxLod", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MaxMipLevel, regex);
Tokens.Add(TokenType.MaxMipLevel);
regex = new Regex(@"MipLodBias", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MipLodBias, regex);
Tokens.Add(TokenType.MipLodBias);
regex = new Regex(@"Clamp", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Clamp, regex);
Tokens.Add(TokenType.Clamp);
regex = new Regex(@"Wrap", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Wrap, regex);
Tokens.Add(TokenType.Wrap);
regex = new Regex(@"Mirror", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Mirror, regex);
Tokens.Add(TokenType.Mirror);
regex = new Regex(@"Border", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Border, regex);
Tokens.Add(TokenType.Border);
regex = new Regex(@"None", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.None, regex);
Tokens.Add(TokenType.None);
regex = new Regex(@"Linear", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Linear, regex);
Tokens.Add(TokenType.Linear);
regex = new Regex(@"Point", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Point, regex);
Tokens.Add(TokenType.Point);
regex = new Regex(@"Anisotropic", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Anisotropic, regex);
Tokens.Add(TokenType.Anisotropic);
regex = new Regex(@"AlphaBlendEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.AlphaBlendEnable, regex);
Tokens.Add(TokenType.AlphaBlendEnable);
regex = new Regex(@"SrcBlend", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SrcBlend, regex);
Tokens.Add(TokenType.SrcBlend);
regex = new Regex(@"DestBlend", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.DestBlend, regex);
Tokens.Add(TokenType.DestBlend);
regex = new Regex(@"BlendOp", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.BlendOp, regex);
Tokens.Add(TokenType.BlendOp);
regex = new Regex(@"ColorWriteEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.ColorWriteEnable, regex);
Tokens.Add(TokenType.ColorWriteEnable);
regex = new Regex(@"ZEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.ZEnable, regex);
Tokens.Add(TokenType.ZEnable);
regex = new Regex(@"ZWriteEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.ZWriteEnable, regex);
Tokens.Add(TokenType.ZWriteEnable);
regex = new Regex(@"ZFunc", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.ZFunc, regex);
Tokens.Add(TokenType.ZFunc);
regex = new Regex(@"DepthBias", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.DepthBias, regex);
Tokens.Add(TokenType.DepthBias);
regex = new Regex(@"CullMode", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.CullMode, regex);
Tokens.Add(TokenType.CullMode);
regex = new Regex(@"FillMode", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.FillMode, regex);
Tokens.Add(TokenType.FillMode);
regex = new Regex(@"MultiSampleAntiAlias", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.MultiSampleAntiAlias, regex);
Tokens.Add(TokenType.MultiSampleAntiAlias);
regex = new Regex(@"ScissorTestEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.ScissorTestEnable, regex);
Tokens.Add(TokenType.ScissorTestEnable);
regex = new Regex(@"SlopeScaleDepthBias", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SlopeScaleDepthBias, regex);
Tokens.Add(TokenType.SlopeScaleDepthBias);
regex = new Regex(@"StencilEnable", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilEnable, regex);
Tokens.Add(TokenType.StencilEnable);
regex = new Regex(@"StencilFail", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilFail, regex);
Tokens.Add(TokenType.StencilFail);
regex = new Regex(@"StencilFunc", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilFunc, regex);
Tokens.Add(TokenType.StencilFunc);
regex = new Regex(@"StencilMask", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilMask, regex);
Tokens.Add(TokenType.StencilMask);
regex = new Regex(@"StencilPass", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilPass, regex);
Tokens.Add(TokenType.StencilPass);
regex = new Regex(@"StencilRef", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilRef, regex);
Tokens.Add(TokenType.StencilRef);
regex = new Regex(@"StencilWriteMask", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilWriteMask, regex);
Tokens.Add(TokenType.StencilWriteMask);
regex = new Regex(@"StencilZFail", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.StencilZFail, regex);
Tokens.Add(TokenType.StencilZFail);
regex = new Regex(@"Never", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Never, regex);
Tokens.Add(TokenType.Never);
regex = new Regex(@"Less", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Less, regex);
Tokens.Add(TokenType.Less);
regex = new Regex(@"Equal", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Equal, regex);
Tokens.Add(TokenType.Equal);
regex = new Regex(@"LessEqual", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.LessEqual, regex);
Tokens.Add(TokenType.LessEqual);
regex = new Regex(@"Greater", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Greater, regex);
Tokens.Add(TokenType.Greater);
regex = new Regex(@"NotEqual", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.NotEqual, regex);
Tokens.Add(TokenType.NotEqual);
regex = new Regex(@"GreaterEqual", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.GreaterEqual, regex);
Tokens.Add(TokenType.GreaterEqual);
regex = new Regex(@"Always", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Always, regex);
Tokens.Add(TokenType.Always);
regex = new Regex(@"Keep", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Keep, regex);
Tokens.Add(TokenType.Keep);
regex = new Regex(@"Zero", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Zero, regex);
Tokens.Add(TokenType.Zero);
regex = new Regex(@"Replace", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Replace, regex);
Tokens.Add(TokenType.Replace);
regex = new Regex(@"IncrSat", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.IncrSat, regex);
Tokens.Add(TokenType.IncrSat);
regex = new Regex(@"DecrSat", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.DecrSat, regex);
Tokens.Add(TokenType.DecrSat);
regex = new Regex(@"Invert", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Invert, regex);
Tokens.Add(TokenType.Invert);
regex = new Regex(@"Incr", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Incr, regex);
Tokens.Add(TokenType.Incr);
regex = new Regex(@"Decr", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Decr, regex);
Tokens.Add(TokenType.Decr);
regex = new Regex(@"Red", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Red, regex);
Tokens.Add(TokenType.Red);
regex = new Regex(@"Green", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Green, regex);
Tokens.Add(TokenType.Green);
regex = new Regex(@"Blue", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Blue, regex);
Tokens.Add(TokenType.Blue);
regex = new Regex(@"Alpha", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Alpha, regex);
Tokens.Add(TokenType.Alpha);
regex = new Regex(@"All", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.All, regex);
Tokens.Add(TokenType.All);
regex = new Regex(@"Cw", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Cw, regex);
Tokens.Add(TokenType.Cw);
regex = new Regex(@"Ccw", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Ccw, regex);
Tokens.Add(TokenType.Ccw);
regex = new Regex(@"Solid", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Solid, regex);
Tokens.Add(TokenType.Solid);
regex = new Regex(@"WireFrame", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.WireFrame, regex);
Tokens.Add(TokenType.WireFrame);
regex = new Regex(@"Add", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Add, regex);
Tokens.Add(TokenType.Add);
regex = new Regex(@"Subtract", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Subtract, regex);
Tokens.Add(TokenType.Subtract);
regex = new Regex(@"RevSubtract", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.RevSubtract, regex);
Tokens.Add(TokenType.RevSubtract);
regex = new Regex(@"Min", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Min, regex);
Tokens.Add(TokenType.Min);
regex = new Regex(@"Max", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.Max, regex);
Tokens.Add(TokenType.Max);
regex = new Regex(@"One", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.One, regex);
Tokens.Add(TokenType.One);
regex = new Regex(@"SrcColor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SrcColor, regex);
Tokens.Add(TokenType.SrcColor);
regex = new Regex(@"InvSrcColor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.InvSrcColor, regex);
Tokens.Add(TokenType.InvSrcColor);
regex = new Regex(@"SrcAlpha", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SrcAlpha, regex);
Tokens.Add(TokenType.SrcAlpha);
regex = new Regex(@"InvSrcAlpha", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.InvSrcAlpha, regex);
Tokens.Add(TokenType.InvSrcAlpha);
regex = new Regex(@"DestAlpha", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.DestAlpha, regex);
Tokens.Add(TokenType.DestAlpha);
regex = new Regex(@"InvDestAlpha", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.InvDestAlpha, regex);
Tokens.Add(TokenType.InvDestAlpha);
regex = new Regex(@"DestColor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.DestColor, regex);
Tokens.Add(TokenType.DestColor);
regex = new Regex(@"InvDestColor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.InvDestColor, regex);
Tokens.Add(TokenType.InvDestColor);
regex = new Regex(@"SrcAlphaSat", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.SrcAlphaSat, regex);
Tokens.Add(TokenType.SrcAlphaSat);
regex = new Regex(@"BlendFactor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.BlendFactor, regex);
Tokens.Add(TokenType.BlendFactor);
regex = new Regex(@"InvBlendFactor", RegexOptions.Compiled | RegexOptions.IgnoreCase);
Patterns.Add(TokenType.InvBlendFactor, regex);
Tokens.Add(TokenType.InvBlendFactor);
}
public void Init(string input)
{
Init(input, "");
}
public void Init(string input, string fileName)
{
this.Input = input;
StartPos = 0;
EndPos = 0;
CurrentFile = fileName;
CurrentLine = 1;
CurrentColumn = 1;
CurrentPosition = 0;
LookAheadToken = null;
}
public Token GetToken(TokenType type)
{
Token t = new Token(this.StartPos, this.EndPos);
t.Type = type;
return t;
}
/// <summary>
/// executes a lookahead of the next token
/// and will advance the scan on the input string
/// </summary>
/// <returns></returns>
public Token Scan(params TokenType[] expectedtokens)
{
Token tok = LookAhead(expectedtokens); // temporarely retrieve the lookahead
LookAheadToken = null; // reset lookahead token, so scanning will continue
StartPos = tok.EndPos;
EndPos = tok.EndPos; // set the tokenizer to the new scan position
CurrentLine = tok.Line + (tok.Text.Length - tok.Text.Replace("\n", "").Length);
CurrentFile = tok.File;
return tok;
}
/// <summary>
/// returns token with longest best match
/// </summary>
/// <returns></returns>
public Token LookAhead(params TokenType[] expectedtokens)
{
int i;
int startpos = StartPos;
int endpos = EndPos;
int currentline = CurrentLine;
string currentFile = CurrentFile;
Token tok = null;
List<TokenType> scantokens;
// this prevents double scanning and matching
// increased performance
if (LookAheadToken != null
&& LookAheadToken.Type != TokenType._UNDETERMINED_
&& LookAheadToken.Type != TokenType._NONE_) return LookAheadToken;
// if no scantokens specified, then scan for all of them (= backward compatible)
if (expectedtokens.Length == 0)
scantokens = Tokens;
else
{
scantokens = new List<TokenType>(expectedtokens);
scantokens.AddRange(SkipList);
}
do
{
int len = -1;
TokenType index = (TokenType)int.MaxValue;
string input = Input.Substring(startpos);
tok = new Token(startpos, endpos);
for (i = 0; i < scantokens.Count; i++)
{
Regex r = Patterns[scantokens[i]];
Match m = r.Match(input);
if (m.Success && m.Index == 0 && ((m.Length > len) || (scantokens[i] < index && m.Length == len )))
{
len = m.Length;
index = scantokens[i];
}
}
if (index >= 0 && len >= 0)
{
tok.EndPos = startpos + len;
tok.Text = Input.Substring(tok.StartPos, len);
tok.Type = index;
}
else if (tok.StartPos == tok.EndPos)
{
if (tok.StartPos < Input.Length)
tok.Text = Input.Substring(tok.StartPos, 1);
else
tok.Text = "EOF";
}
// Update the line and column count for error reporting.
tok.File = currentFile;
tok.Line = currentline;
if (tok.StartPos < Input.Length)
tok.Column = tok.StartPos - Input.LastIndexOf('\n', tok.StartPos);
if (SkipList.Contains(tok.Type))
{
startpos = tok.EndPos;
endpos = tok.EndPos;
currentline = tok.Line + (tok.Text.Length - tok.Text.Replace("\n", "").Length);
currentFile = tok.File;
Skipped.Add(tok);
}
else
{
// only assign to non-skipped tokens
tok.Skipped = Skipped; // assign prior skips to this token
Skipped = new List<Token>(); //reset skips
}
// Check to see if the parsed token wants to
// alter the file and line number.
if (tok.Type == FileAndLine)
{
var match = Patterns[tok.Type].Match(tok.Text);
var fileMatch = match.Groups["File"];
if (fileMatch.Success)
currentFile = fileMatch.Value.Replace("\\\\", "\\");
var lineMatch = match.Groups["Line"];
if (lineMatch.Success)
currentline = int.Parse(lineMatch.Value, NumberStyles.Integer, CultureInfo.InvariantCulture);
}
}
while (SkipList.Contains(tok.Type));
LookAheadToken = tok;
return tok;
}
}
#endregion
#region Token
public enum TokenType
{
//Non terminal tokens:
_NONE_ = 0,
_UNDETERMINED_= 1,
//Non terminal tokens:
Start = 2,
Technique_Declaration= 3,
FillMode_Solid= 4,
FillMode_WireFrame= 5,
FillModes= 6,
CullMode_None= 7,
CullMode_Cw= 8,
CullMode_Ccw= 9,
CullModes= 10,
Colors_None= 11,
Colors_Red= 12,
Colors_Green= 13,
Colors_Blue= 14,
Colors_Alpha= 15,
Colors_All= 16,
Colors_Boolean= 17,
Colors = 18,
ColorsMasks= 19,
Blend_Zero= 20,
Blend_One= 21,
Blend_SrcColor= 22,
Blend_InvSrcColor= 23,
Blend_SrcAlpha= 24,
Blend_InvSrcAlpha= 25,
Blend_DestAlpha= 26,
Blend_InvDestAlpha= 27,
Blend_DestColor= 28,
Blend_InvDestColor= 29,
Blend_SrcAlphaSat= 30,
Blend_BlendFactor= 31,
Blend_InvBlendFactor= 32,
Blends = 33,
BlendOp_Add= 34,
BlendOp_Subtract= 35,
BlendOp_RevSubtract= 36,
BlendOp_Min= 37,
BlendOp_Max= 38,
BlendOps= 39,
CmpFunc_Never= 40,
CmpFunc_Less= 41,
CmpFunc_Equal= 42,
CmpFunc_LessEqual= 43,
CmpFunc_Greater= 44,
CmpFunc_NotEqual= 45,
CmpFunc_GreaterEqual= 46,
CmpFunc_Always= 47,
CmpFunc = 48,
StencilOp_Keep= 49,
StencilOp_Zero= 50,
StencilOp_Replace= 51,
StencilOp_IncrSat= 52,
StencilOp_DecrSat= 53,
StencilOp_Invert= 54,
StencilOp_Incr= 55,
StencilOp_Decr= 56,
StencilOp= 57,
Render_State_CullMode= 58,
Render_State_FillMode= 59,
Render_State_AlphaBlendEnable= 60,
Render_State_SrcBlend= 61,
Render_State_DestBlend= 62,
Render_State_BlendOp= 63,
Render_State_ColorWriteEnable= 64,
Render_State_DepthBias= 65,
Render_State_SlopeScaleDepthBias= 66,
Render_State_ZEnable= 67,
Render_State_ZWriteEnable= 68,
Render_State_ZFunc= 69,
Render_State_MultiSampleAntiAlias= 70,
Render_State_ScissorTestEnable= 71,
Render_State_StencilEnable= 72,
Render_State_StencilFail= 73,
Render_State_StencilFunc= 74,
Render_State_StencilMask= 75,
Render_State_StencilPass= 76,
Render_State_StencilRef= 77,
Render_State_StencilWriteMask= 78,
Render_State_StencilZFail= 79,
Render_State_Expression= 80,
Pass_Declaration= 81,
VertexShader_Pass_Expression= 82,
PixelShader_Pass_Expression= 83,
AddressMode_Clamp= 84,
AddressMode_Wrap= 85,
AddressMode_Mirror= 86,
AddressMode_Border= 87,
AddressMode= 88,
TextureFilter_None= 89,
TextureFilter_Linear= 90,
TextureFilter_Point= 91,
TextureFilter_Anisotropic= 92,
TextureFilter= 93,
Sampler_State_Texture= 94,
Sampler_State_MinFilter= 95,
Sampler_State_MagFilter= 96,
Sampler_State_MipFilter= 97,
Sampler_State_Filter= 98,
Sampler_State_AddressU= 99,
Sampler_State_AddressV= 100,
Sampler_State_AddressW= 101,
Sampler_State_BorderColor= 102,
Sampler_State_MaxMipLevel= 103,
Sampler_State_MaxAnisotropy= 104,
Sampler_State_MipLodBias= 105,
Sampler_State_Expression= 106,
Sampler_Register_Expression= 107,
Sampler_Declaration_States= 108,
Sampler_Declaration= 109,
//Terminal tokens:
BlockComment= 110,
Comment = 111,
Whitespace= 112,
LinePragma= 113,
Pass = 114,
Technique= 115,
Sampler = 116,
SamplerState= 117,
VertexShader= 118,
PixelShader= 119,
Register= 120,
Boolean = 121,
Number = 122,
HexColor= 123,
Identifier= 124,
OpenBracket= 125,
CloseBracket= 126,
Equals = 127,
Colon = 128,
Comma = 129,
Semicolon= 130,
Or = 131,
OpenParenthesis= 132,
CloseParenthesis= 133,
OpenSquareBracket= 134,
CloseSquareBracket= 135,
LessThan= 136,
GreaterThan= 137,
Compile = 138,
ShaderModel= 139,
Code = 140,
EndOfFile= 141,
MinFilter= 142,
MagFilter= 143,
MipFilter= 144,
Filter = 145,
Texture = 146,
AddressU= 147,
AddressV= 148,
AddressW= 149,
BorderColor= 150,
MaxAnisotropy= 151,
MaxMipLevel= 152,
MipLodBias= 153,
Clamp = 154,
Wrap = 155,
Mirror = 156,
Border = 157,
None = 158,
Linear = 159,
Point = 160,
Anisotropic= 161,
AlphaBlendEnable= 162,
SrcBlend= 163,
DestBlend= 164,
BlendOp = 165,
ColorWriteEnable= 166,
ZEnable = 167,
ZWriteEnable= 168,
ZFunc = 169,
DepthBias= 170,
CullMode= 171,
FillMode= 172,
MultiSampleAntiAlias= 173,
ScissorTestEnable= 174,
SlopeScaleDepthBias= 175,
StencilEnable= 176,
StencilFail= 177,
StencilFunc= 178,
StencilMask= 179,
StencilPass= 180,
StencilRef= 181,
StencilWriteMask= 182,
StencilZFail= 183,
Never = 184,
Less = 185,
Equal = 186,
LessEqual= 187,
Greater = 188,
NotEqual= 189,
GreaterEqual= 190,
Always = 191,
Keep = 192,
Zero = 193,
Replace = 194,
IncrSat = 195,
DecrSat = 196,
Invert = 197,
Incr = 198,
Decr = 199,
Red = 200,
Green = 201,
Blue = 202,
Alpha = 203,
All = 204,
Cw = 205,
Ccw = 206,
Solid = 207,
WireFrame= 208,
Add = 209,
Subtract= 210,
RevSubtract= 211,
Min = 212,
Max = 213,
One = 214,
SrcColor= 215,
InvSrcColor= 216,
SrcAlpha= 217,
InvSrcAlpha= 218,
DestAlpha= 219,
InvDestAlpha= 220,
DestColor= 221,
InvDestColor= 222,
SrcAlphaSat= 223,
BlendFactor= 224,
InvBlendFactor= 225
}
public class Token
{
private string file;
private int line;
private int column;
private int startpos;
private int endpos;
private string text;
private object value;
// contains all prior skipped symbols
private List<Token> skipped;
public string File {
get { return file; }
set { file = value; }
}
public int Line {
get { return line; }
set { line = value; }
}
public int Column {
get { return column; }
set { column = value; }
}
public int StartPos {
get { return startpos;}
set { startpos = value; }
}
public int Length {
get { return endpos - startpos;}
}
public int EndPos {
get { return endpos;}
set { endpos = value; }
}
public string Text {
get { return text;}
set { text = value; }
}
public List<Token> Skipped {
get { return skipped;}
set { skipped = value; }
}
public object Value {
get { return value;}
set { this.value = value; }
}
[XmlAttribute]
public TokenType Type;
public Token()
: this(0, 0)
{
}
public Token(int start, int end)
{
Type = TokenType._UNDETERMINED_;
startpos = start;
endpos = end;
Text = ""; // must initialize with empty string, may cause null reference exceptions otherwise
Value = null;
}
public void UpdateRange(Token token)
{
if (token.StartPos < startpos) startpos = token.StartPos;
if (token.EndPos > endpos) endpos = token.EndPos;
}
public override string ToString()
{
if (Text != null)
return Type.ToString() + " '" + Text + "'";
else
return Type.ToString();
}
}
#endregion
}
@@ -0,0 +1,17 @@
// MonoGame - Copyright (C) The MonoGame Team
// This file is subject to the terms and conditions defined in
// file 'LICENSE.txt', which is part of this source code package.
using System;
using System.Collections.Generic;
using System.IO;
namespace TwoMGFX.TPGParser
{
public class ShaderInfo
{
public List<TechniqueInfo> Techniques = new List<TechniqueInfo>();
public Dictionary<string, SamplerStateInfo> SamplerStates = new Dictionary<string, SamplerStateInfo>();
}
}
@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace TwoMGFX.TPGParser
{
public class TechniqueInfo
{
public int startPos;
public int length;
public string name;
public List<PassInfo> Passes = new List<PassInfo>();
}
}
@@ -0,0 +1,10 @@
namespace TwoMGFX
{
public enum TextureFilterType
{
None,
Point,
Linear,
Anisotropic,
}
}