using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; namespace StgSharp.Graphics { public unsafe partial class Form { internal GLcontext* glContext; private int missingAPIcount = 0; private int problemAPIcount = 0; public unsafe IntPtr LoadGLfunc([MarshalAs(UnmanagedType.LPStr)] string name) { IntPtr ret = InternalIO.glfw.GetProcAddress(name); if (ret == default) { InternalIO.InternalWriteLog( $"Cannot load OpenGL api called {name}, this api may not exist or supported.", LogType.Warning); missingAPIcount++; return ret; } return ret; } public unsafe void LoadGlapi() { GLcontext* context = (GLcontext*)InternalIO.internalCreatGLcontext(LoadGLfunc); if ((ulong)context == 0) { throw new Exception($"Failed to load OpenGL api for current context \"{(ulong)glContext}\""); } //check out if all api is converted correctely. FieldInfo[] fieldInfos = typeof(GLcontext).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); string problemLog = "Have problem in converting the fallowing GL API to C# delegates:\n"; foreach (FieldInfo item in fieldInfos) { if (item.FieldType.Name.Contains("PFNG")) { if (item.GetValue(*glContext) == null) { problemLog += item.Name + ","; problemAPIcount++; } } } InternalIO.InternalWriteLog(problemLog, LogType.Error); if (problemAPIcount > missingAPIcount) { InternalIO.InternalWriteLog("Attempt to reload GL APIs", LogType.Info); //use IntPtr as interface GLcontextIO* iopack = (GLcontextIO*)context; FieldInfo[] source = typeof(GLcontextIO).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo item in source) { if (item.FieldType.IsSubclassOf(typeof(Delegate)) && item.GetValue(*context) == null) { IntPtr funcPtr = LoadGLfunc(item.Name); if (funcPtr != IntPtr.Zero) { try { Delegate dele = Marshal.GetDelegateForFunctionPointer(funcPtr, item.FieldType); item.SetValue(*context, dele); } catch (Exception ex) { InternalIO.InternalWriteLog( $"{ex.Message}", LogType.Error); } } } } } glContext = context; GL.gl = glContext; } } }