Make the shaders work on NVidia
[gltest.git] / glutil_gl2.cpp
index e8cc1904787cab795391912a89e26f276344e329..87d8e0cb33c2ec7f8153985e3bc08bf4cc5f3284 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "glutil.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string>
 #include <sstream>
 
-#include "glutil.h"
-
 // extension functions we use
 typedef GLuint (*GLCREATESHADERPROC) (GLenum type);
 typedef void (*GLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
@@ -34,6 +34,7 @@ typedef void (*GLATTACHSHADERPROC) (GLuint program, GLuint shader);
 typedef void (*GLLINKPROGRAMPROC) (GLuint program);
 typedef GLint (*GLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
 typedef void (*GLUSEPROGRAMPROC) (GLuint program);
+
 typedef void (*GLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
 typedef void (*GLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
 typedef void (*GLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
@@ -41,6 +42,13 @@ typedef void (*GLBINDBUFFERPROC) (GLenum target, GLuint buffer);
 typedef void (*GLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
 typedef void (*GLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
 
+#ifdef CON_GL3
+// VAOs are only supported in GL3+, and not needed in earler contexts
+typedef void (*GLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (*GLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (*GLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+#endif
+
 GLGETSHADERIVPROC p_glGetShaderiv = NULL;
 GLGETSHADERINFOLOGPROC p_glGetShaderInfoLog = NULL;
 GLCREATESHADERPROC p_glCreateShader = NULL;
@@ -51,6 +59,7 @@ GLATTACHSHADERPROC p_glAttachShader = NULL;
 GLLINKPROGRAMPROC p_glLinkProgram = NULL;
 GLGETATTRIBLOCATIONPROC p_glGetAttribLocation = NULL;
 GLUSEPROGRAMPROC p_glUseProgram = NULL;
+
 GLVERTEXATTRIBPOINTERPROC p_glVertexAttribPointer = NULL;
 GLENABLEVERTEXATTRIBARRAYPROC p_glEnableVertexAttribArray = NULL;
 GLGENBUFFERSPROC p_glGenBuffers = NULL;
@@ -58,13 +67,18 @@ GLBINDBUFFERPROC p_glBindBuffer = NULL;
 GLBUFFERDATAPROC p_glBufferData = NULL;
 GLDELETEBUFFERSPROC p_glDeleteBuffers = NULL;
 
+#ifdef CON_GL3
+GLBINDVERTEXARRAYPROC p_glBindVertexArray = NULL;
+GLDELETEVERTEXARRAYSPROC p_glDeleteVertexArrays = NULL;
+GLGENVERTEXARRAYSPROC p_glGenVertexArrays = NULL;
+#endif
+
 // resolve function pointers
 static T_proc resolveFunctionPointer(T_glGetProcAddress p_glGetProcAddress, const char *name)
 {
        T_proc proc = p_glGetProcAddress(name);
        if (proc == NULL) {
-               fprintf(stderr, "Error resolvung function %s\n", name);
-               exit(1);
+               die("Error resolvung function %s\n", name);
        }
        return proc;
 }
@@ -81,8 +95,7 @@ void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress)
        int majorVersion;
        ssm >> majorVersion;
        if (majorVersion < 2) {
-               fprintf(stderr, "Need at least GL 2.0 to function properly, but detected version %d\n", majorVersion);
-               exit(1);
+               die("Need at least GL 2.0 to function properly, but detected version %d\n", majorVersion);
        }
 #endif
        
@@ -96,6 +109,13 @@ void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress)
        p_glAttachShader = (GLATTACHSHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glAttachShader");
        p_glLinkProgram = (GLLINKPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glLinkProgram");
        p_glGetAttribLocation = (GLGETATTRIBLOCATIONPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetAttribLocation");
+
+#ifdef CON_GL3
+       p_glBindVertexArray = (GLBINDVERTEXARRAYPROC)resolveFunctionPointer(p_glGetProcAddress, "glBindVertexArray");
+       p_glDeleteVertexArrays = (GLDELETEVERTEXARRAYSPROC)resolveFunctionPointer(p_glGetProcAddress, "glDeleteVertexArrays");
+       p_glGenVertexArrays = (GLGENVERTEXARRAYSPROC)resolveFunctionPointer(p_glGetProcAddress, "glGenVertexArrays");
+#endif
+
        p_glUseProgram = (GLUSEPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glUseProgram");
        p_glVertexAttribPointer = (GLVERTEXATTRIBPOINTERPROC)resolveFunctionPointer(p_glGetProcAddress, "glVertexAttribPointer");
        p_glEnableVertexAttribArray = (GLENABLEVERTEXATTRIBARRAYPROC)resolveFunctionPointer(p_glGetProcAddress, "glEnableVertexAttribArray");
@@ -108,6 +128,8 @@ void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress)
 // shaders
 static const char *vertex_shader_source =
 "#version 100 \n\
+precision mediump float;\n\
+precision mediump int;\n\
 attribute vec2 position; \n\
 attribute vec3 color; \n\
 varying vec3 frag_color; \n\
@@ -118,6 +140,8 @@ void main() \n\
 }";
 static const char *fragment_shader_source =
 "#version 100 \n\
+precision mediump float;\n\
+precision mediump int;\n\
 varying vec3 frag_color; \n\
 void main(void) \n\
 { \n\
@@ -155,6 +179,7 @@ static GLuint compile_shader(GLenum shader_type, const char *source)
                show_info_log(shader);
                exit(1);
        }
+       checkGlError("Compiling shader");
        return shader;
 }
 
@@ -164,6 +189,7 @@ static GLuint createArrayBuffer(GLsizeiptr size, GLfloat *data)
        p_glGenBuffers(1, &buffer);
        p_glBindBuffer(GL_ARRAY_BUFFER, buffer);
        p_glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
+       checkGlError("Creating array buffer");
        return buffer;
 }
 
@@ -184,6 +210,15 @@ void initialise2dProjection()
 void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
 {
        p_glUseProgram(program);
+       checkGlError("Enabling the shaders");
+
+#ifdef CON_GL3
+       // create a vertex array obect and use it
+       GLuint vao;
+       p_glGenVertexArrays(1, &vao);
+       p_glBindVertexArray(vao);
+       checkGlError("Creating a VAO");
+#endif
        
        // send vertex data to card with given attribute
        GLfloat vertex_buffer_data[] = {
@@ -201,7 +236,9 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1,
                0,                                /* stride */
                (void*)0                          /* array buffer offset */
        );
+       checkGlError("Preparing vertex data");
        p_glEnableVertexAttribArray(attributes.position);
+       checkGlError("Sending vertex data");
        
        // same with color data
        GLfloat color_buffer_data[] = {
@@ -219,12 +256,19 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1,
                0,                             /* stride */
                (void*)0                       /* array buffer offset */
        );
+       checkGlError("Preparing color data");
        p_glEnableVertexAttribArray(attributes.color);
+       checkGlError("Sending color data");
        
        // draw
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+       checkGlError("Drawing");
        
        // cleanup
        p_glDeleteBuffers(1, &vertex_buffer);
        p_glDeleteBuffers(1, &color_buffer);
+#ifdef CON_GL3
+       p_glDeleteVertexArrays(1, &vao);
+#endif
+       checkGlError("Doing cleanup");
 }