X-Git-Url: https://git.ralfj.de/gltest.git/blobdiff_plain/520f5e8cbcbbe69da6fa878fac2200f7bf302d68..ce1b46da645fdcac80fc9c71082bb5cb40166576:/glutil_gl2.cpp?ds=sidebyside diff --git a/glutil_gl2.cpp b/glutil_gl2.cpp index e8cc190..666ede9 100644 --- a/glutil_gl2.cpp +++ b/glutil_gl2.cpp @@ -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,6 +67,12 @@ 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) { @@ -96,6 +111,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"); @@ -105,6 +127,32 @@ void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress) p_glDeleteBuffers = (GLDELETEBUFFERSPROC)resolveFunctionPointer(p_glGetProcAddress, "glDeleteBuffers"); } +static const char *glErrorToString(GLenum e) +{ +#define CASE(name) case name: return #name + switch (e) { + CASE(GL_NO_ERROR); + CASE(GL_INVALID_ENUM); + CASE(GL_INVALID_VALUE); + CASE(GL_INVALID_OPERATION); +#ifndef CON_GLES2 + CASE(GL_STACK_OVERFLOW); + CASE(GL_STACK_UNDERFLOW); +#endif + CASE(GL_OUT_OF_MEMORY); + default: return ""; + } +#undef CASE +} + +static void checkGlError(const char *what) +{ + GLenum e = glGetError(); + if (e == GL_NO_ERROR) return; + fprintf(stderr, "GL error %d (%s): %s\n", e, glErrorToString(e), what); + exit(1); +} + // shaders static const char *vertex_shader_source = "#version 100 \n\ @@ -155,6 +203,7 @@ static GLuint compile_shader(GLenum shader_type, const char *source) show_info_log(shader); exit(1); } + checkGlError("Compiling shader"); return shader; } @@ -164,6 +213,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 +234,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 +260,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 +280,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"); }