1 /* gltest - small OpenGL tearing test program
2 * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 // extension functions we use
27 typedef GLuint (*GLCREATESHADERPROC) (GLenum type);
28 typedef void (*GLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
29 typedef void (*GLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
30 typedef void (*GLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length);
31 typedef void (*GLCOMPILESHADERPROC) (GLuint shader);
32 typedef GLuint (*GLCREATEPROGRAMPROC) (void);
33 typedef void (*GLATTACHSHADERPROC) (GLuint program, GLuint shader);
34 typedef void (*GLLINKPROGRAMPROC) (GLuint program);
35 typedef GLint (*GLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
36 typedef void (*GLUSEPROGRAMPROC) (GLuint program);
37 typedef void (*GLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
38 typedef void (*GLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
39 typedef void (*GLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
40 typedef void (*GLBINDBUFFERPROC) (GLenum target, GLuint buffer);
41 typedef void (*GLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
42 typedef void (*GLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
44 GLGETSHADERIVPROC p_glGetShaderiv = NULL;
45 GLGETSHADERINFOLOGPROC p_glGetShaderInfoLog = NULL;
46 GLCREATESHADERPROC p_glCreateShader = NULL;
47 GLSHADERSOURCEPROC p_glShaderSource = NULL;
48 GLCOMPILESHADERPROC p_glCompileShader = NULL;
49 GLCREATEPROGRAMPROC p_glCreateProgram = NULL;
50 GLATTACHSHADERPROC p_glAttachShader = NULL;
51 GLLINKPROGRAMPROC p_glLinkProgram = NULL;
52 GLGETATTRIBLOCATIONPROC p_glGetAttribLocation = NULL;
53 GLUSEPROGRAMPROC p_glUseProgram = NULL;
54 GLVERTEXATTRIBPOINTERPROC p_glVertexAttribPointer = NULL;
55 GLENABLEVERTEXATTRIBARRAYPROC p_glEnableVertexAttribArray = NULL;
56 GLGENBUFFERSPROC p_glGenBuffers = NULL;
57 GLBINDBUFFERPROC p_glBindBuffer = NULL;
58 GLBUFFERDATAPROC p_glBufferData = NULL;
59 GLDELETEBUFFERSPROC p_glDeleteBuffers = NULL;
61 // resolve function pointers
62 static T_proc resolveFunctionPointer(T_glGetProcAddress p_glGetProcAddress, const char *name)
64 T_proc proc = p_glGetProcAddress(name);
66 fprintf(stderr, "Error resolvung function %s\n", name);
72 void resolveFunctionPointers(T_glGetProcAddress p_glGetProcAddress)
75 // we need to check if we have GL 2.0 or greater
76 std::string version = (char*)glGetString(GL_VERSION);
77 std::stringstream ssv(version);
79 std::getline(ssv, major, '.');
80 std::stringstream ssm(major);
83 if (majorVersion < 2) {
84 fprintf(stderr, "Need at least GL 2.0 to function properly, but detected version %d\n", majorVersion);
89 // now get the function pointers
90 p_glGetShaderiv = (GLGETSHADERIVPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetShaderiv");
91 p_glGetShaderInfoLog = (GLGETSHADERINFOLOGPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetShaderInfoLog");
92 p_glCreateShader = (GLCREATESHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glCreateShader");
93 p_glShaderSource = (GLSHADERSOURCEPROC)resolveFunctionPointer(p_glGetProcAddress, "glShaderSource");
94 p_glCompileShader = (GLCOMPILESHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glCompileShader");
95 p_glCreateProgram = (GLCREATEPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glCreateProgram");
96 p_glAttachShader = (GLATTACHSHADERPROC)resolveFunctionPointer(p_glGetProcAddress, "glAttachShader");
97 p_glLinkProgram = (GLLINKPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glLinkProgram");
98 p_glGetAttribLocation = (GLGETATTRIBLOCATIONPROC)resolveFunctionPointer(p_glGetProcAddress, "glGetAttribLocation");
99 p_glUseProgram = (GLUSEPROGRAMPROC)resolveFunctionPointer(p_glGetProcAddress, "glUseProgram");
100 p_glVertexAttribPointer = (GLVERTEXATTRIBPOINTERPROC)resolveFunctionPointer(p_glGetProcAddress, "glVertexAttribPointer");
101 p_glEnableVertexAttribArray = (GLENABLEVERTEXATTRIBARRAYPROC)resolveFunctionPointer(p_glGetProcAddress, "glEnableVertexAttribArray");
102 p_glGenBuffers = (GLGENBUFFERSPROC)resolveFunctionPointer(p_glGetProcAddress, "glGenBuffers");
103 p_glBindBuffer = (GLBINDBUFFERPROC)resolveFunctionPointer(p_glGetProcAddress, "glBindBuffer");
104 p_glBufferData = (GLBUFFERDATAPROC)resolveFunctionPointer(p_glGetProcAddress, "glBufferData");
105 p_glDeleteBuffers = (GLDELETEBUFFERSPROC)resolveFunctionPointer(p_glGetProcAddress, "glDeleteBuffers");
109 static const char *vertex_shader_source =
111 attribute vec2 position; \n\
112 attribute vec3 color; \n\
113 varying vec3 frag_color; \n\
116 frag_color = color; \n\
117 gl_Position = vec4(position * vec2(2) - vec2(1), 0.0, 1.0); \n\
119 static const char *fragment_shader_source =
121 varying vec3 frag_color; \n\
124 gl_FragColor = vec4(frag_color, 1.0); \n\
128 // OpenGL IDs (yeah, this is a bad hack... do we care?)
129 static GLuint program;
135 // some local hlper functions
136 static void show_info_log(GLuint object)
139 p_glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
140 char *log = new char[log_length];
141 p_glGetShaderInfoLog(object, log_length, NULL, log);
142 fprintf(stderr, "%s", log);
146 static GLuint compile_shader(GLenum shader_type, const char *source)
148 GLuint shader = p_glCreateShader(shader_type);
149 p_glShaderSource(shader, 1, &source, NULL);
150 p_glCompileShader(shader);
152 p_glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
154 fprintf(stderr, "Failed to compile shader\n");
155 show_info_log(shader);
161 static GLuint createArrayBuffer(GLsizeiptr size, GLfloat *data)
164 p_glGenBuffers(1, &buffer);
165 p_glBindBuffer(GL_ARRAY_BUFFER, buffer);
166 p_glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
171 void initialise2dProjection()
173 GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source);
174 GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_source);
175 program = p_glCreateProgram();
176 p_glAttachShader(program, vertex_shader);
177 p_glAttachShader(program, fragment_shader);
178 p_glLinkProgram(program);
179 attributes.position = p_glGetAttribLocation(program, "position");
180 attributes.color = p_glGetAttribLocation(program, "color");
184 void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
186 p_glUseProgram(program);
188 // send vertex data to card with given attribute
189 GLfloat vertex_buffer_data[] = {
195 GLuint vertex_buffer = createArrayBuffer(sizeof(vertex_buffer_data), vertex_buffer_data);
196 p_glVertexAttribPointer(
197 attributes.position, /* attribute */
200 GL_FALSE, /* normalized? */
202 (void*)0 /* array buffer offset */
204 p_glEnableVertexAttribArray(attributes.position);
206 // same with color data
207 GLfloat color_buffer_data[] = {
213 GLuint color_buffer = createArrayBuffer(sizeof(color_buffer_data), color_buffer_data);
214 p_glVertexAttribPointer(
215 attributes.color, /* attribute */
218 GL_FALSE, /* normalized? */
220 (void*)0 /* array buffer offset */
222 p_glEnableVertexAttribArray(attributes.color);
225 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
228 p_glDeleteBuffers(1, &vertex_buffer);
229 p_glDeleteBuffers(1, &color_buffer);