Best method to check if a function is available

I have a class Texture2D where I need to create a mutable texture with glTexImage2D, or an immutable texture with glTexStorage2D, depending on the availability given by the OpenGL implementation. Reading the specs I saw that glTexStorage2D is present whenever the extension GL_ARB_texture_storage is available, so I assumed that I could use the function whenever GL_ARB_texture_storage is present in one of the strings returned by glGetStringi(GL_EXTENSIONS, i).

My surprise was that glTexStorage2D was missing even having GL_ARB_texture_storage returned by the driver as one of the available extensions. Another weird issue is that the version of OpenGL running in my laptop (a MacBook Air) is 4.1, which I think it should not provide this extension (specification docs include it from version 4.2).

My question here is what method should I trust more, or what is the better way to perform these checks? Directly checking whether or not the individual function pointers are NULL seems to be a failproof, but rather annoying. Another way I can think of is paying attention to the OpenGL version returned by glGetString(GL_VERSION) and trusting the OpenGL specs for the returned version.

Anyway, it wasn’t until now that I didn’t need to use different code depending on the underlying capabilities of the graphics card, so I don’t know which are the best practices in this subject, so any thoughts on this are welcome.

Thank you guys! :slight_smile:

[QUOTE=jesusdz;1287027]Another weird issue is that the version of OpenGL running in my laptop (a MacBook Air) is 4.1, which I think it should not provide this extension (specification docs include it from version 4.2).
[/QUOTE]
Any implementation can provide an extension, regardless of the base OpenGL versions it provides. An implementation providing OpenGL 4.2 doesn’t need to provide the ARB_texture_storage extension as the functionality provided by the extension is an integral part of 4.2.

Query the OpenGL version first. If that isn’t sufficient, and you can use an extension instead, then query the extension. But note that there can be differences between functionality in extensions and in core, e.g. extension functions often have a suffix, or the two may accept different sets of enumerants.

Checking function pointers isn’t appropriate for cross-platform code, as some platforms return pointers to stub functions which will never be null (although the stub may end up calling a null function pointer if the underlying function isn’t supported by the driver).

I would suggest that flipping between glTexStorage and glTexImage in this manner is not recommended. There are differences in the texture object created by either which can be siginificant post-creation; if you’re primarily concerned about backwards compatibility then forget glTexStorage even exists and just create using glTexImage.

[QUOTE=GClements;1287036]Any implementation can provide an extension, regardless of the base OpenGL versions it provides. An implementation providing OpenGL 4.2 doesn’t need to provide the ARB_texture_storage extension as the functionality provided by the extension is an integral part of 4.2.

Query the OpenGL version first. If that isn’t sufficient, and you can use an extension instead, then query the extension. But note that there can be differences between functionality in extensions and in core, e.g. extension functions often have a suffix, or the two may accept different sets of enumerants.

Checking function pointers isn’t appropriate for cross-platform code, as some platforms return pointers to stub functions which will never be null (although the stub may end up calling a null function pointer if the underlying function isn’t supported by the driver).[/QUOTE]

Thank you very much for the answer. I am doing as you suggested: first checking the OpenGL version to know the core features. Whenever the need of using certain functionality (like glTexStorage2D) is more strict, I will also check for the available extensions, and in this case I will try to get the functions from the dynamic library with the proper suffix. I didn’t try yet, but I am quite sure the reason why the function pointer was NULL i because GLAD missed the suffix…