Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

martinsm

By: a guest on Mar 20th, 2010  |  syntax: C#  |  size: 3.75 KB  |  views: 247  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. using System;
  2. using System.Reflection;
  3. using System.Reflection.Emit;
  4. using System.Collections.Generic;
  5. using System.Runtime.InteropServices;
  6.  
  7. namespace OpenGL
  8. {
  9.     static class GL
  10.     {
  11.         public static unsafe class Private
  12.         {
  13.             [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  14.             public delegate void glCullFace(int mode);
  15.             public static glCullFace CullFace;
  16.  
  17.             [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  18.             public delegate void glFrontFace(int mode);
  19.             public static glFrontFace FrontFace;
  20.         }
  21.     }
  22.  
  23.     static class Loader
  24.     {
  25.         static IntPtr opengl;
  26.  
  27.         public static void Load()
  28.         {
  29.             opengl = Native.LoadLibrary("opengl32.dll");
  30.  
  31.             foreach (var field in typeof(OpenGL.GL.Private).GetFields())
  32.             {
  33.                 Type type = field.FieldType;
  34.                 string name = type.Name;
  35.  
  36.                 IntPtr ptr = Native.wglGetProcAddress(name);
  37.                 if (ptr == IntPtr.Zero)
  38.                 {
  39.                     ptr = Native.GetProcAddress(opengl, name);
  40.                 }
  41.  
  42.                 field.SetValue(null, GetDelegate(ptr, type));
  43.             }
  44.         }
  45.  
  46.         public static void Unload()
  47.         {
  48.             foreach (var field in typeof(OpenGL.GL.Private).GetFields())
  49.             {
  50.                 field.SetValue(null, null);
  51.             }
  52.             Native.FreeLibrary(opengl);
  53.         }
  54.  
  55.         static object GetDelegate(IntPtr ptr, Type type)
  56.         {
  57.             //return Convert.ChangeType(Marshal.GetDelegateForFunctionPointer(ptr, type), type);
  58.  
  59.             var invoke = type.GetMethod("Invoke");
  60.             var retType = invoke.ReturnType;
  61.             var parameters = invoke.GetParameters();
  62.             var argCount = parameters.Length;
  63.             var argTypes = new Type[argCount];
  64.  
  65.             for (int i = 0; i < argCount; i++)
  66.             {
  67.                 argTypes[i] = parameters[i].ParameterType;
  68.             }
  69.  
  70.             var method = new DynamicMethod(type.Name + "_Method", retType, argTypes, typeof(Loader), true);
  71.             var il = method.GetILGenerator();
  72.  
  73.             if (argCount > 0) il.Emit(OpCodes.Ldarg_0);
  74.             if (argCount > 1) il.Emit(OpCodes.Ldarg_1);
  75.             if (argCount > 2) il.Emit(OpCodes.Ldarg_2);
  76.             if (argCount > 3) il.Emit(OpCodes.Ldarg_3);
  77.             for (int i = 4; i < argCount; i++)
  78.             {
  79.                 il.Emit(OpCodes.Ldarg_S, i);
  80.             }
  81.             if (sizeof(int) == IntPtr.Size)
  82.             {
  83.                 il.Emit(OpCodes.Ldc_I4, ptr.ToInt32());
  84.             }
  85.             else
  86.             {
  87.                 il.Emit(OpCodes.Ldc_I8, ptr.ToInt64());
  88.             }
  89.             il.EmitCalli(OpCodes.Calli, CallingConvention.Cdecl, retType, argTypes);
  90.  
  91. #if DEBUG
  92.             if (type != typeof(OpenGL.GL.Private.glGetError))
  93.             {
  94.                 var check = typeof(Loader).GetMethod("CheckGLErrors", BindingFlags.Static | BindingFlags.NonPublic);
  95.                 il.EmitCall(OpCodes.Call, check, null);
  96.             }
  97. #endif
  98.             il.Emit(OpCodes.Ret);
  99.  
  100.             return method.CreateDelegate(type);
  101.         }
  102.  
  103.         static void CheckGLErrors()
  104.         {
  105.             var err = OpenGL.GL.GetError();
  106.             if (err != OpenGL.GL.ErrorCode.NoError)
  107.             {
  108.                 var errors = new List<string>(1);
  109.                 while (err != OpenGL.GL.ErrorCode.NoError)
  110.                 {
  111.                     errors.Add(err.ToString());
  112.                     err = OpenGL.GL.GetError();
  113.                 }
  114.                 throw new ApplicationException("OpenGL error(s): " + String.Join(", ", errors.ToArray()));
  115.             }
  116.         }
  117.     }
  118. }