【发布时间】:2011-08-26 08:42:22
【问题描述】:
目前我正在使用从registry 找到的 Khronos .spec 文件自动生成的 C# OpenGL 绑定。
我对绑定质量非常满意;这是一个函数示例:
/// <summary>
/// Binding for glGenFramebuffers function.
/// </summary>
/// <remarks>
/// This function belongs to 'ARB_framebuffer_object'.
/// <para>
/// Depending on driver implementation, this routine could call the following (equivalent) routines:
/// - glGenFramebuffers
/// - glGenFramebuffersEXT
/// </para>
/// </remarks>
/// <param name="n">
/// A <see cref="Int32"/>.
/// </param>
/// <param name="framebuffers">
/// A <see cref="UInt32*"/>.
/// This parameter holds data returned from function.
/// </param>
public static void GenFramebuffer(Int32 n, [Out] UInt32[] framebuffers) {
unsafe {
fixed (UInt32* fp_framebuffers = framebuffers)
{
if (Delegates.pglGenFramebuffers != null)
Delegates.pglGenFramebuffers(n, fp_framebuffers);
else if (Delegates.pglGenFramebuffersEXT != null)
Delegates.pglGenFramebuffersEXT(n, fp_framebuffers);
else
throw new InvalidOperationException("binding point GenFramebuffer cannot be found");
}
}
LogProc("glGenFramebuffers("+n+", "+framebuffers+")");
}
如您所见,固定块正在尝试调用两个不同的委托(Delegates.pglGenFramebuffers 和 Delegates.pglGenFramebuffersEXT)。
这是可能的,因为它们具有相同的签名:
[System.Security.SuppressUnmanagedCodeSecurity()]
internal unsafe delegate void glGenFramebuffers(Int32 n, [Out] UInt32* framebuffers);
internal static glGenFramebuffers pglGenFramebuffers = null;
[System.Security.SuppressUnmanagedCodeSecurity()]
internal unsafe delegate void glGenFramebuffersEXT(Int32 n, [Out] UInt32* framebuffers);
internal static glGenFramebuffersEXT pglGenFramebuffersEXT = null;
委托具有相同的签名,因为规范(.spec 文件)对于两个例程是相同的,由不同的扩展引入。
以前,绑定仅支持核心、ARB 和 EXT 扩展;绑定生成器只是避免在存在另一个具有更高优先级的等效例程的情况下定义这些例程。
为了增加扩展支持(由SO question 刺激),我还需要为那些已提升为 ARB 或核心实现的例程声明委托和导入声明,并编写一个调用所有等效例程的包装器实现(那些被定义的)。
这样我就得到了上面声明的源码。
问题从处理 2K+ 函数声明开始。我有一个绑定生成器,因为我无法编写所有的 OpenGL 绑定。
但是绑定生成器如何知道一个例程 func 在语义上是否等同于另一个例程 funcARB 或 funcEXT(具有相同的签名)?
我认为我唯一的选择是编写一个列出异常情况的外部文件(开发人员控制)(即两个具有相同名称和相同签名的例程在语义上不等效)。
最终目标应该是一个大部分折叠的 OpenGL 绑定包装库,以最大限度地减少管理 OpenGL 扩展所需的工作量。
经过一些实验……
可能同时实现了两个匹配的扩展(即 ARB_framebuffer_object 和 EXT_framebuffer_object)。由于入口点不同(不同的名称),我需要两个扩展的所有功能......但是!
如果我优先考虑支持的扩展(比如 ARB 的优先级高于 EXT,EXT 的优先级高于 VENDOR),我的问题中提出的实现对于包装框架是可以接受的,因为实现了 ARB 扩展,框架实现比 EXT 实现更喜欢它(不管是什么功能)。
这可行,但副作用是该策略被强制用于 OpenGL 绑定的用户(目前没有人!所以,没有人会抱怨这个!:))。
【问题讨论】: