Skip to content

GL \ Procedures query

Luca Piccioni edited this page Nov 15, 2017 · 6 revisions

Procedures query

OpenGL.Net support various APIs, which function pointers are loaded at run-time. This is performed by calling Gl.BindAPI() method, just after an OpenGL context is made current on the current thread. This method loads the specific OpenGL implementation pointers for the current thread (threads have local storage for every function pointer, hence this function shall be called for each thread). If you use the DeviceContext you don't have to worry about calling Gl.BindAPI() yourself.

Commands filtering and deprecation

OpenGL.Net loads only those methods that are required for the current GL context, having a specific version (i.e. OpenGL 4.5), having a peculiar set of extensions supported and, if supported, a specific profile (i.e. core or compatibility). It is aware of the deprecation model, and it is aware of the context profiles too.

Take the glGetPointerv method as example:

[RequiredByFeature("GL_VERSION_1_1")]
[RequiredByFeature("GL_VERSION_4_3")]
[RequiredByFeature("GL_VERSION_4_3", Profile = "core")]
[RequiredByFeature("GL_VERSION_ES_CM_1_0", Api = "gles1")]
[RequiredByFeature("GL_ES_VERSION_3_2", Api = "gles2")]
[RequiredByFeature("GL_EXT_vertex_array")]
[RequiredByFeature("GL_KHR_debug")]
[RequiredByFeature("GL_KHR_debug", Api = "gles2")]
[RemovedByFeature("GL_VERSION_3_2", Profile = "core")]
public static void GetPointer(GetPointervPName pname, out IntPtr @params)

The command is loaded or not depending on the current OpenGL context. Here some examples:

  • If context is GL 1.4, it will load it.
  • If context is GL 3.2, compatibility profile, it will load it.
  • If context is GL 3.2, core profile, it will not load it.
  • If context is GL >=4.3, core profile, it will load it.
  • If context is GL (or GLES2), and the extension GL_KHR_debug is supported, it will load it.
  • If context is GLES 2.0, it will not load it.

Function aliasing

OpenGL.Net is aware of function aliases. Indeed there is a chance to execute a core function or an extension functions, depending on the current OpenGL implementation offered by the driver.

However, OpenGL.Net does not declare a method for each entry point available. Instead, make use of the function aliasing to scale the execution of the implementation currently available. Indeed a method can actually point to one of the many (aliasing) functions. For example, consider the following code:

[AliasOf("glGenBuffersARB")]
[RequiredByFeature("GL_VERSION_1_5")]
[RequiredByFeature("GL_VERSION_ES_CM_1_0", Api = "gles1")]
[RequiredByFeature("GL_ES_VERSION_2_0", Api = "gles2")]
[RequiredByFeature("GL_ARB_vertex_buffer_object")]
public static void GenBuffers(UInt32[] buffers) { ... }

It means that glGenBuffers can be aliased by glGenBuffers (core API, including ES variants) or glGenBuffersARB (defined by the GL_ARB_vertex_buffer_object_extension). But, which is the function actually called if multiple entry points are available?

The OpenGL.Net procedure loader prefers the following entry points, in that order:

  • Core API functions
  • ARB extension functions (ARB suffix)
  • EXT extension functions (EXT suffix)
  • Vendor-specific extension functions (i.e. _NV, _AMD, _INTEL...)

The actual aliases are filtered depending on the current context: OpenGL.Net is aware about GL API versions and profiles.

Platform library

The library used for querying/loading OpenGL function pointers depends on the version of the current OpenGL context and on the current OS. The currently supported/detectable APIs by Gl.BindAPI() are:

  • OpenGL (up to 4.5)
  • OpenGL ES
  • OpenGL ES 2+ (up to 3.2)

You can find more precise information about on Platform page.

Automatic error checking (debug only builds)

Every function is checked against errors automatically; in this way is is possible to spot any error as soon it is generated, facilitating the application debugging. However, this feature is available only on debug builds.

Undefined function pointer

In the the user executes a function currently undefined on the running system, the method will throw a NullReferenceException. However, if running with a debug build, an assertion is executed with a descriptive message.