Wednesday, May 18, 2016

Supporting Opengl Through Version 3.3

Introduction

I love to write code (both C++ and C) which utilizes Opengl for graphics. However, many of the computers I target are not high-end game machines. Most of the time, they are common, lower-cost systems or business machines which rarely support Opengl versions above 3.2. Today, it seems most of the online documentation and advice assumes you are targeting the most recent versions of Opengl and often I have seen the advice, "download the latest drivers". But it simply doesn't work that way. Many computers are incapable of supporting state-of-the-art graphics without sinking a sizable chunk of money into new cards.


Loading Extensions

Usually, when writing Opengl code, I use GLEW in order to avoid the pain and possible errors of trying to create my own Opengl extension loader.  Most of the projects I create use static linking and in order to statically link GLEW, the best way to avoid certain problems with Visual Studio is to build GLEW from source.  This works well once the proper "make" system is used to create the necessary project files. Recently, I have decided to fore go GLEW and write my own extension loader as an educational exercise.  I thought it would be convenient to target a limited subset of the Opengl functions and definitions aimed at supporting low-end graphics.  I was able to figure out the process looking at various online sources and within a few hours, had a working extension loader which allowed me to create a version 3.0 context.


Opengl Hell

As I tried to expand the extension loading library I began the process of digging much deeper under the hood of Opengl, trying to understand which functions and enum values are required for various versions of Opengl. Once you dive-in, you soon discover the documentation may be scattered around and not always clear. For example, consider the extensions required to support shaders in Open version 2.0. You will need to derive the functions and definitions from extension, #30, GL_ARB_shader_objects; #31, GL_ARB_vertex_shader; #32 GL_ARB_fragment_shader; and #33, GL_ARB_shading_language_100.  However, you will soon discover the final function names are not the same as the onces defined in the extension specifications (see: https://www.opengl.org/registry/). So which functions are supported in "official" Opengl 2.0?  How do I know which functions and definitions are considered "core profile", especially considering certain enum values and functions are deprecated in version 3.1?  Sure, as they say, deprecated does not mean deleted but that statement is usually followed by "but...it is best not to write code using deprecated functions because you never know when the functions and values will be deleted". So if you want your legacy code to be viable in the next decade, avoid deprecated functions.  No problem...so which enumerants are deprecated? Ah! Welcome to Opengl hell, at least it was for me.

Shedding Some Light

Nevertheless, despite the lack of clarity I decided to begin assembling the information I needed to build an extension loading library. So, over the course of a few days, I rummaged through various specifications and sources and assembled a spreadsheet which went a long to way toward giving me the information I needed. On the spreadsheet I listed all known Opengl functions and enumerants and recorded which are considered core, which are deprecated, and in which extensions they are declared. Because, it was not easy to put this together, I decided to make the next person's workload a little easier and have posted it online here.  Hopefully you will find if of value. Later I will expand the information to include versions 4.0 and greater.




No comments:

Post a Comment