This post was written with OS X 10.10 and Xcode 6.4 in mind. With OS X 10.11 and Xcode 7 just around the corner (as of the time this was written) it's safe to say some of the details in this post will become quickly outdated. If I learn that this is the case I will try and update this post. But if you're reading this in 2021 or something don't expect any of this to be accurate.
A few days ago I set out to create a simple OpenGL program on OS X (10.10.4 to be exact) without using a wrapper library like SDL. It turns out there's lots of information out there on how to go about this. But, I never came across anything that had complete start to finish instructions for the latest versions of OS X, Xcode and OpenGL. By "start to finish" I mean from creating a new project all the way up to creating a .app that can run on another person's computer without them needing to install any dependencies. Every blog post or tutorial I came across had at least one frustrating gap somewhere in it where the author had (most likely unintentionally) assumed either the reader knew what they were doing or that the step(s) in question were easy to figure out without lots of detail. I don't know about you, but I have no idea what I'm doing and I'm real dumb, so figuring new things out ain't easy. My goal here is to document the process in as much detail as possible so you can't mess it up. There's definitely other, probably better, ways to do this; but this way works pretty well for me. I'm going to try and assume that you have very little knowledge of any of the tools involved and that you're goal is the same as mine: start from scratch and end up with something you can send to a friend. I will however assume that you're no stranger to C++ or git since they are way outside of the scope of this post.
Before getting started you'll want to acquire the latest version of Xcode (6.4 (6E35b) as of 7/28/15) and Homebrew. Xcode can be downloaded through the App Store. Detailed instructions for installing Homebrew can be found here but you can probably just use the instructions on the home page. Homebrew doesn't really have versions as far as I know, just run
brew update to make sure you're up to date. You'll also want to make sure you've got the Xcode Command Line Tools Package installed; run
xcode-select --install and you'll be good to go.
Now that you've got Xcode and Homebrew you're ready to install the two libraries you're going to use to make working with OpenGL a less shitty experience: GLEW and GLFW. The somewhat ironic thing is that getting GLEW and GLFW set up in an Xcode project is itself a real shitty experience.
A quick aside: the last time I touched OpenGL was probably around 2003, maybe early 2004. At the time I was on Windows XP and wasn't using either GLEW or GLFW (or GLUT or any similar library). Instead I used
wglCreateContext (and a shitload of other boilerplate) to create a window and rendering context, switch statements that approached several hundred lines inside a good old fashioned
WindowProc for handling input, and I don't think I even had a graphics card capable of using anything past OpenGL 1.3 so I definitely wasn't bothering with GLEW.
All that is to say, when I started reading up on OpenGL again I was kind of confused by the purpose of these libraries. If you've actually been keeping up with OpenGL for the last eleven or twelve years then they're probably not so mysterious. But if you're way out of the loop or totally new to this I think I can shed some light on them and hopefully explain in a convincing way why you'd want to use them. You can skip ahead if this is all familiar territory for you. It wasn't for me so I'm going to provide a brief synopsis of each.
Let's start with GLEW. OpenGL, like most standards and specifications, is an ongoing and living thing. Since it is fundamentally tied to its implimentation and the underlying graphics hardware, care has been taken to introduce new features in a controlled manner. This is done through extensions which allow hardware vendors to implement and expose particular features independently. One fairly large downside to the way extensions are implemented is that each extension function's location has to be determined at run time. For this calls to
dlsym are necessary (or if you're on Windows:
wglGetProcAddress). Doing this for every extension function you intend to call is obviously less than ideal. GLEW takes care of this for you and makes calling OpenGL functions a seamless process. You might wonder, "Is this really necessary?", the answer is no, but boilerplate code is no fun to write.
Like GLEW, GLFW serves the purpose of reducing boilerplate code to a minimum. However the type of boilerplate it focuses on is entirely different. Before you can actually start using OpenGL you need a rendering context. To get a rendering context you need a surface or window to render to. It should go without saying that creating a window is extremely platform dependent. Even when you're targeting just one platform the process can be laborious. GLFW's
glfwCreateWindow makes the whole process nice and easy. As an added bonus GLFW also normalizes the process of dealing with multiple monitors and handling input. I'm usually a big believer in DIY, but unless you've got a really good reason you should probably let GLFW or a similar library handle the details of this kind of highly platform specific initialization. If you're curious you will definitely learn something useful by creating windows and handling input without help, but either can be a very deep rabbit hole if you're not careful.