-
Notifications
You must be signed in to change notification settings - Fork 111
GL \ Version and extensions query
Normally, OpenGL applications requires an OpenGL version and uses quite a few extensions to achieve better performances. However, to get this information, the application is required to create a (temporary) OpenGL context in order to execute the necessary methods for retrieving the information.
OpenGL.Net retrieves all information automatically, letting the user to execute all methods without worrying OpenGL version, extensions and limits.
The Gl.CurrentVersion
and Gl.CurrentShadingVersion
defines the OpenGL version and the OpenGL Shading Language version. Their type is KhronosVersion
, indeed compare operators are supported for testing OpenGL versions; in conjunction with the Gl.Version_ constants, you can write if (Gl.Version >= Gl.Version_200) { ... }
.
However, the current OpenGL context version can be different from Gl.CurrentVersion
. To overcome this issue, you can parse the OpenGL context version calling KhronoVersion.Parse
:
KhronosVersion ctxVersion = KhronosVersion.Parse(Gl.GetString(StringName.Version));
The Gl.CurrentExtensions
specifies the currently supported extensions; its type is Gl.Extensions
, which defines for every OpenGL extension the support for the current OpenGL implementation.
Using Gl.CurrentExtensions
can be fast and easy, but there is a problem: the current OpenGL context implementation may support a different set of extensions respect to the ones defined by Gl.CurrentExtensions
. To overcome this issue, users can instantiate their instance of Gl.Extensions
, and query and cache available extensions once an OpenGL context is made current, by calling the Gl.Extensions.Query()
method.
using (DeviceContext device = DeviceContext.Create(display, handle)) {
IntPtr ctx = device.CreateContext(IntPtr.Zero);
if (device.MakeCurrent(ctx) == false)
throw new InvalidOperationException();
// Query context extensions
Gl.Extensions glext = new Gl.Extensions();
glext.Query();
// Now 'glext' fields represent the 'ctx' extensions
if (glext.TextureRectangle_ARB == false)
throw new NotSupportedException();
}
It may be possible that the OpenGL driver actually implements extensions not declared by the standard query mechanism (i.e. glGetStringi). OpenGL.Net can detect those extensions, enabling their usage.
To enable experimental extensions, call one of the Gl.EnableExperimentalExtensions
methods. Note that its possible to pass as argument an Gl.Extensions
instance, which will be updated accordingly with the experimental extensions detected.
Despite of what it seems, it is not necessary to call Gl.EnableExperimentalExtensions
in order to use experimental extensions. OpenGL.Net tries to load all (yes, all) known function pointers from the platform library; indeed, if any experimental method is currently implemented, its function pointers are retrieved anyway.
So, why do you need Gl.EnableExperimentalExtensions
? Because OpenGL.Net does not fake the returned value of glGetStringi
and other related functions. Indeed, the only ways advertise the experimental extension is by using a Gl.Extensions
instance, synchronized by using the dedicated method.
using (DeviceContext device = DeviceContext.Create(display, handle)) {
IntPtr ctx = device.CreateContext(IntPtr.Zero);
if (device.MakeCurrent(ctx) == false)
throw new InvalidOperationException();
// Query context experimental extensions
KhronosVersion ctxVersion = KhronosVersion.Parse(Gl.GetString(StringName.Version));
Gl.Extensions glext = new Gl.Extensions();
glext.Query();
// Update 'glext' fields in case experimental extensions are detected
Gl.EnableExperimentalExtensions(ctxVersion, glext);
// Now 'glext' fields represent the 'ctx' extensions, including the experimental ones
if (glext.ComputeShader_ARB == false)
throw new NotSupportedException();
}
Even Wgl
, Glx
and Egl
classes have their own Extensions type and Current* properties. However, those platform APIs version and extensions are not dependent on the current OpenGL context. Indeed the extension can be directly accesses from the CurrentVersion
and CurrentExtensions
properties.