Skip to content

Instantly share code, notes, and snippets.

@aprilandjan
Created July 21, 2019 10:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aprilandjan/97c256feb36eb5b9f48177703bdc48b8 to your computer and use it in GitHub Desktop.
Save aprilandjan/97c256feb36eb5b9f48177703bdc48b8 to your computer and use it in GitHub Desktop.
OpenGL Startup

Travel Guide to OpenGL

I've figured out several things while trying to extend my knowledge of Computer Graphics.

  1. OpenGL can be a bitch if you don't know what you're doing.
  2. There is no worse pain than to experience CMake without knowing what you're doing.
  3. When walking to the depths of hell, it would be nice to have a travel guide.

And that's what this is, a travel guide.

Preface

I found this article really informative and eye-opening. I recommend reading it if you're really into the idea of writing graphics seriously.

Now if you read that and would like to take that advice seriously, then do yourself a favor and follow this guide instead of reading this document. While OpenGL is great, learning it is not necessary to understanding graphics. You will understand more of what OpenGL allows you to do (and what its doing under the covers) by avoiding it altogether. Or at least until you've fully gone through the motions without any crutches.

I can only imagine how good I would be if I had done this myself...

History

OpenGL is an attempt by a group of people known as Khronos to make a cross-platform API for graphics acceleration hardware (GPUs). Khronos isn't really a company, but rather a consortium of various people/companies that mutually vote/collaborate on how APIs like this should be designed. They have many more APIs and file formats than just OpenGL that each handle something else related to heterogeneous processing.

It is up to the various platforms that OpenGL can be run on to perform that implementation. Thus you have a different implementation of OpenGL (with the same interface) from each independent hardware vendor (IHV) for most operating systems.

OpenGL is old. Many consider it too old and too bloated. It was initially designed in the early 90s when GPUs weren't even a thing. It has evolved over the years to make better use of graphics hardware, but still suffers in some ways (on the driver level) of exposing sub-optimal coding paradigms. Look into Vulkan[1, 2] if you're curious as to why this is. While vulkan is cool and new, I wouldn't blindly tell a beginner to jump straight into it. OpenGL is still alive and being used by many sources. I still personally believe it can be a good introduction to graphics programming.

Programming Languages

OpenGL has been ported to many languages. Everything from Python to Haskell has an interface to the API. Javascript is becoming a popular language for 3D graphics through WebGL and Three.js.

I am going to assume for the remainder of the document that you will be using C++, as is common in the world of high performance graphics.

System

Each OS has its quirks.

  • Apple has depricated OpenGL. They're really pushing support for their own graphics API called Metal.

  • OpenGL works just fine on Windows, but Microsoft also designs an alternative which is exlusive to Windows and XBox called Direct3D.

  • Mobile and web platforms have a forked subset of OpenGL called OpenGL ES.

Editor

This is really subjective. I'll list a few that I think are of note.

  • Visual Studio. An amazing IDE for C++. IMO the best. A good reason to develop on Windows.
  • CLion. It works pretty well if you're on Unix-like platform and acts as an alternative to Visual Studio.
  • Nothing beats Vim/Emacs. Beware. This is a rabbit hole.

The OpenGL Stack

As stated above, OpenGL is an interface to graphics acceleration hardware. It might seem weird at first that you can't just write regular C++ that runs on your GPU. After all, it just works on the CPU. What's so different? Why can't there be a compiler that turns C++ into whatever ISA runs on my GPU? Well outside of things like SYCL, this isn't a trivial thing to do.

You might also wonder why you can't use something like CUDA to write graphics applications. And you most certainly could. The issue is that tools like CUDA actually take significatly simpler paths through the GPU pipeline. You won't have access to graphics-specific fixed-function hardware. In other words, there are special acceleration tools that were designed to perform real-time graphics super fast that are only exposed via graphics APIs, such as OpenGL.

For now, I'll set aside the fact that it would probably take several years of advanced college-level courses for a beginner to fully appreciate the difference between CPU & GPU programming. In short it is a consequence of the programming model behind GPUs, historical factors, a need to be general enough to work well for different hardware companies, and chicken-and-egg interactions between software & hardware companies.

I can see how that can be somewhat unsatisfying. OpenGL exposes an API that can seem extremely opaque and nonsensical if you don't understand what its doing under the covers. I like to think of OpenGL as a series of layers. The pure C functions are the top of the stack (what you interact with), followed by the "driver", followed by command packets or GPU machine code in command queues, followed by the hardware itself.

The OpenGL driver is a notoriously giant piece of code. I know because I've worked on one first-hand. It acts as an interface between applications and hardware. Any texture that needs memory allocation, any commands that need to be translated to GPU machine code, and any error-checking (to avoid your GPU completely crashing) is handled at this level. It even comes with a built-in glsl compiler that translates your shader code to command packets (at runtime). It is more-or-less an arbiter between your intent and the image that is displayed on your monitor.

To fully appreciate how much it does I would suggest working at your favorite IHV. But building (simple) applications shouldn't require much more information than what's written above.

Making/Building

OpenGL projects usually involve slightly complicated compilation processes. This is primarily because most projects include multiple external libraries to aid in handling boilerplate code. You can go the route of writing your own platform-dependant Makefiles, but that tends to get unwieldy.

An alternative that is used by many (including major game/hardware companies) is CMake.

The proper way to build your project would be to create a CMakeLists.txt file and go from there. If you don't understand the CMake language at first (don't be ashamed, its awful) and just want to get into the C++, you can simply compile through the terminal until your project gets unwieldy. At that point, you're going to have to switch.

From personal experience, I would recommend not dealing with CMake all too much. You can waste weeks trying to get your build just right and have nothing to show for it. Focus on the code.

You can start by following (or stealing) something like Glitter. Their CMake system is simple enough to get you going.

Libraries

There are many libraries that one can include to their OpenGL project to make their life easier. Here is a list of popular ones that plenty of people on the internet frequently suggest.

This is a C library with an interface for window management and input. This is basically a requirement. Without this library, there would be no way to see the output of all of your code. This ain't no WebGL, we don't got no canvas element.

With that being said, GLFW is fairly easy to set up with CMake. You can follow this tutorial and add that to your CMakeLists.txt or you can just use Glitter's.

This is an alternative to GLFW and the decision between the two is mostly up to preference. SDL does A LOT of heavy lifting. It is a very specific way of writing graphics with its own best practices. If you are interested in getting past a lot of the graphics API code and seeing something on the display, then this is a good way to go.

You're gonna need a matrix library of some sort. This is a common one that many recommend. It is a C++ header library and as such, does not need to be compiled.

If you look at the Glitter CMakeLists.txt file, you'll notice that GLM is not added as a subdirectory to be compiled via add_subdirectory(). This is because GLM is a header only library (no .cpp files) and as such only needs to be include through include_directories().

See comment below about GLAD.

This another list of header only files. Many are helpful for things you might find yourself doing, such as loading textures or generating noise.

This is a hefty library which is useful for loading 3D geometry.

Getting Started

I often found it annoying to get up and running with an idea or an experiement I wanted to perform when I was first starting out. Setting up the dependencies and patching together a CMake file desolves all creative juices.

If you want something small and simple for just those scenarios, here are a couple of files that can help: opengl.cpp

The two files above assume you've downloaded both the GLFW and GLAD source and placed them into a directory called "deps".

Resources

I don't plan on this being a full graphics course. There are a ton of other people that have put an incredible amount of time and energy into doing this already. When I was starting out, it was hard for me to filter the good from the bad resources.. How do you know if something is poorly worded if you're just starting out?

Here are a collection of links that I've found over several years that have proven useful resources (some more than others). These are basically what I have in my /Developer/Graphics/ bookmarks bar:

OpenGL Specific

Game Engine Architecture

  • Stingray Engine Walkthrough - Walkthrough of the Stingray Game Engine (now defunct) by a core engineer that worked at Autodesk.
  • Our Machinery - Blog series from the former creators of Stingray, talking about various issues/solutions they had while creating a new high-end game engine
  • Unreal Engine 4 Architecture Tutorials - Series of slides walking through various aspects of how UE4 is designed including graphics.

General Graphics Theory

Graphics Relevant Math

3D Assets

Books

Although physical books are not necessary, and can get pretty expensive, I'll list some here for the interested.

Ending Thoughts

This is by no means comprehensive. I will be updating this periodically once I have acquired a greater understanding of what it is that I'm actually doing. Until then...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment