6.1 OpenGL Version, Context, and Profile

What are OpenGL context and profile?

You sometimes see the following lines of code in sample programs. What are their purpose? 

glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);

The above lines set up an OpenGL context of version 3.2 with a compatibility profile. Developers use the combination of an OpenGL context and profile to declare the program's hardware compatibility and whether deprecated APIs are present or allowed in this program. The following is a brief explanation of OpenGL context and profile. 

OpenGL context is a complicated concept. In short, it's a data structure that contains all the data needed to render images using OpenGL. An OpenGL context must be created and attached to a window before any OpenGL API can be called. If an application needs to draw images in multiple windows, then multiple OpenGL contexts must be created, one for each window. OpenGL contexts are created by window management libraries, such as freeglut, SDL, or GLFW. Here is a tutorial on creating OpenGL context using different libraries. The following discussions use freeglut as an example. 

Each OpenGL context and profile is created for a particular version of OpenGL specification. A developer can also see an OpenGL context as a collection of APIs that he/she may use to draw images for the attached window. If an OpenGL API is not included in the current OpenGL context, then it can not be used in the program. Otherwise, the program may not compile or it may crash on execution. 

Each new version of OpenGL specification introduces new functions. Certain versions of OpenGL specifications also mark some functions deprecated.  A deprecated function may be removed in a future version of OpenGL specification. For example, some functions are marked as deprecated in OpenGL version 3.0. The majority of them are removed from OpenGL 3.1. 

For any version of OpenGL specification, an OpenGL function has four possible status:
  • Current: The function is part of the core specification of this version.  
  • Deprecated: The function is deprecated but still part of the core specification of this version. 
  • Removed: The function is removed from the core specification of this version. 
  • Not yet introduced: The function is not yet introduced in this version. 
For software developers, this has two implications:
  • Hardware compatibility: If a program contains a function that is first introduced in OpenGL version X.Y, then this program will not be able to run on GPUs that only supports OpenGL versions lower than X.Y. In this case, a developer may want to declare to users or other developers that this program is only compatible with GPUs that support OpenGL X.Y or higher. 

  • How to deal with deprecated or removed APIs: If a program contains a deprecated or removed function, then this program may not be able to run on a GPU released in the near future. Therefore developers should avoid using deprecated or removed APIs, if possible. 
    However, to maintain backward compatibility, GPU vendors have implement most of the deprecated and removed functions in their latest OpenGL drivers. They give the developers the option to use or not use the deprecated or removed APIs in their programs. This means some developers may choose to allow a mixture of new and old (deprecated or removed) APIs, while other developers may choose to forbid the use of deprecated or removed APIs. 
To address this issue, OpenGL 3.2 introduces the concept of profiles. Developers can use the combination of an OpenGL context and profile to declare the program's hardware compatibility and whether deprecated APIs are present or allowed in this program. 

An OpenGL profile is always declared for a particular version of OpenGL context. There are three types of OpenGL profiles:
  • Core profile: The core profile include all the APIs present in this version of OpenGL specification. This may include some deprecated functions. 
  • Compatibility profile:  The compatibility profile includes the core profile, plus most of the APIs removed in this or earlier versions of OpenGL specification.  It is up to each GPU vendor to decide which removed APIs are included in the compatibility profile. 
  • Forward compatible profile: The forward compatibility profile includes the core profile, minus all the deprecated APIs. However, the use of forward compatibility profile is not recommended. 

What do different context and profile mean?

The following table explains the meaning of different combinations of OpenGL contexts and profiles. OpenGL 3.2 and freeglut are used as examples, but the meaning applies to other versions of OpenGL and other window management libraries. 

 OpenGL context and profile What do they mean?
There is no explicit declaration of OpenGL context or profile in a program.A default OpenGL context and profile will be created by freeglut (or other similar tools). The version of the default OpenGL context and profile is set by the specific GPU vendor and graphics driver. So it may be different on different GPUs. Usually it is the highest version of OpenGL that your GPU can support. 
 glutInitContextVersion( 1, 0 );Same as above.  A default OpenGL context and profile will be created by freeglut (or other similar tools). The version of the default OpenGL context and profile is set by the specific GPU vendor and graphics driver. So it may be different on different GPUs. Usually it is the highest version of OpenGL that your GPU can support. 
 glutInitContextVersion( 3, 2 );
 glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE );
This creates an OpenGL 3.2 context with compatibility profile. It means you can use all the APIs that are current from OpenGL 3.2 up to the highest version OpenGL your GPU can support *. You can also use APIs that are deprecated or removed.

It means you can use almost any API up until the the highest version OpenGL your GPU can support.
 glutInitContextVersion( 3, 2 );
 glutInitContextProfile( GLUT_CORE_PROFILE );
This creates an OpenGL 3.2 context with core profile. It means you can use all the APIs that are current from OpenGL 3.2 up to the highest version OpenGL your GPU can support *. 

You may still use the deprecated APIs in OpenGL 3.2. 

You cannot use the APIs removed from OpenGL 3.2. 

Developers often declare a core profile to enforce certain coding rules. That is, it prevents himself/herself or co-developers from using deprecated or removed APIs in this program. 

* You can use GPU Caps Viewer or Glview to check the highest version of OpenGL that your GPU can support. 

You can use the following function call to check the current version of your OpenGL context. 

// Print out the version of the current OpenGL context. 
printf ("Version: %s\n", glGetString (GL_VERSION)); 

// Print out the version of the current GLSL.  
printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));

Since different GPU vendor implements its own OpenGL, the output of these functions may be different on different GPUs. 

How to set OpenGL context and profile properly? 

To set the OpenGL context version and profile, you need to know two things:
  • What is the version of the newest OpenGL API or GLSL feature in your program? You should set your OpenGL context version to the same version of the newest OpenGL API in your program. For example, Compute Shader is first introduced in OpenGL 4.3. If you use compute shaders in your program, then you should call 
    glutInitContextVersion( 4, 3 );
    In this case, if you set a context version lower than 4.3, the program will not compile. 

  • Once you have determined the version of your OpenGL context, you need to know if your program contains APIs that are removed or deprecated in this version of OpenGL. This includes not only your own program, but also all the supporting libraries that your program depends on, such as GLEW, SOIL, etc.
    • If yes or if you are not sure, then you must declare a compatibility profile by calling
       glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE );
    • If not, then you need to decide whether you want to allow deprecated for removed APIs to be used in your program in the future. 
      • If yes, then you must declare a compatibility profile. 
      • If not, then you must declare a core profile by calling
        glutInitContextProfile( GLUT_CORE_PROFILE );
For novice OpenGL programmers, it is OK not setting any OpenGL context version and profile explicitly. Just let the graphics driver set the default OpenGL context and profile. But it is often desirable to set the OpenGL context version and profile explicitly because it may help users debug your program. 
  • The declared OpenGL context version indicates the hardware compatibility of this program. If your program crashes on a user's computer, the user can use the declared OpenGL context version to check whether his/her GPU is incompatible with your program. Without the OpenGL context version, the user may waste time looking at other causes. 
  • The compatibility profile is a hint that the program may contain legacy APIs and may not run on future graphics hardware. 
  • The OpenGL Debug context is only available from OpenGL 4.3. To enable OpenGL Debug context, you must explicitly specify an OpenGL 4.3 context on some computers. 
You want to set the OpenGL context version as low as possible so that your program can run on as many GPUs as possible. The higher the OpenGL context version, the more exclusive your program will be. 

Common errors associated with OpenGL context and profile

  • Errors related to OpenGL context and profile are often confusing. The error messages don't implicate the OpenGL context or profile. Using debugging techniques you may trace the error to a deprecated OpenGL API. But the API looks normal and correct. It's not that the API is wrong, it's that the API is not compatible the current OpenGL context and profile. For example, if you declare the following OpenGL context and profile, deprecated APIs in old libraries such as SOIL may cause errors.

    glutInitContextVersion( 3, 3 );
    glutInitContextProfile( GLUT_CORE_PROFILE );

    If you trace the error to an OpenGL API in a third party library, you should check the current OpenGL context and profile. Try the following:
    • Change the profile to GLUT_COMPATIBILITY_PROFILE.
    • Change the OpenGL context version number.
    • Comment out the lines that specify an OpenGL context and profile. 
  • You should set OpenGL core profile with care. There may be deprecated or removed functions in the third party library that your program is dependent on. If in doubt, use OpenGL compatibility profile. 

  • Some graphics drivers are picky about the minor version number of the OpenGL context. For example, on some computers creating an OpenGL 3.3 context will work, but creating an OpenGL 3.2 context will not, for no obvious reason. So adjusting the minor version number of your OpenGL context may solve some problems. 
  • Setting the OpenGL context version higher than your GPU can support may cause the program to crash, depending on the GPU vendor. 

  • Unless necessary, don't set the OpenGL context version to the highest OpenGL version your GPU can support. Otherwise, the program may not run on computers older than yours. Set the OpenGL context version as low as possible so that your program can run on as many GPUs as possible.

OpenGL Shading Language (GLSL) versions

In GLSL shaders, the first line of the program is often like this

#version 330

This means the shader program should be compiled for GLSL version 3.3. 

Each OpenGL release contains an OpenGL version and a GLSL version. Before version 3.3, the GLSL version numbers are different from the corresponding OpenGL version numbers, which causes some confusion. From version 3.3 and on, the GLSL version and OpenGL version numbers are the same. The following table lists the OpenGL and GLSL versions. 

 OpenGL version GLSL version
 2.0 1.2
 3.0 1.3
 3.1 1.4
 3.2 1.5
 3.3 3.3
 4.0 4.0
 4.1 4.1
 4.2 4.2
 4.3 4.3
 4.4 4.4
 4.5 4.5

In a program, the GLSL version does not have to be in sync with the OpenGL context version. For example, you may set your OpenGL context version to 4.3 but set your GLSL version to 1.3. A vertex shader and the corresponding fragment shader may use different version numbers.