Merged with gl3 branch.
This commit is contained in:
parent
8f90c9d50f
commit
34e3e388c4
36 changed files with 2573 additions and 2080 deletions
53
Source/Bind/BindStreamWriter.cs
Normal file
53
Source/Bind/BindStreamWriter.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Bind.Structures;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
class BindStreamWriter : StreamWriter
|
||||
{
|
||||
public BindStreamWriter(string file)
|
||||
: base(file)
|
||||
{
|
||||
}
|
||||
|
||||
private string indent = "";
|
||||
|
||||
public void Indent()
|
||||
{
|
||||
indent = " " + indent;
|
||||
}
|
||||
|
||||
public void Unindent()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(indent))
|
||||
indent = indent.Substring(4);
|
||||
}
|
||||
|
||||
public override void Write(string value)
|
||||
{
|
||||
base.Write(indent + value);
|
||||
}
|
||||
|
||||
public override void WriteLine(string value)
|
||||
{
|
||||
base.WriteLine(indent + value);
|
||||
}
|
||||
|
||||
public void Write(Bind.Structures.Enum e)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(e.ToString());
|
||||
sb.Replace(System.Environment.NewLine, System.Environment.NewLine + indent);
|
||||
Write(sb);
|
||||
}
|
||||
|
||||
public void Write(Bind.Structures.Function f)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(f.ToString());
|
||||
sb.Replace(System.Environment.NewLine, System.Environment.NewLine + indent);
|
||||
Write(sb);
|
||||
}
|
||||
}
|
||||
}
|
352
Source/Bind/GL2/Generator.cs
Normal file
352
Source/Bind/GL2/Generator.cs
Normal file
|
@ -0,0 +1,352 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Bind.Structures;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bind.GL2
|
||||
{
|
||||
class Generator : IBind
|
||||
{
|
||||
private SpecReader specReader = new SpecReader();
|
||||
private SpecWriter specWriter = new SpecWriter();
|
||||
DelegateCollection delegates = new DelegateCollection();
|
||||
FunctionCollection wrappers = new FunctionCollection();
|
||||
//List<Bind.Structures.Enum> enums = new List<Bind.Structures.Enum>();
|
||||
EnumCollection enums = new EnumCollection();
|
||||
EnumCollection extEnums = new EnumCollection();
|
||||
Dictionary<string, string> GLTypes = new Dictionary<string, string>();
|
||||
Dictionary<string, string> CSTypes = new Dictionary<string, string>();
|
||||
|
||||
string specFolder;
|
||||
|
||||
public Generator(string folder)
|
||||
{
|
||||
specFolder = folder;
|
||||
}
|
||||
|
||||
#region IBind Members
|
||||
|
||||
/*
|
||||
public ISpecReader SpecReader
|
||||
{
|
||||
get { return specReader; }
|
||||
}
|
||||
*/
|
||||
|
||||
#region public void Process()
|
||||
|
||||
public void Process()
|
||||
{
|
||||
// Read
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, "gl2\\gl.tm"))
|
||||
{
|
||||
GLTypes = specReader.ReadTypeMap(sr);
|
||||
}
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, "gl2\\csharp.tm"))
|
||||
{
|
||||
CSTypes = specReader.ReadCSTypeMap(sr);
|
||||
}
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, "gl2\\gl.spec"))
|
||||
{
|
||||
delegates = specReader.ReadDelegates(sr);
|
||||
}
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, "gl2\\enum.spec"))
|
||||
{
|
||||
enums = specReader.ReadEnums(sr);
|
||||
}
|
||||
using (StreamReader sr = Utilities.OpenSpecFile(Settings.InputPath, "gl2\\enumext.spec"))
|
||||
{
|
||||
extEnums = specReader.ReadEnums(sr);
|
||||
}
|
||||
|
||||
// Merge all opengl enumerants in enums
|
||||
foreach (Bind.Structures.Enum e in extEnums.Values)
|
||||
{
|
||||
//enums.Add(e.Name, e);
|
||||
Utilities.Merge(enums, e);
|
||||
}
|
||||
|
||||
// Process enums and delegates - create wrappers.
|
||||
this.Translate();
|
||||
|
||||
|
||||
// Write
|
||||
using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, "GLEnums.cs")))
|
||||
{
|
||||
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
sw.WriteLine("public static partial class {0}", Settings.GLClass);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
specWriter.WriteEnums(sw, enums);
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, "GLDelegates.cs")))
|
||||
{
|
||||
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
specWriter.WriteTypes(sw, CSTypes);
|
||||
specWriter.WriteDelegates(sw, delegates);
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, "GLCore.cs")))
|
||||
{
|
||||
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
specWriter.WriteTypes(sw, CSTypes);
|
||||
specWriter.WriteImports(sw, delegates);
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
using (BindStreamWriter sw = new BindStreamWriter(Path.Combine(Settings.OutputPath, "GL.cs")))
|
||||
{
|
||||
sw.WriteLine("namespace {0}", Settings.OutputNamespace);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
specWriter.WriteTypes(sw, CSTypes);
|
||||
specWriter.WriteWrappers(sw, wrappers, CSTypes);
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region private void Translate()
|
||||
|
||||
private void Translate()
|
||||
{
|
||||
foreach (Bind.Structures.Enum e in enums.Values)
|
||||
{
|
||||
TranslateEnum(e);
|
||||
}
|
||||
|
||||
foreach (Bind.Structures.Delegate d in delegates.Values)
|
||||
{
|
||||
TranslateReturnType(d);
|
||||
TranslateParameters(d);
|
||||
//wrappers.AddRange(d.CreateWrappers());
|
||||
foreach (Function f in d.CreateWrappers(CSTypes))
|
||||
{
|
||||
if (!f.CLSCompliant)
|
||||
{
|
||||
Function clsFunction = f.GetCLSCompliantFunction(CSTypes);
|
||||
if (clsFunction.Parameters.ToString(true) != f.Parameters.ToString(true))
|
||||
wrappers.Add(clsFunction);
|
||||
}
|
||||
wrappers.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private void TranslateReturnType(Bind.Structures.Delegate d)
|
||||
|
||||
/// <summary>
|
||||
/// Translates the opengl return type to the equivalent C# type.
|
||||
/// </summary>
|
||||
/// <param name="d">The opengl function to translate.</param>
|
||||
/// <remarks>
|
||||
/// First, we use the official typemap (gl.tm) to get the correct type.
|
||||
/// Then we override this, when it is:
|
||||
/// 1) A string (we have to use Marshal.PtrToStringAnsi, to avoid heap corruption)
|
||||
/// 2) An array (translates to IntPtr)
|
||||
/// 3) A generic object or void* (translates to IntPtr)
|
||||
/// 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise).
|
||||
/// Return types must always be CLS-compliant, because .Net does not support overloading on return types.
|
||||
/// </remarks>
|
||||
private void TranslateReturnType(Bind.Structures.Delegate d)
|
||||
{
|
||||
if (GLTypes.ContainsKey(d.ReturnType.Type))
|
||||
{
|
||||
d.ReturnType.Type = GLTypes[d.ReturnType.Type];
|
||||
}
|
||||
|
||||
if (d.ReturnType.Type.ToLower().Contains("void") && d.ReturnType.Pointer)
|
||||
{
|
||||
d.ReturnType.WrapperType = WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.Type == "GLstring")
|
||||
{
|
||||
d.ReturnType.Type = "System.IntPtr";
|
||||
d.ReturnType.WrapperType = WrapperTypes.StringReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.Type.ToLower().Contains("object"))
|
||||
{
|
||||
d.ReturnType.Type = "System.IntPtr";
|
||||
d.ReturnType.WrapperType |= WrapperTypes.GenericReturnType;
|
||||
}
|
||||
|
||||
if (d.ReturnType.Type == "GLenum")
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.None)
|
||||
d.ReturnType.Type = Settings.GLClass + ".Enums.GLenum";
|
||||
else
|
||||
d.ReturnType.Type = "int";
|
||||
}
|
||||
|
||||
if (d.ReturnType.Type.ToLower().Contains("bool") && Settings.Compatibility == Settings.Legacy.Tao)
|
||||
{
|
||||
d.ReturnType.Type = "int";
|
||||
}
|
||||
|
||||
if (d.ReturnType.WrapperType != WrapperTypes.None)
|
||||
{
|
||||
d.NeedsWrapper = true;
|
||||
}
|
||||
|
||||
d.ReturnType.Type = d.ReturnType.GetCLSCompliantType(CSTypes);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private void TranslateParameters(Bind.Structures.Delegate d)
|
||||
|
||||
private void TranslateParameters(Bind.Structures.Delegate d)
|
||||
{
|
||||
string s;
|
||||
Bind.Structures.Enum @enum;
|
||||
|
||||
foreach (Parameter p in d.Parameters)
|
||||
{
|
||||
// Translate enum parameters
|
||||
if (enums.TryGetValue(p.Type, out @enum) && @enum.Name != "GLenum")
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.None)
|
||||
p.Type = p.Type.Insert(0, Settings.GLClass + ".Enums.");
|
||||
else
|
||||
p.Type = "int";
|
||||
}
|
||||
else if (GLTypes.TryGetValue(p.Type, out s))
|
||||
{
|
||||
// Check if the parameter is a generic GLenum. If yes,
|
||||
// check if a better match exists:
|
||||
if (s.Contains("GLenum") && !String.IsNullOrEmpty(d.Category))
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.None)
|
||||
{
|
||||
// Better match: enum.Name == function.Category (e.g. GL_VERSION_1_1 etc)
|
||||
if (enums.ContainsKey(d.Category))
|
||||
{
|
||||
p.Type = Settings.GLClass + ".Enums." + d.Category;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Type = Settings.GLClass + ".Enums.GLenum";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Type = "int";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is not enum, default translation:
|
||||
p.Type = s;
|
||||
}
|
||||
}
|
||||
|
||||
// Translate pointer parameters
|
||||
if (p.Pointer)
|
||||
{
|
||||
p.WrapperType = WrapperTypes.ArrayParameter;
|
||||
|
||||
if (p.Type.ToLower().Contains("char") || p.Type.ToLower().Contains("string"))
|
||||
{
|
||||
// char* or string -> [In] String or [Out] StringBuilder
|
||||
p.Type =
|
||||
p.Flow == Parameter.FlowDirection.Out ?
|
||||
"System.Text.StringBuilder" :
|
||||
"System.String";
|
||||
|
||||
if (d.Name.Contains("ShaderSource"))
|
||||
{
|
||||
// Special case: these functions take a string[]
|
||||
//p.IsPointer = true;
|
||||
p.Array = 1;
|
||||
}
|
||||
|
||||
p.Pointer = false;
|
||||
p.WrapperType = WrapperTypes.None;
|
||||
}
|
||||
else if (p.Type.ToLower().Contains("void"))
|
||||
{
|
||||
p.WrapperType = WrapperTypes.GenericParameter;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for LineStipple (should be unchecked)
|
||||
if (p.Type.ToLower().Contains("ushort") && d.Name.Contains("LineStipple"))
|
||||
{
|
||||
p.WrapperType = WrapperTypes.UncheckedParameter;
|
||||
}
|
||||
|
||||
if (p.Type.ToLower().Contains("bool"))
|
||||
{
|
||||
p.WrapperType = WrapperTypes.BoolParameter;
|
||||
}
|
||||
|
||||
if (p.WrapperType != WrapperTypes.None)
|
||||
{
|
||||
d.NeedsWrapper = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private void TranslateEnum(Bind.Structures.Enum e)
|
||||
|
||||
private void TranslateEnum(Bind.Structures.Enum e)
|
||||
{
|
||||
|
||||
foreach (Constant c in e.ConstantCollection.Values)
|
||||
{
|
||||
// There are cases when a value is an aliased constant, with no enum specified.
|
||||
// (e.g. FOG_COORD_ARRAY_TYPE = GL_FOG_COORDINATE_ARRAY_TYPE)
|
||||
// In this case try searching all enums for the correct constant to alias (stupid opengl specs).
|
||||
if (String.IsNullOrEmpty(c.Reference) && !Char.IsDigit(c.Value[0]))
|
||||
{
|
||||
foreach (Bind.Structures.Enum @enum in enums.Values)
|
||||
{
|
||||
// Skip generic GLenum
|
||||
if (@enum.Name == "GLenum")
|
||||
continue;
|
||||
|
||||
if (@enum.ConstantCollection.ContainsKey(c.Value))
|
||||
{
|
||||
c.Reference = @enum.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
410
Source/Bind/GL2/SpecReader.cs
Normal file
410
Source/Bind/GL2/SpecReader.cs
Normal file
|
@ -0,0 +1,410 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Bind.Structures;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bind.GL2
|
||||
{
|
||||
class SpecReader : ISpecReader
|
||||
{
|
||||
#region --- ISpecReader Members ---
|
||||
|
||||
#region public virtual DelegateCollection ReadDelegates(System.IO.StreamReader specFile)
|
||||
|
||||
public virtual DelegateCollection ReadDelegates(System.IO.StreamReader specFile)
|
||||
{
|
||||
Console.WriteLine("Reading function specs.");
|
||||
|
||||
//List<Bind.Structures.Delegate> delegates = new List<Bind.Structures.Delegate>();
|
||||
DelegateCollection delegates = new DelegateCollection();
|
||||
|
||||
do
|
||||
{
|
||||
string line = NextValidLine(specFile);
|
||||
if (String.IsNullOrEmpty(line))
|
||||
break;
|
||||
|
||||
while (line.Contains("(") && !specFile.EndOfStream)
|
||||
{
|
||||
// Get next OpenGL function
|
||||
|
||||
Bind.Structures.Delegate d = new Bind.Structures.Delegate();
|
||||
|
||||
// Get function name:
|
||||
d.Name = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||
|
||||
if (d.Name == "CallLists")
|
||||
{
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
// Get function parameters and return value
|
||||
|
||||
line = specFile.ReadLine();
|
||||
List<string> words = new List<string>(
|
||||
line.Replace('\t', ' ').Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries)
|
||||
);
|
||||
|
||||
if (words.Count == 0)
|
||||
break;
|
||||
|
||||
// Identify line:
|
||||
switch (words[0])
|
||||
{
|
||||
case "return": // Line denotes return value
|
||||
d.ReturnType.Type = words[1];
|
||||
break;
|
||||
|
||||
case "param": // Line denotes parameter
|
||||
Parameter p = new Parameter();
|
||||
WrapperTypes wrapper;
|
||||
string type;
|
||||
|
||||
p.Name = Utilities.Keywords.Contains(words[1]) ? "@" + words[1] : words[1];
|
||||
p.Type = words[2];
|
||||
p.Pointer = words[4] == "array" ? true : false;
|
||||
p.Flow = words[3] == "in" ? Parameter.FlowDirection.In : Parameter.FlowDirection.Out;
|
||||
|
||||
d.Parameters.Add(p);
|
||||
break;
|
||||
|
||||
// Version directive is not used. GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?)
|
||||
//case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5)
|
||||
// d.UserData.Add("version", words[1]);
|
||||
// break;
|
||||
|
||||
case "category":
|
||||
d.Category = words[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!specFile.EndOfStream);
|
||||
|
||||
delegates.Add(d);
|
||||
}
|
||||
}
|
||||
while (!specFile.EndOfStream);
|
||||
|
||||
return delegates;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public virtual EnumCollection ReadEnums(System.IO.StreamReader specFile)
|
||||
|
||||
public virtual EnumCollection ReadEnums(System.IO.StreamReader specfile)
|
||||
{
|
||||
EnumCollection enums = new EnumCollection();
|
||||
|
||||
// complete_enum contains all opengl enumerants.
|
||||
Bind.Structures.Enum complete_enum = new Bind.Structures.Enum();
|
||||
complete_enum.Name = "GLenum";
|
||||
|
||||
Trace.WriteLine(String.Format("Reading opengl enumerant specs"));
|
||||
Trace.Indent();
|
||||
|
||||
do
|
||||
{
|
||||
string line = NextValidLine(specfile);
|
||||
if (String.IsNullOrEmpty(line))
|
||||
break;
|
||||
|
||||
line = line.Replace('\t', ' ');
|
||||
|
||||
// We just encountered the start of a new enumerant:
|
||||
while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
|
||||
{
|
||||
string[] words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (words.Length == 0)
|
||||
continue;
|
||||
|
||||
// Declare a new enumerant
|
||||
Bind.Structures.Enum e = new Bind.Structures.Enum();
|
||||
e.Name = Char.IsDigit(words[0][0]) ? "GL_" + words[0] : words[0];
|
||||
|
||||
// And fill in the values for this enumerant
|
||||
do
|
||||
{
|
||||
line = NextValidLine(specfile);
|
||||
|
||||
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
if (line.Contains("enum:") || specfile.EndOfStream)
|
||||
break;
|
||||
|
||||
line = line.Replace('\t', ' ');
|
||||
words = line.Split(Utilities.Separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (words.Length == 0)
|
||||
continue;
|
||||
|
||||
// If we reach this point, we have found a new value for the current enumerant
|
||||
Constant c = new Constant();
|
||||
if (line.Contains("="))
|
||||
{
|
||||
// Trim the "GL_" from the start of the string.
|
||||
if (words[0].StartsWith("GL_"))
|
||||
words[0] = words[0].Substring(3);
|
||||
|
||||
if (Char.IsDigit(words[0][0]))
|
||||
words[0] = "GL_" + words[0];
|
||||
|
||||
c.Name = words[0];
|
||||
|
||||
uint number;
|
||||
if (UInt32.TryParse(words[2].Replace("0x", String.Empty), System.Globalization.NumberStyles.AllowHexSpecifier, null, out number))
|
||||
{
|
||||
// The value is a number, check if it should be unchecked.
|
||||
if (number > 0x7FFFFFFF)
|
||||
{
|
||||
c.Unchecked = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The value is not a number.
|
||||
// Strip the "GL_" from the start of the string.
|
||||
if (words[2].StartsWith("GL_"))
|
||||
words[2] = words[2].Substring(3);
|
||||
|
||||
// If the name now starts with a digit (doesn't matter whether we
|
||||
// stripped "GL_" above), add a "GL_" prefix.
|
||||
// (e.g. GL_4_BYTES).
|
||||
if (Char.IsDigit(words[2][0]))
|
||||
words[2] = "GL_" + words[2];
|
||||
}
|
||||
|
||||
c.Value = words[2];
|
||||
}
|
||||
else if (words[0] == "use")
|
||||
{
|
||||
// Trim the "GL_" from the start of the string.
|
||||
if (words[2].StartsWith("GL_"))
|
||||
words[2] = words[2].Substring(3);
|
||||
|
||||
// If the remaining string starts with a digit, we were wrong above.
|
||||
// Re-add the "GL_"
|
||||
if (Char.IsDigit(words[2][0]))
|
||||
words[2] = "GL_" + words[2];
|
||||
|
||||
c.Name = words[2];
|
||||
|
||||
if (words[1] == "LightProperty")
|
||||
{
|
||||
Trace.WriteLine(
|
||||
String.Format(
|
||||
"Spec error: Enum LightProperty.{0} does no exist, changing to LightParameter.{0}",
|
||||
words[2]
|
||||
)
|
||||
);
|
||||
words[1] = "LightParameter";
|
||||
}
|
||||
c.Reference = words[1];
|
||||
c.Value = words[2];
|
||||
}
|
||||
|
||||
//if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
|
||||
//SpecTranslator.Merge(e.Members, c);
|
||||
if (!e.ConstantCollection.ContainsKey(c.Name))
|
||||
{
|
||||
e.ConstantCollection.Add(c.Name, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine(
|
||||
String.Format(
|
||||
"Spec error: Constant {0} defined twice in enum {1}, discarding last definition.",
|
||||
c.Name,
|
||||
e.Name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Insert the current constant in the list of all constants.
|
||||
//SpecTranslator.Merge(complete_enum.Members, c);
|
||||
complete_enum = Utilities.Merge(complete_enum, c);
|
||||
}
|
||||
while (!specfile.EndOfStream);
|
||||
|
||||
// At this point, the complete value list for the current enumerant has been read, so add this
|
||||
// enumerant to the list.
|
||||
//e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
|
||||
//e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));
|
||||
|
||||
// (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
|
||||
//if (!e.Name.Contains("Bool"))
|
||||
//Utilities.Merge(enums, e);
|
||||
|
||||
if (!enums.ContainsKey(e.Name))
|
||||
{
|
||||
enums.Add(e.Name, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The enum already exists, merge constants.
|
||||
Trace.WriteLine(String.Format("Conflict: Enum {0} already exists, merging constants.", e.Name));
|
||||
foreach (Constant t in e.ConstantCollection.Values)
|
||||
{
|
||||
Utilities.Merge(enums[e.Name], t);
|
||||
}
|
||||
}
|
||||
|
||||
//enums.Add(e);
|
||||
}
|
||||
//SpecTranslator.Merge(enums, complete_enum);
|
||||
}
|
||||
while (!specfile.EndOfStream);
|
||||
|
||||
enums.Add(complete_enum.Name, complete_enum);
|
||||
|
||||
// Add missing enum
|
||||
{
|
||||
Trace.WriteLine("Spec error: SGIX_icc_texture enum missing, adding by hand.");
|
||||
|
||||
Bind.Structures.Enum e = new Bind.Structures.Enum("SGIX_icc_texture");
|
||||
e.ConstantCollection.Add("RGB_ICC_SGIX", new Constant("RGB_ICC_SGIX", "0x8460"));
|
||||
e.ConstantCollection.Add("RGBA_ICC_SGIX", new Constant("RGBA_ICC_SGIX", "0x8461"));
|
||||
e.ConstantCollection.Add("ALPHA_ICC_SGIX", new Constant("ALPHA_ICC_SGIX", "0x8462"));
|
||||
e.ConstantCollection.Add("LUMINANCE_ICC_SGIX", new Constant("LUMINANCE_ICC_SGIX", "0x8463"));
|
||||
e.ConstantCollection.Add("INTENSITY_ICC_SGIX", new Constant("INTENSITY_ICC_SGIX", "0x8464"));
|
||||
e.ConstantCollection.Add("LUMINANCE_ALPHA_ICC_SGIX", new Constant("LUMINANCE_ALPHA_ICC_SGIX", "0x8465"));
|
||||
e.ConstantCollection.Add("R5_G6_B5_ICC_SGIX", new Constant("R5_G6_B5_ICC_SGIX", "0x8466"));
|
||||
e.ConstantCollection.Add("R5_G6_B5_A8_ICC_SGIX", new Constant("R5_G6_B5_A8_ICC_SGIX", "0x8467"));
|
||||
e.ConstantCollection.Add("ALPHA16_ICC_SGIX", new Constant("ALPHA16_ICC_SGIX", "0x8468"));
|
||||
e.ConstantCollection.Add("LUMINANCE16_ICC_SGIX", new Constant("LUMINANCE16_ICC_SGIX", "0x8469"));
|
||||
e.ConstantCollection.Add("INTENSITY16_ICC_SGIX", new Constant("INTENSITY16_ICC_SGIX", "0x846A"));
|
||||
e.ConstantCollection.Add("LUMINANCE16_ALPHA8_ICC_SGIX", new Constant("LUMINANCE16_ALPHA8_ICC_SGIX", "0x846B"));
|
||||
|
||||
enums.Add(e.Name, e);
|
||||
}
|
||||
|
||||
Trace.Unindent();
|
||||
|
||||
return enums;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public virtual Dictionary<string, string> ReadTypeMap(System.IO.StreamReader sr)
|
||||
|
||||
public virtual Dictionary<string, string> ReadTypeMap(System.IO.StreamReader sr)
|
||||
{
|
||||
Console.WriteLine("Reading opengl types.");
|
||||
Dictionary<string, string> GLTypes = new Dictionary<string, string>();
|
||||
|
||||
do
|
||||
{
|
||||
string line = sr.ReadLine();
|
||||
|
||||
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
string[] words = line.Split(new char[] { ' ', ',', '*', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (words[0].ToLower() == "void")
|
||||
{
|
||||
// Special case for "void" -> "". We make it "void" -> "void"
|
||||
GLTypes.Add(words[0], "void");
|
||||
}
|
||||
else if (words[0] == "VoidPointer" || words[0] == "ConstVoidPointer")
|
||||
{
|
||||
// "(Const)VoidPointer" -> "void*"
|
||||
GLTypes.Add(words[0], "void*");
|
||||
}
|
||||
/*else if (words[0] == "CharPointer" || words[0] == "charPointerARB")
|
||||
{
|
||||
GLTypes.Add(words[0], "System.String");
|
||||
}
|
||||
else if (words[0].Contains("Pointer"))
|
||||
{
|
||||
GLTypes.Add(words[0], words[1].Replace("Pointer", "*"));
|
||||
}*/
|
||||
else if (words[1].Contains("GLvoid"))
|
||||
{
|
||||
GLTypes.Add(words[0], "void");
|
||||
}
|
||||
else
|
||||
{
|
||||
GLTypes.Add(words[0], words[1]);
|
||||
}
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
|
||||
return GLTypes;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public virtual Dictionary<string, string> ReadCSTypeMap(System.IO.StreamReader sr)
|
||||
|
||||
public virtual Dictionary<string, string> ReadCSTypeMap(System.IO.StreamReader sr)
|
||||
{
|
||||
Dictionary<string, string> CSTypes = new Dictionary<string, string>();
|
||||
Console.WriteLine("Reading C# types.");
|
||||
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
string line = sr.ReadLine();
|
||||
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
string[] words = line.Split(" ,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
if (words.Length < 2)
|
||||
continue;
|
||||
|
||||
CSTypes.Add(words[0], words[1]);
|
||||
}
|
||||
|
||||
return CSTypes;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected virtual string NextValidLine(StreamReader sr)
|
||||
|
||||
protected virtual string NextValidLine(System.IO.StreamReader sr)
|
||||
{
|
||||
string line;
|
||||
|
||||
do
|
||||
{
|
||||
if (sr.EndOfStream)
|
||||
return null;
|
||||
|
||||
line = sr.ReadLine().Trim();
|
||||
|
||||
if (String.IsNullOrEmpty(line) ||
|
||||
line.StartsWith("#") || // Disregard comments.
|
||||
line.StartsWith("passthru") || // Disregard passthru statements.
|
||||
line.StartsWith("required-props:") ||
|
||||
line.StartsWith("param:") ||
|
||||
line.StartsWith("dlflags:") ||
|
||||
line.StartsWith("glxflags:") ||
|
||||
line.StartsWith("vectorequiv:") ||
|
||||
//line.StartsWith("category:") ||
|
||||
line.StartsWith("version:") ||
|
||||
line.StartsWith("glxsingle:") ||
|
||||
line.StartsWith("glxropcode:") ||
|
||||
line.StartsWith("glxvendorpriv:") ||
|
||||
line.StartsWith("glsflags:") ||
|
||||
line.StartsWith("glsopcode:") ||
|
||||
line.StartsWith("glsalias:") ||
|
||||
line.StartsWith("wglflags:") ||
|
||||
line.StartsWith("extension:") ||
|
||||
line.StartsWith("alias:") ||
|
||||
line.StartsWith("offset:"))
|
||||
continue;
|
||||
|
||||
return line;
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
206
Source/Bind/GL2/SpecWriter.cs
Normal file
206
Source/Bind/GL2/SpecWriter.cs
Normal file
|
@ -0,0 +1,206 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Bind.Structures;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bind.GL2
|
||||
{
|
||||
class SpecWriter : ISpecWriter
|
||||
{
|
||||
#region --- ISpecWriter Members ---
|
||||
|
||||
#region void WriteDelegates
|
||||
|
||||
public void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates)
|
||||
{
|
||||
Trace.WriteLine(String.Format("Writing delegates to {0}.{1}", Settings.OutputNamespace, Settings.DelegatesClass));
|
||||
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("internal static class {0}", Settings.DelegatesClass);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
// Disable BeforeFieldInit
|
||||
sw.WriteLine("static {0}()", Settings.DelegatesClass);
|
||||
sw.WriteLine("{");
|
||||
//sw.Indent();
|
||||
//sw.WriteLine("{0}.ReloadFunctions();", Settings.GLClass);
|
||||
//sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
sw.WriteLine();
|
||||
foreach (Bind.Structures.Delegate d in delegates.Values)
|
||||
{
|
||||
sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]");
|
||||
sw.WriteLine("internal {0};", d.ToString());
|
||||
if (d.Extension == "Core")
|
||||
{
|
||||
sw.WriteLine(
|
||||
"internal {0}static {1} gl{1} = ({1}){2}.{3}(\"gl{1}\", typeof({1})) ?? new {1}({4}.{1});",
|
||||
d.Unsafe ? "unsafe " : "",
|
||||
d.Name,
|
||||
Settings.GLClass,
|
||||
"GetDelegateForExtensionMethod",
|
||||
Settings.ImportsClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
sw.WriteLine(
|
||||
"internal {0}static {1} gl{1} = ({1}){2}.{3}(\"gl{1}\", typeof({1}));",
|
||||
d.Unsafe ? "unsafe " : "",
|
||||
d.Name,
|
||||
Settings.GLClass,
|
||||
"GetDelegateForExtensionMethod");
|
||||
}
|
||||
}
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region void WriteImports
|
||||
|
||||
public void WriteImports(BindStreamWriter sw, DelegateCollection delegates)
|
||||
{
|
||||
Trace.WriteLine(String.Format("Writing imports to {0}.{1}", Settings.OutputNamespace, Settings.ImportsClass));
|
||||
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("internal static class {0}", Settings.ImportsClass);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
sw.WriteLine("static {0}() {1} {2}", Settings.ImportsClass, "{", "}"); // Disable BeforeFieldInit
|
||||
sw.WriteLine();
|
||||
foreach (Bind.Structures.Delegate d in delegates.Values)
|
||||
{
|
||||
sw.WriteLine("[System.Security.SuppressUnmanagedCodeSecurity()]");
|
||||
sw.WriteLine(
|
||||
"[System.Runtime.InteropServices.DllImport({0}.Library, EntryPoint = \"gl{1}\", ExactSpelling = true)]",
|
||||
Settings.GLClass,
|
||||
d.Name
|
||||
);
|
||||
sw.WriteLine("internal extern static {0};", d.DeclarationString());
|
||||
}
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region void WriteWrappers
|
||||
|
||||
public void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
Trace.WriteLine(String.Format("Writing wrappers to {0}.{1}", Settings.OutputNamespace, Settings.GLClass));
|
||||
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("public static partial class {0}", Settings.GLClass);
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
sw.WriteLine("static {0}() {1} {2}", Settings.GLClass, "{", "}"); // Disable BeforeFieldInit
|
||||
sw.WriteLine();
|
||||
foreach (string key in wrappers.Keys)
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.None && key != "Core")
|
||||
{
|
||||
sw.WriteLine("public static class {0}", key);
|
||||
sw.WriteLine("{");
|
||||
sw.Indent();
|
||||
}
|
||||
|
||||
foreach (Function f in wrappers[key])
|
||||
{
|
||||
if (Settings.Compatibility != Settings.Legacy.Tao)
|
||||
Utilities.StripGL2Extension(f);
|
||||
|
||||
if (f.Name == "ActiveTexture")
|
||||
{
|
||||
}
|
||||
|
||||
if (!f.CLSCompliant)
|
||||
{
|
||||
sw.WriteLine("[System.CLSCompliant(false)]");
|
||||
}
|
||||
sw.WriteLine("public static ");
|
||||
sw.Write(f);
|
||||
sw.WriteLine();
|
||||
}
|
||||
|
||||
if (Settings.Compatibility == Settings.Legacy.None && key != "Core")
|
||||
{
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
sw.WriteLine();
|
||||
}
|
||||
}
|
||||
sw.Unindent();
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region void WriteTypes
|
||||
|
||||
public void WriteTypes(BindStreamWriter sw, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
sw.WriteLine("using System;");
|
||||
sw.WriteLine();
|
||||
foreach (string s in CSTypes.Keys)
|
||||
{
|
||||
sw.WriteLine("using {0} = System.{1};", s, CSTypes[s]);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region void WriteEnums
|
||||
|
||||
public void WriteEnums(BindStreamWriter sw, EnumCollection enums)
|
||||
{
|
||||
Trace.WriteLine(String.Format("Writing enums to {0}.{1}", Settings.OutputNamespace, Settings.GLClass));
|
||||
|
||||
if (Settings.Compatibility == Settings.Legacy.None)
|
||||
{
|
||||
sw.WriteLine("public class Enums");
|
||||
sw.WriteLine("{");
|
||||
|
||||
sw.Indent();
|
||||
foreach (Bind.Structures.Enum @enum in enums.Values)
|
||||
{
|
||||
sw.Write(@enum);
|
||||
sw.WriteLine();
|
||||
}
|
||||
sw.Unindent();
|
||||
|
||||
sw.WriteLine("}");
|
||||
}
|
||||
else if (Settings.Compatibility == Settings.Legacy.Tao)
|
||||
{
|
||||
// Tao legacy mode: dump all enums as constants in GLClass.
|
||||
foreach (Bind.Structures.Constant c in enums["GLenum"].ConstantCollection.Values)
|
||||
{
|
||||
// Print constants avoiding circular definitions
|
||||
if (c.Name != c.Value)
|
||||
{
|
||||
sw.WriteLine(String.Format(
|
||||
"public const int {0} = {2}((int){1});",
|
||||
c.Name.StartsWith("GL_") ? c.Name : "GL_" + c.Name,
|
||||
Char.IsDigit(c.Value[0]) ? c.Value : c.Value.StartsWith("GL_") ? c.Value : "GL_" + c.Value,
|
||||
c.Unchecked ? "unchecked" : ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
12
Source/Bind/IBind.cs
Normal file
12
Source/Bind/IBind.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
interface IBind
|
||||
{
|
||||
//ISpecReader SpecReader { get; }
|
||||
void Process();
|
||||
}
|
||||
}
|
15
Source/Bind/ISpecReader.cs
Normal file
15
Source/Bind/ISpecReader.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
interface ISpecReader
|
||||
{
|
||||
Bind.Structures.DelegateCollection ReadDelegates(StreamReader specFile);
|
||||
Bind.Structures.EnumCollection ReadEnums(StreamReader specFile);
|
||||
Dictionary<string, string> ReadTypeMap(StreamReader specFile);
|
||||
Dictionary<string, string> ReadCSTypeMap(StreamReader specFile);
|
||||
}
|
||||
}
|
16
Source/Bind/ISpecWriter.cs
Normal file
16
Source/Bind/ISpecWriter.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Bind.Structures;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
interface ISpecWriter
|
||||
{
|
||||
void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates);
|
||||
void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, Dictionary<string, string> CSTypes);
|
||||
void WriteEnums(BindStreamWriter sw, EnumCollection enums);
|
||||
void WriteTypes(BindStreamWriter sw, Dictionary<string, string> CSTypes);
|
||||
}
|
||||
}
|
|
@ -33,19 +33,40 @@ using System.Security.Permissions;
|
|||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.CodeDom;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind
|
||||
{
|
||||
enum GeneratorMode
|
||||
{
|
||||
GL2,
|
||||
GL3,
|
||||
Wgl,
|
||||
Glx,
|
||||
Glu
|
||||
}
|
||||
|
||||
static class MainClass
|
||||
{
|
||||
static GeneratorMode mode;
|
||||
|
||||
static void Main(string[] arguments)
|
||||
{
|
||||
Debug.Listeners.Clear();
|
||||
Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
|
||||
Debug.AutoFlush = true;
|
||||
Trace.Listeners.Clear();
|
||||
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
|
||||
Trace.AutoFlush = true;
|
||||
|
||||
Console.WriteLine("OpenGL binding generator {0} for OpenTK.",
|
||||
System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
Console.WriteLine("For comments, bugs and suggestions visit http://opentk.sourceforge.net");
|
||||
//Console.WriteLine(" - the OpenTK team ;-)");
|
||||
Console.WriteLine();
|
||||
|
||||
IBind bind;
|
||||
|
||||
#region Handle Arguments
|
||||
|
||||
try
|
||||
|
@ -66,14 +87,36 @@ namespace OpenTK.OpenGL.Bind
|
|||
Settings.InputPath = b[1];
|
||||
break;
|
||||
case "out":
|
||||
case "Properties.Bind.Default.OutputPath":
|
||||
case "output":
|
||||
Settings.OutputPath = b[1];
|
||||
break;
|
||||
case "mode":
|
||||
mode =
|
||||
b[1].ToLower() == "gl2" ? GeneratorMode.GL2 :
|
||||
b[1].ToLower() == "gl3" ? GeneratorMode.GL3 : GeneratorMode.GL2;
|
||||
break;
|
||||
case "namespace":
|
||||
case "ns":
|
||||
Settings.OutputNamespace = b[1];
|
||||
break;
|
||||
case "gl":
|
||||
Settings.GLClass = b[1];
|
||||
break;
|
||||
case "glu":
|
||||
Settings.GluClass = b[1];
|
||||
break;
|
||||
case "legacy":
|
||||
Settings.Compatibility = b[1].ToLower() == "tao" ? Settings.Legacy.Tao : Settings.Legacy.None;
|
||||
Settings.OutputNamespace = "Tao.OpenGl";
|
||||
Settings.GLClass = "Gl";
|
||||
break;
|
||||
case "class":
|
||||
Settings.GLClass = b[1];
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Argument " + a + " not recognized. Use the '/?' switch for help.");
|
||||
throw new ArgumentException(
|
||||
String.Format("Argument {0} not recognized. Use the '/?' switch for help.", a)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,34 +138,36 @@ namespace OpenTK.OpenGL.Bind
|
|||
{
|
||||
long ticks = System.DateTime.Now.Ticks;
|
||||
|
||||
List<CodeMemberMethod> functions;
|
||||
List<CodeTypeDelegate> delegates;
|
||||
CodeTypeDeclarationCollection enums;
|
||||
CodeTypeDeclarationCollection enums2;
|
||||
switch (mode)
|
||||
{
|
||||
case GeneratorMode.GL2:
|
||||
bind = new Bind.GL2.Generator(Settings.InputPath);
|
||||
break;
|
||||
|
||||
delegates = SpecReader.ReadFunctionSpecs("gl.spec");
|
||||
SpecReader.ReadEnumSpecs("enum.spec", out enums);
|
||||
SpecReader.ReadEnumSpecs("enumext.spec", out enums2);
|
||||
enums = SpecTranslator.Merge(enums, enums2);
|
||||
enums = SpecTranslator.TranslateEnums(enums);
|
||||
default:
|
||||
throw new NotImplementedException(String.Format("Mode {0} not implemented.", mode));
|
||||
}
|
||||
|
||||
functions = SpecTranslator.TranslateDelegates(delegates, enums);
|
||||
|
||||
// Generate the code
|
||||
SpecWriter.Generate(delegates, functions, enums);
|
||||
bind.Process();
|
||||
|
||||
ticks = System.DateTime.Now.Ticks - ticks;
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Bindings generated in {0} seconds.", ticks / (double)10000000.0);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Press enter to continue...");
|
||||
Console.ReadLine();
|
||||
Console.WriteLine("Press any key to continue...");
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
Console.WriteLine("Security violation \"{0}\" in method \"{1}\".", e.Message, e.Method);
|
||||
Console.WriteLine("This application does not have permission to take the requested actions.");
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Console.WriteLine("The requested functionality is not implemented yet.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.9.1.0")]
|
||||
[assembly: AssemblyFileVersion("0.9.1.0")]
|
||||
[assembly: AssemblyVersion("0.9.5.1")]
|
||||
[assembly: AssemblyFileVersion("0.9.5.1")]
|
||||
|
|
|
@ -7,18 +7,25 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind
|
||||
{
|
||||
static class Settings
|
||||
{
|
||||
public static string InputPath = "..\\..\\..\\Source\\OpenGL\\Specifications";
|
||||
public static string OutputPath = "..\\..\\..\\Source\\OpenGL\\OpenGL\\Bindings";
|
||||
public static string InputPath = "..\\..\\..\\Source\\Bind\\Specifications";
|
||||
public static string OutputPath = "..\\..\\..\\Source\\OpenTK\\OpenGL\\Bindings";
|
||||
public static string OutputNamespace = "OpenTK.OpenGL";
|
||||
public static string GLClass = "GL";
|
||||
public static string DelegatesClass = "Delegates";
|
||||
public static string ImportsClass = "Imports";
|
||||
public static string WglClass = "Wgl";
|
||||
public static string GlxClass = "Glx";
|
||||
public static string GluClass = "Glu";
|
||||
public static Legacy Compatibility = Legacy.None;
|
||||
|
||||
public static string GLFunctionPrepend = String.Empty;
|
||||
public enum Legacy
|
||||
{
|
||||
None,
|
||||
Tao,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,433 +0,0 @@
|
|||
#region --- License ---
|
||||
/*
|
||||
MIT License
|
||||
Copyright ©2006-2007 Tao Framework Team
|
||||
http://www.taoframework.com
|
||||
Copyright ©2005-2007 OpenTK
|
||||
http://sourceforge.net/projects/opentk
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#endregion License
|
||||
|
||||
#region --- Using Directives ---
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.CodeDom;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
{
|
||||
static class SpecReader
|
||||
{
|
||||
#region internal static string FilePath
|
||||
internal static string FilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
string filePath = Path.Combine("..", "..");
|
||||
string fileDirectory = Settings.InputPath;
|
||||
string fileName = "gl.spec";
|
||||
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
filePath = "";
|
||||
fileDirectory = "";
|
||||
}
|
||||
else if (File.Exists(Path.Combine(fileDirectory, fileName)))
|
||||
{
|
||||
filePath = "";
|
||||
}
|
||||
return Path.Combine(filePath, fileDirectory);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static StreamReader OpenSpecFile(string file)
|
||||
private static StreamReader OpenSpecFile(string file)
|
||||
{
|
||||
string path = Path.Combine(FilePath, file);
|
||||
StreamReader sr;
|
||||
|
||||
try
|
||||
{
|
||||
sr = new StreamReader(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Error opening spec file: {0}", path);
|
||||
Console.WriteLine("Error: {0}", e.Message);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return sr;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static bool IsExtension(string function_name)
|
||||
private static bool IsExtension(string function_name)
|
||||
{
|
||||
return (function_name.EndsWith("ARB") ||
|
||||
function_name.EndsWith("EXT") ||
|
||||
function_name.EndsWith("ATI") ||
|
||||
function_name.EndsWith("NV") ||
|
||||
function_name.EndsWith("SUN") ||
|
||||
function_name.EndsWith("SUNX") ||
|
||||
function_name.EndsWith("SGI") ||
|
||||
function_name.EndsWith("SGIS") ||
|
||||
function_name.EndsWith("SGIX") ||
|
||||
function_name.EndsWith("MESA") ||
|
||||
function_name.EndsWith("3DFX") ||
|
||||
function_name.EndsWith("IBM") ||
|
||||
function_name.EndsWith("GREMEDY") ||
|
||||
function_name.EndsWith("HP") ||
|
||||
function_name.EndsWith("INTEL") ||
|
||||
function_name.EndsWith("PGI") ||
|
||||
function_name.EndsWith("INGR") ||
|
||||
function_name.EndsWith("APPLE") ||
|
||||
function_name.EndsWith("OML") ||
|
||||
function_name.EndsWith("I3D"));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static string NextValidLine(StreamReader sr)
|
||||
private static string NextValidLine(StreamReader sr)
|
||||
{
|
||||
string line;
|
||||
|
||||
do
|
||||
{
|
||||
if (sr.EndOfStream)
|
||||
return null;
|
||||
|
||||
line = sr.ReadLine().Trim();
|
||||
|
||||
if (String.IsNullOrEmpty(line) ||
|
||||
line.StartsWith("#") || // Disregard comments.
|
||||
line.StartsWith("passthru") || // Disregard passthru statements.
|
||||
line.StartsWith("required-props:") ||
|
||||
line.StartsWith("param:") ||
|
||||
line.StartsWith("dlflags:") ||
|
||||
line.StartsWith("glxflags:") ||
|
||||
line.StartsWith("vectorequiv:") ||
|
||||
//line.StartsWith("category:") ||
|
||||
line.StartsWith("version:") ||
|
||||
line.StartsWith("glxsingle:") ||
|
||||
line.StartsWith("glxropcode:") ||
|
||||
line.StartsWith("glxvendorpriv:") ||
|
||||
line.StartsWith("glsflags:") ||
|
||||
line.StartsWith("glsopcode:") ||
|
||||
line.StartsWith("glsalias:") ||
|
||||
line.StartsWith("wglflags:") ||
|
||||
line.StartsWith("extension:") ||
|
||||
line.StartsWith("alias:") ||
|
||||
line.StartsWith("offset:"))
|
||||
continue;
|
||||
|
||||
return line;
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static void ReadFunctionSpecs(string file, out List<CodeTypeDelegate> delegates, out List<CodeMemberMethod> functions)
|
||||
public static List<CodeTypeDelegate> ReadFunctionSpecs(string file)
|
||||
{
|
||||
StreamReader sr = OpenSpecFile(file);
|
||||
Console.WriteLine("Reading function specs from file: {0}", file);
|
||||
|
||||
List<CodeTypeDelegate> delegates = new List<CodeTypeDelegate>();
|
||||
|
||||
do
|
||||
{
|
||||
string line = NextValidLine(sr);
|
||||
if (String.IsNullOrEmpty(line))
|
||||
break;
|
||||
|
||||
// Get next OpenGL function
|
||||
while (line.Contains("(") && !sr.EndOfStream)
|
||||
{
|
||||
CodeTypeDelegate d = new CodeTypeDelegate();
|
||||
d.Attributes = MemberAttributes.Static;
|
||||
d.CustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SuppressUnmanagedCodeSecurity"));
|
||||
|
||||
// Get function name:
|
||||
d.Name = line.Split(SpecTranslator.Separators, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||
if (IsExtension(d.Name))
|
||||
{
|
||||
d.UserData.Add("Extension", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
d.UserData.Add("Extension", false);
|
||||
}
|
||||
|
||||
//d.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, d.Name));
|
||||
//d.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, d.Name));
|
||||
|
||||
// Get function parameters and return value:
|
||||
do
|
||||
{
|
||||
line = sr.ReadLine();
|
||||
List<string> words = new List<string>(
|
||||
line.Replace('\t', ' ').Split(SpecTranslator.Separators, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
if (words.Count == 0)
|
||||
break;
|
||||
|
||||
// Identify line:
|
||||
switch (words[0])
|
||||
{
|
||||
case "return": // Line denotes return value
|
||||
CodeTypeReference tr = new CodeTypeReference(
|
||||
words[1]
|
||||
);
|
||||
|
||||
//if (tr.BaseType == "GLvoid")
|
||||
// tr.BaseType = "System.Void";
|
||||
|
||||
d.ReturnType = tr;
|
||||
break;
|
||||
|
||||
case "param": // Line denotes parameter
|
||||
CodeParameterDeclarationExpression p =
|
||||
new CodeParameterDeclarationExpression();
|
||||
p.Name = words[1];
|
||||
p.Type = new CodeTypeReference(words[2]);
|
||||
p.Direction = words[3] == "in" ? FieldDirection.In : FieldDirection.Out;
|
||||
if (words[3] != "in")
|
||||
p.CustomAttributes.Add(new CodeAttributeDeclaration("In, Out"));
|
||||
p.Type.ArrayRank = words[4] == "array" ? 1 : 0;
|
||||
|
||||
d.Parameters.Add(p);
|
||||
break;
|
||||
|
||||
/* version directive is not used. GetTexParameterIivEXT and GetTexParameterIuivEXT define two(!) versions (why?)
|
||||
case "version": // Line denotes function version (i.e. 1.0, 1.2, 1.5)
|
||||
d.UserData.Add("version", words[1]);
|
||||
break;
|
||||
*/
|
||||
|
||||
case "category":
|
||||
d.UserData.Add("Category", words[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
|
||||
delegates.Add(d);
|
||||
}
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
|
||||
return delegates;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static void ReadEnumSpecs(string file, out List<CodeMemberField> enums)
|
||||
public static void ReadEnumSpecs(string file, out CodeTypeDeclarationCollection enums)
|
||||
{
|
||||
enums = new CodeTypeDeclarationCollection();
|
||||
// comple_enum contains all opengl enumerants.
|
||||
CodeTypeDeclaration complete_enum = new CodeTypeDeclaration();
|
||||
complete_enum.IsEnum = true;
|
||||
complete_enum.Name = "GLenum";
|
||||
|
||||
StreamReader sr = OpenSpecFile(file);
|
||||
Console.WriteLine("Reading constant specs from file: {0}", file);
|
||||
|
||||
do
|
||||
{
|
||||
string line = NextValidLine(sr);
|
||||
if (String.IsNullOrEmpty(line))
|
||||
break;
|
||||
|
||||
line = line.Replace('\t', ' ');
|
||||
|
||||
// We just encountered the start of a new enumerant:
|
||||
while (!String.IsNullOrEmpty(line) && line.Contains("enum"))
|
||||
{
|
||||
string[] words = line.Split(SpecTranslator.Separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (words.Length == 0)
|
||||
continue;
|
||||
|
||||
// Declare a new enumerant
|
||||
CodeTypeDeclaration e = new CodeTypeDeclaration();
|
||||
e.IsEnum = true;
|
||||
e.Name = SpecTranslator.GetTranslatedEnum(words[0]);
|
||||
//d.Attributes = MemberAttributes.Const | MemberAttributes.Public;
|
||||
|
||||
// And fill in the values for this enumerant
|
||||
do
|
||||
{
|
||||
line = NextValidLine(sr);
|
||||
|
||||
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
if (line.Contains("enum:") || sr.EndOfStream)
|
||||
break;
|
||||
|
||||
line = line.Replace('\t', ' ');
|
||||
words = line.Split(SpecTranslator.Separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (words.Length == 0)
|
||||
continue;
|
||||
|
||||
// If we reach this point, we have found a new value for the current enumerant
|
||||
CodeMemberField c = new CodeMemberField();
|
||||
if (line.Contains("="))
|
||||
{
|
||||
c.Name = SpecTranslator.GetTranslatedEnum(words[0]);
|
||||
|
||||
uint number;
|
||||
if (UInt32.TryParse(words[2].Replace("0x", String.Empty), System.Globalization.NumberStyles.AllowHexSpecifier, null, out number))
|
||||
{
|
||||
if (number > 0x7FFFFFFF)
|
||||
{
|
||||
words[2] = "unchecked((Int32)" + words[2] + ")";
|
||||
}
|
||||
}
|
||||
else if (words[2].StartsWith("GL_"))
|
||||
{
|
||||
words[2] = words[2].Substring(3);
|
||||
}
|
||||
|
||||
//c.InitExpression = new CodeFieldReferenceExpression(null, words[2]);
|
||||
//c.UserData.Add("InitExpression", " = " + words[2]);
|
||||
c.UserData.Add("ObjectReference", null);
|
||||
c.UserData.Add("FieldReference", words[2]);
|
||||
}
|
||||
else if (words[0] == "use")
|
||||
{
|
||||
c.Name = SpecTranslator.GetTranslatedEnum(words[2]);
|
||||
|
||||
//c.InitExpression = new CodeFieldReferenceExpression(new CodeSnippetExpression(words[1]), SpecTranslator.GetTranslatedEnum(words[2]));
|
||||
//c.UserData.Add("InitExpression", " = " + words[1] + "." + SpecTranslator.GetTranslatedEnum(words[2]));
|
||||
c.UserData.Add("ObjectReference", words[1]);
|
||||
c.UserData.Add("FieldReference", words[2]);
|
||||
}
|
||||
|
||||
//if (!String.IsNullOrEmpty(c.Name) && !e.Members.Contains.Contains(c))
|
||||
SpecTranslator.Merge(e.Members, c);
|
||||
|
||||
// Insert the current constant in the list of all constants.
|
||||
SpecTranslator.Merge(complete_enum.Members, c);
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
|
||||
// At this point, the complete value list for the current enumerant has been read, so add this
|
||||
// enumerant to the list.
|
||||
e.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "public enum " + e.Name));
|
||||
e.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "public enum " + e.Name));
|
||||
|
||||
// (disabled) Hack - discard Boolean enum, it fsucks up the fragile translation code ahead.
|
||||
//if (!e.Name.Contains("Bool"))
|
||||
SpecTranslator.Merge(enums, e);
|
||||
}
|
||||
SpecTranslator.Merge(enums, complete_enum);
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static bool ListContainsConstant(List<CodeMemberField> enums, CodeMemberField c)
|
||||
public static bool ListContainsConstant(List<CodeMemberField> constants, CodeMemberField c)
|
||||
{
|
||||
foreach (CodeMemberField d in constants)
|
||||
if (d.Name == c.Name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static Dictionary<string, CodeTypeReference> ReadTypeMap(string file)
|
||||
public static Dictionary<string, CodeTypeReference> ReadTypeMap(string file)
|
||||
{
|
||||
Dictionary<string, CodeTypeReference> map =
|
||||
new Dictionary<string, CodeTypeReference>();
|
||||
|
||||
string path = Path.Combine(FilePath, file);
|
||||
StreamReader sr;
|
||||
|
||||
try
|
||||
{
|
||||
sr = new StreamReader(path);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine("Error opening typemap file: {0}", path);
|
||||
return null;
|
||||
}
|
||||
Console.WriteLine("Reading typemaps from file: {0}", file);
|
||||
|
||||
do
|
||||
{
|
||||
string line = sr.ReadLine();
|
||||
|
||||
if (String.IsNullOrEmpty(line) || line.StartsWith("#"))
|
||||
continue;
|
||||
|
||||
string[] words = line.Split(new char[] { ' ', ',', '*', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (words[0] == "void")
|
||||
{
|
||||
// Special case for "void" -> ""
|
||||
map.Add(words[0], new CodeTypeReference(String.Empty));
|
||||
}
|
||||
else if (words[0] == "VoidPointer")
|
||||
{ // Special case for "VoidPointer" -> "GLvoid*"
|
||||
map.Add(words[0], new CodeTypeReference("System.Object"));
|
||||
}
|
||||
else if (words[0] == "CharPointer" || words[0] == "charPointerARB")
|
||||
{
|
||||
map.Add(words[0], new CodeTypeReference("System.String"));
|
||||
}
|
||||
else if (words[0].Contains("Pointer"))
|
||||
{
|
||||
map.Add(words[0], new CodeTypeReference(words[1], 1));
|
||||
}
|
||||
//else if (words[1].Contains("Boolean"))
|
||||
//{
|
||||
// // Do not add this to the typemap!
|
||||
//}
|
||||
/*else if (words[1] == "GLenum")
|
||||
{
|
||||
// Do not throw away the type to generic GLenum. We want type checking!
|
||||
}*/
|
||||
else
|
||||
{
|
||||
map.Add(words[0], new CodeTypeReference(words[1]));
|
||||
}
|
||||
}
|
||||
while (!sr.EndOfStream);
|
||||
|
||||
return map;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,937 +0,0 @@
|
|||
#region --- License ---
|
||||
/*
|
||||
MIT License
|
||||
Copyright ©2006-2007 Tao Framework Team
|
||||
http://www.taoframework.com
|
||||
Copyright ©2005-2007 OpenTK
|
||||
http://sourceforge.net/projects/opentk
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#endregion License
|
||||
|
||||
#region --- Using Directives ---
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.CodeDom;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
{
|
||||
#region WrapperTypes enum
|
||||
|
||||
public enum WrapperTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// No wrapper needed.
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// Function takes bool parameter - C uses Int for bools, so we have to marshal.
|
||||
/// </summary>
|
||||
BoolParameter,
|
||||
/// <summary>
|
||||
/// Function takes generic parameters - add ref/out generic and generic overloads.
|
||||
/// </summary>
|
||||
GenericParameter,
|
||||
/// <summary>
|
||||
/// Function takes arrays as parameters - add ref/out and ([Out]) array overloads.
|
||||
/// </summary>
|
||||
ArrayParameter,
|
||||
/// <summary>
|
||||
/// Function with bitmask parameters. Bitmask parameters map to UInt, but since we can only use signed
|
||||
/// types (for CLS compliance), we must add the unchecked keyword.
|
||||
/// Usually found in bitmasks
|
||||
/// </summary>
|
||||
UncheckedParameter,
|
||||
/// <summary>
|
||||
/// Function that takes (in/ref/out) a naked pointer as a parameter - we pass an IntPtr.
|
||||
/// </summary>
|
||||
PointerParameter,
|
||||
/// <summary>
|
||||
/// Function returns string - needs manual marshalling through IntPtr to prevent the managed GC
|
||||
/// from freeing memory allocated on the unmanaged side (e.g. glGetString).
|
||||
/// </summary>
|
||||
StringReturnValue,
|
||||
/// <summary>
|
||||
/// Function returns a void pointer - maps to IntPtr, and the user has to manually marshal the type.
|
||||
/// </summary>
|
||||
GenericReturnValue,
|
||||
/// <summary>
|
||||
/// Function returns a typed pointer - we have to copy the data to an array to protect it from the GC.
|
||||
/// </summary>
|
||||
ArrayReturnValue
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static class SpecTranslator
|
||||
{
|
||||
#region static SpecTranslator()
|
||||
// Do not remove! - forces BeforeFieldInit to false.
|
||||
static SpecTranslator()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields and Properties
|
||||
public static char[] Separators = { ' ', '\n', ',', '(', ')', ';', '#' };
|
||||
|
||||
#region GL types dictionary
|
||||
|
||||
private static Dictionary<string, CodeTypeReference> _gl_types = SpecReader.ReadTypeMap("gl.tm");
|
||||
|
||||
public static Dictionary<string, CodeTypeReference> GLTypes
|
||||
{
|
||||
get { return SpecTranslator._gl_types; }
|
||||
set { SpecTranslator._gl_types = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CS types dictionary
|
||||
|
||||
private static Dictionary<string, CodeTypeReference> _cs_types = SpecReader.ReadTypeMap("csharp.tm");
|
||||
|
||||
public static Dictionary<string, CodeTypeReference> CSTypes
|
||||
{
|
||||
get { return SpecTranslator._cs_types; }
|
||||
set { SpecTranslator._cs_types = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GLX types dictionary
|
||||
|
||||
private static Dictionary<string, string> _glx_types;
|
||||
|
||||
public static Dictionary<string, string> GLXTypes
|
||||
{
|
||||
get { return _glx_types; }
|
||||
set { _glx_types = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WGL types dictionary
|
||||
|
||||
private static Dictionary<string, string> _wgl_types;
|
||||
|
||||
public static Dictionary<string, string> WGLTypes
|
||||
{
|
||||
get { return _wgl_types; }
|
||||
set { _wgl_types = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region public static List<CodeMemberMethod> TranslateDelegates(List<CodeTypeDelegate> delegates, CodeTypeDeclarationCollection enums)
|
||||
public static List<CodeMemberMethod> TranslateDelegates(List<CodeTypeDelegate> delegates, CodeTypeDeclarationCollection enums)
|
||||
{
|
||||
List<CodeMemberMethod> functions = new List<CodeMemberMethod>();
|
||||
foreach (CodeTypeDelegate d in delegates)
|
||||
{
|
||||
TranslateReturnValue(d);
|
||||
TranslateParameters(d, enums);
|
||||
functions.AddRange(CreateWrappers(d));
|
||||
}
|
||||
|
||||
return functions;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static void TranslateReturnValue(CodeTypeDelegate d)
|
||||
private static void TranslateReturnValue(CodeTypeDelegate d)
|
||||
{
|
||||
CodeTypeReference s;
|
||||
|
||||
if (d.ReturnType.BaseType == "void")
|
||||
d.ReturnType.BaseType = "System.Void";
|
||||
|
||||
if (GLTypes.TryGetValue(d.ReturnType.BaseType, out s))
|
||||
d.ReturnType = s;
|
||||
|
||||
if (d.ReturnType.BaseType == "GLstring")
|
||||
{
|
||||
d.ReturnType = new CodeTypeReference("IntPtr");
|
||||
d.ReturnType.UserData.Add("Wrapper", WrapperTypes.StringReturnValue);
|
||||
}
|
||||
|
||||
if (d.ReturnType.BaseType.ToLower().Contains("object"))
|
||||
{
|
||||
d.ReturnType.BaseType = "IntPtr";
|
||||
d.ReturnType.UserData.Add("Wrapper", WrapperTypes.GenericReturnValue);
|
||||
d.ReturnType.ArrayRank = 0;
|
||||
}
|
||||
|
||||
if (d.ReturnType.BaseType == "GLenum")
|
||||
{
|
||||
d.ReturnType.BaseType = "Enums.GLenum";
|
||||
}
|
||||
|
||||
if (d.ReturnType.UserData.Contains("Wrapper"))
|
||||
{
|
||||
d.UserData.Add("Wrapper", null);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static void TranslateParameters(CodeTypeDelegate d)
|
||||
private static void TranslateParameters(CodeTypeDelegate d, CodeTypeDeclarationCollection enums)
|
||||
{
|
||||
CodeTypeReference s;
|
||||
|
||||
if (d.Name == "CreateShader")
|
||||
{
|
||||
}
|
||||
|
||||
// Translate each parameter of the function while checking for needed wrappers:
|
||||
foreach (CodeParameterDeclarationExpression p in d.Parameters)
|
||||
{
|
||||
if (Search(enums, p.Type.BaseType) && p.Type.BaseType != "GLenum")
|
||||
{
|
||||
// If there is a specific enumerant entry for this parameter, then take this.
|
||||
p.Type.BaseType = "Enums." + p.Type.BaseType;
|
||||
}
|
||||
else if (GLTypes.TryGetValue(p.Type.BaseType, out s))
|
||||
{
|
||||
if (s.BaseType == "GLenum" && d.UserData.Contains("Category"))
|
||||
{
|
||||
// If there isn't, try to see if any of the generic enumerants
|
||||
// (category: VERSION_1_1 etc) match the needed name.
|
||||
bool found = false;
|
||||
foreach (CodeTypeDeclaration enumerant in enums)
|
||||
{
|
||||
if (enumerant.Name == (string)d.UserData["Category"])
|
||||
{
|
||||
p.Type.BaseType = "Enums." + (string)d.UserData["Category"];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If none match, then fall back to the global enum list.
|
||||
if (!found)
|
||||
{
|
||||
p.Type.BaseType = "Enums.GLenum";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Type.BaseType = s.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.Type.ArrayRank == 0 && p.Type.BaseType.ToLower().Contains("enums."))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (p.Type.ArrayRank > 0 && p.Type.BaseType.Contains("char") ||
|
||||
p.Type.ArrayRank == 0 && p.Type.BaseType.ToLower().Contains("string"))
|
||||
{
|
||||
// GLchar[] parameters should become (in) string or (out) StringBuilder
|
||||
if (p.Direction == FieldDirection.Out || p.Direction == FieldDirection.Ref)
|
||||
p.Type = new CodeTypeReference("System.Text.StringBuilder");
|
||||
else
|
||||
p.Type = new CodeTypeReference("System.String");
|
||||
}
|
||||
else if (p.Type.ArrayRank > 0 && p.Type.BaseType.ToLower().Contains("string"))
|
||||
{
|
||||
// string parameters do not need special wrappers. We add this here
|
||||
// to simplify the next if-statements.
|
||||
// p.Type.ArrayRank = 0;
|
||||
}
|
||||
else if (p.Type.ArrayRank > 0)
|
||||
{
|
||||
// All other array parameters need wrappers (around IntPtr).
|
||||
if (p.Type.BaseType.Contains("void") || p.Type.BaseType.Contains("Void"))
|
||||
{
|
||||
p.UserData.Add("Wrapper", WrapperTypes.GenericParameter);
|
||||
}
|
||||
else if (p.Type.BaseType.Contains("IntPtr"))
|
||||
{
|
||||
//p.UserData.Add("Wrapper", WrapperTypes.PointerParameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.UserData.Add("Wrapper", WrapperTypes.ArrayParameter);
|
||||
p.UserData.Add("OriginalType", new string(p.Type.BaseType.ToCharArray()));
|
||||
}
|
||||
|
||||
// We do not want an array of IntPtrs (IntPtr[]) - it is the IntPtr that points to the array.
|
||||
p.Type = new CodeTypeReference();
|
||||
p.Type.BaseType = "System.IntPtr";
|
||||
p.Type.ArrayRank = 0;
|
||||
p.UserData.Add("Flow", p.Direction);
|
||||
// The same wrapper works for either in or out parameters.
|
||||
//p.CustomAttributes.Add(new CodeAttributeDeclaration("In, Out"));
|
||||
}
|
||||
else if (p.Type.BaseType.Contains("ushort") && d.Name.Contains("LineStipple"))
|
||||
{
|
||||
// glLineStipple needs wrapper to allow large unsigned mask values.
|
||||
p.UserData.Add("Wrapper", WrapperTypes.UncheckedParameter);
|
||||
}
|
||||
|
||||
|
||||
if (p.Type.BaseType.ToLower().Contains("boolean"))
|
||||
{
|
||||
p.Type.BaseType = "System.Boolean";
|
||||
//p.UserData.Add("Wrapper", WrapperTypes.BoolParameter);
|
||||
p.CustomAttributes.Add(
|
||||
new CodeAttributeDeclaration(
|
||||
"MarshalAs",
|
||||
new CodeAttributeArgument(new CodeSnippetExpression("UnmanagedType.Bool"))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (p.UserData.Contains("Wrapper") && !d.UserData.Contains("Wrapper"))
|
||||
{
|
||||
// If there is at least 1 parameter that needs wrappers, mark the funcction for wrapping.
|
||||
d.UserData.Add("Wrapper", null);
|
||||
}
|
||||
|
||||
//p.Direction = FieldDirection.In;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static bool Search(CodeTypeDeclarationCollection enums, string name)
|
||||
|
||||
private static bool Search(CodeTypeDeclarationCollection enums, string name)
|
||||
{
|
||||
foreach (CodeTypeDeclaration enumerant in enums)
|
||||
{
|
||||
if (enumerant.Name == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static List<CodeMemberMethod> CreateWrappers(CodeTypeDelegate d)
|
||||
private static List<CodeMemberMethod> CreateWrappers(CodeTypeDelegate d)
|
||||
{
|
||||
List<CodeMemberMethod> wrappers = new List<CodeMemberMethod>();
|
||||
CodeMemberMethod f = new CodeMemberMethod();
|
||||
|
||||
// Check if a wrapper is needed:
|
||||
if (!d.UserData.Contains("Wrapper"))
|
||||
{
|
||||
// If not, add just add a function that calls the delegate.
|
||||
f = CreatePrototype(d);
|
||||
|
||||
if (!f.ReturnType.BaseType.Contains("Void"))
|
||||
f.Statements.Add(new CodeMethodReturnStatement(GenerateInvokeExpression(f)));
|
||||
else
|
||||
f.Statements.Add(GenerateInvokeExpression(f));
|
||||
|
||||
wrappers.Add(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to add wrappers for all possible WrapperTypes.
|
||||
|
||||
// First, check if the return type needs wrapping:
|
||||
if (d.ReturnType.UserData.Contains("Wrapper"))
|
||||
{
|
||||
switch ((WrapperTypes)d.ReturnType.UserData["Wrapper"])
|
||||
{
|
||||
// If the function returns a string (glGetString) we must manually marshal it
|
||||
// using Marshal.PtrToStringXXX. Otherwise, the GC will try to free the memory
|
||||
// used by the string, resulting in corruption (the memory belongs to the
|
||||
// unmanaged boundary).
|
||||
case WrapperTypes.StringReturnValue:
|
||||
f = CreatePrototype(d);
|
||||
f.ReturnType = new CodeTypeReference("System.String");
|
||||
|
||||
f.Statements.Add(
|
||||
new CodeMethodReturnStatement(
|
||||
new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("Marshal"),
|
||||
"PtrToStringAnsi",
|
||||
new CodeExpression[] { GenerateInvokeExpression(f) }
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
wrappers.Add(f);
|
||||
break;
|
||||
|
||||
// If the function returns a void* (GenericReturnValue), we'll have to return an IntPtr.
|
||||
// The user will unfortunately need to marshal this IntPtr to a data type manually.
|
||||
case WrapperTypes.GenericReturnValue:
|
||||
f = CreatePrototype(d);
|
||||
|
||||
if (!f.ReturnType.BaseType.Contains("Void"))
|
||||
f.Statements.Add(new CodeMethodReturnStatement(GenerateInvokeExpression(f)));
|
||||
else
|
||||
f.Statements.Add(GenerateInvokeExpression(f));
|
||||
|
||||
wrappers.Add(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d.Name.Contains("LineStipple"))
|
||||
{
|
||||
// glLineStipple accepts a GLushort bitfield. Since GLushort is mapped to Int16, not UInt16
|
||||
// (for CLS compliance), we'll have to add the unchecked keyword.
|
||||
f = CreatePrototype(d);
|
||||
|
||||
CodeSnippetExpression e =
|
||||
new CodeSnippetExpression("Delegates.glLineStipple(factor, unchecked((GLushort)pattern))");
|
||||
f.Statements.Add(e);
|
||||
|
||||
wrappers.Add(f);
|
||||
}
|
||||
|
||||
WrapPointersMonsterFunctionMK2(String.IsNullOrEmpty(f.Name) ? CreatePrototype(d) : f, wrappers);
|
||||
}
|
||||
|
||||
return wrappers;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static void WrapPointersMonsterFunctionMK2(CodeTypeDelegate d, List<CodeMemberMethod> wrappers)
|
||||
// This function needs some heavy refactoring. I'm ashamed I ever wrote it, but it works...
|
||||
// What it does is this: it adds to the wrapper list all possible wrapper permutations
|
||||
// for functions that have more than one IntPtr parameter. Example:
|
||||
// "void Delegates.f(IntPtr p, IntPtr q)" where p and q are pointers to void arrays needs the following wrappers:
|
||||
// "void f(IntPtr p, IntPtr q)"
|
||||
// "void f(IntPtr p, object q)"
|
||||
// "void f(object p, IntPtr q)"
|
||||
// "void f(object p, object q)"
|
||||
private static int count = 0;
|
||||
private static void WrapPointersMonsterFunctionMK2(CodeMemberMethod f, List<CodeMemberMethod> wrappers)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
bool functionContainsIntPtrParameters = false;
|
||||
// Check if there are any IntPtr parameters (we may have come here from a ReturnType wrapper
|
||||
// such as glGetString, which contains no IntPtr parameters)
|
||||
foreach (CodeParameterDeclarationExpression p in f.Parameters)
|
||||
{
|
||||
if (p.Type.BaseType.Contains("IntPtr"))
|
||||
{
|
||||
functionContainsIntPtrParameters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (functionContainsIntPtrParameters)
|
||||
{
|
||||
wrappers.Add(IntPtrToIntPtr(f));
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= 0 && count < f.Parameters.Count)
|
||||
{
|
||||
if (f.Parameters[count].UserData.Contains("Wrapper"))
|
||||
{
|
||||
//++count;
|
||||
//WrapPointersMonsterFunctionMK2(d, wrappers);
|
||||
//--count;
|
||||
|
||||
if ((WrapperTypes)f.Parameters[count].UserData["Wrapper"] == WrapperTypes.ArrayParameter)
|
||||
{
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(f, wrappers);
|
||||
--count;
|
||||
|
||||
CodeMemberMethod w = IntPtrToArray(f, count);
|
||||
wrappers.Add(w);
|
||||
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(w, wrappers);
|
||||
--count;
|
||||
|
||||
w = IntPtrToReference(f, count);
|
||||
wrappers.Add(w);
|
||||
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(w, wrappers);
|
||||
--count;
|
||||
}
|
||||
else if ((WrapperTypes)f.Parameters[count].UserData["Wrapper"] == WrapperTypes.GenericParameter)
|
||||
{
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(f, wrappers);
|
||||
--count;
|
||||
|
||||
CodeMemberMethod w = IntPtrToObject(f, count);
|
||||
wrappers.Add(w);
|
||||
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(w, wrappers);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++count;
|
||||
WrapPointersMonsterFunctionMK2(f, wrappers);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod IntPtrToIntPtr(CodeMemberMethod f)
|
||||
private static CodeMemberMethod IntPtrToIntPtr(CodeMemberMethod f)
|
||||
{
|
||||
CodeMemberMethod w = CreatePrototype(f);
|
||||
if (!w.ReturnType.BaseType.Contains("Void"))
|
||||
{
|
||||
w.Statements.Add(new CodeMethodReturnStatement(GenerateInvokeExpression(w)));
|
||||
}
|
||||
else
|
||||
{
|
||||
w.Statements.Add(GenerateInvokeExpression(w));
|
||||
}
|
||||
return w;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod IntPtrToObject(CodeMemberMethod f, int index)
|
||||
private static CodeMemberMethod IntPtrToObject(CodeMemberMethod f, int index)
|
||||
{
|
||||
CodeMemberMethod w = CreatePrototype(f);
|
||||
|
||||
CodeParameterDeclarationExpression newp = new CodeParameterDeclarationExpression();
|
||||
newp.Name = f.Parameters[index].Name;
|
||||
newp.Type = new CodeTypeReference("System.Object");
|
||||
//if (newp.Flow == Parameter.FlowDirection.Out)
|
||||
// newp.Flow = Parameter.FlowDirection.Undefined;
|
||||
w.Parameters[index] = newp;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
w.Statements.AddRange(GenerateInvokeExpressionWithPins(w));
|
||||
|
||||
return w;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod IntPtrToArray(CodeMemberMethod f, int index)
|
||||
// IntPtr -> GL[...] wrapper.
|
||||
private static CodeMemberMethod IntPtrToArray(CodeMemberMethod f, int index)
|
||||
{
|
||||
CodeMemberMethod w = CreatePrototype(f);
|
||||
|
||||
// Search and replace IntPtr parameters with the known parameter types:
|
||||
CodeParameterDeclarationExpression newp = new CodeParameterDeclarationExpression();
|
||||
newp.Name = f.Parameters[index].Name;
|
||||
newp.Type.BaseType = (string)f.Parameters[index].UserData["OriginalType"];
|
||||
newp.Type.ArrayRank = 1;
|
||||
w.Parameters[index] = newp;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
w.Statements.AddRange(GenerateInvokeExpressionWithPins(w));
|
||||
|
||||
return w;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod IntPtrToReference(CodeMemberMethod f, int index)
|
||||
/// <summary>
|
||||
/// Obtain an IntPtr to the reference passed by the user.
|
||||
/// </summary>
|
||||
/// <param name="f"></param>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
private static CodeMemberMethod IntPtrToReference(CodeMemberMethod f, int index)
|
||||
{
|
||||
CodeMemberMethod w = CreatePrototype(f);
|
||||
|
||||
// Search and replace IntPtr parameters with the known parameter types:
|
||||
CodeParameterDeclarationExpression newp = new CodeParameterDeclarationExpression();
|
||||
newp.Name = f.Parameters[index].Name;
|
||||
newp.Type.BaseType = (string)f.Parameters[index].UserData["OriginalType"];
|
||||
if (f.Parameters[index].UserData.Contains("Flow") &&
|
||||
(FieldDirection)f.Parameters[index].UserData["Flow"] == FieldDirection.Out)
|
||||
newp.Direction = FieldDirection.Out;
|
||||
else
|
||||
newp.Direction = FieldDirection.Ref;
|
||||
w.Parameters[index] = newp;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
w.Statements.AddRange(GenerateInvokeExpressionWithPins(w));
|
||||
|
||||
return w;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod CreatePrototype(CodeTypeDelegate d)
|
||||
private static CodeMemberMethod CreatePrototype(CodeTypeDelegate d)
|
||||
{
|
||||
CodeMemberMethod f = new CodeMemberMethod();
|
||||
|
||||
f.Name = Settings.GLFunctionPrepend + d.Name;
|
||||
f.Parameters.AddRange(d.Parameters);
|
||||
f.ReturnType = d.ReturnType;
|
||||
f.Attributes = MemberAttributes.Static | MemberAttributes.Public;
|
||||
|
||||
//f.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, f.Name));
|
||||
//f.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, f.Name));
|
||||
|
||||
/*f.Comments.Add(new CodeCommentStatement("<summary>", true));
|
||||
f.Comments.Add(new CodeCommentStatement(" ", true));
|
||||
f.Comments.Add(new CodeCommentStatement("</summary>", true));*/
|
||||
|
||||
return f;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeMemberMethod CreatePrototype(CodeMemberMethod d)
|
||||
private static CodeMemberMethod CreatePrototype(CodeMemberMethod d)
|
||||
{
|
||||
CodeMemberMethod f = new CodeMemberMethod();
|
||||
|
||||
f.Name = d.Name;
|
||||
f.Parameters.AddRange(d.Parameters);
|
||||
f.ReturnType = d.ReturnType;
|
||||
f.Attributes = MemberAttributes.Static | MemberAttributes.Public;
|
||||
|
||||
//f.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, f.Name));
|
||||
//f.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, f.Name));
|
||||
|
||||
foreach (object key in d.UserData.Keys)
|
||||
{
|
||||
f.UserData.Add(key, d.UserData[key]);
|
||||
}
|
||||
|
||||
/*f.Comments.Add(new CodeCommentStatement("<summary>", true));
|
||||
f.Comments.Add(new CodeCommentStatement(" ", true));
|
||||
f.Comments.Add(new CodeCommentStatement("</summary>", true));*/
|
||||
|
||||
return f;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeExpression GenerateInvokeExpression(CodeMemberMethod f)
|
||||
private static CodeExpression GenerateInvokeExpression(CodeMemberMethod f)
|
||||
{
|
||||
CodeVariableReferenceExpression[] parameters = new CodeVariableReferenceExpression[f.Parameters.Count];
|
||||
int i = 0;
|
||||
foreach (CodeParameterDeclarationExpression p in f.Parameters)
|
||||
{
|
||||
parameters[i++] = new CodeVariableReferenceExpression(p.Name);
|
||||
}
|
||||
|
||||
return new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("Delegates"),
|
||||
"gl" + f.Name,
|
||||
parameters
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeStatementCollection GenerateInvokeExpressionWithPins(CodeMemberMethod f)
|
||||
private static CodeStatementCollection GenerateInvokeExpressionWithPins(CodeMemberMethod f)
|
||||
{
|
||||
CodeVariableReferenceExpression[] parameters = new CodeVariableReferenceExpression[f.Parameters.Count];
|
||||
CodeTryCatchFinallyStatement m = new CodeTryCatchFinallyStatement();
|
||||
CodeStatementCollection statements = new CodeStatementCollection();
|
||||
|
||||
int h = 0;
|
||||
int i = 0;
|
||||
foreach (CodeParameterDeclarationExpression p in f.Parameters)
|
||||
{
|
||||
// Do manual marshalling for objects and arrays, but not strings.
|
||||
if (p.Type.BaseType == "object" || p.Type.BaseType == "System.Object" ||
|
||||
(p.Type.ArrayRank > 0 && !p.Type.BaseType.ToLower().Contains("string")) ||
|
||||
((p.Direction == FieldDirection.Ref || p.Direction == FieldDirection.Out) &&
|
||||
!p.Type.BaseType.ToLower().Contains("string")))
|
||||
{
|
||||
if (p.Direction == FieldDirection.Out)
|
||||
{
|
||||
statements.Add(
|
||||
new CodeAssignStatement(
|
||||
new CodeVariableReferenceExpression(p.Name),
|
||||
new CodeSnippetExpression("default(" + p.Type.BaseType + ")")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Pin the object and store the resulting GCHandle to h0, h1, ...
|
||||
CodeVariableDeclarationStatement s = new CodeVariableDeclarationStatement();
|
||||
s.Type = new CodeTypeReference("GCHandle");
|
||||
s.Name = "h" + h;
|
||||
s.InitExpression =
|
||||
new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("GCHandle"),
|
||||
"Alloc",
|
||||
new CodeTypeReferenceExpression[] {
|
||||
new CodeTypeReferenceExpression(p.Name),
|
||||
new CodeTypeReferenceExpression("GCHandleType.Pinned")
|
||||
}
|
||||
);
|
||||
statements.Add(s);
|
||||
|
||||
// Free the object using the h0, h1, ... variables
|
||||
m.FinallyStatements.Add(
|
||||
new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("h" + h),
|
||||
"Free"
|
||||
)
|
||||
);
|
||||
|
||||
// Add the h(n) variable to the list of parameters
|
||||
parameters[i] = new CodeVariableReferenceExpression("h" + h + ".AddrOfPinnedObject()");
|
||||
|
||||
// Add an assignment statement: "variable_name = (variable_type)h(n).Target" for out parameters.
|
||||
if (p.Direction == FieldDirection.Out)
|
||||
{
|
||||
m.TryStatements.Add(
|
||||
new CodeAssignStatement(
|
||||
new CodeVariableReferenceExpression(p.Name),
|
||||
new CodeSnippetExpression("(" + p.Type.BaseType + ")h" + h + ".Target")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
h++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the normal paramater to the parameter list
|
||||
parameters[i] = new CodeVariableReferenceExpression(p.Name);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (f.ReturnType.BaseType.Contains("Void"))
|
||||
{
|
||||
m.TryStatements.Insert(0,
|
||||
new CodeExpressionStatement(
|
||||
new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("Delegates"),
|
||||
"gl" + f.Name,
|
||||
parameters
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.TryStatements.Insert(0, new CodeVariableDeclarationStatement(f.ReturnType, "retval"));
|
||||
m.TryStatements.Insert(1,
|
||||
new CodeAssignStatement(
|
||||
new CodeVariableReferenceExpression("retval"),
|
||||
new CodeMethodInvokeExpression(
|
||||
new CodeTypeReferenceExpression("Delegates"),
|
||||
"gl" + f.Name,
|
||||
parameters
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
m.TryStatements.Add(
|
||||
new CodeMethodReturnStatement(new CodeVariableReferenceExpression("retval"))
|
||||
);
|
||||
}
|
||||
|
||||
statements.Add(m);
|
||||
|
||||
return statements;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static CodeTypeDeclarationCollection Merge(CodeTypeDeclarationCollection list1, CodeTypeDeclarationCollection list2)
|
||||
public static CodeTypeDeclarationCollection Merge(CodeTypeDeclarationCollection list1, CodeTypeDeclarationCollection list2)
|
||||
{
|
||||
foreach (CodeTypeDeclaration d in list2)
|
||||
{
|
||||
Merge(list1, d);
|
||||
}
|
||||
|
||||
return list1;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static CodeTypeDeclarationCollection Merge(CodeTypeDeclarationCollection list, CodeTypeDeclaration item)
|
||||
public static CodeTypeDeclarationCollection Merge(CodeTypeDeclarationCollection list, CodeTypeDeclaration item)
|
||||
{
|
||||
bool t_exists = false;
|
||||
foreach (CodeTypeDeclaration d in list)
|
||||
{
|
||||
if (d.Name == item.Name)
|
||||
{
|
||||
t_exists = true;
|
||||
foreach (CodeTypeMember m in item.Members)
|
||||
{
|
||||
Merge(d.Members, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!t_exists)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static CodeTypeMemberCollection Merge(CodeTypeMemberCollection list, CodeTypeMember item)
|
||||
public static CodeTypeMemberCollection Merge(CodeTypeMemberCollection list, CodeTypeMember item)
|
||||
{
|
||||
bool t_exists = false;
|
||||
foreach (CodeTypeMember d in list)
|
||||
{
|
||||
if (d.Name == item.Name)
|
||||
{
|
||||
t_exists = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!t_exists)
|
||||
{
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static CodeTypeDeclarationCollection TranslateEnums(CodeTypeDeclarationCollection enums)
|
||||
public static CodeTypeDeclarationCollection TranslateEnums(CodeTypeDeclarationCollection enums)
|
||||
{
|
||||
// Add missing enums.
|
||||
{
|
||||
CodeTypeDeclaration e = new CodeTypeDeclaration("SGIX_icc_texture");
|
||||
e.IsEnum = true;
|
||||
CodeMemberField c;
|
||||
c = new CodeMemberField(); c.Name = "RGB_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8460"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "RGBA_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8461"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "ALPHA_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8462"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "LUMINANCE_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8463"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "INTENSITY_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8464"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "LUMINANCE_ALPHA_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8465"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "R5_G6_B5_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8466"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "R5_G6_B5_A8_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8467"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "ALPHA16_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8468"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "LUMINANCE16_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x8469"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "INTENSITY16_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x846A"); e.Members.Add(c);
|
||||
c = new CodeMemberField(); c.Name = "LUMINANCE16_ALPHA8_ICC_SGIX"; c.InitExpression = new CodeFieldReferenceExpression(null, "0x846B"); e.Members.Add(c);
|
||||
|
||||
enums.Add(e);
|
||||
}
|
||||
|
||||
// Translate enums.
|
||||
foreach (CodeTypeDeclaration e in enums)
|
||||
{
|
||||
if (Char.IsDigit(e.Name[0]))
|
||||
e.Name = e.Name.Insert(0, "_");
|
||||
|
||||
if (e.Name == "Boolean")
|
||||
continue;
|
||||
|
||||
foreach (CodeMemberField c in e.Members)
|
||||
{
|
||||
// Prepend an '_' if the first letter is a number (e.g. 4_BYTES -> _4_BYTES)
|
||||
if (Char.IsDigit(c.Name[0]))
|
||||
c.Name = c.Name.Insert(0, "_");
|
||||
|
||||
if (c.UserData["FieldReference"] == null)
|
||||
continue;
|
||||
|
||||
c.UserData["ObjectReference"] = GetTranslatedEnum((string)c.UserData["ObjectReference"]);
|
||||
c.UserData["FieldReference"] = GetTranslatedEnum((string)c.UserData["FieldReference"]);
|
||||
|
||||
// There are cases when a value is not a number but an aliased constant, with no enum specified.
|
||||
// In this case try searching all enums for the correct constant to alias (stupid opengl specs).
|
||||
if (c.UserData["ObjectReference"] == null &&
|
||||
!((string)c.UserData["FieldReference"]).StartsWith("0x") &&
|
||||
!Char.IsDigit(((string)c.UserData["FieldReference"])[0]))
|
||||
{
|
||||
if (((string)c.UserData["FieldReference"]).StartsWith("GL_"))
|
||||
c.UserData["FieldReference"] = ((string)c.UserData["FieldReference"]).Substring(3);
|
||||
|
||||
foreach (CodeTypeDeclaration enumerant in enums)
|
||||
{
|
||||
foreach (CodeTypeMember member in enumerant.Members)
|
||||
{
|
||||
if (member.Name == (string)c.UserData["FieldReference"] ||
|
||||
member.Name == ((string)c.UserData["FieldReference"]).TrimStart('_'))
|
||||
{
|
||||
c.UserData["ObjectReference"] = enumerant.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.InitExpression =
|
||||
new CodeFieldReferenceExpression(
|
||||
c.UserData["ObjectReference"] == null ? null : new CodeSnippetExpression((string)c.UserData["ObjectReference"]),
|
||||
(string)c.UserData["FieldReference"]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return enums;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public static string GetTranslatedEnum(string name)
|
||||
public static string GetTranslatedEnum(string name)
|
||||
{
|
||||
int useless;
|
||||
|
||||
if (String.IsNullOrEmpty(name))
|
||||
return null;
|
||||
|
||||
// Check if the name starts with a number, and prepend a "_" if yes.
|
||||
if (!name.StartsWith("0x") &&
|
||||
!Int32.TryParse(name, out useless) &&
|
||||
Char.IsDigit(name[0]))
|
||||
{
|
||||
return name.Insert(0, "_");
|
||||
}
|
||||
|
||||
if (name == "LightProperty")
|
||||
{
|
||||
return "LightParameter";
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,350 +0,0 @@
|
|||
#region --- License ---
|
||||
/*
|
||||
MIT License
|
||||
Copyright ©2006-2007 Tao Framework Team
|
||||
http://www.taoframework.com
|
||||
Copyright ©2005-2007 OpenTK
|
||||
http://sourceforge.net/projects/opentk
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#endregion License
|
||||
|
||||
#region --- Using Directives ---
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.CodeDom;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
{
|
||||
static class SpecWriter
|
||||
{
|
||||
#region internal class CodeTypeNameComparer<T> : Comparer<T> where T : CodeTypeMember
|
||||
internal class CodeTypeNameComparer<T> : Comparer<T> where T : CodeTypeMember
|
||||
{
|
||||
public override int Compare(T x, T y)
|
||||
{
|
||||
return x.Name.CompareTo(y.Name);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Generate
|
||||
|
||||
public static void Generate(
|
||||
List<CodeTypeDelegate> delegates,
|
||||
List<CodeMemberMethod> functions,
|
||||
CodeTypeDeclarationCollection enums
|
||||
)
|
||||
{
|
||||
if (!Directory.Exists(Settings.OutputPath))
|
||||
Directory.CreateDirectory(Settings.OutputPath);
|
||||
|
||||
CodeNamespace ns = new CodeNamespace(Settings.OutputNamespace);
|
||||
|
||||
ns.Imports.Add(new CodeNamespaceImport("System"));
|
||||
ns.Imports.Add(new CodeNamespaceImport("System.Runtime.InteropServices"));
|
||||
ns.Imports.Add(new CodeNamespaceImport("System.Text"));
|
||||
//ns.Imports.Add(new CodeNamespaceImport(Settings.OutputNamespace + ".Enums"));
|
||||
|
||||
foreach (string key in SpecTranslator.CSTypes.Keys)
|
||||
{
|
||||
ns.Imports.Add(new CodeNamespaceImport(key + " = System." + SpecTranslator.CSTypes[key].BaseType));
|
||||
}
|
||||
|
||||
functions.Sort(new CodeTypeNameComparer<CodeMemberMethod>());
|
||||
delegates.Sort(new CodeTypeNameComparer<CodeTypeDelegate>());
|
||||
|
||||
|
||||
ns.Types.Add(GenerateGLClass(functions));
|
||||
ns.Types.Add(GenerateDelegatesClass(delegates));
|
||||
ns.Types.Add(GenerateImportsClass(delegates));
|
||||
|
||||
CodeCompileUnit cu = new CodeCompileUnit();
|
||||
|
||||
cu.StartDirectives.Add(new CodeDirective());
|
||||
cu.Namespaces.Add(ns);
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(Path.Combine(Settings.OutputPath, Settings.GLClass + ".cs"), false))
|
||||
{
|
||||
Console.WriteLine("Writing {0} class", Settings.OutputNamespace + "." + Settings.GLClass);
|
||||
|
||||
Microsoft.CSharp.CSharpCodeProvider cs = new Microsoft.CSharp.CSharpCodeProvider();
|
||||
System.CodeDom.Compiler.CodeGeneratorOptions options = new System.CodeDom.Compiler.CodeGeneratorOptions();
|
||||
options.BracingStyle = "C";
|
||||
options.BlankLinesBetweenMembers = false;
|
||||
options.VerbatimOrder = true;
|
||||
|
||||
cs.GenerateCodeFromCompileUnit(cu, sw, options);
|
||||
|
||||
sw.Flush();
|
||||
}
|
||||
|
||||
ns.Name = Settings.OutputNamespace + ".Enums";
|
||||
ns.Imports.Clear();
|
||||
ns.Imports.Add(new CodeNamespaceImport("System"));
|
||||
ns.Types.Clear();
|
||||
//enums.Sort(new CodeTypeNameComparer<CodeTypeDeclaration>());
|
||||
//CodeTypeDeclaration d = new CodeTypeDeclaration("Enums");
|
||||
//d.IsStruct = true;
|
||||
//d.Members.AddRange(enums);
|
||||
//ns.Types.Add(d);
|
||||
ns.Types.AddRange(enums);
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(Path.Combine(Settings.OutputPath, Settings.GLClass + "enums.cs"), false))
|
||||
{
|
||||
Console.WriteLine("Writing {0} enums", Settings.OutputNamespace + "." + Settings.GLClass);
|
||||
|
||||
Microsoft.CSharp.CSharpCodeProvider cs = new Microsoft.CSharp.CSharpCodeProvider();
|
||||
System.CodeDom.Compiler.CodeGeneratorOptions options = new System.CodeDom.Compiler.CodeGeneratorOptions();
|
||||
options.BracingStyle = "C";
|
||||
options.BlankLinesBetweenMembers = false;
|
||||
options.VerbatimOrder = true;
|
||||
|
||||
cs.GenerateCodeFromCompileUnit(cu, sw, options);
|
||||
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static CodeTypeDeclaration GenerateGLClass(List<CodeMemberMethod> functions, List<CodeMemberField> enums)
|
||||
private static CodeTypeDeclaration GenerateGLClass(List<CodeMemberMethod> functions)
|
||||
{
|
||||
CodeTypeDeclaration gl_class = new CodeTypeDeclaration(Settings.GLClass);
|
||||
gl_class.IsClass = true;
|
||||
gl_class.IsPartial = true;
|
||||
gl_class.TypeAttributes = System.Reflection.TypeAttributes.Public;
|
||||
|
||||
gl_class.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "GL class"));
|
||||
gl_class.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "GL class"));
|
||||
|
||||
gl_class.Members.Add(new CodeSnippetTypeMember(" #pragma warning disable 1591"));
|
||||
|
||||
gl_class.Members.Add(new CodeSnippetTypeMember(
|
||||
@"
|
||||
#region Private Constants
|
||||
|
||||
#region string GL_NATIVE_LIBRARY
|
||||
/// <summary>
|
||||
/// Specifies OpenGl's native library archive.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specifies opengl32.dll everywhere; will be mapped via .config for mono.
|
||||
/// </remarks>
|
||||
internal const string GL_NATIVE_LIBRARY = ""opengl32.dll"";
|
||||
#endregion string GL_NATIVE_LIBRARY
|
||||
|
||||
#endregion Private Constants
|
||||
"));
|
||||
/*
|
||||
if (constants.Count > 0)
|
||||
{
|
||||
constants[0].StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "OpenGL constants"));
|
||||
constants[constants.Count - 1].EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "OpenGL constants"));
|
||||
}
|
||||
gl_class.Members.AddRange(constants.ToArray());
|
||||
*/
|
||||
if (functions.Count > 0)
|
||||
{
|
||||
functions[0].StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "OpenGL functions"));
|
||||
functions[functions.Count - 1].EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, "OpenGL functions"));
|
||||
}
|
||||
gl_class.Members.AddRange(functions.ToArray());
|
||||
|
||||
return gl_class;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeTypeDeclaration GenerateDelegatesClass(List<CodeTypeDelegate> delegates)
|
||||
private static CodeTypeDeclaration GenerateDelegatesClass(List<CodeTypeDelegate> delegates)
|
||||
{
|
||||
CodeTypeDeclaration delegate_class = new CodeTypeDeclaration("Delegates");
|
||||
delegate_class.TypeAttributes = System.Reflection.TypeAttributes.NotPublic;
|
||||
|
||||
CodeStatementCollection statements = new CodeStatementCollection();
|
||||
|
||||
foreach (CodeTypeDelegate d in delegates)
|
||||
{
|
||||
// Hack - turn FieldDirection.Out parameters to FieldDirection.In. The parameter flow
|
||||
// is handle by the [In, Out()] parameter attribute.
|
||||
foreach (CodeParameterDeclarationExpression p in d.Parameters)
|
||||
{
|
||||
p.Direction = FieldDirection.In;
|
||||
}
|
||||
delegate_class.Members.Add(d);
|
||||
|
||||
CodeMemberField m = new CodeMemberField();
|
||||
m.Name = "gl" + d.Name;
|
||||
m.Type = new CodeTypeReference(d.Name);
|
||||
m.Attributes = MemberAttributes.Public | MemberAttributes.Static;
|
||||
|
||||
//m.InitExpression =
|
||||
//new CodeCastExpression(
|
||||
// "Delegates." + d.Name,
|
||||
// new CodeMethodInvokeExpression(
|
||||
// new CodeMethodReferenceExpression(
|
||||
// new CodeTypeReferenceExpression(Properties.Bind.Default.OutputClass),
|
||||
// "GetDelegateForExtensionMethod"
|
||||
// ),
|
||||
// new CodeExpression[] {
|
||||
// new CodeSnippetExpression("\"gl" + d.Name + "\""),
|
||||
// new CodeTypeOfExpression("Delegates." + d.Name)
|
||||
// }
|
||||
// )
|
||||
//);
|
||||
|
||||
// Hack - generate inline initialisers in the form:
|
||||
// public static Accum glAccum = GetDelegate[...] ?? new Accum(Imports.Accum);
|
||||
CodeSnippetExpression expr = new CodeSnippetExpression();
|
||||
//expr.Value = "public static " + d.Name + " gl" + d.Name + " = ";
|
||||
expr.Value +=
|
||||
"((" + d.Name + ")(" + Settings.GLClass +".GetDelegateForExtensionMethod(\"" + "gl" + d.Name + "\", typeof(" + d.Name + "))))";
|
||||
if (d.UserData.Contains("Extension") && !(bool)d.UserData["Extension"])
|
||||
{
|
||||
expr.Value += " ?? ";
|
||||
expr.Value += "new " + d.Name + "(Imports." + d.Name + ")";
|
||||
}
|
||||
|
||||
m.InitExpression = expr;
|
||||
delegate_class.Members.Add(m);
|
||||
|
||||
/*
|
||||
if (!(bool)d.UserData["Extension"])
|
||||
{
|
||||
statements.Add(
|
||||
new CodeSnippetExpression(
|
||||
"Delegates.gl" + d.Name + " = Delegates.gl" + d.Name + " ?? new Delegates." + d.Name + "(Imports." + d.Name + ")"
|
||||
)
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Disable BeforeFieldInit attribute and initialize OpenGL core.
|
||||
CodeTypeConstructor con = new CodeTypeConstructor();
|
||||
//con.Statements.AddRange(statements);
|
||||
delegate_class.Members.Add(con);
|
||||
|
||||
delegate_class.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, delegate_class.Name));
|
||||
delegate_class.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, delegate_class.Name));
|
||||
|
||||
return delegate_class;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private static CodeTypeDeclaration GenerateImportsClass(List<CodeTypeDelegate> delegates)
|
||||
private static CodeTypeDeclaration GenerateImportsClass(List<CodeTypeDelegate> delegates)
|
||||
{
|
||||
CodeTypeDeclaration import_class = new CodeTypeDeclaration("Imports");
|
||||
import_class.TypeAttributes = System.Reflection.TypeAttributes.NotPublic;
|
||||
import_class.Members.Add(new CodeTypeConstructor());
|
||||
|
||||
foreach (CodeTypeDelegate d in delegates)
|
||||
{
|
||||
if (!(bool)d.UserData["Extension"])
|
||||
{
|
||||
CodeMemberMethodImport m = new CodeMemberMethodImport();
|
||||
|
||||
m.Name = d.Name;
|
||||
m.CustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SuppressUnmanagedCodeSecurity()"));
|
||||
m.CustomAttributes.Add(
|
||||
new CodeAttributeDeclaration(
|
||||
"DllImport(" + Settings.GLClass + ".GL_NATIVE_LIBRARY, EntryPoint = \"" + "gl" + m.Name + "\", ExactSpelling = true)"
|
||||
)
|
||||
);
|
||||
m.Parameters.AddRange(d.Parameters);
|
||||
m.ReturnType = d.ReturnType;
|
||||
|
||||
import_class.Members.Add(new CodeSnippetTypeMember(m.Text));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
import_class.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, import_class.Name));
|
||||
import_class.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, import_class.Name));
|
||||
|
||||
return import_class;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region class CodeMemberMethodImport : CodeMemberMethod
|
||||
/// <summary>
|
||||
/// A hack to create the C# code for a DllImported function;
|
||||
/// CodeDom does not directly support static extern methods.
|
||||
/// </summary>
|
||||
class CodeMemberMethodImport : CodeMemberMethod
|
||||
{
|
||||
public string Text
|
||||
{
|
||||
get
|
||||
{
|
||||
string s;
|
||||
//m.Attributes = MemberAttributes.Static | MemberAttributes.Public;
|
||||
s = " #region " + this.Name + Environment.NewLine;
|
||||
s += " [System.Security.SuppressUnmanagedCodeSecurity()]" + Environment.NewLine;
|
||||
s += " [DllImport(" + Settings.GLClass + ".GL_NATIVE_LIBRARY, EntryPoint = \"" + "gl" + this.Name + "\", ExactSpelling = true)]" + Environment.NewLine;
|
||||
s += " public extern static ";
|
||||
if (this.ReturnType.BaseType == "System.Void")
|
||||
{
|
||||
s += "void";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += this.ReturnType.BaseType;
|
||||
}
|
||||
|
||||
s += " " + this.Name + "(";
|
||||
foreach (CodeParameterDeclarationExpression p in this.Parameters)
|
||||
{
|
||||
s += p.Type.BaseType;
|
||||
if (p.Type.ArrayRank > 0)
|
||||
s += "[]";
|
||||
s += " ";
|
||||
if (p.Name == "base")
|
||||
s += "@base";
|
||||
else if (p.Name == "params")
|
||||
s += "@params";
|
||||
else if (p.Name == "string")
|
||||
s += "@string";
|
||||
else if (p.Name == "ref")
|
||||
s += "@ref";
|
||||
else
|
||||
s += p.Name;
|
||||
s += ", ";
|
||||
}
|
||||
s = s.TrimEnd(',', ' ') + ");" + Environment.NewLine;
|
||||
s += " #endregion" + Environment.NewLine;
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -3,17 +3,17 @@ GLsizei, Int32
|
|||
GLsizeiptr, IntPtr
|
||||
GLintptr, IntPtr
|
||||
# GLenum, Int32
|
||||
GLboolean, Boolean #Int32 #Boolean
|
||||
GLbitfield, Int32 #UInt32
|
||||
GLboolean, Boolean #Int32
|
||||
GLbitfield, UInt32
|
||||
# GLvoid*, IntPtr
|
||||
GLvoid, Object
|
||||
# GLvoid, Void #Object
|
||||
GLchar, Char
|
||||
GLbyte, Byte #SByte
|
||||
GLbyte, SByte
|
||||
GLubyte, Byte
|
||||
GLshort, Int16
|
||||
GLushort, Int16 #UInt16
|
||||
GLushort, UInt16
|
||||
GLint, Int32
|
||||
GLuint, Int32 #UInt32
|
||||
GLuint, UInt32
|
||||
GLfloat, Single
|
||||
GLclampf, Single
|
||||
GLdouble, Double
|
||||
|
@ -23,13 +23,13 @@ GLstring, String
|
|||
# ARB and NV types.
|
||||
GLsizeiptrARB, IntPtr
|
||||
GLintptrARB, IntPtr
|
||||
GLhandleARB, Int32 #UInt32
|
||||
GLhalfARB, Int16 #UInt16
|
||||
GLhalfNV, Int16 #UInt16
|
||||
GLhandleARB, UInt32
|
||||
GLhalfARB, UInt16
|
||||
GLhalfNV, UInt16
|
||||
GLcharARB, Char
|
||||
|
||||
# 64 bit types (introduced in 2.1)
|
||||
GLint64EXT, Int64
|
||||
GLuint64EXT, Int64
|
||||
GLuint64EXT, UInt64
|
||||
GLint64, Int64
|
||||
GLuint64, Int64
|
||||
GLuint64, UInt64
|
|
@ -7,10 +7,8 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind.Structures
|
||||
{
|
||||
#region Constant class
|
||||
|
||||
/// <summary>
|
||||
/// Represents an opengl constant in C# format. Both the constant name and value
|
||||
/// can be retrieved or set. The value can be either a number, another constant
|
||||
|
@ -18,7 +16,7 @@ namespace OpenTK.OpenGL.Bind
|
|||
/// </summary>
|
||||
public class Constant
|
||||
{
|
||||
#region Name
|
||||
#region public string Name
|
||||
|
||||
string _name;
|
||||
|
||||
|
@ -37,7 +35,7 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region Value
|
||||
#region public string Value
|
||||
|
||||
string _value;
|
||||
|
||||
|
@ -56,6 +54,37 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region public string Reference
|
||||
|
||||
string _reference;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the opengl constant (eg. 0x00000001).
|
||||
/// </summary>
|
||||
public string Reference
|
||||
{
|
||||
get { return _reference; }
|
||||
set
|
||||
{
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
_reference = value.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool Unchecked
|
||||
|
||||
private bool @unchecked = false;
|
||||
|
||||
public bool Unchecked
|
||||
{
|
||||
get { return @unchecked; }
|
||||
set { @unchecked = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
|
@ -78,20 +107,24 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region public string ToString()
|
||||
#region public override string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the full constant declaration without decorations
|
||||
/// (eg const uint GL_XXX_YYY = 0xDEADBEEF).
|
||||
/// (eg GL_XXX_YYY = (int)0xDEADBEEF or GL_XXX_YYY = GL_ZZZ.FOOBAR).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
override public string ToString()
|
||||
public override string ToString()
|
||||
{
|
||||
return Name + " = " + Value;
|
||||
return String.Format(
|
||||
"{0} = {1}((int){2}{3})",
|
||||
Name,
|
||||
Unchecked ? "unchecked" : "",
|
||||
!String.IsNullOrEmpty(Reference) ? Reference + "." : "",
|
||||
Value
|
||||
);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
793
Source/Bind/Structures/Delegate.cs
Normal file
793
Source/Bind/Structures/Delegate.cs
Normal file
|
@ -0,0 +1,793 @@
|
|||
#region License
|
||||
//Copyright (c) 2006 Stefanos Apostolopoulos
|
||||
//See license.txt for license info
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Bind.Structures
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an opengl function.
|
||||
/// The return value, function name, function parameters and opengl version can be retrieved or set.
|
||||
/// </summary>
|
||||
public class Delegate
|
||||
{
|
||||
#region --- Constructors ---
|
||||
|
||||
public Delegate()
|
||||
{
|
||||
Parameters = new ParameterCollection();
|
||||
}
|
||||
|
||||
public Delegate(Delegate d)
|
||||
{
|
||||
this.Category = new string(d.Category.ToCharArray());
|
||||
//this.Extension = !String.IsNullOrEmpty(d.Extension) ? new string(d.Extension.ToCharArray()) : "";
|
||||
this.Name = new string(d.Name.ToCharArray());
|
||||
this.NeedsWrapper = d.NeedsWrapper;
|
||||
this.Parameters = new ParameterCollection(d.Parameters);
|
||||
this.ReturnType = new Parameter(d.ReturnType);
|
||||
this.Version = !String.IsNullOrEmpty(d.Version) ? new string(d.Version.ToCharArray()) : "";
|
||||
//this.Unsafe = d.Unsafe;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Properties ---
|
||||
|
||||
#region public bool CLSCompliant
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CLSCompliant property. True if the delegate is not CLSCompliant.
|
||||
/// </summary>
|
||||
public bool CLSCompliant
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Unsafe)
|
||||
return false;
|
||||
|
||||
if (!ReturnType.CLSCompliant)
|
||||
return false;
|
||||
|
||||
foreach (Parameter p in Parameters)
|
||||
{
|
||||
if (!p.CLSCompliant)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string Category
|
||||
|
||||
private string _category;
|
||||
|
||||
public string Category
|
||||
{
|
||||
get { return _category; }
|
||||
set { _category = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool NeedsWrapper
|
||||
|
||||
bool _needs_wrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this function needs to be wrapped with a Marshaling function.
|
||||
/// This flag is set if a function contains an Array parameter, or returns
|
||||
/// an Array or string.
|
||||
/// </summary>
|
||||
public bool NeedsWrapper
|
||||
{
|
||||
get { return _needs_wrapper; }
|
||||
set { _needs_wrapper = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public virtual bool Unsafe
|
||||
|
||||
/// <summary>
|
||||
/// True if the delegate must be declared as 'unsafe'.
|
||||
/// </summary>
|
||||
public virtual bool Unsafe
|
||||
{
|
||||
//get { return @unsafe; }
|
||||
//set { @unsafe = value; }
|
||||
get
|
||||
{
|
||||
if (ReturnType.Pointer)
|
||||
return true;
|
||||
|
||||
foreach (Parameter p in Parameters)
|
||||
{
|
||||
if (p.Pointer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public Parameter ReturnType
|
||||
|
||||
Parameter _return_type = new Parameter();
|
||||
/// <summary>
|
||||
/// Gets or sets the return value of the opengl function.
|
||||
/// </summary>
|
||||
public Parameter ReturnType
|
||||
{
|
||||
get { return _return_type; }
|
||||
set
|
||||
{
|
||||
_return_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string Name
|
||||
|
||||
string _name;
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the opengl function.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
_name = value.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public ParameterCollection Parameters
|
||||
|
||||
ParameterCollection _parameters;
|
||||
|
||||
public ParameterCollection Parameters
|
||||
{
|
||||
get { return _parameters; }
|
||||
set { _parameters = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string Version
|
||||
|
||||
string _version;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the opengl version that introduced this function.
|
||||
/// </summary>
|
||||
public string Version
|
||||
{
|
||||
get { return _version; }
|
||||
set { _version = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool Extension
|
||||
|
||||
string _extension;
|
||||
|
||||
public string Extension
|
||||
{
|
||||
//get { return _extension; }
|
||||
//set { _extension = value; }
|
||||
get
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Name))
|
||||
{
|
||||
_extension = Utilities.GetGL2Extension(Name);
|
||||
return String.IsNullOrEmpty(_extension) ? "Core" : _extension;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Strings ---
|
||||
|
||||
#region public string CallString()
|
||||
|
||||
public string CallString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(Settings.DelegatesClass);
|
||||
sb.Append(".gl");
|
||||
sb.Append(Name);
|
||||
sb.Append("(");
|
||||
if (this.Name == "CallLists")
|
||||
{
|
||||
}
|
||||
if (Parameters.Count > 0)
|
||||
{
|
||||
foreach (Parameter p in Parameters)
|
||||
{
|
||||
if (p.Unchecked)
|
||||
sb.Append("unchecked((" + p.Type + ")");
|
||||
|
||||
if (p.Type != "object")
|
||||
{
|
||||
if (p.Type.ToLower().Contains("string"))
|
||||
{
|
||||
sb.Append(String.Format(
|
||||
"({0}{1})",
|
||||
p.Type,
|
||||
(p.Array > 0) ? "[]" : ""));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(String.Format(
|
||||
"({0}{1})",
|
||||
p.Type,
|
||||
(p.Pointer || p.Array > 0 || p.Reference) ? "*" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(
|
||||
Utilities.Keywords.Contains(p.Name) ? "@" + p.Name : p.Name
|
||||
);
|
||||
|
||||
if (p.Unchecked)
|
||||
sb.Append(")");
|
||||
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Replace(", ", ")", sb.Length - 2, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(")");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string DeclarationString()
|
||||
|
||||
public string DeclarationString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(Unsafe ? "unsafe " : "");
|
||||
sb.Append(ReturnType);
|
||||
sb.Append(" ");
|
||||
sb.Append(Name);
|
||||
sb.Append(Parameters.ToString());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region override public string ToString()
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representing the full function declaration without decorations
|
||||
/// (ie "void glClearColor(float red, float green, float blue, float alpha)"
|
||||
/// </summary>
|
||||
override public string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(Unsafe ? "unsafe " : "");
|
||||
sb.Append("delegate ");
|
||||
sb.Append(ReturnType);
|
||||
sb.Append(" ");
|
||||
sb.Append(Name);
|
||||
sb.Append(Parameters.ToString());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Delegate GetCLSCompliantDelegate(Dictionary<string, string> CSTypes)
|
||||
{
|
||||
Delegate f = new Delegate(this);
|
||||
|
||||
for (int i = 0; i < f.Parameters.Count; i++)
|
||||
{
|
||||
f.Parameters[i].Type = f.Parameters[i].GetCLSCompliantType(CSTypes);
|
||||
}
|
||||
|
||||
f.ReturnType.Type = f.ReturnType.GetCLSCompliantType(CSTypes);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Wrapper Creation ---
|
||||
|
||||
#region public List<Function> CreateWrappers(Dictionary<string, string> CSTypes)
|
||||
|
||||
public List<Function> CreateWrappers(Dictionary<string, string> CSTypes)
|
||||
{
|
||||
if (this.Name == "MapBuffer")
|
||||
{
|
||||
}
|
||||
|
||||
List<Function> wrappers = new List<Function>();
|
||||
if (!NeedsWrapper)
|
||||
{
|
||||
// No special wrapper needed - just call this delegate:
|
||||
Function f = new Function(this);
|
||||
|
||||
if (f.ReturnType.Type.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", f.CallString()));
|
||||
else
|
||||
f.Body.Add(String.Format("return {0};", f.CallString()));
|
||||
|
||||
wrappers.Add(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to add wrappers for all possible WrapperTypes.
|
||||
Function f;
|
||||
|
||||
// First, check if the return type needs wrapping:
|
||||
switch (this.ReturnType.WrapperType)
|
||||
{
|
||||
// If the function returns a string (glGetString) we must manually marshal it
|
||||
// using Marshal.PtrToStringXXX. Otherwise, the GC will try to free the memory
|
||||
// used by the string, resulting in corruption (the memory belongs to the
|
||||
// unmanaged boundary).
|
||||
case WrapperTypes.StringReturnType:
|
||||
f = new Function(this);
|
||||
f.ReturnType.Type = "System.String";
|
||||
|
||||
f.Body.Add(
|
||||
String.Format(
|
||||
"return System.Runtime.InteropServices.Marshal.PtrToStringAnsi({0});",
|
||||
this.CallString()
|
||||
)
|
||||
);
|
||||
|
||||
wrappers.Add(f);
|
||||
return wrappers; // Only occurs in glGetString, there's no need to check parameters.
|
||||
|
||||
// If the function returns a void* (GenericReturnValue), we'll have to return an IntPtr.
|
||||
// The user will unfortunately need to marshal this IntPtr to a data type manually.
|
||||
case WrapperTypes.GenericReturnType:
|
||||
ReturnType.Type = "IntPtr";
|
||||
ReturnType.Pointer = false;
|
||||
/*
|
||||
f = new Function(this);
|
||||
f.ReturnType.Type = "IntPtr";
|
||||
f.ReturnType.Pointer = false;
|
||||
|
||||
if (f.ReturnType.Type.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format("{0};", f.CallString()));
|
||||
else
|
||||
f.Body.Add(String.Format("return {0};", f.CallString()));
|
||||
|
||||
wrappers.Add(f);
|
||||
*/
|
||||
break;
|
||||
|
||||
case WrapperTypes.None:
|
||||
default:
|
||||
// No return wrapper needed
|
||||
break;
|
||||
}
|
||||
|
||||
// Then, create wrappers for each parameter:
|
||||
WrapParameters(new Function(this), wrappers, CSTypes);
|
||||
}
|
||||
|
||||
return wrappers;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected void WrapParameters(Function function, List<Function> wrappers)
|
||||
|
||||
protected static int index = 0;
|
||||
|
||||
/// <summary>
|
||||
/// This function needs some heavy refactoring. I'm ashamed I ever wrote it, but it works...
|
||||
/// What it does is this: it adds to the wrapper list all possible wrapper permutations
|
||||
/// for functions that have more than one IntPtr parameter. Example:
|
||||
/// "void Delegates.f(IntPtr p, IntPtr q)" where p and q are pointers to void arrays needs the following wrappers:
|
||||
/// "void f(IntPtr p, IntPtr q)"
|
||||
/// "void f(IntPtr p, object q)"
|
||||
/// "void f(object p, IntPtr q)"
|
||||
/// "void f(object p, object q)"
|
||||
/// </summary>
|
||||
protected void WrapParameters(Function function, List<Function> wrappers, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
if (function.Name == "LineStipple")
|
||||
{
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
bool containsPointerParameters = false;
|
||||
// Check if there are any IntPtr parameters (we may have come here from a ReturnType wrapper
|
||||
// such as glGetString, which contains no IntPtr parameters)
|
||||
foreach (Parameter p in function.Parameters)
|
||||
{
|
||||
if (p.Pointer)
|
||||
{
|
||||
containsPointerParameters = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsPointerParameters)
|
||||
{
|
||||
wrappers.Add(DefaultWrapper(function));
|
||||
}
|
||||
else
|
||||
{
|
||||
wrappers.Add(DefaultWrapper(function));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0 && index < function.Parameters.Count)
|
||||
{
|
||||
Function f;
|
||||
|
||||
if (function.Parameters[index].WrapperType == WrapperTypes.None)
|
||||
{
|
||||
// No wrapper needed, visit the next parameter
|
||||
++index;
|
||||
WrapParameters(function, wrappers, CSTypes);
|
||||
--index;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (function.Parameters[index].WrapperType)
|
||||
{
|
||||
case WrapperTypes.ArrayParameter:
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
WrapParameters(function, wrappers, CSTypes);
|
||||
--index;
|
||||
|
||||
// On stack rewind, create array wrappers
|
||||
f = ArrayWrapper(new Function(function), index, CSTypes);
|
||||
wrappers.Add(f);
|
||||
|
||||
// Recurse to the last parameter again, keeping the Array wrappers
|
||||
++index;
|
||||
WrapParameters(f, wrappers, CSTypes);
|
||||
--index;
|
||||
|
||||
// On stack rewind, create Ref wrappers.
|
||||
f = ReferenceWrapper(new Function(function), index, CSTypes);
|
||||
wrappers.Add(f);
|
||||
|
||||
// Keeping the current Ref wrapper, visit all other parameters once more
|
||||
++index;
|
||||
WrapParameters(f, wrappers, CSTypes);
|
||||
--index;
|
||||
|
||||
break;
|
||||
|
||||
case WrapperTypes.GenericParameter:
|
||||
// Recurse to the last parameter
|
||||
++index;
|
||||
WrapParameters(function, wrappers, CSTypes);
|
||||
--index;
|
||||
|
||||
// On stack rewind, create array wrappers
|
||||
f = GenericWrapper(new Function(function), index, CSTypes);
|
||||
wrappers.Add(f);
|
||||
|
||||
// Keeping the current Object wrapper, visit all other parameters once more
|
||||
++index;
|
||||
WrapParameters(f, wrappers, CSTypes);
|
||||
--index;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected Function GenericWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
|
||||
protected Function GenericWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
// Search and replace IntPtr parameters with the known parameter types:
|
||||
function.Parameters[index].Reference = false;
|
||||
function.Parameters[index].Array = 0;
|
||||
function.Parameters[index].Pointer = false;
|
||||
function.Parameters[index].Type = "object";
|
||||
function.Parameters[index].Flow = Parameter.FlowDirection.Undefined;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
function.Body.Clear();
|
||||
//function.Body.AddRange(GetBodyWithFixedPins(function));
|
||||
function.Body.AddRange(GetBodyWithPins(function, CSTypes, false));
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected Function ReferenceWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
|
||||
protected Function ReferenceWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
// Search and replace IntPtr parameters with the known parameter types:
|
||||
function.Parameters[index].Reference = true;
|
||||
function.Parameters[index].Array = 0;
|
||||
function.Parameters[index].Pointer = false;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
function.Body.Clear();
|
||||
function.Body.AddRange(GetBodyWithPins(function, CSTypes, false));
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected Function ArrayWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
|
||||
protected Function ArrayWrapper(Function function, int index, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
// Search and replace IntPtr parameters with the known parameter types:
|
||||
function.Parameters[index].Array = 1;
|
||||
function.Parameters[index].Pointer = false;
|
||||
function.Parameters[index].Flow = Parameter.FlowDirection.Undefined;
|
||||
|
||||
// In the function body we should pin all objects in memory before calling the
|
||||
// low-level function.
|
||||
function.Body.Clear();
|
||||
function.Body.AddRange(GetBodyWithPins(function, CSTypes, false));
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected Function DefaultWrapper(Function f)
|
||||
|
||||
protected Function DefaultWrapper(Function f)
|
||||
{
|
||||
bool returns = f.ReturnType.Type.ToLower().Contains("void") && !f.ReturnType.Pointer;
|
||||
string callString = String.Format(
|
||||
"{0} {1}{2}; {3}",
|
||||
Unsafe ? "unsafe {" : "",
|
||||
returns ? "" : "return ",
|
||||
f.CallString(),
|
||||
Unsafe ? "}" : "");
|
||||
|
||||
f.Body.Add(callString);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region protected static FunctionBody GetBodyWithPins(Function function, Dictionary<string, string> CSTypes, bool wantCLSCompliance)
|
||||
|
||||
/// <summary>
|
||||
/// Generates a body which calls the specified function, pinning all needed parameters.
|
||||
/// </summary>
|
||||
/// <param name="function"></param>
|
||||
protected static FunctionBody GetBodyWithPins(Function function, Dictionary<string, string> CSTypes, bool wantCLSCompliance)
|
||||
{
|
||||
// We'll make changes, but we want the original intact.
|
||||
Function f = new Function(function);
|
||||
f.Body.Clear();
|
||||
// Unsafe only if
|
||||
//function.Unsafe = false;
|
||||
|
||||
// Add default initliazers for out parameters:
|
||||
foreach (Parameter p in function.Parameters)
|
||||
{
|
||||
if (p.Flow == Parameter.FlowDirection.Out)
|
||||
{
|
||||
f.Body.Add(
|
||||
String.Format(
|
||||
"{0} = default({1});",
|
||||
p.Name,
|
||||
p.GetFullType(CSTypes, wantCLSCompliance)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
// All GCHandles statements will go here. This will allow to place only one opening '{'
|
||||
// on fixed statements.
|
||||
int handleStart = f.Body.Count;
|
||||
|
||||
// Indicates the index where the last GCHandle statement is. Used to add an unsafe stamement
|
||||
// (if needed) at exactl that spot, i.e. after the GCHandles but before the fixed statements.
|
||||
int handleEnd = f.Body.Count;
|
||||
|
||||
// True if at least on GCHandle is allocated. Used to remove the try { } finally { }
|
||||
// block if no handle has been allocated.
|
||||
bool handleAllocated = false;
|
||||
|
||||
// True if function body contains at least one fixed statement. Add a statement-level
|
||||
// unsafe block if true (and the function is not unsafe at the function-level).
|
||||
bool fixedAllocated = false;
|
||||
|
||||
// Obtain pointers by pinning the parameters
|
||||
foreach (Parameter p in f.Parameters)
|
||||
{
|
||||
if (p.NeedsPin)
|
||||
{
|
||||
// Use GCHandle to obtain pointer to generic parameters and 'fixed' for arrays.
|
||||
// This is because fixed can only take the address of fields, not managed objects.
|
||||
if (p.WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
f.Body.Insert(
|
||||
handleStart,
|
||||
String.Format(
|
||||
"{0} {1} = {0}.Alloc({2}, System.Runtime.InteropServices.GCHandleType.Pinned);",
|
||||
"System.Runtime.InteropServices.GCHandle",
|
||||
p.Name + "_ptr",
|
||||
p.Name
|
||||
)
|
||||
);
|
||||
// Note! The following line modifies f.Parameters, *not* function.Parameters
|
||||
p.Name = "(void*)" + p.Name + "_ptr.AddrOfPinnedObject()";
|
||||
|
||||
handleAllocated = true;
|
||||
|
||||
handleEnd++;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Body.Add(
|
||||
String.Format(
|
||||
" fixed ({0}* {1} = {2})",
|
||||
wantCLSCompliance && !p.CLSCompliant ? p.GetCLSCompliantType(CSTypes) : p.Type,
|
||||
p.Name + "_ptr",
|
||||
p.Array > 0 ? p.Name : "&" + p.Name
|
||||
)
|
||||
);
|
||||
p.Name = p.Name + "_ptr";
|
||||
|
||||
fixedAllocated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!function.Unsafe)
|
||||
{
|
||||
f.Body.Insert(handleEnd, "unsafe");
|
||||
f.Body.Insert(handleEnd + 1, "{");
|
||||
}
|
||||
|
||||
if (handleAllocated)
|
||||
{
|
||||
f.Body.Add(" try");
|
||||
}
|
||||
|
||||
f.Body.Add(" {");
|
||||
// Add delegate call:
|
||||
if (f.ReturnType.Type.ToLower().Contains("void"))
|
||||
f.Body.Add(String.Format(" {0};", f.CallString()));
|
||||
else
|
||||
f.Body.Add(String.Format(" {0} {1} = {2};", f.ReturnType.Type, "retval", f.CallString()));
|
||||
|
||||
// Assign out parameters:
|
||||
foreach (Parameter p in function.Parameters)
|
||||
{
|
||||
if (p.Flow == Parameter.FlowDirection.Out)
|
||||
{
|
||||
// Check each out parameter. If it has been pinned, get the Target of the GCHandle.
|
||||
// Otherwise, nothing needs be done.
|
||||
if (p.NeedsPin)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.GenericParameter)
|
||||
{
|
||||
f.Body.Add(
|
||||
String.Format(
|
||||
" {0} = ({1}){2}.Target;",
|
||||
p.Name,
|
||||
p.Type,
|
||||
p.Name + "_ptr"
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Body.Add(
|
||||
String.Format(
|
||||
" {0} = *{0}_ptr;",
|
||||
p.Name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return:
|
||||
if (!f.ReturnType.Type.ToLower().Contains("void"))
|
||||
{
|
||||
f.Body.Add(" return retval;");
|
||||
}
|
||||
|
||||
if (handleAllocated)
|
||||
{
|
||||
f.Body.Add(" }");
|
||||
f.Body.Add(" finally");
|
||||
f.Body.Add(" {");
|
||||
foreach (Parameter p in function.Parameters)
|
||||
{
|
||||
// Free all allocated GCHandles
|
||||
if (p.NeedsPin)
|
||||
{
|
||||
if (p.WrapperType == WrapperTypes.GenericParameter)
|
||||
f.Body.Add(String.Format(" {0}_ptr.Free();", p.Name));
|
||||
//else
|
||||
// f.Body.Add("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
f.Body.Add(" }");
|
||||
|
||||
if (!function.Unsafe)
|
||||
{
|
||||
f.Body.Add("}");
|
||||
}
|
||||
|
||||
return f.Body;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
class DelegateCollection : Dictionary<string, Delegate>
|
||||
{
|
||||
public void Add(Delegate d)
|
||||
{
|
||||
if (!this.ContainsKey(d.Name))
|
||||
{
|
||||
this.Add(d.Name, d);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.WriteLine(String.Format(
|
||||
"Spec error: function {0} redefined, ignoring second definition.",
|
||||
d.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,12 +7,20 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind.Structures
|
||||
{
|
||||
#region class Enum
|
||||
|
||||
public class Enum
|
||||
{
|
||||
public Enum()
|
||||
{ }
|
||||
|
||||
public Enum(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
string _name;
|
||||
|
||||
public string Name
|
||||
|
@ -33,17 +41,40 @@ namespace OpenTK.OpenGL.Bind
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.AppendLine(" public enum " + Name + " : uint");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine("public enum " + Name);
|
||||
sb.AppendLine("{");
|
||||
foreach (Constant c in ConstantCollection.Values)
|
||||
{
|
||||
sb.AppendLine(" " + c.Name + " = " + c.Value + ",");
|
||||
sb.Append(" ");
|
||||
sb.Append(c.ToString());
|
||||
sb.AppendLine(",");
|
||||
}
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region class EnumCollection
|
||||
|
||||
class EnumCollection : Dictionary<string, Enum>
|
||||
{
|
||||
/*
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (Bind.Structures.Enum e in this.Values)
|
||||
{
|
||||
sb.AppendLine(e.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -1,45 +1,44 @@
|
|||
#region License
|
||||
//Copyright (c) 2006 Stefanos Apostolopoulos
|
||||
//See license.txt for license info
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind.Structures
|
||||
{
|
||||
#region class Function
|
||||
|
||||
/// <summary>
|
||||
/// Represents an opengl function.
|
||||
/// The return value, function name, function parameters and opengl version can be retrieved or set.
|
||||
/// </summary>
|
||||
public class Function
|
||||
public class Function : Delegate
|
||||
{
|
||||
#region Constructors
|
||||
#region --- Constructors ---
|
||||
|
||||
public Function()
|
||||
: base()
|
||||
{
|
||||
Parameters = new ParameterCollection();
|
||||
Body = new FunctionBody();
|
||||
}
|
||||
|
||||
public Function(Function f)
|
||||
: base(f)
|
||||
{
|
||||
this.Body = new FunctionBody(f.Body);
|
||||
this.Category = new string(f.Category.ToCharArray());
|
||||
this.Extension = f.Extension;
|
||||
this.Name = new string(f.Name.ToCharArray());
|
||||
this.NeedsWrapper = f.NeedsWrapper;
|
||||
this.Parameters = new ParameterCollection(f.Parameters);
|
||||
this.ReturnValue = new string(f.ReturnValue.ToCharArray());
|
||||
this.Version = new string(f.Version.ToCharArray());
|
||||
this.WrapperType = f.WrapperType;
|
||||
}
|
||||
|
||||
public Function(Delegate d)
|
||||
: base(d)
|
||||
{
|
||||
this.Body = new FunctionBody();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Unsafe
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Settings.Compatibility == Settings.Legacy.Tao)
|
||||
return false;
|
||||
|
||||
return base.Unsafe;
|
||||
}
|
||||
}
|
||||
|
||||
#region Function body
|
||||
|
||||
FunctionBody _body;
|
||||
|
@ -49,169 +48,28 @@ namespace OpenTK.OpenGL.Bind
|
|||
get { return _body; }
|
||||
set { _body = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Category property
|
||||
|
||||
private string _category;
|
||||
|
||||
public string Category
|
||||
{
|
||||
get { return _category; }
|
||||
set { _category = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Wrapper type property
|
||||
#region public override string ToString()
|
||||
|
||||
private WrapperTypes _wrapper_type = WrapperTypes.None;
|
||||
|
||||
public WrapperTypes WrapperType
|
||||
{
|
||||
get { return _wrapper_type; }
|
||||
set { _wrapper_type = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Needs wrapper property
|
||||
|
||||
bool _needs_wrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this function needs to be wrapped with a Marshaling function.
|
||||
/// This flag is set if a function contains an Array parameter, or returns
|
||||
/// an Array or string.
|
||||
/// </summary>
|
||||
public bool NeedsWrapper
|
||||
{
|
||||
get { return _needs_wrapper; }
|
||||
set { _needs_wrapper = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Return value property
|
||||
|
||||
string _return_value;
|
||||
/// <summary>
|
||||
/// Gets or sets the return value of the opengl function.
|
||||
/// </summary>
|
||||
public string ReturnValue
|
||||
{
|
||||
get { return _return_value; }
|
||||
set { _return_value = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Name property
|
||||
|
||||
string _name;
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the opengl function.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
_name = value.Trim();
|
||||
else
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Parameter collection property
|
||||
|
||||
ParameterCollection _parameters;
|
||||
|
||||
public ParameterCollection Parameters
|
||||
{
|
||||
get { return _parameters; }
|
||||
set { _parameters = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Version property
|
||||
|
||||
string _version;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the opengl version that introduced this function.
|
||||
/// </summary>
|
||||
public string Version
|
||||
{
|
||||
get { return _version; }
|
||||
set { _version = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Extension property
|
||||
|
||||
bool _extension = false;
|
||||
|
||||
public bool Extension
|
||||
{
|
||||
get { return _extension; }
|
||||
set { _extension = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Call function string
|
||||
|
||||
public string CallString()
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(Unsafe ? "unsafe " : "");
|
||||
sb.Append(ReturnType);
|
||||
sb.Append(" ");
|
||||
if (Settings.Compatibility == Settings.Legacy.Tao)
|
||||
{
|
||||
sb.Append("gl");
|
||||
}
|
||||
sb.Append(Name);
|
||||
sb.Append("(");
|
||||
foreach (Parameter p in Parameters)
|
||||
{
|
||||
if (p.Unchecked)
|
||||
sb.Append("unchecked((" + p.Type + ")");
|
||||
|
||||
sb.Append(p.Name);
|
||||
|
||||
if (p.Unchecked)
|
||||
sb.Append(")");
|
||||
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Replace(", ", ")", sb.Length - 2, 2);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ToString function
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string representing the full function declaration without decorations
|
||||
/// (ie "void glClearColor(float red, float green, float blue, float alpha)"
|
||||
/// </summary>
|
||||
override public string ToString()
|
||||
{
|
||||
return ToString("");
|
||||
}
|
||||
|
||||
public string ToString(string indentation)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append(indentation + ReturnValue + " " + Name + Parameters.ToString());
|
||||
sb.Append(Parameters.ToString(true));
|
||||
if (Body.Count > 0)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append(Body.ToString(indentation));
|
||||
sb.Append(Body.ToString());
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
@ -219,9 +77,36 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region public Function GetCLSCompliantFunction(Dictionary<string, string> CSTypes)
|
||||
|
||||
#endregion
|
||||
public Function GetCLSCompliantFunction(Dictionary<string, string> CSTypes)
|
||||
{
|
||||
Function f = new Function(this);
|
||||
|
||||
for (int i = 0; i < f.Parameters.Count; i++)
|
||||
{
|
||||
f.Parameters[i].Type = f.Parameters[i].GetCLSCompliantType(CSTypes);
|
||||
}
|
||||
|
||||
f.Body.Clear();
|
||||
if (!f.NeedsWrapper)
|
||||
{
|
||||
f.Body.Add((f.ReturnType.Type != "void" ? "return " + this.CallString() : this.CallString()) + ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Body.AddRange(Function.GetBodyWithPins(this, CSTypes, true));
|
||||
}
|
||||
|
||||
// The type system cannot differentiate between functions with the same parameters
|
||||
// but different return types. Tough, only CLS-Compliant function in that case.
|
||||
//f.ReturnType.Type = f.ReturnType.GetCLSCompliantType(CSTypes);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region class FunctionBody : List<string>
|
||||
|
||||
|
@ -240,27 +125,46 @@ namespace OpenTK.OpenGL.Bind
|
|||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString("");
|
||||
}
|
||||
|
||||
public string ToString(string indentation)
|
||||
{
|
||||
if (this.Count == 0)
|
||||
return String.Empty;
|
||||
|
||||
StringBuilder sb = new StringBuilder(this.Count);
|
||||
|
||||
sb.AppendLine(indentation + "{");
|
||||
|
||||
sb.AppendLine("{");
|
||||
foreach (string s in this)
|
||||
{
|
||||
sb.AppendLine(indentation + " " + s);
|
||||
sb.AppendLine(" " + s);
|
||||
}
|
||||
sb.AppendLine(indentation + "}");
|
||||
sb.AppendLine("}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
class FunctionCollection : Dictionary<string, List<Function>>
|
||||
{
|
||||
public void Add(Function f)
|
||||
{
|
||||
if (!this.ContainsKey(f.Extension))
|
||||
{
|
||||
this.Add(f.Extension, new List<Function>());
|
||||
this[f.Extension].Add(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
this[f.Extension].Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<Function> functions)
|
||||
{
|
||||
foreach (Function f in functions)
|
||||
{
|
||||
this.Add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.OpenGL.Bind
|
||||
namespace Bind.Structures
|
||||
{
|
||||
#region Parameter class
|
||||
|
||||
|
@ -35,15 +35,19 @@ namespace OpenTK.OpenGL.Bind
|
|||
if (p == null)
|
||||
return;
|
||||
|
||||
this.Array = p.Array;
|
||||
this.Flow = p.Flow;
|
||||
this.Name = new string(p.Name.ToCharArray());
|
||||
this.NeedsWrapper = p.NeedsWrapper;
|
||||
this.PreviousType = new string(p.PreviousType.ToCharArray());
|
||||
this.Type = new string(p.Type.ToCharArray());
|
||||
this.Name = !String.IsNullOrEmpty(p.Name) ? new string(p.Name.ToCharArray()) : "";
|
||||
//this.NeedsWrapper = p.NeedsWrapper;
|
||||
this.PreviousType = !String.IsNullOrEmpty(p.PreviousType) ? new string(p.PreviousType.ToCharArray()) : "";
|
||||
this.Unchecked = p.Unchecked;
|
||||
this.UnmanagedType = p.UnmanagedType;
|
||||
this.WrapperType = p.WrapperType;
|
||||
|
||||
this.Type = new string(p.Type.ToCharArray());
|
||||
this.Flow = p.Flow;
|
||||
this.Array = p.Array;
|
||||
this.Pointer = p.Pointer;
|
||||
this.Reference = p.Reference;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -84,12 +88,34 @@ namespace OpenTK.OpenGL.Bind
|
|||
/// </summary>
|
||||
public string Type
|
||||
{
|
||||
get { return _type; }
|
||||
//get { return _type; }
|
||||
get
|
||||
{
|
||||
//if (Pointer && Settings.Compatibility == Settings.Legacy.Tao)
|
||||
// return "IntPtr";
|
||||
|
||||
return _type;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_type != null)
|
||||
if (!String.IsNullOrEmpty(_type))
|
||||
PreviousType = _type;
|
||||
_type = value;
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
_type = value.Trim();
|
||||
if (_type.EndsWith("*"))
|
||||
{
|
||||
_type = _type.TrimEnd('*');
|
||||
Pointer = true;
|
||||
}
|
||||
|
||||
clsCompliant =
|
||||
!(
|
||||
(Pointer && (Settings.Compatibility != Settings.Legacy.Tao)) ||
|
||||
(Type.Contains("GLu") && !Type.Contains("GLubyte")) ||
|
||||
Type == "GLbitfield" ||
|
||||
Type.Contains("GLhandle") ||
|
||||
Type.Contains("GLhalf") ||
|
||||
Type == "GLbyte");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,19 +160,54 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region Array property
|
||||
#region public bool Reference
|
||||
|
||||
bool _array = false;
|
||||
bool reference;
|
||||
|
||||
public bool Array
|
||||
public bool Reference
|
||||
{
|
||||
get { return _array; }
|
||||
set { _array = value; }
|
||||
get { return reference; }
|
||||
set { reference = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unchecked property
|
||||
#region public bool Array
|
||||
|
||||
int array;
|
||||
|
||||
public int Array
|
||||
{
|
||||
get { return array; }
|
||||
set { array = value > 0 ? value : 0; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool Pointer
|
||||
|
||||
bool pointer = false;
|
||||
|
||||
public bool Pointer
|
||||
{
|
||||
get { return pointer; }
|
||||
set { pointer = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool NeedsPin
|
||||
|
||||
public bool NeedsPin
|
||||
{
|
||||
get { return
|
||||
(Array > 0 || Reference || Type == "object") &&
|
||||
!Type.ToLower().Contains("string"); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public bool Unchecked
|
||||
|
||||
private bool _unchecked;
|
||||
|
||||
|
@ -158,18 +219,6 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region NeedsWrapper property
|
||||
|
||||
private bool _needs_wrapper;
|
||||
|
||||
public bool NeedsWrapper
|
||||
{
|
||||
get { return _needs_wrapper; }
|
||||
set { _needs_wrapper = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WrapperType property
|
||||
|
||||
private WrapperTypes _wrapper_type = WrapperTypes.None;
|
||||
|
@ -182,29 +231,137 @@ namespace OpenTK.OpenGL.Bind
|
|||
|
||||
#endregion
|
||||
|
||||
#region ToString function
|
||||
#region public bool CLSCompliant
|
||||
|
||||
private bool clsCompliant;
|
||||
|
||||
public bool CLSCompliant
|
||||
{
|
||||
get
|
||||
{
|
||||
// Checked when setting the Type property.
|
||||
return clsCompliant || (Pointer && Settings.Compatibility == Settings.Legacy.Tao);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string GetFullType()
|
||||
|
||||
public string GetFullType(Dictionary<string, string> CSTypes, bool compliant)
|
||||
{
|
||||
if (Pointer && Settings.Compatibility == Settings.Legacy.Tao)
|
||||
return "IntPtr";
|
||||
|
||||
if (!compliant)
|
||||
{
|
||||
return
|
||||
Type +
|
||||
(Pointer ? "*" : "") +
|
||||
(Array > 0 ? "[]" : "");
|
||||
}
|
||||
|
||||
return
|
||||
GetCLSCompliantType(CSTypes) +
|
||||
(Pointer ? "*" : "") +
|
||||
(Array > 0 ? "[]" : "");
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string GetCLSCompliantType(Dictionary<string, string> CSTypes)
|
||||
|
||||
public string GetCLSCompliantType(Dictionary<string, string> CSTypes)
|
||||
{
|
||||
if (!CLSCompliant)
|
||||
{
|
||||
if (Pointer && Settings.Compatibility == Settings.Legacy.Tao)
|
||||
return "IntPtr";
|
||||
|
||||
if (CSTypes.ContainsKey(Type))
|
||||
{
|
||||
switch (CSTypes[Type])
|
||||
{
|
||||
case "UInt16":
|
||||
return "Int16";
|
||||
case "UInt32":
|
||||
return "Int32";
|
||||
case "UInt64":
|
||||
return "Int64";
|
||||
case "SByte":
|
||||
return "Byte";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Type;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region override public string ToString()
|
||||
|
||||
override public string ToString()
|
||||
{
|
||||
return ToString(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public string ToString(bool taoCompatible)
|
||||
|
||||
public string ToString(bool taoCompatible)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (UnmanagedType == UnmanagedType.AsAny && Flow == FlowDirection.In)
|
||||
sb.Append("[MarshalAs(UnmanagedType.AsAny)] ");
|
||||
//if (UnmanagedType == UnmanagedType.AsAny && Flow == FlowDirection.In)
|
||||
// sb.Append("[MarshalAs(UnmanagedType.AsAny)] ");
|
||||
|
||||
if (UnmanagedType == UnmanagedType.LPArray)
|
||||
sb.Append("[MarshalAs(UnmanagedType.LPArray)] ");
|
||||
//if (UnmanagedType == UnmanagedType.LPArray)
|
||||
// sb.Append("[MarshalAs(UnmanagedType.LPArray)] ");
|
||||
|
||||
//if (Flow == FlowDirection.Out && !Array && !(Type == "IntPtr"))
|
||||
// sb.Append("out ");
|
||||
|
||||
sb.Append(Type);
|
||||
if (Array)
|
||||
sb.Append("[]");
|
||||
if (Reference)
|
||||
{
|
||||
if (Flow == FlowDirection.Out)
|
||||
sb.Append("out ");
|
||||
else
|
||||
sb.Append("ref ");
|
||||
}
|
||||
|
||||
sb.Append(" ");
|
||||
sb.Append(Name);
|
||||
if (taoCompatible && Settings.Compatibility == Settings.Legacy.Tao)
|
||||
{
|
||||
if (Pointer)
|
||||
{
|
||||
sb.Append("IntPtr");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Type);
|
||||
if (Array > 0)
|
||||
sb.Append("[]");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Type);
|
||||
if (Pointer)
|
||||
sb.Append("*");
|
||||
if (Array > 0)
|
||||
sb.Append("[]");
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(Name))
|
||||
{
|
||||
sb.Append(" ");
|
||||
sb.Append(Utilities.Keywords.Contains(Name) ? "@" + Name : Name);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
@ -236,10 +393,30 @@ namespace OpenTK.OpenGL.Bind
|
|||
#region override public string ToString()
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Gets the parameter declaration string.
|
||||
/// </summary>
|
||||
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
|
||||
override public string ToString()
|
||||
{
|
||||
return ToString(false, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public string ToString(bool taoCompatible)
|
||||
{
|
||||
return ToString(true, null);
|
||||
}
|
||||
|
||||
#region public string ToString(bool taoCompatible, Dictionary<string, string> CSTypes)
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter declaration string.
|
||||
/// </summary>
|
||||
/// <param name="getCLSCompliant">If true, all types will be replaced by their CLSCompliant C# equivalents</param>
|
||||
/// <param name="CSTypes">The list of C# types equivalent to the OpenGL types.</param>
|
||||
/// <returns>The parameter list of an opengl function in the form ( [parameters] )</returns>
|
||||
public string ToString(bool taoCompatible, Dictionary<string, string> CSTypes)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("(");
|
||||
|
@ -247,7 +424,14 @@ namespace OpenTK.OpenGL.Bind
|
|||
{
|
||||
foreach (Parameter p in this)
|
||||
{
|
||||
sb.Append(p.ToString());
|
||||
if (taoCompatible)
|
||||
{
|
||||
sb.Append(p.ToString(true));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(p.ToString());
|
||||
}
|
||||
sb.Append(", ");
|
||||
}
|
||||
sb.Replace(", ", ")", sb.Length - 2, 2);
|
||||
|
@ -258,6 +442,8 @@ namespace OpenTK.OpenGL.Bind
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public bool ContainsType(string type)
|
||||
{
|
||||
foreach (Parameter p in this)
|
||||
|
@ -265,87 +451,6 @@ namespace OpenTK.OpenGL.Bind
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public ParameterCollection ReplaceAll(Parameter, Parameter)
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all parameters that match the old_param with the new_param.
|
||||
/// </summary>
|
||||
/// <param name="old_param"></param>
|
||||
/// <param name="new_param"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>The PreviousType property is ignored in parameter matching, and is set to the previous type in case of replacement.</remarks>
|
||||
public ParameterCollection ReplaceAll(Parameter old_param, Parameter new_param)
|
||||
{
|
||||
if (old_param == null || new_param == null)
|
||||
return null;
|
||||
|
||||
ParameterCollection pc = new ParameterCollection(this);
|
||||
|
||||
foreach (Parameter p in pc)
|
||||
{
|
||||
if (p.Array == old_param.Array &&
|
||||
p.Flow == old_param.Flow &&
|
||||
p.Name == old_param.Name &&
|
||||
//p.PreviousType == old_param.PreviousType &&
|
||||
p.Type == old_param.Type &&
|
||||
p.UnmanagedType == old_param.UnmanagedType)
|
||||
{
|
||||
p.Array = new_param.Array;
|
||||
p.Flow = new_param.Flow;
|
||||
p.Name = new_param.Name;
|
||||
p.PreviousType = p.Type;
|
||||
p.Type = new_param.Type;
|
||||
p.UnmanagedType = new_param.UnmanagedType;
|
||||
}
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public ParameterCollection Replace(Parameter, Parameter)
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the first parameter that matches old_param with new_param.
|
||||
/// </summary>
|
||||
/// <param name="old_param"></param>
|
||||
/// <param name="new_param"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>The PreviousType property is ignored in parameter matching, and is set to the previous type in case of replacement.</remarks>
|
||||
public ParameterCollection Replace(Parameter old_param, Parameter new_param)
|
||||
{
|
||||
if (old_param == null || new_param == null)
|
||||
return null;
|
||||
|
||||
ParameterCollection pc = new ParameterCollection(this);
|
||||
|
||||
foreach (Parameter p in pc)
|
||||
{
|
||||
if (p.Array == old_param.Array &&
|
||||
p.Flow == old_param.Flow &&
|
||||
p.Name == old_param.Name &&
|
||||
//p.PreviousType == old_param.PreviousType &&
|
||||
p.Type == old_param.Type &&
|
||||
p.UnmanagedType == old_param.UnmanagedType)
|
||||
{
|
||||
p.Array = new_param.Array;
|
||||
p.Flow = new_param.Flow;
|
||||
p.Name = new_param.Name;
|
||||
p.PreviousType = p.Type;
|
||||
p.Type = new_param.Type;
|
||||
p.UnmanagedType = new_param.UnmanagedType;
|
||||
return pc;
|
||||
}
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
231
Source/Bind/Utilities.cs
Normal file
231
Source/Bind/Utilities.cs
Normal file
|
@ -0,0 +1,231 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using Bind.Structures;
|
||||
|
||||
namespace Bind
|
||||
{
|
||||
#region WrapperTypes enum
|
||||
|
||||
[Flags]
|
||||
public enum WrapperTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// No wrapper needed.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Function takes bool parameter - C uses Int for bools, so we have to marshal.
|
||||
/// </summary>
|
||||
BoolParameter,
|
||||
/// <summary>
|
||||
/// Function takes generic parameters - add ref/out generic and generic overloads.
|
||||
/// </summary>
|
||||
GenericParameter,
|
||||
/// <summary>
|
||||
/// Function takes arrays as parameters - add ref/out and ([Out]) array overloads.
|
||||
/// </summary>
|
||||
ArrayParameter,
|
||||
/// <summary>
|
||||
/// Function with bitmask parameters. Bitmask parameters map to UInt, but since we can only use signed
|
||||
/// types (for CLS compliance), we must add the unchecked keyword.
|
||||
/// Usually found in bitmasks
|
||||
/// </summary>
|
||||
UncheckedParameter,
|
||||
/// <summary>
|
||||
/// Function that takes (in/ref/out) a naked pointer as a parameter - we pass an IntPtr.
|
||||
/// </summary>
|
||||
PointerParameter,
|
||||
/// <summary>
|
||||
/// Function returns string - needs manual marshalling through IntPtr to prevent the managed GC
|
||||
/// from freeing memory allocated on the unmanaged side (e.g. glGetString).
|
||||
/// </summary>
|
||||
StringReturnType,
|
||||
/// <summary>
|
||||
/// Function returns a void pointer - maps to IntPtr, and the user has to manually marshal the type.
|
||||
/// </summary>
|
||||
GenericReturnType,
|
||||
/// <summary>
|
||||
/// Function returns a typed pointer - we have to copy the data to an array to protect it from the GC.
|
||||
/// </summary>
|
||||
ArrayReturnType
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static class Utilities
|
||||
{
|
||||
public static char[] Separators = { ' ', '\n', ',', '(', ')', ';', '#' };
|
||||
|
||||
#region internal StreamReader OpenSpecFile(string file)
|
||||
|
||||
internal static StreamReader OpenSpecFile(string folder, string file)
|
||||
{
|
||||
string path = Path.Combine(folder, file);
|
||||
return new StreamReader(path);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region C# keywords
|
||||
|
||||
public static readonly List<string> Keywords = new List<string>(
|
||||
new string[]
|
||||
{
|
||||
"abstract", "event", "new", "struct",
|
||||
"as", "explicit", "null", "switch",
|
||||
"base", "extern", "object", "this",
|
||||
"bool", "false", "operator", "throw",
|
||||
"break", "finally", "out", "true",
|
||||
"byte", "fixed", "override", "try",
|
||||
"case", "float", "params", "typeof",
|
||||
"catch", "for", "private", "uint",
|
||||
"char", "foreach", "protected", "ulong",
|
||||
"checked", "goto", "public", "unchecked",
|
||||
"class", "if", "readonly", "unsafe",
|
||||
"const", "implicit", "ref", "ushort",
|
||||
"continue", "in", "return", "using",
|
||||
"decimal", "int", "sbyte", "virtual",
|
||||
"default", "interface", "sealed", "volatile",
|
||||
"delegate", "internal", "short", "void",
|
||||
"do", "is", "sizeof", "while",
|
||||
"double", "lock", "stackalloc",
|
||||
"else", "long", "static",
|
||||
"enum", "namespace", "string"
|
||||
}
|
||||
);
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal static void Merge(EnumCollection enums, Bind.Structures.Enum t)
|
||||
|
||||
/// <summary>
|
||||
/// Merges the given enum into the enum list. If an enum of the same name exists,
|
||||
/// it merges their respective constants.
|
||||
/// </summary>
|
||||
/// <param name="enums"></param>
|
||||
/// <param name="t"></param>
|
||||
internal static void Merge(EnumCollection enums, Bind.Structures.Enum t)
|
||||
{
|
||||
if (!enums.ContainsKey(t.Name))
|
||||
{
|
||||
enums.Add(t.Name, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bind.Structures.Enum e = enums[t.Name];
|
||||
foreach (Bind.Structures.Constant c in t.ConstantCollection.Values)
|
||||
{
|
||||
Merge(e, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal static Bind.Structures.Enum Merge(Bind.Structures.Enum s, Bind.Structures.Constant t)
|
||||
|
||||
/// <summary>
|
||||
/// Places a new constant in the specified enum, if it doesn't already exist.
|
||||
/// The existing constant is replaced iff the new has a numeric value and the old
|
||||
/// has a reference value (eg 0x5 is preferred over AttribMask.Foo)
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="t"></param>
|
||||
/// <returns></returns>
|
||||
internal static Bind.Structures.Enum Merge(Bind.Structures.Enum s, Bind.Structures.Constant t)
|
||||
{
|
||||
if (!s.ConstantCollection.ContainsKey(t.Name))
|
||||
{
|
||||
s.ConstantCollection.Add(t.Name, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Tried to add a constant that already exists. If one constant
|
||||
// is like: 'Foo = 0x5' and the other like: 'Foo = Bar.Foo', then
|
||||
// keep the first one.
|
||||
if (!Char.IsDigit(((Constant)s.ConstantCollection[t.Name]).Value[0]))
|
||||
{
|
||||
s.ConstantCollection.Remove(t.Name);
|
||||
s.ConstantCollection.Add(t.Name, t);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal static string StripGL2Extension(Function f)
|
||||
|
||||
internal static string StripGL2Extension(Function f)
|
||||
{
|
||||
string ext = GetGL2Extension(f.Name);
|
||||
if (String.IsNullOrEmpty(ext))
|
||||
return null;
|
||||
|
||||
f.Name = f.Name.Substring(0, f.Name.Length - ext.Length);
|
||||
return ext;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal static string GetGL2Extension(string name)
|
||||
|
||||
internal static string GetGL2Extension(string name)
|
||||
{
|
||||
if (name.EndsWith("ARB")) { return "ARB"; }
|
||||
if (name.EndsWith("EXT")) { return "EXT"; }
|
||||
if (name.EndsWith("ATI")) { return "ATI"; }
|
||||
if (name.EndsWith("ATIX")) { return "ATIX"; }
|
||||
if (name.EndsWith("NV")) { return "NV"; }
|
||||
if (name.EndsWith("SUN")) { return "SUN"; }
|
||||
if (name.EndsWith("SUNX")) { return "SUNX"; }
|
||||
if (name.EndsWith("SGI")) { return "SGI"; }
|
||||
if (name.EndsWith("SGIS")) { return "SGIS"; }
|
||||
if (name.EndsWith("SGIX")) { return "SGIX"; }
|
||||
if (name.EndsWith("MESA")) { return "MESA"; }
|
||||
if (name.EndsWith("G3DFX")) { return "G3DFX"; }
|
||||
if (name.EndsWith("IBM")) { return "IBM"; }
|
||||
if (name.EndsWith("GREMEDY")) { return "GREMEDY"; }
|
||||
if (name.EndsWith("HP")) { return "HP"; }
|
||||
if (name.EndsWith("PGI")) { return "PGI"; }
|
||||
if (name.EndsWith("INGR")) { return "INGR"; }
|
||||
if (name.EndsWith("APPLE")) { return "APPLE"; }
|
||||
if (name.EndsWith("OML")) { return "OML"; }
|
||||
if (name.EndsWith("I3D")) { return "I3D"; }
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region private static bool IsGL2Extension(string function)
|
||||
|
||||
private static bool IsGL2Extension(string function)
|
||||
{
|
||||
return (function.EndsWith("ARB") ||
|
||||
function.EndsWith("EXT") ||
|
||||
function.EndsWith("ATI") ||
|
||||
function.EndsWith("NV") ||
|
||||
function.EndsWith("SUN") ||
|
||||
function.EndsWith("SUNX") ||
|
||||
function.EndsWith("SGI") ||
|
||||
function.EndsWith("SGIS") ||
|
||||
function.EndsWith("SGIX") ||
|
||||
function.EndsWith("MESA") ||
|
||||
function.EndsWith("3DFX") ||
|
||||
function.EndsWith("IBM") ||
|
||||
function.EndsWith("GREMEDY") ||
|
||||
function.EndsWith("HP") ||
|
||||
function.EndsWith("INTEL") ||
|
||||
function.EndsWith("PGI") ||
|
||||
function.EndsWith("INGR") ||
|
||||
function.EndsWith("APPLE") ||
|
||||
function.EndsWith("OML") ||
|
||||
function.EndsWith("I3D"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue