Merge branch 'master' of ssh://glfw.git.sourceforge.net/gitroot/glfw/glfw

Conflicts:
	examples/CMakeLists.txt
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bccab08
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+CMakeFiles
+cmake_install.cmake
+CMakeCache.txt
+Makefile
+cmake_uninstall.cmake
+src/config.h
+src/x11/libglfw.pc
+src/win32/libglfw.pc
+src/cocoa/libglfw.pc
+*.so
+*.a
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 2a4e0bd..21e5bce 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -21,9 +21,10 @@
   add_executable(splitview WIN32 splitview.c)
   add_executable(triangle WIN32 triangle.c)
   add_executable(wave WIN32 wave.c)
+  add_executable(heightmap WIN32 heightmap.c)
 endif(APPLE)
 
-set(WINDOWS_BINARIES boing gears splitview triangle wave)
+set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave)
 set(CONSOLE_BINARIES listmodes)
 
 if(MSVC)
diff --git a/examples/heightmap.c b/examples/heightmap.c
new file mode 100644
index 0000000..90c4213
--- /dev/null
+++ b/examples/heightmap.c
@@ -0,0 +1,849 @@
+//========================================================================
+// Heightmap example program using OpenGL 3 core profile
+// Copyright (c) 2010 Olivier Delannoy
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+//    claim that you wrote the original software. If you use this software
+//    in a product, an acknowledgment in the product documentation would
+//    be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not
+//    be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source
+//    distribution.
+//
+//========================================================================
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <assert.h>
+#include <stddef.h>
+#include "getopt.h"
+
+
+#define GLFW_NO_GLU 1 
+#include <GL/glfw3.h>
+
+/* OpenGL 3.3 support  
+ * Functions are effectively mapped in init_opengl() */
+#ifndef GL_VERSION_3_0
+/* no defines */
+#endif
+
+#ifndef GL_VERSION_2_0
+
+typedef char GLchar;
+
+#define GL_BLEND_EQUATION_RGB             0x8009
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED    0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE       0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE     0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE       0x8625
+#define GL_CURRENT_VERTEX_ATTRIB          0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE      0x8642
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER    0x8645
+#define GL_STENCIL_BACK_FUNC              0x8800
+#define GL_STENCIL_BACK_FAIL              0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803
+#define GL_MAX_DRAW_BUFFERS               0x8824
+#define GL_DRAW_BUFFER0                   0x8825
+#define GL_DRAW_BUFFER1                   0x8826
+#define GL_DRAW_BUFFER2                   0x8827
+#define GL_DRAW_BUFFER3                   0x8828
+#define GL_DRAW_BUFFER4                   0x8829
+#define GL_DRAW_BUFFER5                   0x882A
+#define GL_DRAW_BUFFER6                   0x882B
+#define GL_DRAW_BUFFER7                   0x882C
+#define GL_DRAW_BUFFER8                   0x882D
+#define GL_DRAW_BUFFER9                   0x882E
+#define GL_DRAW_BUFFER10                  0x882F
+#define GL_DRAW_BUFFER11                  0x8830
+#define GL_DRAW_BUFFER12                  0x8831
+#define GL_DRAW_BUFFER13                  0x8832
+#define GL_DRAW_BUFFER14                  0x8833
+#define GL_DRAW_BUFFER15                  0x8834
+#define GL_BLEND_EQUATION_ALPHA           0x883D
+#define GL_MAX_VERTEX_ATTRIBS             0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_IMAGE_UNITS        0x8872
+#define GL_FRAGMENT_SHADER                0x8B30
+#define GL_VERTEX_SHADER                  0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS  0x8B4A
+#define GL_MAX_VARYING_FLOATS             0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE                    0x8B4F
+#define GL_FLOAT_VEC2                     0x8B50
+#define GL_FLOAT_VEC3                     0x8B51
+#define GL_FLOAT_VEC4                     0x8B52
+#define GL_INT_VEC2                       0x8B53
+#define GL_INT_VEC3                       0x8B54
+#define GL_INT_VEC4                       0x8B55
+#define GL_BOOL                           0x8B56
+#define GL_BOOL_VEC2                      0x8B57
+#define GL_BOOL_VEC3                      0x8B58
+#define GL_BOOL_VEC4                      0x8B59
+#define GL_FLOAT_MAT2                     0x8B5A
+#define GL_FLOAT_MAT3                     0x8B5B
+#define GL_FLOAT_MAT4                     0x8B5C
+#define GL_SAMPLER_1D                     0x8B5D
+#define GL_SAMPLER_2D                     0x8B5E
+#define GL_SAMPLER_3D                     0x8B5F
+#define GL_SAMPLER_CUBE                   0x8B60
+#define GL_SAMPLER_1D_SHADOW              0x8B61
+#define GL_SAMPLER_2D_SHADOW              0x8B62
+#define GL_DELETE_STATUS                  0x8B80
+#define GL_COMPILE_STATUS                 0x8B81
+#define GL_LINK_STATUS                    0x8B82
+#define GL_VALIDATE_STATUS                0x8B83
+#define GL_INFO_LOG_LENGTH                0x8B84
+#define GL_ATTACHED_SHADERS               0x8B85
+#define GL_ACTIVE_UNIFORMS                0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH      0x8B87
+#define GL_SHADER_SOURCE_LENGTH           0x8B88
+#define GL_ACTIVE_ATTRIBUTES              0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH    0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION       0x8B8C
+#define GL_CURRENT_PROGRAM                0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN      0x8CA0
+#define GL_LOWER_LEFT                     0x8CA1
+#define GL_UPPER_LEFT                     0x8CA2
+#define GL_STENCIL_BACK_REF               0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK         0x8CA5
+#endif 
+
+
+
+#ifndef GL_VERSION_1_5
+
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+
+#define GL_BUFFER_SIZE                    0x8764
+#define GL_BUFFER_USAGE                   0x8765
+#define GL_QUERY_COUNTER_BITS             0x8864
+#define GL_CURRENT_QUERY                  0x8865
+#define GL_QUERY_RESULT                   0x8866
+#define GL_QUERY_RESULT_AVAILABLE         0x8867
+#define GL_ARRAY_BUFFER                   0x8892
+#define GL_ELEMENT_ARRAY_BUFFER           0x8893
+#define GL_ARRAY_BUFFER_BINDING           0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY                      0x88B8
+#define GL_WRITE_ONLY                     0x88B9
+#define GL_READ_WRITE                     0x88BA
+#define GL_BUFFER_ACCESS                  0x88BB
+#define GL_BUFFER_MAPPED                  0x88BC
+#define GL_BUFFER_MAP_POINTER             0x88BD
+#define GL_STREAM_DRAW                    0x88E0
+#define GL_STREAM_READ                    0x88E1
+#define GL_STREAM_COPY                    0x88E2
+#define GL_STATIC_DRAW                    0x88E4
+#define GL_STATIC_READ                    0x88E5
+#define GL_STATIC_COPY                    0x88E6
+#define GL_DYNAMIC_DRAW                   0x88E8
+#define GL_DYNAMIC_READ                   0x88E9
+#define GL_DYNAMIC_COPY                   0x88EA
+#define GL_SAMPLES_PASSED                 0x8914
+#endif 
+
+
+
+
+/* OpenGL 3.0 */
+typedef void (APIENTRY * PFN_glGenVertexArrays)(GLsizei n, GLuint *arrays);
+typedef void (APIENTRY * PFN_glBindVertexArray)(GLuint array);
+typedef void (APIENTRY * PFN_glDeleteVertexArrays)(GLsizei n, GLuint *arrays);
+/* OpenGL 2.0 */
+typedef GLuint (APIENTRY * PFN_glCreateShader)(GLenum type);
+typedef void (APIENTRY * PFN_glDeleteShader)(GLuint shader);
+typedef void (APIENTRY * PFN_glCompileShader)(GLuint shader);
+typedef void (APIENTRY * PFN_glShaderSource)(GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRY * PFN_glGetShaderiv)(GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFN_glGetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef GLuint (APIENTRY * PFN_glCreateProgram)(void);
+typedef void (APIENTRY * PFN_glDeleteProgram)(GLuint program);
+typedef void (APIENTRY * PFN_glAttachShader)(GLuint program, GLuint shader);
+typedef void (APIENTRY * PFN_glLinkProgram)(GLuint program);
+typedef void (APIENTRY * PFN_glGetProgramiv)(GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFN_glGetProgramInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRY * PFN_glValidateProgram)(GLuint program);
+typedef void (APIENTRY * PFN_glUseProgram)(GLuint program);
+typedef GLint (APIENTRY * PFN_glGetUniformLocation)(GLuint program, const GLchar *name);
+typedef void (APIENTRY * PFN_glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef GLint (APIENTRY * PFN_glGetAttribLocation)(GLuint program, const GLchar *name);
+typedef void (APIENTRY * PFN_glEnableVertexAttribArray)(GLuint index);
+typedef void (APIENTRY * PFN_glVertexAttrib1f)(GLuint index, GLfloat x);
+typedef void (APIENTRY * PFN_glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+/* OpenGL 1.5 */ 
+typedef void (APIENTRY * PFN_glBindBuffer)(GLenum target, GLuint buffer);
+typedef void (APIENTRY * PFN_glDeleteBuffers)(GLsizei n, const GLuint *buffers);
+typedef void (APIENTRY * PFN_glGenBuffers)(GLsizei n, GLuint *buffers);
+typedef void (APIENTRY * PFN_glBufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRY * PFN_glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+
+/* OpenGL function pointers */ 
+static PFN_glGenBuffers                 pglGenBuffers = NULL;
+static PFN_glGenVertexArrays            pglGenVertexArrays = NULL;
+static PFN_glDeleteVertexArrays         pglDeleteVertexArrays = NULL;
+static PFN_glCreateShader               pglCreateShader = NULL;
+static PFN_glShaderSource               pglShaderSource = NULL;
+static PFN_glCompileShader              pglCompileShader = NULL;
+static PFN_glGetShaderiv                pglGetShaderiv = NULL;
+static PFN_glGetShaderInfoLog           pglGetShaderInfoLog = NULL;
+static PFN_glDeleteShader               pglDeleteShader = NULL;
+static PFN_glCreateProgram              pglCreateProgram = NULL;
+static PFN_glAttachShader               pglAttachShader = NULL;
+static PFN_glLinkProgram                pglLinkProgram = NULL;
+static PFN_glUseProgram                 pglUseProgram = NULL;
+static PFN_glGetProgramiv               pglGetProgramiv = NULL;
+static PFN_glGetProgramInfoLog          pglGetProgramInfoLog = NULL;
+static PFN_glDeleteProgram              pglDeleteProgram = NULL;
+static PFN_glGetUniformLocation         pglGetUniformLocation = NULL;
+static PFN_glUniformMatrix4fv           pglUniformMatrix4fv = NULL;
+static PFN_glGetAttribLocation          pglGetAttribLocation = NULL;
+
+/* Map height updates */
+#define MAX_CIRCLE_SIZE (5.0f)
+#define MAX_DISPLACEMENT (1.0f)
+#define DISPLACEMENT_SIGN_LIMIT (0.3f)
+#define MAX_ITER (200)
+#define NUM_ITER_AT_A_TIME (1)
+
+/* Map general information */
+#define MAP_SIZE (10.0f)
+#define MAP_NUM_VERTICES (80)
+#define MAP_NUM_TOTAL_VERTICES (MAP_NUM_VERTICES*MAP_NUM_VERTICES)
+#define MAP_NUM_LINES (3* (MAP_NUM_VERTICES - 1) * (MAP_NUM_VERTICES - 1) + \
+               2 * (MAP_NUM_VERTICES - 1))
+
+
+/* OpenGL function pointers */
+
+static PFN_glBindVertexArray            pglBindVertexArray = NULL;
+static PFN_glBufferData                 pglBufferData = NULL;
+static PFN_glBindBuffer                 pglBindBuffer = NULL;
+static PFN_glBufferSubData              pglBufferSubData = NULL;
+static PFN_glEnableVertexAttribArray    pglEnableVertexAttribArray = NULL;
+static PFN_glVertexAttribPointer        pglVertexAttribPointer = NULL;
+
+#define RESOLVE_GL_FCN(type, var, name) \
+    if (status == GL_TRUE) \
+    {\
+        var = glfwGetProcAddress((name));\
+        if ((var) == NULL)\
+        {\
+            status = GL_FALSE;\
+        }\
+    }
+
+
+static GLboolean init_opengl(void)
+{
+    GLboolean status = GL_TRUE;
+    RESOLVE_GL_FCN(PFN_glCreateShader, pglCreateShader, "glCreateShader");
+    RESOLVE_GL_FCN(PFN_glShaderSource, pglShaderSource, "glShaderSource");
+    RESOLVE_GL_FCN(PFN_glCompileShader, pglCompileShader, "glCompileShader");
+    RESOLVE_GL_FCN(PFN_glGetShaderiv, pglGetShaderiv, "glGetShaderiv");
+    RESOLVE_GL_FCN(PFN_glGetShaderInfoLog, pglGetShaderInfoLog, "glGetShaderInfoLog");
+    RESOLVE_GL_FCN(PFN_glDeleteShader, pglDeleteShader, "glDeleteShader");
+    RESOLVE_GL_FCN(PFN_glCreateProgram, pglCreateProgram, "glCreateProgram");
+    RESOLVE_GL_FCN(PFN_glAttachShader, pglAttachShader, "glAttachShader");
+    RESOLVE_GL_FCN(PFN_glLinkProgram, pglLinkProgram, "glLinkProgram");
+    RESOLVE_GL_FCN(PFN_glUseProgram, pglUseProgram, "glUseProgram");
+    RESOLVE_GL_FCN(PFN_glGetProgramiv, pglGetProgramiv, "glGetProgramiv");
+    RESOLVE_GL_FCN(PFN_glGetProgramInfoLog, pglGetProgramInfoLog, "glGetProgramInfoLog");
+    RESOLVE_GL_FCN(PFN_glDeleteProgram, pglDeleteProgram, "glDeleteProgram");
+    RESOLVE_GL_FCN(PFN_glGetUniformLocation, pglGetUniformLocation, "glGetUniformLocation");
+    RESOLVE_GL_FCN(PFN_glUniformMatrix4fv, pglUniformMatrix4fv, "glUniformMatrix4fv");
+    RESOLVE_GL_FCN(PFN_glGetAttribLocation, pglGetAttribLocation, "glGetAttribLocation");
+    RESOLVE_GL_FCN(PFN_glGenVertexArrays, pglGenVertexArrays, "glGenVertexArrays");
+    RESOLVE_GL_FCN(PFN_glDeleteVertexArrays, pglDeleteVertexArrays, "glDeleteVertexArrays");
+    RESOLVE_GL_FCN(PFN_glBindVertexArray, pglBindVertexArray, "glBindVertexArray");
+    RESOLVE_GL_FCN(PFN_glGenBuffers, pglGenBuffers, "glGenBuffers");
+    RESOLVE_GL_FCN(PFN_glBindBuffer, pglBindBuffer, "glBindBuffer");
+    RESOLVE_GL_FCN(PFN_glBufferData, pglBufferData, "glBufferData");
+    RESOLVE_GL_FCN(PFN_glBufferSubData, pglBufferSubData, "glBufferSubData");
+    RESOLVE_GL_FCN(PFN_glEnableVertexAttribArray, pglEnableVertexAttribArray, "glEnableVertexAttribArray");
+    RESOLVE_GL_FCN(PFN_glVertexAttribPointer, pglVertexAttribPointer, "glVertexAttribPointer");
+    return status;
+}
+/**********************************************************************
+ * Default shader programs
+ *********************************************************************/
+
+static const char* default_vertex_shader =
+"#version 150\n"
+"uniform mat4 project;\n"
+"uniform mat4 modelview;\n"
+"in float x;\n"
+"in float y;\n"
+"in float z;\n"
+"\n"
+"void main()\n"
+"{\n"
+"   gl_Position = project * modelview * vec4(x, y, z, 1.0);\n"
+"}\n";
+
+static const char* default_fragment_shader =
+"#version 150\n"
+"out vec4 gl_FragColor;\n"
+"void main()\n"
+"{\n"
+"    gl_FragColor = vec4(0.2, 1.0, 0.2, 1.0); \n"
+"}\n";
+
+/**********************************************************************
+ * Values for shader uniforms
+ *********************************************************************/
+
+/* Frustum configuration */
+static GLfloat view_angle = 45.0f;
+static GLfloat aspect_ratio = 4.0f/3.0f;
+static GLfloat z_near = 1.0f;
+static GLfloat z_far = 100.f;
+
+/* Projection matrix */
+static GLfloat projection_matrix[16] = {
+    1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 1.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 1.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f
+};
+
+/* Model view matrix */
+static GLfloat modelview_matrix[16] = {
+    1.0f, 0.0f, 0.0f, 0.0f,
+    0.0f, 1.0f, 0.0f, 0.0f,
+    0.0f, 0.0f, 1.0f, 0.0f,
+    0.0f, 0.0f, 0.0f, 1.0f
+};
+
+/**********************************************************************
+ * Heightmap vertex and index data
+ *********************************************************************/
+
+static GLfloat map_vertices[3][MAP_NUM_TOTAL_VERTICES];
+static GLuint  map_line_indices[2*MAP_NUM_LINES];
+
+/* Store uniform location for the shaders
+ * Those values are setup as part of the process of creating
+ * the shader program. They should not be used before creating
+ * the program.
+ */
+static GLuint mesh;
+static GLuint mesh_vbo[4];
+
+/**********************************************************************
+ * OpenGL helper functions
+ *********************************************************************/
+
+/* Load a (text) file into memory and return its contents
+ */
+static char* read_file_content(const char* filename)
+{
+    FILE* fd;
+    size_t size = 0;
+    char* result = NULL;
+
+    fd = fopen(filename, "r");
+    if (fd != NULL)
+    {
+        size = fseek(fd, 0, SEEK_END);
+        (void) fseek(fd, 0, SEEK_SET);
+
+        result = malloc(size + 1);
+        result[size] = '\0';
+        if (fread(result, size, 1, fd) != 1)
+        {
+            free(result);
+            result = NULL;
+        }
+        (void) fclose(fd);
+    }
+    return result;
+}
+
+/* Creates a shader object of the specified type using the specified text
+ */
+static GLuint make_shader(GLenum type, const char* shader_src)
+{
+    GLuint shader;
+    GLint shader_ok;
+    GLsizei log_length;
+    char info_log[8192];
+
+    shader = pglCreateShader(type);
+    if (shader != 0)
+    {
+        pglShaderSource(shader, 1, (const GLchar**)&shader_src, NULL);
+        pglCompileShader(shader);
+        pglGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
+        if (shader_ok != GL_TRUE)
+        {
+            fprintf(stderr, "ERROR: Failed to compile %s shader\n", (type == GL_FRAGMENT_SHADER) ? "fragment" : "vertex" );
+            pglGetShaderInfoLog(shader, 8192, &log_length,info_log);
+            fprintf(stderr, "ERROR: \n%s\n\n", info_log);
+            pglDeleteShader(shader);
+            shader = 0;
+        }
+    }
+    return shader;
+}
+
+/* Creates a program object using the specified vertex and fragment text
+ */
+static GLuint make_shader_program(const char* vertex_shader_src, const char* fragment_shader_src)
+{
+    GLuint program = 0u;
+    GLint program_ok;
+    GLuint vertex_shader = 0u;
+    GLuint fragment_shader = 0u;
+    GLsizei log_length;
+    char info_log[8192];
+
+    vertex_shader = make_shader(GL_VERTEX_SHADER, (vertex_shader_src == NULL) ? default_vertex_shader : vertex_shader_src);
+    if (vertex_shader != 0u)
+    {
+        fragment_shader = make_shader(GL_FRAGMENT_SHADER, (fragment_shader_src == NULL) ? default_fragment_shader : fragment_shader_src);
+        if (fragment_shader != 0u)
+        {
+            /* make the program that connect the two shader and link it */
+            program = pglCreateProgram();
+            if (program != 0u)
+            {
+                /* attach both shader and link */
+                pglAttachShader(program, vertex_shader);
+                pglAttachShader(program, fragment_shader);
+                pglLinkProgram(program);
+                pglGetProgramiv(program, GL_LINK_STATUS, &program_ok);
+
+                if (program_ok != GL_TRUE)
+                {
+                    fprintf(stderr, "ERROR, failed to link shader program\n");
+                    pglGetProgramInfoLog(program, 8192, &log_length, info_log);
+                    fprintf(stderr, "ERROR: \n%s\n\n", info_log);
+                    pglDeleteProgram(program);
+                    pglDeleteShader(fragment_shader);
+                    pglDeleteShader(vertex_shader);
+                    program = 0u;
+                }
+            }
+        }
+        else
+        {
+            fprintf(stderr, "ERROR: Unable to load fragment shader\n");
+            pglDeleteShader(vertex_shader);
+        }
+    }
+    else
+    {
+        fprintf(stderr, "ERROR: Unable to load vertex shader\n");
+    }
+    return program;
+}
+
+/**********************************************************************
+ * Geometry creation functions
+ *********************************************************************/
+
+/* Generate vertices and indices for the heightmap
+ */
+static void init_map(void)
+{
+    int i;
+    int j;
+    int k;
+    GLfloat step = MAP_SIZE / (MAP_NUM_VERTICES - 1);
+    GLfloat x = 0.0f;
+    GLfloat z = 0.0f;
+    /* Create a flat grid */
+    k = 0;
+    for (i = 0 ; i < MAP_NUM_VERTICES ; ++i)
+    {
+        for (j = 0 ; j < MAP_NUM_VERTICES ; ++j)
+        {
+            map_vertices[0][k] = x;
+            map_vertices[1][k] = 0.0f;
+            map_vertices[2][k] = z;
+            z += step;
+            ++k;
+        }
+        x += step;
+        z = 0.0f;
+    }
+#if DEBUG_ENABLED
+    for (i = 0 ; i < MAP_NUM_TOTAL_VERTICES ; ++i)
+    {
+        printf ("Vertice %d (%f, %f, %f)\n",
+                i, map_vertices[0][i], map_vertices[1][i], map_vertices[2][i]);
+
+    }
+#endif
+    /* create indices */
+    /* line fan based on i
+     * i+1
+     * |  / i + n + 1
+     * | /
+     * |/
+     * i --- i + n
+     */
+
+    /* close the top of the square */
+    k = 0;
+    for (i = 0 ; i < MAP_NUM_VERTICES  -1 ; ++i)
+    {
+        map_line_indices[k++] = (i + 1) * MAP_NUM_VERTICES -1;
+        map_line_indices[k++] = (i + 2) * MAP_NUM_VERTICES -1;
+    }
+    /* close the right of the square */
+    for (i = 0 ; i < MAP_NUM_VERTICES -1 ; ++i)
+    {
+        map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i;
+        map_line_indices[k++] = (MAP_NUM_VERTICES - 1) * MAP_NUM_VERTICES + i + 1;
+    }
+
+    for (i = 0 ; i < (MAP_NUM_VERTICES - 1) ; ++i)
+    {
+        for (j = 0 ; j < (MAP_NUM_VERTICES - 1) ; ++j)
+        {
+            int ref = i * (MAP_NUM_VERTICES) + j;
+            map_line_indices[k++] = ref;
+            map_line_indices[k++] = ref + 1;
+
+            map_line_indices[k++] = ref;
+            map_line_indices[k++] = ref + MAP_NUM_VERTICES;
+
+            map_line_indices[k++] = ref;
+            map_line_indices[k++] = ref + MAP_NUM_VERTICES + 1;
+        }
+    }
+
+#ifdef DEBUG_ENABLED
+    for (k = 0 ; k < 2 * MAP_NUM_LINES ; k += 2)
+    {
+        int beg, end;
+        beg = map_line_indices[k];
+        end = map_line_indices[k+1];
+        printf ("Line %d: %d -> %d (%f, %f, %f) -> (%f, %f, %f)\n",
+                k / 2, beg, end,
+                map_vertices[0][beg], map_vertices[1][beg], map_vertices[2][beg],
+                map_vertices[0][end], map_vertices[1][end], map_vertices[2][end]);
+    }
+#endif
+}
+
+static void generate_heightmap__circle(float* center_x, float* center_y,
+        float* size, float* displacement)
+{
+    float sign;
+    /* random value for element in between [0-1.0] */
+    *center_x = (MAP_SIZE * rand()) / (1.0f * RAND_MAX);
+    *center_y = (MAP_SIZE * rand()) / (1.0f * RAND_MAX);
+    *size = (MAX_CIRCLE_SIZE * rand()) / (1.0f * RAND_MAX);
+    sign = (1.0f * rand()) / (1.0f * RAND_MAX);
+    sign = (sign < DISPLACEMENT_SIGN_LIMIT) ? -1.0f : 1.0f;
+    *displacement = (sign * (MAX_DISPLACEMENT * rand())) / (1.0f * RAND_MAX);
+}
+
+/* Run the specified number of iterations of the generation process for the
+ * heightmap
+ */
+static void update_map(int num_iter)
+{
+    assert(num_iter > 0);
+    while(num_iter)
+    {
+        /* center of the circle */
+        float center_x;
+        float center_z;
+        float circle_size;
+        float disp;
+        size_t ii;
+        generate_heightmap__circle(&center_x, &center_z, &circle_size, &disp);
+        disp = disp / 2.0f;
+        for (ii = 0u ; ii < MAP_NUM_TOTAL_VERTICES ; ++ii)
+        {
+            GLfloat dx = center_x - map_vertices[0][ii];
+            GLfloat dz = center_z - map_vertices[2][ii];
+            GLfloat pd = (2.0f * sqrtf((dx * dx) + (dz * dz))) / circle_size;
+            if (fabs(pd) <= 1.0f)
+            {
+                /* tx,tz is within the circle */
+                GLfloat new_height = disp + (cos(pd*3.14f)*disp);
+                map_vertices[1][ii] += new_height;
+            }
+        }
+        --num_iter;
+    }
+}
+
+/**********************************************************************
+ * OpenGL helper functions
+ *********************************************************************/
+
+/* Create VBO, IBO and VAO objects for the heightmap geometry and bind them to
+ * the specified program object
+ */
+static void make_mesh(GLuint program)
+{
+    GLuint attrloc;
+
+    pglGenVertexArrays(1, &mesh);
+    pglGenBuffers(4, mesh_vbo);
+    pglBindVertexArray(mesh);
+    /* Prepare the data for drawing through a buffer inidices */
+    pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_vbo[3]);
+    pglBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)* MAP_NUM_LINES * 2, map_line_indices, GL_STATIC_DRAW);
+
+    /* Prepare the attributes for rendering */
+    attrloc = pglGetAttribLocation(program, "x");
+    pglBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[0]);
+    pglBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[0][0], GL_STATIC_DRAW);
+    pglEnableVertexAttribArray(attrloc);
+    pglVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
+
+    attrloc = pglGetAttribLocation(program, "z");
+    pglBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[2]);
+    pglBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[2][0], GL_STATIC_DRAW);
+    pglEnableVertexAttribArray(attrloc);
+    pglVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
+
+    attrloc = pglGetAttribLocation(program, "y");
+    pglBindBuffer(GL_ARRAY_BUFFER, mesh_vbo[1]);
+    pglBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0], GL_DYNAMIC_DRAW);
+    pglEnableVertexAttribArray(attrloc);
+    pglVertexAttribPointer(attrloc, 1, GL_FLOAT, GL_FALSE, 0, 0);
+}
+
+/* Update VBO vertices from source data
+ */
+static void update_mesh(void)
+{
+    pglBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * MAP_NUM_TOTAL_VERTICES, &map_vertices[1][0]);
+}
+
+/**********************************************************************
+ * GLFW callback functions
+ *********************************************************************/
+
+/* The program runs as long as this is GL_TRUE
+ */
+static GLboolean running = GL_TRUE;
+
+/* GLFW Window management functions */
+static int window_close_callback(GLFWwindow window)
+{
+    running = GL_FALSE;
+
+    /* Disallow window closing
+     * The window will be closed when the main loop terminates */
+    return 0;
+}
+
+static void key_callback(GLFWwindow window, int key, int action)
+{
+    switch(key)
+    {
+        case GLFW_KEY_ESC:
+            /* Exit program on Escape */
+            running = GL_FALSE;
+            break;
+    }
+}
+
+/* Print usage information */
+static void usage(void)
+{
+    printf("Usage: heightmap [-v <vertex_shader_path>] [-f <fragment_shader_path>]\n");
+    printf("       heightmap [-h]\n");
+}
+
+int main(int argc, char** argv)
+{
+    GLFWwindow window;
+    int ch, iter;
+    double dt;
+    double last_update_time;
+    int frame;
+    float f;
+    GLint uloc_modelview;
+    GLint uloc_project;
+
+    char* vertex_shader_path = NULL;
+    char* fragment_shader_path = NULL;
+    char* vertex_shader_src = NULL;
+    char* fragment_shader_src = NULL;
+    GLuint shader_program;
+
+    while ((ch = getopt(argc, argv, "f:v:h")) != -1)
+    {
+        switch (ch)
+        {
+            case 'f':
+                fragment_shader_path = optarg;
+                break;
+            case 'v':
+                vertex_shader_path = optarg;
+                break;
+            case 'h':
+                usage();
+                exit(EXIT_SUCCESS);
+            default:
+                usage();
+                exit(EXIT_FAILURE);
+        }
+    }
+
+    if (fragment_shader_path)
+    {
+        vertex_shader_src = read_file_content(fragment_shader_path);
+        if (!fragment_shader_src)
+        {
+            fprintf(stderr,
+                    "ERROR: unable to load fragment shader from '%s'\n",
+                    fragment_shader_path);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    if (vertex_shader_path)
+    {
+        vertex_shader_src = read_file_content(vertex_shader_path);
+        if (!vertex_shader_src)
+        {
+            fprintf(stderr,
+                    "ERROR: unable to load vertex shader from '%s'\n",
+                    fragment_shader_path);
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    if (GL_TRUE != glfwInit())
+    {
+        fprintf(stderr, "ERROR: Unable to initialize GLFW\n");
+        usage();
+
+        free(vertex_shader_src);
+        free(fragment_shader_src);
+        exit(EXIT_FAILURE);
+    }
+
+    glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE);
+    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
+    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
+    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+    glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
+
+    window = glfwOpenWindow(800, 600, GLFW_WINDOWED, "GLFW OpenGL3 Heightmap demo");
+    if (! window )
+    {
+        fprintf(stderr, "ERROR: Unable to create the OpenGL context and associated window\n");
+        usage();
+
+        free(vertex_shader_src);
+        free(fragment_shader_src);
+        exit(EXIT_FAILURE);
+    }
+    glfwSetWindowCloseCallback(window, window_close_callback);
+    glfwSetKeyCallback(window, key_callback);
+    /* Register events callback */
+
+    if (GL_TRUE != init_opengl())
+    {
+        fprintf(stderr, "ERROR: unable to resolve OpenGL function pointers\n");
+        free(vertex_shader_src);
+        free(fragment_shader_src);
+        exit(EXIT_FAILURE);
+    }
+    /* Prepare opengl resources for rendering */
+    shader_program = make_shader_program(vertex_shader_src , fragment_shader_src);
+    free(vertex_shader_src);
+    free(fragment_shader_src);
+
+    if (shader_program == 0u)
+    {
+        fprintf(stderr, "ERROR: during creation of the shader program\n");
+        usage();
+        exit(EXIT_FAILURE);
+    }
+
+    pglUseProgram(shader_program);
+    uloc_project   = pglGetUniformLocation(shader_program, "project");
+    uloc_modelview = pglGetUniformLocation(shader_program, "modelview");
+
+    /* Compute the projection matrix */
+    f = 1.0f / tanf(view_angle / 2.0f);
+    projection_matrix[0]  = f / aspect_ratio;
+    projection_matrix[5]  = f;
+    projection_matrix[10] = (z_far + z_near)/ (z_near - z_far);
+    projection_matrix[11] = -1.0f;
+    projection_matrix[14] = 2.0f * (z_far * z_near) / (z_near - z_far);
+    pglUniformMatrix4fv(uloc_project, 1, GL_FALSE, projection_matrix);
+
+    /* Set the camera position */
+    modelview_matrix[12]  = -5.0f;
+    modelview_matrix[13]  = -5.0f;
+    modelview_matrix[14]  = -20.0f;
+    pglUniformMatrix4fv(uloc_modelview, 1, GL_FALSE, modelview_matrix);
+
+    /* Create mesh data */
+    init_map();
+    make_mesh(shader_program);
+
+    /* Create vao + vbo to store the mesh */
+    /* Create the vbo to store all the information for the grid and the height */
+
+    /* setup the scene ready for rendering */
+    glViewport(0, 0, 800, 600);
+    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+    /* main loop */
+    frame = 0;
+    iter = 0;
+    dt = last_update_time = glfwGetTime();
+
+    while (running)
+    {
+        ++frame;
+        /* render the next frame */
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDrawElements(GL_LINES, 2* MAP_NUM_LINES , GL_UNSIGNED_INT, 0);
+
+        /* display and process events through callbacks */
+        glfwSwapBuffers();
+        glfwPollEvents();
+        /* Check the frame rate and update the heightmap if needed */
+        dt = glfwGetTime();
+        if ((dt - last_update_time) > 0.2)
+        {
+            /* generate the next iteration of the heightmap */
+            if (iter < MAX_ITER)
+            {
+                update_map(NUM_ITER_AT_A_TIME);
+                update_mesh();
+                iter += NUM_ITER_AT_A_TIME;
+            }
+            last_update_time = dt;
+            frame = 0;
+        }
+    }
+
+    exit(EXIT_SUCCESS);
+}
+
diff --git a/src/x11/platform.h b/src/x11/platform.h
index 59852e2..6a05953 100644
--- a/src/x11/platform.h
+++ b/src/x11/platform.h
@@ -40,10 +40,11 @@
 #include <X11/Xlib.h>
 #include <X11/keysym.h>
 #include <X11/Xatom.h>
+#define GLX_GLXEXT_LEGACY 1 
 #include <GL/glx.h>
-
-#include "../../include/GL/glfw3.h"
 #include "../../include/GL/glxext.h"
+#include "../../include/GL/glfw3.h"
+
 
 // We need declarations for GLX version 1.3 or above even if the server doesn't
 // support version 1.3