Test if extension is available

Hello,

I am asking me right now, if OpenTK has a helper method, which tests if a certain OpenGL extension is available?

Something like:

public static bool IsExtAvailable(string ext)
{
   return GL.GetString(StringName.Extensions).Contains(ext);
}

Or is there another way to test for extensions at runtime?


Comments

Assuming this ain't an april fool's joke and the question is serious: This is covered by the functions GL.SupportsExtension / GL.SupportsFunction

It might be useful to create an overload with enum as parameter, instead of a string. (to avoid typing errors) Anyone besides objarni votes for that idea? ;)

Thanks!
I looked for Is* or Has* kind of method signature. But I didn't found GL.SupportsExtension. Sorry!

An enum overload would be really useful.

Yeah, I second the enum overload. That would be very useful, if just for the intellisense.

Re: Test if extension is available
posted by georgwaechter

i agree ... an enum overload would be helpful

I STRONGLY DISAGREEE!!!!

.

.

.

.

.

.

.

.

.

.

.

.

Fooled ya! ;)

It's known that you're into coder pr0n and overloads like this are your thing ;)

thanks really cool demo given 256 bytes :)

Re: Test if extension is available
posted by the Fiddler

Something like this would work:

// types found in Source/Bind/Specifications/GL2/gl.tm
enum Extension
{
    VERSION_1_2,
    VERSION_1_3,
    ...
    EXT_texture_integer
}

public static bool SupportsExtension(Extension e)
{
    return SupportsExtension(e.ToString());
}

A prettier solution would be to use a struct with constants:

struct Extension
{
    public const string Version12 = "VERSION_1_2";
    public const string Version13 = "VERSION_1_3";
}

The latter could be added to the generator, although it might be simpler to write by hand (but more boring).

Also happy April's fool!

Mhmm I don't know why the discussion moved to pm's *apologizes*

Imo both solutions have their benefits:

  1. Enum
    The advantage of easy iteration through all extensions for debugging purposes.
    public enum Extension: uint
    {
        VERSION_1_2 =0,
        VERSION_1_3,
        ...
        EXT_texture_integer,
        Last, // reserved for marking the highest/last value in the enum
    }

    The disadvantage of this is obviously that it's not as nice as Extension.Version12 and not "C#-ish" (C) objarni. But on the other hand, it's exactly the token name that GL expects.

    Example:
    GL.SupportsExtension( Extension.WGL_ARB_randomly_chosen_token ); // new enum overload
    GL.SupportsExtension( Extension.WGL_ARB_randomly_chosen_token.ToString() ); // string param

  2. Struct
    Nicer to handle, but requires some extra thinking/understanding how Extension.WglArbRandomlyChosenToken translates into WGL_ARB_randomly_chosen_token.

    Example:
    GL.SupportsExtension( Extension.WglArbRandomlyChosenToken ); // string param

I have no clear favorite, but if you put a pistol to my head I'd say 1) because it's closer to the C API.

Sleeping over it, I created the function using an enum for now. Imo it will be much less confusing to the user, since it's more logical to query for presence of GL_ARB_vertex_buffer_object than GLArbVertexBufferObject. It should also aid in looking up the spec on opengl.org, or googling for tutorials.

The overload can be used like this:

GL.SupportsExtension( GL.Extension.WGL_ARB_randomly_chosen_token ); // new enum overload
GL.SupportsExtension( GL.Extension.WGL_ARB_randomly_chosen_token.ToString() ); // string param

// also nice, we can iterate through all available GL extensions and dump that into a debug log.
for ( int i = 0; i < (int) GL.Extension.Last; i++ )
{
  Debug.WriteLine( ( (GL.Extension) i ).ToString( ) + " available: " + GL.SupportsExtension( (GL.Extension) i ) );
}

This can be simplified using the Enum.GetValues()-method:

foreach(GL.Extension ext in Enum.GetValues(typeof(GL.Extension)))
  Debug.WriteLine(ext.ToString() + " available: " + GL.SupportsExtension(ext));

Only problem is the GL.Extension.Last-value.

I think GL.Extension.Last should be removed from the GL.Extension enum. GL.Extension.Last or something like GL.Extension.Count values are a relict from pre managed times, when one needed such values for iteration or array initialization.
By the way, Enum.GetValues returns Array, so it's no problem to get the Length.

Re: Test if extension is available
posted by the Fiddler

Thanks for the pointer, I'm going to remove 'Last' from this enum, as well as from mouse and keyboard button/keys.

GetValues is actually very inefficient (slow and allocates memory), but its return value can be cached so it won't be a problem.

Just out of curiosity, how slow is it..?

Re: Test if extension is available
posted by the Fiddler

1024 calls take 8ms on my machine and allocate ~250KB of memory, on an enum with 26 values (the alphabet).

Well I don't think it matters much which of the options, it's not the normal use case iterating through all extensions.

What might be interesting is adding custom extensions DIRECTX_9, DIRECTX_10 which returns true if the set of extensions (which represent the functionality) are available. Might be a bad idea though, since Geforce 5, 6 & 7 are all DX9 cards but vary in functionality and performance quite a bit.

Re: Test if extension is available
posted by the Fiddler

Definitely a bad idea, even DX9 hardware differs wildly in capabilities. Testing for specific opengl extensions is the way to go.

What would make sense is automatic detection of Shader Model (2, 3, 4). Here is a good reference, in case someone is interested in implementing this.

The idea was more like the iterate-through-all-extensions for debug purposes. An OpenGL app should indeed rather check for the required extensions than relying on DIRECTX_10, etc. You're right, it's probably not a good idea.

GL.SupportsShadermodel
The problem with testing for a single extension is that it works for Nvidia and Ati cards, but will fail for others although they might support SM3. I'd be interested in such a function, but the torusknot test has proven that you spend way more time kicking your "testers" in the butt to run the test and forward it to you or teaching how to navigate directories and what c&p is. Don't have the nerve to do this again so soon tbh.

Just compiling the SM3 one and fall back to a SM2 one (or fixed-func) is the way to go, unless there's alot of motivated people supporting the testing. It might be best to add this with the the benchmark/diagnostics app, which requires alot of testing anyways.