Skip to content

GL \ Version and extensions query

Luca Piccioni edited this page Apr 13, 2017 · 3 revisions

Versions and Extensions

Scope

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.

Versions

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

Extensions

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

Experimental extensions

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

Platform APIs

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.