There are a lot of web pages and websites that discuss OpenGL programming. So why am I writing yet another post about this? Because I had a hard time developing a simple OpenGL based program using Visual Studio. The are several reasons reasons for this:
- Some of the pages and posts are very old, with code dating back to OpenGL 1.0. The current specification is 4.5. Other authors state that you should not code this way because there is heavy use of deprecated functions.
- Every page starts at a different place; for example, some of the sample code starts with SFML, SDL, or GLFW, others with GLUT or FreeGLUT, and still others start with wxWidgets or Qt or the Win32 API. That’s a lot of acronyms and alternatives. The biggest problem is that while the code MAY show you how to do things, they don’t really explain what each of these choices are and why they chose the specific windowing API that they used.
- Every author makes many assumptions about what you already know. “Just code this and it will work”, they say, but when you try it, it doesn’t because the build system can’t find the header files needed, or the libraries. If you ever do get an executable file, it crashes when you run it.
- Many of the websites and books on OpenGL programming provide their own libraries that hide parts of OpenGL. Don’t teach me to use your libraries, teach me OpenGL programming!
OpenGL and the Rendering Pipeline
OpenGL is a specification (an API); it is not a library. That is, you cannot find a website that provides a download for an OpenGL library. Instead, the OpenGL specification is provided as part of your operating system or its drivers. For example, on Microsoft Windows, OpenGL functions are included in the driver for you graphics card, on Mac/OS X, Apple has provided an implementation, and on Linux, OpenGL is provided as an extension to the X Windowing system.
Note that OpenGL is concerned only with rendering graphics; it does not provide functions for animation, timing, file I/O, image file format processing, or a GUI.
OpenGL provides a C API, not C++, but of course is callable from C++.
For more information about OpenGL and the rendering pipeline see the following references:
- The OpenGL Wiki
- The Wikipedia OpenGL entry
- An intro to modern OpenGL. Chapter 1: The Graphics Pipeline by Joe Groff
- OpenGL Programming Guide – Chapter 1 – Introduction to OpenGL
The C++ header file, gl.h, contains declarations only for OpenGL 1.1. At the time of writing this post, the most up-to-date specification is OpenGL 4.5. Then there are the header files glu.h and glaux.h. How do we get access to the most up-to-date functionality? That is the job of extension loading libraries.
Extension Loading Libraries
On the OpenGL website, these are referred to as OpenGL loading libraries. A few of these libraries are mentioned below:
The OpenGL Extension Wrangler (GLEW) is an open source, cross platform C/C++ extension loading library. The version that is current as of the writing of this post is 1.13.0, which contains support for OpenGL 4.5, OpenGL extensions, WGL extensions, and GLX extensions. Source code for GLEW is available from GitHub and Sourceforge. The Sourceforge GLEW page also provides Windows binaries.
The Windows binaries are also included in a NuGet package for Visual Studio. This package will be mentioned in a future post on OpenGL programming with Visual Studio.
GL3W is a simple OpenGL core profile loading library. How simple you may ask? There are only 3 functions: gl3wInit, gl3wIsSupported, and gl3wGetProcAddress. More information and the source code are available on GitHub.
glLoadGen, the OpenGL Load Generator, is a LUA script that you use to create OpenGL header files and loading code for your specific needs. More information and the script are available on the glLoadGen wiki. Because glLoadGen generates the headers and code from the latest OpenGL specifications, the headers and code that you generate will always be up-to-date when you generate them.
glad is a multi-language GL/GLES/EGL/GLX/WGL loader-generator written in python. Like glLoadGen, its inputs are the latest OpenGL specifications, and it generates only the functionality that you need. The source code for glad is available on GitHub.
The Unofficial OpenGL Software Development Kit is a large toolkit that contains GL Load, to gain access to OpenGL functions, GL Image to load image files into memory and OpenGL textures, GL Utility to provide simple text drawing, a matrix stack and mouse-based camera and object manipulation, GL Mesh to render mesh data, OpenGL Mathematics to provide useful math classes and functions for OpenGL, GLFW (described later in this post), FreeGLUT (also described later in this post), the Boost libraries, and the OpenGL Load Generator which is a command-line script tool for generating OpenGL loader code. glsdk is a cross-platform build system. Note: glsdk is still in alpha release at this time.
glbinding is a generated, cross-platform C++ binding for OpenGL based on the new xml-based OpenGL API specification. It is a full fledged OpenGL API binding that is generated using python scripts. glbinding is available on GitHub.
As mentioned above, OpenGL’s only function is to render graphics. How can we program all of the other stuff that a graphical program needs: windowing, image file processing, file I/O, and so forth? The answer to that question depends on what hardware and operating system you are using. You can use standard windowing toolkits like Win32, MFC, wxWidgets, Qt, GTK+ and FLTK. There are also a few utility toolkits that provide cross-platform Window management and a GUI toolkit and API. These toolkits include GLUT, FreeGLUT, GLFW, GLUI UI Library, NGL, SDL, and SFML. Each of these is discussed below.
GLUT, the OpenGL Utility Toolkit is a window system independent toolkit for writing OpenGL programs. It provides a portable API that allows you to write a single OpenGL program that can be compiled across all PC and workstation platforms. GLUT is a simple toolkit that does not provide all functionality that you might need in a large application; you should use one of the standard windowing toolkits for that.
GLUT is not open source. It has also not been updated since about 2000, so you should look at alternatives.
FreeGLUT is an open source alternative to the GLUT toolkit. You should use FreeGLUT rather than GLUT.
The source code and Windows binaries are available on Sourceforge.
GLUI UI Library
GLUI is a GLUT-based C++ UI library that provides controls to OpenGL applications. It is window system independent. It can be used with either GLUT or FreeGLUT. This library is quite old, with the last update in 2006. Source code is available on Sourceforge.
NGL allows you to build your user interface as a composition of widgets and behaviours. NGL takes care of positioning, resizing, anchoring and texture stretching. It supports both single and multithreaded applications. The source code and documentation are available on GitHub.
SDL, the Simple DirectMedia Layer, is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL. The source code is available on the SDL website.
SFML provides interfaces to system, window, graphics, audio and network components of your PC to ease the development of games and multimedia applications. Source code and binary downloads are available on the SFML website.
Standard Windowing Toolkits
Win32 is the standard C interface to the Windows GUI. Information on programming OpenGL in Win32 is provided in MSDN. It includes information on WGL extensions.
nupengl.core and nupengl.core.redist Nuget packages are provided in Visual Studio to support OpenGL 3 and 4. These packages will be discussed in a future post.
There are simpler ways of programming OpenGL for Microsoft Windows. See the additional toolkits below.
As with Win32, it is possible to use OpenGL with MFC. There are a few web pages that describe what you need to do, so use your search engine to find them.
Does anybody start new projects using MFC anymore?
wxWidgets is a cross-platform C++ library for developing widget- and window-based applications on Windows, Mac OS/X, Linux and some other platforms. wxWidgets has the advantage of giving applications a truly native look and feel because it uses the platform’s native API. This is the only windowing toolkit that does this. Source code and binaries are available on the wxWidgets website.
wxWidgets supports OpenGL through the use of the wxGLCanvas widget. Sample OpenGL applications using wxWidgets will be developed in future posts.
Qt is another cross-platform windowing library. There are a number of different license requirements, so be sure to check before you begin using Qt. Qt libraries and source code are included on some platforms (e.g. Linux) because Qt is the library used by the KDE windowing system. Downloads are available on the Qt website. Applications developed with Qt look the same on every platform because Qt does not use a platform’s native API.
Qt supplies the QOpenGLWidget class for rendering OpenGL graphics.
GTKMM is the C++ wrapper over GTK+. GTK+ is a multi-platform toolkit for creating graphical user interfaces. GTK+ is part of the GNU Project and is licensed under the GNU LPGL. It is the toolkit used as the base for the GNOME windowing system and others. GTK+ is included with most Linux distributions for that reason. The GTK+ source code is available on the GTK+ website for those platforms that do not otherwise provide it.
Like Qt, GTK+ does not use a platform’s native API.
FLTK, the Fast Light ToolKit, is a cross-platform C++ GUI toolkit. It is lighter weight than the toolkits mentioned above. FLTK source code and documentation are available from the FLTK website. A separate widget or window is not provided by FLTK for OpenGL rendering. Rather, the FLTK documentation suggests subclassing the Fl_Gl_Window class.
So Which Windowing Toolkit Should You Use?
That depends on a number of factors:
- What is the target platform (hardware and operating system) for your application? Is there more than one?
- Must the application have the native look and feel on every platform?
- How complex is your application: simple, complex?
- Are you already familiar with some of the toolkits?
So here are potential answers to these questions:
- If you are developing for only one platform, then you can use any of the toolkits that are specific to that platform, or any of the multi-platform toolkits. If you are developing for multiple environments, then you will want to use one of the cross-platform toolkits.
- If the application must have the native look and feel on every platform, you are very limited. You must either use wxWidgets if that toolkit supports every one of your target platforms, or you must write windowing code for each of the environments, either as separate programs, or with platform specific code inside #ifdef — #endif preprocessor directives.
- If your application has simple to moderate complexity, then one of the utility toolkits will probably do the job. For complex applications, that is, applications with a lot of user interaction (menus, widgets, windows and dialogs), then one of the standard windowing toolkits should be chosen based on the other answers.
- If you are already familiar with one or more of the toolkits and those toolkits fit your requirements, then obviously you will save time by use one of those toolkits. However, you should at least consider the other toolkits to see it they are a better fit for your application.
What am I using? That is the subject of the next post.