Files
stgsharp/源代码/StgSharp/Graphics/GL/GLloader.cs
T

103 lines
3.3 KiB
C#

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;
}
}
}