Samuel wrote:Thank you luis for all the information.
You are wellllllcome.
Samuel wrote:
I forgot to mention in my last post that importing glDrawArrays from Opengl32.lib solves my problem.
Good. I noticed something was missing
Samuel wrote:
On the other platforms what would be the best way of testing if a function is available for use if I can't rely on the functions return values?
Actually I've already answered that, the right thing to do on any platform is:
5) Unless you are using a specific OpenGL version with a CORE profile where you can rely on having all the core functions available, when you use any GL function above 1.2 in a compatibility profile (like PB does) or a plain old legacy one (<= 2.1) you should always test for the presence of the extension and only then use the commands provided by that (see point 4).
Testing for the OpenGL version may be ok for a broader test but often things are available as extensions in drivers long before they become core in a higher version.
I'll try to explain it better.
I'll tell you even something extra not strictly pertinent to your question so maybe this post can be useful to other people since with all the types of rendering contexts nowadays available in OpenGL this is often cause of confusion.
I'm talking mainly Windows only here, on other OSes the principle is more or less the same anyway, some stuff by other names. In Win you use wgl_ functions, in linux you'll have similar glx_ functions, in Win you look for a certain "pixel format" in linux the equivalent is a "visual", etc.
In OpenGL one of the first things you have to decide is the type of RC you want to work with.
There are three types, two "official" and one I call "legacy". Let's start with the last one, the oldest type available.
The legacy RC.
This is the one you get when you ask for a RC to a GL driver supporting only 2.1 or lower.
A driver <= 2.1 does not know of any other type of RC, and can give you only this type of RC.
This is the oldest type, with which you can use all legacy GL commands from 1.1 up to <= 2.1.
Shaders are supported only in version 2.0 and 2.1.
If I were to target an absolute minimum for a new software I would ask the user to have a driver supporting GL 2.1.
So I could have a reasonable modern GL implementation, I could use shaders, I would have a lot of powerful commands previously supported only as extensions now promoted to core functions in 2.1 and I would need only a very limited number of extensions (probably 2 or 3).
One would certainly be
ARB_FrameBuffer_object which is usually available without problems on 2.1 hardware.
How does it work:
In Windows you select a pixel format supporting the features you need (double buffer, depth buffer size, etc.),
then you ask for the RC with wglCreateContext_(hDC),
and then you make the context current with wglMakeCurrent_(hDC, hRC).
When you ask for the RC, you get a RC associated to the highest version of OpenGL supported by that driver.
So if the drivers supports GL 1.5, you get that. If the drivers supports GL 2.1, you get that.
Simple.
The RC for the CORE PROFILE.
This is the one you get when the GL driver is recent enough and you ask explicitly for a precise version and for a CORE PROFILE.
Modern GL is considered anything above 3.0, but for all practical purposes you can consider only 3.2 or higher.
If you want to do CORE GL programming, asks for 3.2 or higher when requesting a RC.
3.0 - 3.1 are a transitional phase no one wants to talk about, where things were behaving differently and those versions had a very short life.
You'll be hard pressed to find in real life a GL driver supporting only 3.0, 3.1. Don't care about them is my suggestion.
Just go for 3.2 or higher.
In the CORE PROFILE, there is a list of deprecated GL commands from the previous versions (almost all come from the 1.1 version really) which are not usable anymore.
You can only use modern GL commands and you can't mix legacy commands with the modern ones.
Also practically all work is done through shaders, and the more traditional GL commands are used mostly to prepare the stage and supply the data.
How does it work:
First you have to ask for a legacy RC (see above), then you use that to import the extension
WGL_ARB_create_context_profile and with that at hand you
ask for another RC, asking for a CORE PROFILE and a specific GL version (>= 3.2).
If WGL_ARB_create_context_profile is not available the driver does not support this mode and you can fallback to use the legacy GL context you already have, which will support at max GL 2.1.
If the extension is present, you will get a RC supporting the AT LEAST (usually EXACTLY) the version you are asking for, or NULL if the version is not supported.
BTW: to know which version of GL your RC does support you use
Code: Select all
PeekS(glGetString_(#GL_VERSION),-1,#PB_Ascii))
and parse the string to extract the version (legacy context only) and use instead
Code: Select all
glGetIntegerv_(#GL_MAJOR_VERSION, @Major)
glGetIntegerv_(#GL_MINOR_VERSION, @Minor)
for a modern CORE PROFILE context.
The RC for the COMPATIBILITY PROFILE
This is the one you get when the GL driver is recent enough (>= 3.2) and:
- you ask explicitly for it: you specify you want a COMPATIBILITY PROFILE instead of a CORE PROFILE by using again WGL_ARB_create_context_profile, asking for an OpenGL version equal to 1.0.
- you ask for a RC like you did for GL <= 2.1 without specify nothing more: you just use wglCreateContext_(hDC) and stop there (this is equivalent to the above steps).
The COMPATIBILITY PROFILE is *OPTIONAL*.
Not all vendors support it.
When it is available, you get the highest GL version supporting it.
You may get an higher GL version asking for a CORE PROFILE.
Sometimes you may get the same highest possible version in both ways (nVidia for example does that and expressed the will to continue to do so).
Real life: afaik INTEL, ATI, NVIDIA all support it, at least on Win and Linux.
Example: you have a nVidia GL 4.3 driver.
You ask for a legacy RC, you get a COMPATIBILITY PROFILE (see above) supporting GL 4.3.
You ask for a COMPATIBILITY PROFILE, you get a COMPATIBILITY PROFILE supporting GL 4.3.
You ask for a CORE PROFILE for the 4.1 version, you get a CORE PROFILE supporting GL 4.1.
You ask for a CORE PROFILE for the 4.5 version, you get NULL.
In OSX, because Apple is what it is, supposing the driver is supporting GL 4.3 again:
You ask for a legacy RC, you get a legacy RC supporting GL 2.1.
You ask for a COMPATIBILITY PROFILE, you get a legacy RC supporting GL 2.1.
You ask for a CORE PROFILE for the 4.1 version, you get a CORE PROFILE supporting GL 4.1.
You ask for a CORE PROFILE for the 4.5 version, you get NULL.
In short, in OSX you get only GL 2.1 when you are note using a CORE PROFILE.
What you do with a COMPATIBILITY PROFILE ? You can use and mix all the GL commands, CORE and legacy, deprecated or not up to the returned GL version.
The result of all this mix and match is up to you.
Back to your question:
Samuel wrote:
On the other platforms what would be the best way of testing if a function is available for use if I can't rely on the functions return values?
On all platforms:
If you are using a CORE PROFILE, and so a GL version > 3.2 you can joyfully use all the functions declared as CORE.
Let's suppose you asked for a 4.0 CORE.
You can use a lot of functions: all the GL commands up to 2.1 (minus the deprecated ones) and all the new commands available in 3.0, 3.1, 3.2. 3.3, 4.0.
You very rarely will need an extension with all that stuff available.
If you do, you'll have to check if the extension is available by collecting and then query the list of the available extensions using
Code: Select all
glGetIntegerv_(#GL_NUM_EXTENSIONS, @Count)
and then a loop from 0 to Count - 1
Code: Select all
PeekS(glGetStringi_(#GL_EXTENSIONS, i), -1, #PB_Ascii)
If the extension is available, you get the address, use a prototype, set the global var to the address, and use it.
If you are using a COMPATIBILITY PROFILE, and so a GL version from 1.1 to the highest supported by the driver in compatibility mode (potentially all the way to the highest) you can use everything.
Legacy, core only, deprecated, and all the supported extensions.
Generally when you ask for a COMPATIBILITY PROFILE, you ask for the highest possible (by conventionally specifying 1.0 as the version), because you want to access all the possible modern stuff while still writing legacy style code occasionally spiced up.
So you just use wglCreateContext_(hDC) and USUALLY (99% of the times) if the driver support a COMPATIBILITY PROFILE, it will returns just that with the highest possible GL version you can use with it.
If you need extensions, again you just test for them, and if available you can use them as seen in the previous example.
The way to retrieve the list of supported extensions differs from legacy and modern mode.
What we saw above was the modern one, the other is discussed below in the legacy section.
In COMPATIBILITY mode you can use actually both, but since probably your code is written legacy style, it's straightforward to use the legacy mode, but both will work.
If you are using a legacy RC, and so a GL version between 1.1 and 2.1, you can use all the functions available up to that version, and all the extensions supported by your driver.
BTW: try to use ARB extensions when more then one type (EXT, SGI, etc.) is available, they are the "standard" way that set of commands will be implemented in higher version as a core functionality.
Again, to use those "recent" or "modern" commands, available only as extensions, you have to check if the extension if present. If it is, same story: you get the address, use a prototype, set the global var to the address, and use it.
To check for extension in legacy mode you have to collect and then query the list of the available extensions using
Code: Select all
*p = glGetString_(#GL_EXTENSIONS)
Buffer$ = PeekS(*p,-1,#PB_Ascii)
and then split the string to the list of the extension names the call returned all concatenated in one string (space separated).
NOTE: I suppose PB simply ask for a legacy RC, so if your driver is 4.10 and supports a COMPATIBILITY PROFILE all the way up to 4.10, that's why you get that and it's thank to that (the driver implementation) you can use all OpenGL commands up to 4.10. A driver could legitimately return only a 2.1 version even when supporting OpenGL 4.5 if it does not include a COMPATIBILITY PROFILE.
Some useful links:
OpenGL version history ->
http://en.wikipedia.org/wiki/OpenGL
about extensions ->
https://www.opengl.org/wiki/OpenGL_Extension
extensions registry ->
https://www.opengl.org/registry/
context creation ->
https://www.opengl.org/wiki/Creating_an ... _%28WGL%29
deprecated, what and when ->
https://www.opengl.org/registry/oldspecs/gl.spec
Hope this helps.