Index: SimpleGL3Window.cpp
===================================================================
--- SimpleGL3Window.cpp	(revision 0)
+++ SimpleGL3Window.cpp	(working copy)
@@ -0,0 +1,130 @@
+
+#include <stdio.h>
+#include <FL/Fl.H>
+#include <FL/Fl_Gl_Window.H>
+#include <FL/gl.h>
+#ifdef __APPLE__
+#  include <OpenGL/gl3.h>
+#  include <OpenGL/OpenGL.h>
+#endif
+
+class SimpleGL3Window : public Fl_Gl_Window {
+  GLuint shaderProgram;
+  GLuint vertexArrayObject;
+  GLuint vertexBuffer;
+  
+  GLint positionUniform;
+  GLint colourAttribute;
+  GLint positionAttribute;
+public:
+  SimpleGL3Window(int w, int h) :  Fl_Gl_Window(w, h) {
+#ifdef __APPLE__
+    static int array[] = { // equivalent to FL_RGB | FL_SINGLE
+    kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
+    0 };
+    mode(array);
+#endif
+    shaderProgram = 0;
+  }
+  void draw() {
+    if (!shaderProgram) {
+      GLuint  vs;
+      GLuint  fs;
+      const char    *vss="#version 150\n\
+      uniform vec2 p;\
+      in vec4 position;\
+      in vec4 colour;\
+      out vec4 colourV;\
+      void main (void)\
+      {\
+      colourV = colour;\
+      gl_Position = vec4(p, 0.0, 0.0) + position;\
+      }";
+      const char    *fss="#version 150\n\
+      in vec4 colourV;\
+      out vec4 fragColour;\
+      void main(void)\
+      {\
+      fragColour = colourV;\
+      }";
+      vs = glCreateShader(GL_VERTEX_SHADER);
+      glShaderSource(vs, 1, &vss, NULL);
+      glCompileShader(vs);
+      fs = glCreateShader(GL_FRAGMENT_SHADER);
+      glShaderSource(fs, 1, &fss, NULL);
+      glCompileShader(fs);
+      //printf("vs: %i, fs: %i\n",vs,fs);
+      
+      // Attach the shaders
+      shaderProgram = glCreateProgram();
+      glAttachShader(shaderProgram, vs);
+      glAttachShader(shaderProgram, fs);
+      glBindFragDataLocation(shaderProgram, 0, "fragColour");
+      glLinkProgram(shaderProgram);
+      
+      // Get pointers to uniforms and attributes
+      positionUniform = glGetUniformLocation(shaderProgram, "p");
+      colourAttribute = glGetAttribLocation(shaderProgram, "colour");
+      positionAttribute = glGetAttribLocation(shaderProgram, "position");
+      glDeleteShader(vs);
+      glDeleteShader(fs);
+      //printf("positionUniform: %i, colourAttribute: %i, positionAttribute: %i\n",positionUniform,colourAttribute,positionAttribute);
+      
+      // Upload vertices (1st four values in a row) and colours (following four values)
+      GLfloat vertexData[]= { -0.5,-0.5,0.0,1.0,   1.0,0.0,0.0,1.0,
+        -0.5, 0.5,0.0,1.0,   0.0,1.0,0.0,1.0,
+        0.5, 0.5,0.0,1.0,   0.0,0.0,1.0,1.0,
+        0.5,-0.5,0.0,1.0,   1.0,1.0,1.0,1.0};
+      glGenVertexArrays(1, &vertexArrayObject);
+      glBindVertexArray(vertexArrayObject);
+      
+      glGenBuffers(1, &vertexBuffer);
+      glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
+      glBufferData(GL_ARRAY_BUFFER, 4*8*sizeof(GLfloat), vertexData, GL_STATIC_DRAW);
+      
+      glEnableVertexAttribArray((GLuint)positionAttribute);
+      glEnableVertexAttribArray((GLuint)colourAttribute  );
+      glVertexAttribPointer((GLuint)positionAttribute, 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), 0);
+      glVertexAttribPointer((GLuint)colourAttribute  , 4, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (char*)0+4*sizeof(GLfloat));
+    }
+    else if ((!valid())) {
+      glViewport(0,0,pixel_w(),pixel_h());
+    }
+    glClearColor(0.5, 0.5, 0.5, 1.0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glUseProgram(shaderProgram);
+    GLfloat p[]={0,0};
+    glUniform2fv(positionUniform, 1, (const GLfloat *)&p);
+    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+  }
+  int handle(int event) {
+    if (event == FL_PUSH) {
+      static float factor = 1.1;
+      GLfloat data[4];
+      glGetBufferSubData(GL_ARRAY_BUFFER, 0, 4*sizeof(GLfloat), data);
+      if (data[0] < -0.88 || data[0] > -0.5) factor = 1/factor;
+      data[0] *= factor;
+      glBufferSubData(GL_ARRAY_BUFFER, 0, 4*sizeof(GLfloat), data);
+      glGetBufferSubData(GL_ARRAY_BUFFER, 24*sizeof(GLfloat), 4*sizeof(GLfloat), data);
+      data[0] *= factor;
+      glBufferSubData(GL_ARRAY_BUFFER, 24*sizeof(GLfloat), 4*sizeof(GLfloat), data);
+     redraw();
+      return 1;
+    }
+    return Fl_Gl_Window::handle(event);
+  }
+};
+
+
+int main(int argc, char **argv)
+{
+  Fl::use_high_res_GL(1);
+  SimpleGL3Window *win = new SimpleGL3Window(500, 500);
+  win->end();
+  win->resizable(win);
+  win->show();
+  Fl::run();
+}
+
+// end of file
+
