I'm a bit confused about when exactly I need to use an OpenGL function loader like GLEW. In general, it seems like you first obtain a window and valid OpenGL context and then attempt to load functions.
Sometimes these functions are referred to as extensions, sometimes they are called core functions as well. It seems like what's loaded and classified as 'core' and 'extension' is platform dependent. Are the functions that are loaded in addition to some base set?
Do you need to load functions in the same way on OpenGL ES platforms as well? Taking a quick look at GLEW, I don't see any explicit support for Open GL ES. Other GL function loader libs do explicitly mention support specifically for ES however (like https://github.com/Dav1dde/glad)
OpenGL functions (core or extension) must be loaded at runtime, dynamically, whenever the function in question is not part of the platforms original OpenGL ABI (application binary interface).
For Windows the ABI covers is OpenGL-1.1
For Linux the ABI covers OpenGL-1.2 (there's no official OpenGL ABI for other *nixes, but they usually require OpenGL-1.2 as well)
For MacOS X the OpenGL version available and with it the ABI is defined by the OS version.
This leads to the following rules:
In Windows you're going to need a function loader for pretty much everything, except single textured, shaderless, fixed function drawing; it may be possible to load further functionality, but this is not a given.
In Linux you're going to need a function loader for pretty much everything, except basic multitextured with just the basic texenv modes, shaderless, fixed function drawing; it may be possible to load further functionality, but this is not a given.
In MacOS X you don't need a function loader at all, but the OpenGL features you can use are strictly determined by the OS version, either you have it, or you don't.
The difference between core OpenGL functions and extensions is, that core functions are found in the OpenGL specification, while extensions are functionality that may or may be not available in addition to what the OpenGL version available provides.
Both extensions and newer version core functions are loaded through the same mechanism.
datenwolf's answer is great, but I wanted to clarify something you said in the first bullet point of your question.
Core and extension status is not platform-dependent or even mutually exclusive.
Core means that some feature was introduced in a certain version of OpenGL. There are core functions, which are things that are guaranteed to exist in version X.Y and there are even core extensions, which are extensions that were introduced alongside version X.Y. Core extensions provide the same functions, types, enums, etc. as the core feature only in an extension form that does not require a specific version.
Framebuffer Objects went core in OpenGL 3.0, and are slightly less restrictive than the EXT extension (GL_EXT_framebuffer_object) that predates OpenGL 3.0. However, it is not necessary to have an OpenGL 3.0 implementation to have access to the core version of FBOs - an OpenGL 2.1 implementation might offer the core functionality.
In the extension specification for GL_ARB_framebuffer_object, you will find:
Issues
(8) Why don't the new tokens and entry points in this extension have
"ARB" suffixes like other ARB extensions?
RESOLVED: Unlike most ARB extensions, this is a strict subset of
functionality already approved in OpenGL 3.0. This extension
exists only to support that functionality on older hardware that
cannot implement a full OpenGL 3.0 driver. Since there are no
possible behavior changes between the ARB extension and core
features, source code compatibility is improved by not using
suffixes on the extension.
That is the first mention of a core extension that I can recall, but it is not the last. Since then many ARB extensions have been created that "backport" (if you will) core functionality from a higher version.
Here is some sample output gathered by parsing gl.xml for another core extension:
>> Command: void glBufferStorage (GLenum target, GLsizeiptr size, const void *
data, GLbitfield flags)
* Provided by GL_ARB_buffer_storage (gl|glcore)
* Core in GL_VERSION_4_4 ( gl 4.4)
It is core in 4.4 (guaranteed to exist in a 4.4 implementation), but because the extension that provides it is glcore, this core function may be available in older implementations if the core extension is available.
The simple piece of software I wrote to parse gl.xml for this information can be found here if you are interested.
Function loaders are only needed on Windows and Linux. Here's a quick overview of how you build for various OpenGL versions on different platforms.
Windows
The Windows development tools only contain headers for OpenGL 1.1. The conspiracy theorists would probably claim that Microsoft is not interested in making the use of OpenGL easy because it wants developers to use a proprietary API instead.
For anything beyond 1.1, you need to load the entry points dynamically by calling wglGetProcAddress(). Libraries like GLEW provide header files for higher OpenGL versions, and encapsulate the logic for loading the entry points.
Linux
I haven't done OpenGL programming on Linux. From what I hear, it requires function loading similar to Windows. I'll defer to #datenwolf's answer for the details.
Mac OS
Mac OS supports two main OpenGL feature sets:
OpenGL 2.1 with legacy features. This is used by including <OpenGL/gl.h>.
OpenGL 3.x and higher, Core Profile only. Used by including <OpenGL/gl3.h>.
In both cases, you don't need any dynamic function loading. The header files contain all the declarations/definitions for the maximum version that can be supported, and the framework you link against (using -framework OpenGL) resolves the function names.
The maximum version you can use at build time is determined by the platform SDK you build against. By default, this is he platform SDK that matches the OS of your build machine. But you can change it by using the -isysroot build option.
At runtime, the machine has to run at least the OS matching the platform SDK used at build time, and you can only use features up to the version supported by the GPU. You can get an overview of what version is supported on which hardware on:
https://developer.apple.com/opengl/capabilities/
http://support.apple.com/en-us/HT202823
Android, NDK
With native code on Android, you choose the OpenGL version while setting up the context and surface. Your code then includes the desired header (like <GLES2/gl2.h> or <GLES3/gl3.h>) and links against the matching libraries. There is no dynamic function loading needed.
If the target device does not support the version you are trying to use, the context creation will fail. You can have an entry in the manifest that prevents the app from being installed on devices that will not support the required ES version.
Android, Java
This is very similar to the NDK case. The desired version is specified during setup, e.g. while creating a GLSurfaceView.
The GLES20 class contains the definitions for ES 2.0. GLES30 derives from GLES20, and adds the additional definitions for ES 3.0.
iOS
Not surprisingly, this is very similar to Mac OS. You include the header file that matches the desired OpenGL ES version (e.g. <OpenGLES/ES3/gl.h>), link against the framework, and you're all done.
Also matching Mac OS, the maximum version you can build against is determined by the platform SDK version you choose. Devices you want to run on then have to use at least the OS version that matches this platform SDK version, and support the OpenGL ES version you are using.
One main difference is obviously that you cross compile the app on a Mac. iOS uses a different set of platform SDKs with different headers and frameworks, but the overall process is pretty much the same as building for Mac OS.
Related
I want to use latest OpenGL features on Ubuntu. And I have installed mesa-common-dev but as far as I understand mesa does not support OpenGL 4.5 features. Also how can I use OpenGL via hardware without any API ?
Note :
glxinfo | grep "OpenGL version"
OpenGL version string: 4.5.13397 Compatibility Profile Context 15.20.1046
I want to use latest OpenGL features on Ubuntu. And I have installed mesa-common-dev but as far as I understand mesa does not support OpenGL 4.5 features.
All that matters is, that your actual OpenGL implementation supports the profile you want. The Linux ABI on OpenGL is pinned to OpenGL-1.2 (LSB5 has been released recently, so expect upcoming distribution releases to follow it, which bumped it to OpenGL-2.1).
Anything that goes beyond the ABI requirements is done through the extension mechanism. I.e. use load function pointers through …GetProcAddress and introduce new tokens with a glext.h. This processes has been repacked into OpenGL extension wrapper-loader libraries like GLEW.
The stuff mesa-common-dev provides is what's written down in the Linux LSB ABI specs… in a vendor neutral way, so you can compile your program using mesa-common-dev stuff, but it will work with the NVidia or AMD/ATI drivers as well.
Also how can I use OpenGL via hardware without any API ?
By definition you can't. OpenGL is an API. If you remove the API you remove OpenGL. If your intention is working the naked GPU on the bare metal, well, that would boil down to writing a full driver. In a few weeks/months Vulkan will be released and this gets you much closer to the GPU than OpenGL.
I set up OpenGl with DevC++ following a tutorial and everything works. I've looked into the main OpenGl project page (https://www.opengl.org/) but I can't find an official repository where I can download the packages that I need (I've found .zip but I can't understand the correct files that I need :(). I have seen many tutorials but they use unofficial repositories and they install packages in so many different ways even for the same IDE! :(. Is there an official repository? What files do I need? Is there a unique way to install OpenGL and if not could you tell me the most important steps of the installation ?
Is there a unique way to install OpenGL and if not could you tell me the most important steps of the installation?
Install drivers for your graphics card with OpenGL support. Done!
OpenGL is different than Direct3D or Mantle (or, soon to come, Vulkan): Back in 1996 OpenGL-1.1 was included into the Windows 32 bit platform ABI (Application Binary Interface). That means that for every Windows version after "Windows 95B" and "Windows NT 4.0" programs are assured for OpenGL-1.1 to be available.
Being part of the platform ABI has the nice side effect and consequence, that everything that's required for OpenGL development must be included in every compiler package that targets the Windows 32 bit (and by heritage the 64 bit) platform.
However the ABI covers only OpenGL-1.1. For everything that comes after the so called "extension mechanism" is provided. By using the extension mechanism programs can determine at runtime, which OpenGL capabilities (beyond v1.1) are available and load them. No extra libraries or SDKs are required for this!
Yet, since the process of enumerating available OpenGL capabilities and loading them is so tedious, a number of helper libraries exists that alleviate one from this annoying task.
you probably have OpenGL in your system as a part of your graphic card... You can see how to have a project running for different OS by taking a look at the OpenGL superbible:
https://sgar91.files.wordpress.com/2010/11/opengl-superbible-comprehensive-tutorial-and-reference-5th-edition-2010.pdf
Page 48 starts to talk about how to have a program running with OpenGL
I'm a bit confused about when exactly I need to use an OpenGL function loader like GLEW. In general, it seems like you first obtain a window and valid OpenGL context and then attempt to load functions.
Sometimes these functions are referred to as extensions, sometimes they are called core functions as well. It seems like what's loaded and classified as 'core' and 'extension' is platform dependent. Are the functions that are loaded in addition to some base set?
Do you need to load functions in the same way on OpenGL ES platforms as well? Taking a quick look at GLEW, I don't see any explicit support for Open GL ES. Other GL function loader libs do explicitly mention support specifically for ES however (like https://github.com/Dav1dde/glad)
OpenGL functions (core or extension) must be loaded at runtime, dynamically, whenever the function in question is not part of the platforms original OpenGL ABI (application binary interface).
For Windows the ABI covers is OpenGL-1.1
For Linux the ABI covers OpenGL-1.2 (there's no official OpenGL ABI for other *nixes, but they usually require OpenGL-1.2 as well)
For MacOS X the OpenGL version available and with it the ABI is defined by the OS version.
This leads to the following rules:
In Windows you're going to need a function loader for pretty much everything, except single textured, shaderless, fixed function drawing; it may be possible to load further functionality, but this is not a given.
In Linux you're going to need a function loader for pretty much everything, except basic multitextured with just the basic texenv modes, shaderless, fixed function drawing; it may be possible to load further functionality, but this is not a given.
In MacOS X you don't need a function loader at all, but the OpenGL features you can use are strictly determined by the OS version, either you have it, or you don't.
The difference between core OpenGL functions and extensions is, that core functions are found in the OpenGL specification, while extensions are functionality that may or may be not available in addition to what the OpenGL version available provides.
Both extensions and newer version core functions are loaded through the same mechanism.
datenwolf's answer is great, but I wanted to clarify something you said in the first bullet point of your question.
Core and extension status is not platform-dependent or even mutually exclusive.
Core means that some feature was introduced in a certain version of OpenGL. There are core functions, which are things that are guaranteed to exist in version X.Y and there are even core extensions, which are extensions that were introduced alongside version X.Y. Core extensions provide the same functions, types, enums, etc. as the core feature only in an extension form that does not require a specific version.
Framebuffer Objects went core in OpenGL 3.0, and are slightly less restrictive than the EXT extension (GL_EXT_framebuffer_object) that predates OpenGL 3.0. However, it is not necessary to have an OpenGL 3.0 implementation to have access to the core version of FBOs - an OpenGL 2.1 implementation might offer the core functionality.
In the extension specification for GL_ARB_framebuffer_object, you will find:
Issues
(8) Why don't the new tokens and entry points in this extension have
"ARB" suffixes like other ARB extensions?
RESOLVED: Unlike most ARB extensions, this is a strict subset of
functionality already approved in OpenGL 3.0. This extension
exists only to support that functionality on older hardware that
cannot implement a full OpenGL 3.0 driver. Since there are no
possible behavior changes between the ARB extension and core
features, source code compatibility is improved by not using
suffixes on the extension.
That is the first mention of a core extension that I can recall, but it is not the last. Since then many ARB extensions have been created that "backport" (if you will) core functionality from a higher version.
Here is some sample output gathered by parsing gl.xml for another core extension:
>> Command: void glBufferStorage (GLenum target, GLsizeiptr size, const void *
data, GLbitfield flags)
* Provided by GL_ARB_buffer_storage (gl|glcore)
* Core in GL_VERSION_4_4 ( gl 4.4)
It is core in 4.4 (guaranteed to exist in a 4.4 implementation), but because the extension that provides it is glcore, this core function may be available in older implementations if the core extension is available.
The simple piece of software I wrote to parse gl.xml for this information can be found here if you are interested.
Function loaders are only needed on Windows and Linux. Here's a quick overview of how you build for various OpenGL versions on different platforms.
Windows
The Windows development tools only contain headers for OpenGL 1.1. The conspiracy theorists would probably claim that Microsoft is not interested in making the use of OpenGL easy because it wants developers to use a proprietary API instead.
For anything beyond 1.1, you need to load the entry points dynamically by calling wglGetProcAddress(). Libraries like GLEW provide header files for higher OpenGL versions, and encapsulate the logic for loading the entry points.
Linux
I haven't done OpenGL programming on Linux. From what I hear, it requires function loading similar to Windows. I'll defer to #datenwolf's answer for the details.
Mac OS
Mac OS supports two main OpenGL feature sets:
OpenGL 2.1 with legacy features. This is used by including <OpenGL/gl.h>.
OpenGL 3.x and higher, Core Profile only. Used by including <OpenGL/gl3.h>.
In both cases, you don't need any dynamic function loading. The header files contain all the declarations/definitions for the maximum version that can be supported, and the framework you link against (using -framework OpenGL) resolves the function names.
The maximum version you can use at build time is determined by the platform SDK you build against. By default, this is he platform SDK that matches the OS of your build machine. But you can change it by using the -isysroot build option.
At runtime, the machine has to run at least the OS matching the platform SDK used at build time, and you can only use features up to the version supported by the GPU. You can get an overview of what version is supported on which hardware on:
https://developer.apple.com/opengl/capabilities/
http://support.apple.com/en-us/HT202823
Android, NDK
With native code on Android, you choose the OpenGL version while setting up the context and surface. Your code then includes the desired header (like <GLES2/gl2.h> or <GLES3/gl3.h>) and links against the matching libraries. There is no dynamic function loading needed.
If the target device does not support the version you are trying to use, the context creation will fail. You can have an entry in the manifest that prevents the app from being installed on devices that will not support the required ES version.
Android, Java
This is very similar to the NDK case. The desired version is specified during setup, e.g. while creating a GLSurfaceView.
The GLES20 class contains the definitions for ES 2.0. GLES30 derives from GLES20, and adds the additional definitions for ES 3.0.
iOS
Not surprisingly, this is very similar to Mac OS. You include the header file that matches the desired OpenGL ES version (e.g. <OpenGLES/ES3/gl.h>), link against the framework, and you're all done.
Also matching Mac OS, the maximum version you can build against is determined by the platform SDK version you choose. Devices you want to run on then have to use at least the OS version that matches this platform SDK version, and support the OpenGL ES version you are using.
One main difference is obviously that you cross compile the app on a Mac. iOS uses a different set of platform SDKs with different headers and frameworks, but the overall process is pretty much the same as building for Mac OS.
I am trying to get an OpenGL/glew program from a template made by my uni lecturer work. He has added this code to his program:
if(!GLEW_VERSION_3_1) {
std::cerr << "Driver does not support OpenGL 3.1" << std::endl;
return 1;
}
This prints the error on my mac. After some experimenting, I have found out that my mac is actually running OpenGL (2.1 INTEL-8.28.30). I have worked my way around this using a nasty #ifndef APPLE before that part of the code, but I cannot do this in the long term.
Is there any way in which I can upgrade to 3.1?
The issue is related to the concept of core and compatibility contexts in OpenGL, and Apple's implementation. You need to make sure the application requests a core profile OpenGL context.
Apple support a compatibility OpenGL context (with support for all of the old deprecated features) up until a maximum of OpenGL 2.1 (plus several extensions).
Apple support a core OpenGL context (with old deprecated features removed) up until a maximum of OpenGL 4.1 (dependent on hardware support, 3.3 on older hardware) with OSX Mavericks. If you download a program called OpenGL Extension Viewer, you can see what you've got available.
When your program creates an OpenGL context, it gets compatibility by default (to avoid breaking old programs). You need to specifically flag that you want a core profile. The way to do this will depend what windowing library you're using. If you happen to be using SDL2, there's just an extra flag to set when creating the context. If using Apple GL directly, you'd need to check their documentation.
See: http://www.opengl.org/wiki/Core_And_Compatibility_in_Contexts
Note: I notice you're using GLEW. I encountered issues with GLEW and core contexts in the past. This is because it was requesting extension strings using a method that's deprecated (and therefore fails in a core context). It made it look like no extensions were supported. If this happens, refer to the GLEW website, there was an experimental option you could pass to its init to make it work.
Wikipedia says that OpenGl V4.x is the latest. However my Visual Studio 2012 just offers the following version
#define GL_VERSION_1_1 1
So my questions:
Which version is the most common that I should use? E.g. version 2.x because there are many tutorials, it is backward compatible etc.? I may have to mention that I normally prefer to write in C++, so is any version of Opengl e.g. offering namespaces? Are there huge differences between OpenGl 2,3 and 4?
And where can I get the Libs+Header files e.g. for OpenGl 4?
And where can I get the Libs+Header files e.g. for OpenGl 4?
You don't. OpenGL uses the so called "extension mechanism" to load functionality that's beyond the system ABI version. There exist third party libraries that do the extension loading and provide a header with the extended functionality.
Most popular is GLEW, which has its homepage at http://glew.sourceforge.net ; be warned though that right now of writing this GLEW is not up to date with OpenGL-3 and later core profiles. You must use compatibility profiles with GLEW or things get unstable.
AFAIK, the most popular GL development library is GLEW:
http://glew.sourceforge.net
There is no official OpenGL SDK. If you want to use newer functions you have to use a third party library such as GLEW or GLFW.