X-Git-Url: https://git.ralfj.de/gltest.git/blobdiff_plain/a0cb14324fbd2791d62df09e8d10541f280b60ee..dac0dad539be501c94cb8646d979e6e7787e1992:/glutil_gl2.cpp diff --git a/glutil_gl2.cpp b/glutil_gl2.cpp index ad89138..e8cc190 100644 --- a/glutil_gl2.cpp +++ b/glutil_gl2.cpp @@ -18,12 +18,92 @@ #include #include +#include +#include #include "glutil.h" -#if defined(CON_GL1) -#error "GL1 contexts do not support GL2 functionality" +// extension functions we use +typedef GLuint (*GLCREATESHADERPROC) (GLenum type); +typedef void (*GLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (*GLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (*GLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length); +typedef void (*GLCOMPILESHADERPROC) (GLuint shader); +typedef GLuint (*GLCREATEPROGRAMPROC) (void); +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); +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); + +GLGETSHADERIVPROC p_glGetShaderiv = NULL; +GLGETSHADERINFOLOGPROC p_glGetShaderInfoLog = NULL; +GLCREATESHADERPROC p_glCreateShader = NULL; +GLSHADERSOURCEPROC p_glShaderSource = NULL; +GLCOMPILESHADERPROC p_glCompileShader = NULL; +GLCREATEPROGRAMPROC p_glCreateProgram = NULL; +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; +GLBINDBUFFERPROC p_glBindBuffer = NULL; +GLBUFFERDATAPROC p_glBufferData = NULL; +GLDELETEBUFFERSPROC p_glDeleteBuffers = NULL; + +// 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); + } + return proc; +} + +void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress) +{ +#ifdef CON_GL1 + // we need to check if we have GL 2.0 or greater + std::string version = (char*)glGetString(GL_VERSION); + std::stringstream ssv(version); + std::string major; + std::getline(ssv, major, '.'); + std::stringstream ssm(major); + 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); + } #endif + + // now get the function pointers + p_glGetShaderiv = (GLGETSHADERIVPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetShaderiv"); + p_glGetShaderInfoLog = (GLGETSHADERINFOLOGPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetShaderInfoLog"); + p_glCreateShader = (GLCREATESHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glCreateShader"); + p_glShaderSource = (GLSHADERSOURCEPROC)resolveFunctionPointer(p_glGetProcAddress, "glShaderSource"); + p_glCompileShader = (GLCOMPILESHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glCompileShader"); + p_glCreateProgram = (GLCREATEPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glCreateProgram"); + p_glAttachShader = (GLATTACHSHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glAttachShader"); + p_glLinkProgram = (GLLINKPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glLinkProgram"); + p_glGetAttribLocation = (GLGETATTRIBLOCATIONPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetAttribLocation"); + p_glUseProgram = (GLUSEPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glUseProgram"); + p_glVertexAttribPointer = (GLVERTEXATTRIBPOINTERPROC)resolveFunctionPointer(p_glGetProcAddress, "glVertexAttribPointer"); + p_glEnableVertexAttribArray = (GLENABLEVERTEXATTRIBARRAYPROC)resolveFunctionPointer(p_glGetProcAddress, "glEnableVertexAttribArray"); + p_glGenBuffers = (GLGENBUFFERSPROC)resolveFunctionPointer(p_glGetProcAddress, "glGenBuffers"); + p_glBindBuffer = (GLBINDBUFFERPROC)resolveFunctionPointer(p_glGetProcAddress, "glBindBuffer"); + p_glBufferData = (GLBUFFERDATAPROC)resolveFunctionPointer(p_glGetProcAddress, "glBufferData"); + p_glDeleteBuffers = (GLDELETEBUFFERSPROC)resolveFunctionPointer(p_glGetProcAddress, "glDeleteBuffers"); +} // shaders static const char *vertex_shader_source = @@ -56,20 +136,20 @@ static struct { static void show_info_log(GLuint object) { GLint log_length; - glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length); + p_glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length); char *log = new char[log_length]; - glGetShaderInfoLog(object, log_length, NULL, log); + p_glGetShaderInfoLog(object, log_length, NULL, log); fprintf(stderr, "%s", log); delete[] log; } static GLuint compile_shader(GLenum shader_type, const char *source) { - GLuint shader = glCreateShader(shader_type); - glShaderSource(shader, 1, &source, NULL); - glCompileShader(shader); + GLuint shader = p_glCreateShader(shader_type); + p_glShaderSource(shader, 1, &source, NULL); + p_glCompileShader(shader); GLint shader_ok; - glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); + p_glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); if (!shader_ok) { fprintf(stderr, "Failed to compile shader\n"); show_info_log(shader); @@ -81,9 +161,9 @@ static GLuint compile_shader(GLenum shader_type, const char *source) static GLuint createArrayBuffer(GLsizeiptr size, GLfloat *data) { GLuint buffer; - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); + p_glGenBuffers(1, &buffer); + p_glBindBuffer(GL_ARRAY_BUFFER, buffer); + p_glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); return buffer; } @@ -92,18 +172,18 @@ void initialise2dProjection() { GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source); GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_source); - program = glCreateProgram(); - glAttachShader(program, vertex_shader); - glAttachShader(program, fragment_shader); - glLinkProgram(program); - attributes.position = glGetAttribLocation(program, "position"); - attributes.color = glGetAttribLocation(program, "color"); + program = p_glCreateProgram(); + p_glAttachShader(program, vertex_shader); + p_glAttachShader(program, fragment_shader); + p_glLinkProgram(program); + attributes.position = p_glGetAttribLocation(program, "position"); + attributes.color = p_glGetAttribLocation(program, "color"); } // draw a quad void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { - glUseProgram(program); + p_glUseProgram(program); // send vertex data to card with given attribute GLfloat vertex_buffer_data[] = { @@ -113,7 +193,7 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, x1, y2, }; GLuint vertex_buffer = createArrayBuffer(sizeof(vertex_buffer_data), vertex_buffer_data); - glVertexAttribPointer( + p_glVertexAttribPointer( attributes.position, /* attribute */ 2, /* size */ GL_FLOAT, /* type */ @@ -121,7 +201,7 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, 0, /* stride */ (void*)0 /* array buffer offset */ ); - glEnableVertexAttribArray(attributes.position); + p_glEnableVertexAttribArray(attributes.position); // same with color data GLfloat color_buffer_data[] = { @@ -131,7 +211,7 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, red, green, blue, }; GLuint color_buffer = createArrayBuffer(sizeof(color_buffer_data), color_buffer_data); - glVertexAttribPointer( + p_glVertexAttribPointer( attributes.color, /* attribute */ 3, /* size */ GL_FLOAT, /* type */ @@ -139,12 +219,12 @@ void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, 0, /* stride */ (void*)0 /* array buffer offset */ ); - glEnableVertexAttribArray(attributes.color); + p_glEnableVertexAttribArray(attributes.color); // draw glDrawArrays(GL_TRIANGLE_FAN, 0, 4); // cleanup - glDeleteBuffers(1, &vertex_buffer); - glDeleteBuffers(1, &color_buffer); + p_glDeleteBuffers(1, &vertex_buffer); + p_glDeleteBuffers(1, &color_buffer); }