2007-07-23 00:15:18 +00:00
|
|
|
#region --- License ---
|
2008-01-20 17:26:53 +00:00
|
|
|
/* Copyright (c) 2006-2008 the OpenTK team.
|
2007-07-23 00:15:18 +00:00
|
|
|
* See license.txt for license info
|
2007-11-10 23:29:25 +00:00
|
|
|
*
|
|
|
|
* Contributions by Andy Gill.
|
2007-07-23 00:15:18 +00:00
|
|
|
*/
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region --- Using Directives ---
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Text;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
using System.Reflection;
|
2007-09-02 13:34:44 +00:00
|
|
|
using System.Diagnostics;
|
2007-09-05 19:53:48 +00:00
|
|
|
using System.Reflection.Emit;
|
2007-11-04 15:30:44 +00:00
|
|
|
|
2007-10-26 13:12:24 +00:00
|
|
|
using OpenTK.Math;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2008-02-02 00:58:26 +00:00
|
|
|
// Add a dummy namespace to keep old code compiling.
|
|
|
|
namespace OpenTK.Graphics.OpenGL.Enums
|
|
|
|
{
|
|
|
|
internal static class Dummy { }
|
|
|
|
}
|
|
|
|
|
2008-02-02 00:25:54 +00:00
|
|
|
namespace OpenTK.Graphics.OpenGL
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// OpenGL binding for .NET, implementing OpenGL 2.1, plus extensions.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// <para>
|
2007-11-10 18:11:34 +00:00
|
|
|
/// This class contains all OpenGL enums and functions defined in the 2.1 specification.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// The official .spec files can be found at: http://opengl.org/registry/.
|
|
|
|
/// </para>
|
2008-01-19 15:27:15 +00:00
|
|
|
/// <para> A valid OpenGL context must be created before calling any OpenGL function.</para>
|
2007-07-23 00:15:18 +00:00
|
|
|
/// <para>
|
2007-11-10 18:11:34 +00:00
|
|
|
/// Use the GL.Load and GL.LoadAll methods to prepare function entry points prior to use. To maintain
|
|
|
|
/// cross-platform compatibility, this must be done for both core and extension functions. The GameWindow
|
|
|
|
/// and the GLControl class will take care of this automatically.
|
2008-01-19 15:27:15 +00:00
|
|
|
/// </para>
|
2007-07-23 00:15:18 +00:00
|
|
|
/// <para>
|
2007-11-10 18:11:34 +00:00
|
|
|
/// You can use the GL.SupportsExtension method to check whether any given category of extension functions
|
|
|
|
/// exists in the current OpenGL context. Keep in mind that different OpenGL contexts may support different
|
|
|
|
/// extensions, and under different entry points. Always check if all required extensions are still supported
|
|
|
|
/// when changing visuals or pixel formats.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
|
|
|
/// <para>
|
2007-09-05 19:53:48 +00:00
|
|
|
/// You may retrieve the entry point for an OpenGL function using the GL.GetDelegate method.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
2008-01-19 15:27:15 +00:00
|
|
|
/// </remarks>
|
2007-07-23 00:15:18 +00:00
|
|
|
/// <see href="http://opengl.org/registry/"/>
|
2007-09-05 19:53:48 +00:00
|
|
|
/// <seealso cref="GL.SupportsExtension"/>
|
|
|
|
/// <seealso cref="GL.GetDelegate"/>
|
|
|
|
/// <seealso cref="GL.LoadAll"/>
|
|
|
|
/// <seealso cref="GL.Load"/>
|
2007-07-23 00:15:18 +00:00
|
|
|
public static partial class GL
|
|
|
|
{
|
2008-01-19 15:27:15 +00:00
|
|
|
delegate void VoidGLDelegate(object @class, object[] parameters);
|
|
|
|
delegate object ObjectGLDelegate(object @class, object[] parameters);
|
|
|
|
|
2007-11-10 18:11:34 +00:00
|
|
|
#region --- Fields ---
|
|
|
|
|
|
|
|
internal const string Library = "opengl32.dll";
|
|
|
|
|
2007-11-06 13:33:56 +00:00
|
|
|
static StringBuilder sb = new StringBuilder();
|
|
|
|
static object gl_lock = new object();
|
|
|
|
|
2007-11-10 18:11:34 +00:00
|
|
|
private static SortedList<string, bool> AvailableExtensions = new SortedList<string, bool>();
|
|
|
|
private static bool rebuildExtensionList;
|
|
|
|
|
|
|
|
private static Type glClass;
|
|
|
|
private static Type delegatesClass;
|
|
|
|
private static Type importsClass;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region --- Constructor ---
|
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
static GL()
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
2007-11-10 18:11:34 +00:00
|
|
|
glClass = typeof(GL);
|
2007-08-20 10:46:37 +00:00
|
|
|
delegatesClass = glClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
importsClass = glClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
}
|
2007-07-23 00:15:18 +00:00
|
|
|
|
2007-11-10 18:11:34 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region --- Imports ---
|
|
|
|
|
2007-09-09 15:42:51 +00:00
|
|
|
internal static partial class Imports
|
2007-09-05 19:53:48 +00:00
|
|
|
{
|
2007-11-10 18:11:34 +00:00
|
|
|
internal static SortedList<string, MethodInfo> FunctionMap; // This is faster than either Dictionary or SortedDictionary
|
2007-09-05 19:53:48 +00:00
|
|
|
static Imports()
|
|
|
|
{
|
|
|
|
MethodInfo[] methods = importsClass.GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
|
2007-11-10 18:11:34 +00:00
|
|
|
FunctionMap = new SortedList<string, MethodInfo>(methods.Length);
|
2007-09-05 19:53:48 +00:00
|
|
|
foreach (MethodInfo m in methods)
|
|
|
|
{
|
2007-11-10 18:11:34 +00:00
|
|
|
FunctionMap.Add(m.Name, m);
|
2007-09-05 19:53:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
#endregion
|
|
|
|
|
2008-01-22 23:58:50 +00:00
|
|
|
#region --- Public Methods ---
|
2007-11-10 18:11:34 +00:00
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
#region public static bool SupportsExtension(string name)
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Determines whether the specified OpenGL extension category is available in
|
|
|
|
/// the current OpenGL context. Equivalent to IsExtensionSupported(name, true)
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The string for the OpenGL extension category (eg. "GL_ARB_multitexture")</param>
|
|
|
|
/// <returns>True if the specified extension is available, false otherwise.</returns>
|
2007-08-20 10:46:37 +00:00
|
|
|
public static bool SupportsExtension(string name)
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
2007-08-20 10:46:37 +00:00
|
|
|
if (rebuildExtensionList)
|
|
|
|
BuildExtensionList();
|
2008-01-11 20:20:42 +00:00
|
|
|
|
2007-11-06 13:33:56 +00:00
|
|
|
lock (gl_lock)
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
2007-11-06 13:33:56 +00:00
|
|
|
sb.Remove(0, sb.Length);
|
|
|
|
if (!name.StartsWith("GL_"))
|
|
|
|
sb.Append("gl_");
|
|
|
|
sb.Append(name.ToLower());
|
|
|
|
|
|
|
|
// Search the cache for the string.
|
|
|
|
return AvailableExtensions.ContainsKey(sb.ToString());
|
2007-07-23 00:15:18 +00:00
|
|
|
}
|
|
|
|
}
|
2007-08-20 10:46:37 +00:00
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
#endregion
|
|
|
|
|
2008-01-19 15:27:15 +00:00
|
|
|
#region public static Delegate GetDelegate(string name)
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns a System.Delegate wrapping the specified OpenGL function. You must use the
|
|
|
|
/// base OpenGL name of the function (e.g. "glVertex3fv" instead of "Vertex3").
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
|
|
|
|
/// <param name="signature">The signature of the OpenGL function.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// A System.Delegate that can be used to call this OpenGL function or null, if the specified
|
|
|
|
/// function name does not correspond to an OpenGL function or if the function is not
|
|
|
|
/// supported by the video drivers.
|
|
|
|
/// </returns>
|
|
|
|
public static Delegate GetDelegate(string name)
|
|
|
|
{
|
|
|
|
FieldInfo info = typeof(Delegates).GetField(name, BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (info == null)
|
|
|
|
return null;
|
|
|
|
return (Delegate)info.GetValue(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
#region public static Delegate GetDelegate(string name, Type signature)
|
|
|
|
|
|
|
|
/// <summary>
|
2008-01-19 15:27:15 +00:00
|
|
|
/// Returns a System.Delegate wrapping an OpenGL function.
|
2007-08-20 10:46:37 +00:00
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
|
|
|
|
/// <param name="signature">The signature of the OpenGL function.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// A System.Delegate that can be used to call this OpenGL function, or null if the specified
|
|
|
|
/// function name did not correspond to an OpenGL function.
|
|
|
|
/// </returns>
|
2008-01-19 15:27:15 +00:00
|
|
|
[Obsolete("Use GetDelegate(string name) instead.")]
|
2007-08-20 10:46:37 +00:00
|
|
|
public static Delegate GetDelegate(string name, Type signature)
|
|
|
|
{
|
2008-01-19 15:27:15 +00:00
|
|
|
return LoadDelegate(name, signature);
|
2007-07-23 00:15:18 +00:00
|
|
|
}
|
2007-08-20 10:46:37 +00:00
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
#endregion
|
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
#region public static void LoadAll()
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
/// <summary>
|
2007-08-20 10:46:37 +00:00
|
|
|
/// Loads all OpenGL functions (core and extensions).
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// <para>
|
2007-08-20 10:46:37 +00:00
|
|
|
/// This function will be automatically called the first time you use any opengl function. There is
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
|
|
|
/// <para>
|
2007-08-20 10:46:37 +00:00
|
|
|
/// Call this function manually whenever you need to update OpenGL entry points.
|
|
|
|
/// This need may arise if you change the pixelformat/visual, or in case you cannot
|
2007-09-02 19:54:01 +00:00
|
|
|
/// (or do not want) to use the automatic initialization of the GL class.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
|
|
|
/// </remarks>
|
2007-08-20 10:46:37 +00:00
|
|
|
public static void LoadAll()
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
2008-01-31 14:39:54 +00:00
|
|
|
//TODO: Route GameWindow context creation through GraphicsContext.
|
|
|
|
//if (GraphicsContext.CurrentContext == null)
|
2008-01-22 23:58:50 +00:00
|
|
|
// throw new InvalidOperationException("You must create an OpenGL context before using the GL class.");
|
2008-03-01 13:15:31 +00:00
|
|
|
if (GraphicsContext.CurrentContext != null)
|
|
|
|
OpenTK.Platform.Utilities.LoadExtensions(glClass);
|
|
|
|
else
|
|
|
|
throw new InvalidOperationException("No GraphicsContext available in the calling thread.");
|
2007-09-05 19:53:48 +00:00
|
|
|
}
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
#endregion
|
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
#region public static bool Load(string function)
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Tries to reload the given OpenGL function (core or extension).
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the OpenGL function (i.e. glShaderSource)</param>
|
|
|
|
/// <returns>True if the function was found and reloaded, false otherwise.</returns>
|
|
|
|
/// <remarks>
|
|
|
|
/// <para>
|
|
|
|
/// Use this function if you require greater granularity when loading OpenGL entry points.
|
|
|
|
/// </para>
|
|
|
|
/// <para>
|
|
|
|
/// While the automatic initialisation will load all OpenGL entry points, in some cases
|
|
|
|
/// the initialisation can take place before an OpenGL Context has been established.
|
|
|
|
/// In this case, use this function to load the entry points for the OpenGL functions
|
|
|
|
/// you will need, or use ReloadFunctions() to load all available entry points.
|
|
|
|
/// </para>
|
|
|
|
/// <para>
|
2007-08-20 10:46:37 +00:00
|
|
|
/// This function returns true if the given OpenGL function is supported, false otherwise.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
|
|
|
/// <para>
|
2007-08-20 10:46:37 +00:00
|
|
|
/// To query for supported extensions use the IsExtensionSupported() function instead.
|
2007-07-23 00:15:18 +00:00
|
|
|
/// </para>
|
|
|
|
/// </remarks>
|
2007-08-20 10:46:37 +00:00
|
|
|
public static bool Load(string function)
|
2007-07-23 00:15:18 +00:00
|
|
|
{
|
2007-08-22 16:13:41 +00:00
|
|
|
FieldInfo f = delegatesClass.GetField(function, BindingFlags.Static | BindingFlags.NonPublic);
|
2007-07-23 00:15:18 +00:00
|
|
|
if (f == null)
|
|
|
|
return false;
|
|
|
|
|
2007-09-05 19:53:48 +00:00
|
|
|
Delegate old = f.GetValue(null) as Delegate;
|
2008-01-19 15:27:15 +00:00
|
|
|
Delegate @new = LoadDelegate(f.Name, f.FieldType);
|
2007-09-05 19:53:48 +00:00
|
|
|
if (old.Target != @new.Target)
|
|
|
|
{
|
|
|
|
f.SetValue(null, @new);
|
|
|
|
rebuildExtensionList = true;
|
|
|
|
}
|
2007-09-29 15:27:18 +00:00
|
|
|
return @new != null;
|
2007-07-23 00:15:18 +00:00
|
|
|
}
|
2007-08-20 10:46:37 +00:00
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
#endregion
|
2007-08-21 09:01:24 +00:00
|
|
|
|
2008-01-19 15:27:15 +00:00
|
|
|
#region static Delegate LoadDelegate(string name, Type signature)
|
|
|
|
|
|
|
|
/// <private />
|
|
|
|
/// <summary>
|
|
|
|
/// Loads an OpenGL function into a type-safe System.Delegate.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
|
|
|
|
/// <param name="signature">The signature of the OpenGL function.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// A System.Delegate that can be used to call this OpenGL function, or null if the specified
|
|
|
|
/// function name did not correspond to an OpenGL function.
|
|
|
|
/// </returns>
|
|
|
|
static Delegate LoadDelegate(string name, Type signature)
|
|
|
|
{
|
|
|
|
MethodInfo m;
|
|
|
|
return
|
|
|
|
GetExtensionDelegate(name, signature) ??
|
|
|
|
/*((m = importsClass.GetMethod(name.Substring(2), BindingFlags.Static | BindingFlags.NonPublic)) != null ?*/
|
|
|
|
(Imports.FunctionMap.TryGetValue((name.Substring(2)), out m) ?
|
|
|
|
Delegate.CreateDelegate(signature, m) : null);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-11-06 13:33:56 +00:00
|
|
|
#region public static bool SupportsFunction(string function)
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Checks if a given OpenGL function is supported by the current context
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="function">The name of the OpenGL function (i.e. glShaderSource)</param>
|
|
|
|
/// <returns>True if the function is supported, false otherwise</returns>
|
|
|
|
public static bool SupportsFunction(string function)
|
|
|
|
{
|
|
|
|
lock (gl_lock)
|
|
|
|
{
|
|
|
|
if (function == null)
|
|
|
|
throw new ArgumentNullException("function");
|
|
|
|
|
|
|
|
sb.Remove(0, sb.Length);
|
|
|
|
if (!function.StartsWith("gl"))
|
|
|
|
sb.Append("gl");
|
|
|
|
sb.Append(function);
|
|
|
|
FieldInfo f = delegatesClass.GetField(sb.ToString(), BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (f == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return f.GetValue(null) != null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public static bool SupportsFunction(string function, string extension)
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Checks if a given OpenGL function is supported by the current context
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="function">The name of the OpenGL function (e.g. glShaderSource)</param>
|
|
|
|
/// <param name="extension">The name of the extension catagory (e.g. ARB, EXT, ATI, ...)</param>
|
|
|
|
/// <returns>True if the function is supported, false otherwise</returns>
|
|
|
|
public static bool SupportsFunction(string function, string extension)
|
|
|
|
{
|
|
|
|
lock (gl_lock)
|
|
|
|
{
|
|
|
|
if (function == null)
|
|
|
|
throw new ArgumentNullException("function");
|
|
|
|
if (extension == null)
|
|
|
|
throw new ArgumentNullException("extension");
|
|
|
|
|
|
|
|
sb.Remove(0, sb.Length);
|
|
|
|
if (!function.StartsWith("gl"))
|
|
|
|
sb.Append("gl");
|
|
|
|
sb.Append(function);
|
|
|
|
if (!function.EndsWith(extension))
|
|
|
|
sb.Append(extension);
|
|
|
|
|
|
|
|
FieldInfo f = delegatesClass.GetField(sb.ToString(), BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (f == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return f.GetValue(null) != null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2008-03-01 13:15:31 +00:00
|
|
|
#region static bool SupportsFunction(Type function)
|
2007-11-06 13:33:56 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Checks if a given OpenGL function is supported by the current context
|
|
|
|
/// </summary>
|
2008-03-01 13:15:31 +00:00
|
|
|
/// <param name="method">The System.Reflection.MethodInfo of the OpenGL function.</param>
|
2007-11-06 13:33:56 +00:00
|
|
|
/// <returns>True if the function is supported, false otherwise</returns>
|
2008-03-01 13:15:31 +00:00
|
|
|
static bool SupportsFunction(MethodInfo method)
|
2007-11-06 13:33:56 +00:00
|
|
|
{
|
2008-03-01 13:15:31 +00:00
|
|
|
throw new NotImplementedException();
|
2007-11-06 13:33:56 +00:00
|
|
|
lock (gl_lock)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
if (function == null)
|
|
|
|
throw new ArgumentNullException("function");
|
|
|
|
|
|
|
|
sb.Remove(0, sb.Length);
|
|
|
|
if (!function.Name.StartsWith("gl"))
|
|
|
|
sb.Append("gl");
|
|
|
|
sb.Append(function);
|
|
|
|
//if (!function.EndsWith(extension))
|
|
|
|
// sb.Append(extension);
|
|
|
|
|
|
|
|
FieldInfo f = delegatesClass.GetField(sb.ToString(), BindingFlags.Static | BindingFlags.NonPublic);
|
|
|
|
if (f == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return f.GetValue(null) != null;
|
|
|
|
*/
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-11-10 18:11:34 +00:00
|
|
|
#region private static void BuildExtensionList()
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Builds a cache of the supported extensions to speed up searches.
|
|
|
|
/// </summary>
|
|
|
|
private static void BuildExtensionList()
|
|
|
|
{
|
|
|
|
// Assumes there is an opengl context current.
|
|
|
|
AvailableExtensions.Clear();
|
|
|
|
string version_string = GL.GetString(StringName.Version);
|
|
|
|
if (String.IsNullOrEmpty(version_string))
|
|
|
|
{
|
|
|
|
throw new ApplicationException("Failed to build extension list. Is there an opengl context current?");
|
|
|
|
}
|
|
|
|
|
|
|
|
string version;
|
|
|
|
|
|
|
|
// Most drivers return the version in the 3 first characters of the version string,
|
|
|
|
// (e.g. on Ati X1950 with Catalyst 7.10 -> "2.0.6956 Release"). However, Mesa seems
|
|
|
|
// to do something strange: "1.4 (2.1 Mesa 7.0.1).".
|
2008-03-03 12:44:56 +00:00
|
|
|
// Update: this seems to occur with indirect rendering. E.g. Ati 8.2: 1.4 (2.1.7281 ...)
|
2007-11-10 18:11:34 +00:00
|
|
|
// We'll do some trickery to get the second number (2.1), but this may break on
|
|
|
|
// some implementations...
|
2008-03-03 12:44:56 +00:00
|
|
|
//if (version_string.ToLower().Contains("mesa"))
|
2007-11-10 18:11:34 +00:00
|
|
|
{
|
|
|
|
int index = version_string.IndexOf('(');
|
|
|
|
if (index != -1)
|
|
|
|
version = version_string.Substring(index + 1, 3);
|
|
|
|
else
|
|
|
|
version = version_string.TrimStart(' ');
|
|
|
|
}
|
2008-03-03 12:44:56 +00:00
|
|
|
//else
|
|
|
|
// version = version_string.TrimStart(' ');
|
2007-11-10 18:11:34 +00:00
|
|
|
|
|
|
|
Debug.Print(version);
|
|
|
|
|
|
|
|
if (version.StartsWith("1.2"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
}
|
|
|
|
else if (version.StartsWith("1.3"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_3", true);
|
|
|
|
}
|
|
|
|
else if (version.StartsWith("1.4"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_3", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_4", true);
|
|
|
|
}
|
|
|
|
else if (version.StartsWith("1.5"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_3", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_4", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_5", true);
|
|
|
|
}
|
|
|
|
else if (version.StartsWith("2.0"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_3", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_4", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_5", true);
|
|
|
|
AvailableExtensions.Add("gl_version_2_0", true);
|
|
|
|
}
|
|
|
|
else if (version.StartsWith("2.1"))
|
|
|
|
{
|
|
|
|
AvailableExtensions.Add("gl_version_1_1", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_2", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_3", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_4", true);
|
|
|
|
AvailableExtensions.Add("gl_version_1_5", true);
|
|
|
|
AvailableExtensions.Add("gl_version_2_0", true);
|
|
|
|
AvailableExtensions.Add("gl_version_2_1", true);
|
|
|
|
}
|
|
|
|
|
2008-02-02 00:25:54 +00:00
|
|
|
string extension_string = GL.GetString(StringName.Extensions);
|
2007-11-10 18:11:34 +00:00
|
|
|
if (String.IsNullOrEmpty(extension_string))
|
|
|
|
return; // no extensions are available
|
|
|
|
|
|
|
|
string[] extensions = extension_string.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (string ext in extensions)
|
|
|
|
AvailableExtensions.Add(ext.ToLower(), true);
|
|
|
|
|
|
|
|
foreach (string s in AvailableExtensions.Keys)
|
|
|
|
Debug.Print(s);
|
|
|
|
|
|
|
|
rebuildExtensionList = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-09-22 14:59:33 +00:00
|
|
|
#region --- GetProcAddress ---
|
|
|
|
|
|
|
|
private static IGetProcAddress getProcAddress;
|
|
|
|
|
|
|
|
internal interface IGetProcAddress
|
|
|
|
{
|
|
|
|
IntPtr GetProcAddress(string function);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal class GetProcAddressWindows : IGetProcAddress
|
|
|
|
{
|
2007-09-22 15:07:28 +00:00
|
|
|
[System.Runtime.InteropServices.DllImport(Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true)]
|
|
|
|
private static extern IntPtr wglGetProcAddress(String lpszProc);
|
|
|
|
|
2007-09-22 14:59:33 +00:00
|
|
|
public IntPtr GetProcAddress(string function)
|
|
|
|
{
|
2007-09-22 15:07:28 +00:00
|
|
|
return wglGetProcAddress(function);
|
2007-09-22 14:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal class GetProcAddressX11 : IGetProcAddress
|
|
|
|
{
|
2007-09-22 15:07:28 +00:00
|
|
|
[DllImport(Library, EntryPoint = "glXGetProcAddress")]
|
|
|
|
private static extern IntPtr glxGetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
|
|
|
|
|
2007-09-22 14:59:33 +00:00
|
|
|
public IntPtr GetProcAddress(string function)
|
|
|
|
{
|
2007-09-22 15:07:28 +00:00
|
|
|
return glxGetProcAddress(function);
|
2007-09-22 14:59:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
internal class GetProcAddressOSX : IGetProcAddress
|
|
|
|
{
|
2007-09-22 15:07:28 +00:00
|
|
|
private const string Library = "libdl.dylib";
|
|
|
|
|
|
|
|
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
|
|
|
private static extern bool NSIsSymbolNameDefined(string s);
|
|
|
|
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
|
|
|
private static extern IntPtr NSLookupAndBindSymbol(string s);
|
|
|
|
[DllImport(Library, EntryPoint = "NSAddressOfSymbol")]
|
|
|
|
private static extern IntPtr NSAddressOfSymbol(IntPtr symbol);
|
|
|
|
|
2007-09-22 14:59:33 +00:00
|
|
|
public IntPtr GetProcAddress(string function)
|
|
|
|
{
|
|
|
|
string fname = "_" + function;
|
2007-09-22 15:07:28 +00:00
|
|
|
if (!NSIsSymbolNameDefined(fname))
|
2007-09-22 14:59:33 +00:00
|
|
|
return IntPtr.Zero;
|
|
|
|
|
2007-09-22 15:07:28 +00:00
|
|
|
IntPtr symbol = NSLookupAndBindSymbol(fname);
|
2007-09-22 14:59:33 +00:00
|
|
|
if (symbol != IntPtr.Zero)
|
2007-09-22 15:07:28 +00:00
|
|
|
symbol = NSAddressOfSymbol(symbol);
|
2007-09-22 14:59:33 +00:00
|
|
|
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#region private static IntPtr GetAddress(string function)
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Retrieves the entry point for a dynamically exported OpenGL function.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The function string for the OpenGL function (eg. "glNewList")</param>
|
|
|
|
/// <returns>
|
|
|
|
/// An IntPtr contaning the address for the entry point, or IntPtr.Zero if the specified
|
|
|
|
/// OpenGL function is not dynamically exported.
|
|
|
|
/// </returns>
|
|
|
|
/// <remarks>
|
|
|
|
/// <para>
|
|
|
|
/// The Marshal.GetDelegateForFunctionPointer method can be used to turn the return value
|
|
|
|
/// into a call-able delegate.
|
|
|
|
/// </para>
|
|
|
|
/// <para>
|
|
|
|
/// This function is cross-platform. It determines the underlying platform and uses the
|
|
|
|
/// correct wgl, glx or agl GetAddress function to retrieve the function pointer.
|
|
|
|
/// </para>
|
|
|
|
/// <see cref="Marshal.GetDelegateForFunctionPointer"/>
|
|
|
|
/// <seealso cref="Gl.GetDelegateForExtensionMethod"/>
|
|
|
|
/// </remarks>
|
|
|
|
private static IntPtr GetAddress(string function)
|
|
|
|
{
|
|
|
|
if (getProcAddress == null)
|
|
|
|
{
|
|
|
|
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT ||
|
|
|
|
System.Environment.OSVersion.Platform == PlatformID.Win32S ||
|
|
|
|
System.Environment.OSVersion.Platform == PlatformID.Win32Windows ||
|
|
|
|
System.Environment.OSVersion.Platform == PlatformID.WinCE)
|
|
|
|
{
|
|
|
|
getProcAddress = new GetProcAddressWindows();
|
|
|
|
}
|
|
|
|
else if (System.Environment.OSVersion.Platform == PlatformID.Unix)
|
|
|
|
{
|
|
|
|
getProcAddress = new GetProcAddressX11();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new PlatformNotSupportedException(
|
|
|
|
"Extension loading is only supported under X11 and Windows. We are sorry for the inconvience.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return getProcAddress.GetProcAddress(function);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-09-22 15:07:28 +00:00
|
|
|
#region internal static Delegate GetExtensionDelegate(string name, Type signature)
|
2007-09-22 14:59:33 +00:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="name">The name of the OpenGL function (eg. "glNewList")</param>
|
|
|
|
/// <param name="signature">The signature of the OpenGL function.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// A System.Delegate that can be used to call this OpenGL function or null
|
|
|
|
/// if the function is not available in the current OpenGL context.
|
|
|
|
/// </returns>
|
2007-09-22 15:07:28 +00:00
|
|
|
internal static Delegate GetExtensionDelegate(string name, Type signature)
|
2007-09-22 14:59:33 +00:00
|
|
|
{
|
|
|
|
IntPtr address = GetAddress(name);
|
|
|
|
|
|
|
|
if (address == IntPtr.Zero ||
|
|
|
|
address == new IntPtr(1) || // Workaround for buggy nvidia drivers which return
|
|
|
|
address == new IntPtr(2)) // 1 or 2 instead of IntPtr.Zero for some extensions.
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return Marshal.GetDelegateForFunctionPointer(address, signature);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#endregion
|
2007-10-26 13:12:24 +00:00
|
|
|
|
|
|
|
#region --- GL Overloads ---
|
|
|
|
|
|
|
|
#region public static void Color[34]() overloads
|
|
|
|
|
2007-12-09 19:54:47 +00:00
|
|
|
public static void Color3(System.Drawing.Color color)
|
|
|
|
{
|
|
|
|
GL.Color3(color.R, color.G, color.B);
|
|
|
|
}
|
|
|
|
|
2007-10-26 13:12:24 +00:00
|
|
|
public static void Color4(System.Drawing.Color color)
|
|
|
|
{
|
|
|
|
GL.Color4(color.R, color.G, color.B, color.A);
|
|
|
|
}
|
|
|
|
|
2007-12-09 19:54:47 +00:00
|
|
|
public static void Color3(Vector3 color)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
2007-12-09 19:54:47 +00:00
|
|
|
GL.Color3(color.X, color.Y, color.Z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Color4(Vector4 color)
|
|
|
|
{
|
|
|
|
GL.Color4(color.X, color.Y, color.Z, color.W);
|
2007-10-26 13:12:24 +00:00
|
|
|
}
|
|
|
|
|
2007-12-09 19:54:47 +00:00
|
|
|
|
2007-10-26 13:12:24 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public static void ClearColor() overloads
|
|
|
|
|
|
|
|
public static void ClearColor(System.Drawing.Color color)
|
|
|
|
{
|
|
|
|
GL.ClearColor(color.R/255.0f, color.G/255.0f, color.B/255.0f, color.A/255.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region overloads using OpenTK.Math classes
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Normal3(Vector3 normal)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glNormal3f(normal.X, normal.Y, normal.Z);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void RasterPos2(Vector2 pos)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glRasterPos2f(pos.X, pos.Y);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void RasterPos3(Vector3 pos)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glRasterPos3f(pos.X, pos.Y, pos.Z);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void RasterPos4(Vector4 pos)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glRasterPos4f(pos.X, pos.Y, pos.Z, pos.W);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Vertex2(Vector2 v)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glVertex2f(v.X, v.Y);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Vertex3(Vector3 v)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glVertex3f(v.X, v.Y, v.Z);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Vertex4(Vector4 v)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glVertex4f(v.X, v.Y, v.Z, v.W);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void TexCoord2(Vector2 v)
|
|
|
|
{
|
|
|
|
Delegates.glTexCoord2f(v.X, v.Y);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void TexCoord3(Vector3 v)
|
|
|
|
{
|
|
|
|
Delegates.glTexCoord3f(v.X, v.Y, v.Z);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void TexCoord4(Vector4 v)
|
|
|
|
{
|
|
|
|
Delegates.glTexCoord4f(v.X, v.Y, v.Z, v.W);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Rotate(Single angle, Vector3 axis)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glRotatef((Single)angle, axis.X, axis.Y, axis.Z);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Scale(Vector3 scale)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glScalef(scale.X, scale.Y, scale.Z);
|
|
|
|
}
|
|
|
|
|
2007-11-06 21:01:07 +00:00
|
|
|
public static void Translate(Vector3 trans)
|
2007-10-26 13:12:24 +00:00
|
|
|
{
|
|
|
|
Delegates.glTranslatef(trans.X, trans.Y, trans.Z);
|
|
|
|
}
|
|
|
|
|
2008-04-11 19:33:56 +00:00
|
|
|
public static void MultMatrix(ref Matrix4 mat)
|
2007-11-10 18:53:25 +00:00
|
|
|
{
|
2008-04-11 19:33:56 +00:00
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
fixed (Single* m_ptr = &mat.Row0.X)
|
|
|
|
{
|
|
|
|
Delegates.glMultMatrixf((Single*)m_ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void LoadMatrix(ref Matrix4 mat)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
fixed (Single* m_ptr = &mat.Row0.X)
|
|
|
|
{
|
|
|
|
Delegates.glLoadMatrixf((Single*)m_ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void LoadTransposeMatrix(ref Matrix4 mat)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
fixed (Single* m_ptr = &mat.Row0.X)
|
|
|
|
{
|
|
|
|
Delegates.glLoadTransposeMatrixf((Single*)m_ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void MultTransposeMatrix(ref Matrix4 mat)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
fixed (Single* m_ptr = &mat.Row0.X)
|
|
|
|
{
|
|
|
|
Delegates.glMultTransposeMatrixf((Single*)m_ptr);
|
|
|
|
}
|
|
|
|
}
|
2007-11-10 18:53:25 +00:00
|
|
|
}
|
|
|
|
|
2007-12-09 19:54:47 +00:00
|
|
|
public static void Materialv(MaterialFace face, MaterialParameter pname, Vector4 @params)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
Materialv(face, pname, &@params.X);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-26 13:12:24 +00:00
|
|
|
#endregion
|
|
|
|
|
2007-11-10 23:29:25 +00:00
|
|
|
#region public static void ShaderSource(Int32 shader, System.String @string)
|
|
|
|
|
|
|
|
public static void ShaderSource(Int32 shader, System.String @string)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
int length = @string.Length;
|
|
|
|
Delegates.glShaderSource((UInt32)shader, 1, new string[] { @string }, &length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region public static void GetShaderInfoLog(Int32 shader, out string info)
|
|
|
|
|
|
|
|
public static void GetShaderInfoLog(Int32 shader, out string info)
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
|
|
|
int length;
|
2008-01-04 17:16:43 +00:00
|
|
|
GL.GetShader(shader, ShaderParameter.InfoLogLength, out length);
|
2007-11-10 23:29:25 +00:00
|
|
|
if (length == 0)
|
|
|
|
{
|
|
|
|
info = "";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder(length);
|
|
|
|
Delegates.glGetShaderInfoLog((UInt32)shader, sb.Capacity, &length, sb);
|
|
|
|
info = sb.ToString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2008-01-04 17:16:43 +00:00
|
|
|
#region public static void PointParameter(PointSpriteCoordOriginParameter param)
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Helper function that defines the coordinate origin of the Point Sprite.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="param">
|
2008-02-02 00:58:26 +00:00
|
|
|
/// A OpenTK.Graphics.OpenGL.GL.PointSpriteCoordOriginParameter token,
|
2008-01-04 17:16:43 +00:00
|
|
|
/// denoting the origin of the Point Sprite.
|
|
|
|
/// </param>
|
|
|
|
public static void PointParameter(PointSpriteCoordOriginParameter param)
|
|
|
|
{
|
|
|
|
GL.PointParameter(PointParameterName.PointSpriteCoordOrigin, (int)param);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
2007-10-26 13:12:24 +00:00
|
|
|
#endregion
|
2007-07-23 00:15:18 +00:00
|
|
|
}
|
|
|
|
}
|