Skip to content

Instantly share code, notes, and snippets.

Last active December 21, 2018 18:25
Show Gist options
  • Save hahuang65/0c7d14a6fedb221c8b87 to your computer and use it in GitHub Desktop.
Save hahuang65/0c7d14a6fedb221c8b87 to your computer and use it in GitHub Desktop.
Beginning OpenGL Development on OS X: Post 1 - 5/7/2014
# GLFW is a windowing manager for OpenGL. Makes things easier when working with windows, as well as input via keyboard or mouse.
# GLFW is in homebrew/versions so we'll have to tap that to be able to install.
brew tap homebrew/versions
brew install glfw3
# GLEW offers bindings for your OS so that you don't have to call some OS specific OpenGL calls.
brew install glew
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
// Define some of the global variables we're using for this sample
GLuint program;
GLuint vao;
// This is the callback we'll be registering with GLFW for errors.
// It'll just print out the error to the STDERR stream.
void error_callback(int error, const char* description) {
fputs(description, stderr);
// This is the callback we'll be registering with GLFW for keyboard handling.
// The only thing we're doing here is setting up the window to close when we press ESC
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
int main() {
// Initialize GLFW, and if it fails to initialize for any reason, print it out to STDERR.
if (!glfwInit()) {
fprintf(stderr, "Failed initialize GLFW.");
// Set the error callback, as mentioned above.
// Set up OpenGL options.
// Use OpenGL verion 4.1,
// GLFW_OPENGL_FORWARD_COMPAT specifies whether the OpenGL context should be forward-compatible, i.e. one where all functionality deprecated in the requested version of OpenGL is removed.
// Indicate we only want the newest core profile, rather than using backwards compatible and deprecated features.
// Make the window resize-able.
// Create a window to put our stuff in.
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
// If the window fails to be created, print out the error, clean up GLFW and exit the program.
if(!window) {
fprintf(stderr, "Failed to create GLFW window.");
// Use the window as the current context (everything that's drawn will be place in this window).
// Set the keyboard callback so that when we press ESC, it knows what to do.
glfwSetKeyCallback(window, key_callback);
printf("OpenGL version supported by this platform (%s): \n", glGetString(GL_VERSION));
// Makes sure all extensions will be exposed in GLEW and initialize GLEW.
glewExperimental = GL_TRUE;
// Shaders is the next part of our program. Notice that we use version 410 core. This has to match our version of OpenGL we are using, which is the core profile in version 4.1, thus 410 core.
// Vertex shader source code. This draws the vertices in our window. We have 3 vertices since we're drawing an triangle.
// Each vertex is represented by a vector of size 4 (x, y, z, w) coordinates.
static const char * vs_source[] =
"#version 410 core \n"
" \n"
"void main(void) \n"
"{ \n"
" const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0), \n"
" vec4(-0.25, -0.25, 0.5, 1.0), \n"
" vec4( 0.25, 0.25, 0.5, 1.0)); \n"
" \n"
" gl_Position = vertices[gl_VertexID]; \n"
"} \n"
// Fragment shader source code. This determines the colors in the fragment generated in the shader pipeline. In this case, it colors the inside of our triangle specified by our vertex shader.
static const char * fs_source[] =
"#version 410 core \n"
" \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = vec4(0.0, 0.8, 1.0, 1.0); \n"
"} \n"
// This next section we'll generate the OpenGL program and attach the shaders to it so that we can render our triangle.
program = glCreateProgram();
// We create a shader with our fragment shader source code and compile it.
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
// We create a shader with our vertex shader source code and compile it.
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
// We'll attach our two compiled shaders to the OpenGL program.
glAttachShader(program, vs);
glAttachShader(program, fs);
// Generate vertex arrays for our program. More explanation on this will come in the future.
glGenVertexArrays(1, &vao);
// We'll specify that we want to use this program that we've attached the shaders to.
// This is our render loop. As long as our window remains open (ESC is not pressed), we'll continue to render things.
// Set up our green background color
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
// Clear the entire buffer with our green color (sets the background to be green).
glClearBufferfv(GL_COLOR, 0, green);
// Draw our triangles
glDrawArrays(GL_TRIANGLES, 0, 3);
// Swap the buffers so that what we drew will appear on the screen.
// Program clean up when the window gets closed.
glDeleteVertexArrays(1, &vao);
# OBJS specifies which files to compile as part of the project
OBJS = main.cpp
# CC specifies which compiler we're using
CC = g++
# INCLUDE_PATHS specifies the additional include paths we'll need
INCLUDE_PATHS = -I/usr/local/include -I/opt/X11/include
# LIBRARY_PATHS specifies the additional library paths we'll need
LIBRARY_PATHS = -L/usr/local/lib -I/opt/X11/lib
# COMPILER_FLAGS specifies the additional compilation options we're using
# -w suppresses all warnings
# LINKER_FLAGS specifies the libraries we're linking against
# Cocoa, IOKit, and CoreVideo are needed for static GLFW3.
LINKER_FLAGS = -framework OpenGL -lglfw3 -lglew
# OBJ_NAME specifies the name of our exectuable
OBJ_NAME = main
#This is the target that compiles our executable
all : $(OBJS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment