Can I limit OpenGL version to 4.3? - opengl

I have an OpenGL 4.5 capable GPU and I wish to test if my application runs on an OpenGL 4.3 capable system. Can I set my GPU to use OpenGL 4.3?

Can you forcibly limit your OpenGL implementation to a specific version? No. Implementations are permitted to give you any version which is 100% compatible with the one you asked for. And 4.5 is compatible with 4.3.
However, using the right OpenGL loading library, you can forcibly limit your header. Several libraries allow you to generate version-specific headers, which will provide APIs and enums for just that version and nothing else. And any extensions you wish to use.

Related

ARB_texture_storage vs OpenGL hardware version

ARB_texture_storage is a core feature since OpenGL 4.2. The extension had been released before OpenGL 4.2. I would like to determine what is minimum OpenGL version which has to be supported by hardware to use that extension, for example glTexStorage2DARB. The documentations says:
This extension is written against the OpenGL 3.2 Core Profile
specification.
Does it mean that GPU should support at least OpenGL 3.2 ?
ARB_texture_storage is not something that is "supported by hardware". By and large, it is an API improvement; it doesn't expose something which some GPUs can do and others cannot.
As such, in the dependencies section, the extension specification states:
OpenGL ES 1.0, OpenGL ES 2.0 or OpenGL 1.2 is required.
This represents the oldest OpenGL version with which this extension is meaningfully compatible. Of course, you are highly unlikely to find 1.2 implementations in the wild, let alone implementations that are still being supported without implementing higher GL versions.
Basically, most hardware that was/is still having its drivers maintained since the time of this extension's release will have an implementation of it. And outside of open source drivers, most of that hardware will be GL 4.x of some form.
Also, this extension does not have ARB versions of its functions. This is a compatibility extension; it allows you to use GL 4.2 API functionality on hardware that cannot support GL 4.2 (assuming the driver is updated) without forcing you to rename functions or whatever.

Performance gain when using newer Versions over extensions?

For my Application I need a renderer. The renderer uses the OpenGL 3.3 core profile as a basic. In newer OpenGL versions, there are some neat features, which are also available via extensions. If available I want to use newer features, based on the newest OpenGL version. Since it's a mess to test for available versions and adjust the loader, I decided to remain at core 3.3 and use extensions where available (as this are extensions for, right?).
Are Extensions as fast as the same funcionality in newer OpenGL versions?
Let's take the GL_ARB_direct_state_access-extension. It's available in core since 4.5 via Direct State Access. Is the latter faster than the former? I.e. are the functions implemented in newer versions faster than extensions? Or do driver link to the same function anyway?
E: This is not a question about software design rather than about how extensions are handled (mostly?) and about performance.
Actually, the OpenGL API spec XML description has the nice property of alias. A GL function aliasing another one is basically both syntactically and semantically identical to the function it is aliasing - and this feature is used a lot when extension function become promoted to core functionality and have their names changed.
There are GL Loaders out there which actually use that information. Two examples I know of are:
libepoxy
glad2 (glad2 is current in-development branch of the glad loader generator - but I'm using it since 2 years without any issue). You'll have to explicitely enable the aliasing feature. There is also a web service which lets you generate the needed files (note the "aliasing" button on the bottom). Also have a look at the GLAD documentation.
With such a loader, you do not have to care about whether a particular function comes from an extension or from the GL core functionality, you can just use them if they are available somehow.
Also note that with newer extensions, the OpenGL ARB more often is creating ARB extensions without the ARB suffix on the function and enum names, which means that it is describing the exact same entities in any case. This is basically done for extensions which were created after the features were incorporated into the core standard. They just create an extension for it so that a vendor, who might not be able to fulfill some other requirement of the new standard version, is still available to provide the isoltated feature.
One of the first examples of this was the GL_ARB_sync extension, which itself relates to this fact in issue #13:
13) Why don't the entry points/enums have ARB appended?
This functionality is going directly into the OpenGL 3.2 core
and also being defined as an extension for older > platforms at
the same time, so it does not use ARB suffixes, like other such
new features going directly into the GL core.
You wrote :
Let's take the GL_ARB_direct_state_access-extension. It's available in core since 4.5 via Direct State Access. Is the latter faster than the former? I.e. are the functions implemented in newer versions faster than extensions? Or do driver link to the same function anyway?
GL_ARB_direct_state_access falls into the same category as GL_ARB_sync. The GL functions are identified by name, and two entities having the same name means that they are referencing the very same thing. (You can't export two different functions with the same name in a library, and *glGetProcAddress also takes only the name string as input, so it can't decide which version you wanted if there were more than one).
However, it will still depend on your GL loading meachanism how this situation is dealt with, because it might not attempt on loading functions which are not implied by the GL version you got. glad2 for example will just work if you choose it to generate a >= 4.5 loader or to support the GL_ARB_direct_state_access extension.
Since it's a mess to test for available versions and adjust the loader, [...]
Well. That will greatly depend on the loader you are using. As I have shown, there are already options which will basically jsut work, not only in the case of absolute identical function names, but also with aliased functions.
Are Extensions as fast as the same funcionality in newer OpenGL
versions
An extension is sort of a preview of the feature. Many (most?) extensions are included in the standard when a new version arrives, so performance will be equal.
You should look at your target platform(s).
When I run OpenGL Extensions Viewer it tells that my HD3000 supports all features up to 3.1, 70% of 3.2 / 3.3 and 21% of 4.0.
So you can check in advance if the feature you need is implemented on your target platform(s) with the hardware and drivers you want to use. Most recent hardware will support 4.4 / 4.5 because it's been around for years. It's up to you how much you value backwards compatibility.
When I look at Intel graphics since Skylake and beyond it supports 4.4, Skylake is around since 08/2015. All AMD/NVidia hardware will also support 4.4 / 4.5. Note that the support level may very between OS and driver versions.

Testing OpenGL compatibility

I'm having concern about my code which was developed with OpenGL 3.3 hardware level support in mind. However I would like to use certain extesntions, and want to make sure they all require OpenGL version 3.3 or lower before I use them. Let take an example, ARB_draw_indirect. It says that "OpengGL 3.1 is required", however there is according to this document which seems to also state that the extension is not available in 3.3. The problem here is that both of my dev machines have hardware support for 4.5, which means that everything works, including those features that requires OpenGL 4.x. So I would like to know how can I test 3.3 compatibility without having to purchase 3.3 class graphic card? To put it simple, my dev hardware is too powerful compare to what I plan to support, and thus not sure how to test my code.
EDIT: On a related note, there is EXT_direct_state_access extension, and DSA is in the OpenGL 4.5 core profile. The main difference is EXT suffix in function names. Suppose that I want to stick to OpenGL 3.3 support, should I use function names with EXT suffix? Example: TextureParameteriEXT( ) vs TextureParameteri( )
When looking at the versions, it sounds like you're mixing up two aspects. To make this clearer, there are typically two main steps in adding new functionality to OpenGL:
An extension is defined. It can be used on implementations that support the specific extension. When you use it, the entry points will have EXT, ARB, or a vendor name as part of their name.
For some extensions, it is later decided that they should become core functionality. Sometimes the new core functionality might be exactly like the extension, sometimes it might get tweaked while being promoted to core functionality. Once it's core functionality, the entry points will look like any other OpenGL entry point, without any special pre-/postfix.
Now, if you look at an extension specification, and you see:
OpengGL 3.1 is required
This refers to step 1 above. Somebody defined an extension, and says that the extension is based on OpenGL 3.1. So any OpenGL implementation that supports at least version 3.1 can provide support for this extension. It is still an extension, which means it's optional. To use it, you need to:
Have at least OpenGL 3.1.
Test that the extension is available.
Use the EXT/ARB/vendor prefix/postfix in the entry points.
It most definitely does not mean that the functionality is part of core OpenGL 3.1.
If somebody says:
DSA is in the OpenGL 4.5 core profile
This refers to step 2 above. The functionality originally defined in the DSA extension was promoted to core functionality in 4.5. To use this core functionality, you need to:
Have at least OpenGL 4.5.
Not use the EXT/ARB/vendor prefix/postfix in the entry points.
Once an extension is core functionality in the OpenGL version you are targeting, this is typically what you should do. So in this case, you do not use the prefix/postfix anymore.
Making sure that you're only using functionality from your targeted OpenGL version is not as simple as you'd think. Creating an OpenGL context of this version is often not sufficient. Implementations can, and often do, give you a context that supports a higher version. Your specified version is treated as a minimum, not as the exact version you get.
If you work on a platform that requires extension loaders (Windows, Linux), I believe there are some extension loaders that let you generate header files for a specific OpenGL version. That's probably you best option. Other than that, you need to check the specs to verify that the calls you want to use are available in the version you're targeting.

Supporting between GL versions 3.1 and 4.x

Since I've been studying OpenGL, I've been running into a bit of dilemma: while I have a good video card which supports GL 4.3 (nVidia GTX 550 ti model), my laptop is running off of integrated graphics (Intel HD 3000, from an i5-2410M to be exact), which runs version 3.1. I have no idea if this card is even capable of supporting OpenGL 3.2.
Either way, if it turns out that a driver update is all that's needed for core i3/i5 processors to support OpenGL 3.2+, I'm still not sure where I should look or what exactly I need to pay attention to in order support between 3.x and 4.x.
For example, AFAIK GLSL 1.4 doesn't support a shader which uses the layout(location=x) in blah blah feature. But, does GLSL 1.5?
What about preprocessor directives in C/C++ as well as GLSL which I can use to distinguish between what features work with what? Or, is it more recommended (in either GLSL's or C/C++'s case) to just write completely separate header/source/shader files which take care of this?
Since I only plan to be supporting 3.x to 4.x, I know this should be simpler than it very well could be.
Update
After a recent driver update on my laptop, it turns out that, as Nicol Bolas also stated, there currently is not (and likely won't ever be) any support for 3.2 on Intel 3000 cards. Therefore, to make this question simpler, I'd like to know what shading language features (be it in an answer or an external URL) I can and cannot implement on version 3.1 in comparison to 3.3 and above. Any OpenGL specific C/C++ features/functions which pertain to this would also be appreciated.
My goal is to basically be able to know what I have to do in order to mediate between the project I'm working on (which is currently using a GL 4.0 context) to be compatible with a 3.1 context.
If anything is still unclear I'll update accordingly. Thanks.
What I usually do is check out the latest header at the OpenGL registry called glcorearb.h. It has a list of every function definition from 1.0 onwards, broken up with defines labeling the respective versions in which they were introduced (and eligible for).
I'm not 100% sure of where to get GLSL information, but they do keep the specifications for older releases, so you may be able to compare the latest to the older ones for that.
Edit: Corrected wrong link.
Check the spec and this for preprocessor directives and such.
Does this help?

Which OpenGL version is most stable and currently used?

I've been thinking of making an additional wrapper for my project to use OpenGL rather then Allegro. I was not sure which OpenGL version to go for since I know that some computers cannot run recent versions such as v4.4. Also, I need a version which compiles no problem in Linux, Windows, Mac.
You'll want to look at what kinds of graphics cards will be available on your target systems and bear some details in mind:
OpenGL up to 1.5 can be completely emulated in software in real time on most systems. You don't necessarily need hardware support for good performance.
OpenGL 1.4 has universal support. Virtually all hardware supports it.
Mac OS X only supports up to OpenGL 2.0 and OpenGL 2.1, depending on OS version and hardware. Systems using GMA950 have only OGL1.4 support. Mac OS X Lion 10.7 supports OpenGL 3.2 Core profile on supported hardware.
On Linux, it's not unusual for users to specifically prefer open source drivers over the alternative "binary blobs," so bear in mind that the version of Mesa that most people have supports only up to about OpenGL 2.1 compatibility. Upcoming versions have support for OpenGL 3.x. Closed-source "binary blobs" will generally support the highest OpenGL version for the hardware, including up to OpenGL 4.2 Core.
When considering what hardware is available to your users, the Steam hardware Survey may help. Note that most users have DirectX 9-compatible hardware, which is roughly feature-equivalent to OpenGL 2.0. Wikipedia's OpenGL article also specifies what hardware came with initial support for which versions.
If you use a library like GLEW or GLEE or any toolkit that depends on them or offers similar functionality (like SFML, or even Allegro since 4.3), then you'll not need to concern yourself with whether your code will compile. These toolkits will take care of the details of enabling extensions and providing all of the symbols you need.
Given all of this, I'd suggest targeting OpenGL 2.1 to get the widest audience possible with the best feature support.
Your safe bet is OpenGL 2.1, it needs to be supported by the driver on your target system though. OpenGL ES, used on several mobile platforms, is basically a simplified OpenGL 2, so even porting to those would be fairly easy. I highly recommend using libGlew as VJo said.
It's less about operating systems, and more about video card drivers.
I think 1.4 is the highest version which enjoys support by all consumer graphics systems: ATI (AMD), nVidia, and Intel IGP. Intel is definitely the limiting factor here, even when ATI or nVidia doesn't have hardware support, they release OpenGL 4.1 drivers which use software to emulate the missing features. Not so with Intel.
OpenGL is not a library you usually compile and ship yourself (unless you're a Linux distributor and are packaging X.Org/Mesa). Your program just dynamically links against libGL.so (Linux/BSD), opengl32.dll (Windows, on 64 Bit systems, it's also calles opengl32.dll, but it's in fact a 64 Bit DLL) or the OpenGL Framework (MacOS X). This gives your program access to the system's OpenGL installation. The version/profile you want to use has no influence on the library you link!
Then after your program has been initialized you can test, which OpenGL version is available. If you want to use OpenGL-3 or 4 you'll have to jump a few additional hoops in Windows to make full use of it, but normally some kind of wrapper helps you with context creation anyway, boiling it down to only a few lines.
Then in the program you can implement multiple code paths for the various versions. Usually lower OpenGL verion codepaths share a large subset with higher version codepaths. I recommend writing new code in the highest version available, then adding additional code paths (oftenly just substitutions which can be done by C preprocessor macros or similar) for lower versions until you reach the lowest common denominator of features you really need.
Then you need to use OpenGL 1.1, and use needed (and supported) functions through the use of wglGetProcAddress (on windows) or glXGetProcAddress (on linux).
Instead of using those two functions, you can use GLEW library, which does that for you and is cross platform.