我在C#中编写了一些基本的OpenGL3代码,其中有许多(可怕的)pinvokes。 OpenGL3需要通过OpenGL32.wglGetProcAddress将某些扩展函数(例如wglCreateContextAttribsARB)加载到IntPtr中。为了在C#中使用它们,我需要使用Marshal.GetDelegateForFunctionPointer将函数指针转换为委托。
我想保存我已经加载的函数(因为其中一些被定期使用),并试图通过保留委托的副本来做到这一点(我也存储IntPtrs以防它们变得垃圾收集)。
但是,在某些计算机上(不一致,有时从Visual Studio运行但运行.exe不运行...),wglCreateContextAttribsARB以这种方式保存时返回IntPtr.Zero。但是,如果我在调用函数时,在每次调用期间使用Marshal.GetDelegateForFunctionPointer将函数指针转换为委托,它工作正常......
为什么会这样,并且在每次通话期间进行转换都有开销?请记住,在渲染调用期间会使用其中一些调用,这些调用可能有许多操作(每个基元一个)。
渲染上下文创建代码:
int[] attribs = { (int)ArbCreateContext.MajorVersion, major, (int)ArbCreateContext.MinorVersion, minor, (int)ArbCreateContext.ContextFlags, 0 };
//create temp context to be able to call wglGetProcAddress
IntPtr tempContext = OpenGL32.wglCreateContext(DeviceContext);
if (tempContext == IntPtr.Zero)
throw new Exception("tempContext failed to create.");
if (!OpenGL32.wglMakeCurrent(DeviceContext, tempContext))
throw new Exception("wglMakeCurrent Failed");
OpenGL32.LoadWGLExtensions();
RenderContext = OpenGL32.wglCreateContextAttribsARB(DeviceContext, IntPtr.Zero, attribs);
if (RenderContext == IntPtr.Zero)
throw new HaighException("Something went wrong with wglCreateContextAttribsARB: {0}", Marshal.GetLastWin32Error());
在上面的代码中调用wglCreateContextAttribsARB的代码有时会导致最后的异常:
private static Dictionary<string, IntPtr> _entryPoints = new Dictionary<string, IntPtr>();
private delegate IntPtr DEL_wglCreateContextAttribsARB(IntPtr hDc, IntPtr sharedContext, int[] attribList);
private static DEL_wglCreateContextAttribsARB _wglCreateContextAttribsARB;
public static void LoadWGLExtensions()
{
IntPtr procAddress;
//get the handle to the WGL extension function pointer we need
procAddress = OpenGL32.wglGetProcAddress("wglCreateContextAttribsARB");
if (procAddress == IntPtr.Zero)
throw new Exception("something went wrong with wglGetProcAddress");
//convert intptr to delegate and save the function
_wglCreateContextAttribsARB = (DEL_wglCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(DEL_wglCreateContextAttribsARB));
//store the IntPtr just in case...
_entryPoints.Add("wglCreateContextAttribsARB", procAddress);
}
public static IntPtr wglCreateContextAttribsARB(IntPtr hDc, IntPtr sharedContext, int[] attribList)
{
return _wglCreateContextAttribsARB(hDc, sharedContext, attribList);
}
调用wglCreateContextAttribsARB始终有效的代码:
private static Dictionary<string, IntPtr> _entryPoints = new Dictionary<string, IntPtr>();
private delegate IntPtr DEL_wglCreateContextAttribsARB(IntPtr hDc, IntPtr sharedContext, int[] attribList);
public static void LoadWGLExtensions()
{
IntPtr procAddress;
//get the handle to the WGL extension function pointer we need
procAddress = OpenGL32.wglGetProcAddress("wglCreateContextAttribsARB");
if (procAddress == IntPtr.Zero)
throw new Exception("something went wrong with wglGetProcAddress");
//convert intptr to delegate and save the function
_wglCreateContextAttribsARB = (DEL_wglCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(DEL_wglCreateContextAttribsARB));
//store the IntPtr just in case...
_entryPoints.Add("wglCreateContextAttribsARB", procAddress);
}
public static IntPtr wglCreateContextAttribsARB(IntPtr hDc, IntPtr sharedContext, int[] attribList)
{
return ((DEL_wglCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(_entryPoints["wglCreateContextAttribsARB"], typeof(DEL_wglCreateContextAttribsARB)))(hDc, sharedContext, attribList);
}
答案 0 :(得分:1)
使用chrome.runtime.onMessage.addListener(function(msg) {
console.log(msg.urls)
chrome.tabs.create({url: msg.urls[i]});
})
获得的函数指针与相应的OpenGL上下文相关联。因此,当您存储指针时,必须将它们与从中获取的OpenGL上下文一起存储。基本上你需要一个从一对background-image: url("http://i.imgur.com/7h8ejPJ.png")
映射的字典。
在没有相应的OpenGL上下文激活的情况下调用OpenGL函数指针会导致WGL中出现未定义的行为。