support for GLES2
[gltest.git] / glutil_gl2.cpp
diff --git a/glutil_gl2.cpp b/glutil_gl2.cpp
new file mode 100644 (file)
index 0000000..c14b3a5
--- /dev/null
@@ -0,0 +1,145 @@
+/* gltest - small OpenGL tearing test program
+ * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "glutil.h"
+
+// shaders
+static const char *vertex_shader_source =
+"#version 100 \n\
+attribute vec2 position; \n\
+attribute vec3 color; \n\
+varying vec3 frag_color; \n\
+void main() \n\
+{ \n\
+       frag_color = color; \n\
+       gl_Position = vec4(position * vec2(2) - vec2(1), 0.0, 1.0); \n\
+}";
+static const char *fragment_shader_source =
+"#version 100 \n\
+varying vec3 frag_color; \n\
+void main(void) \n\
+{ \n\
+       gl_FragColor = vec4(frag_color, 1.0); \n\
+}";
+
+
+// OpenGL IDs (yeah, this is a bad hack... do we care?)
+static GLuint program;
+static struct {
+       GLint position;
+       GLint color;
+} attributes;
+
+// some local hlper functions
+static void show_info_log(GLuint object)
+{
+       GLint log_length;
+       glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
+       char *log = new char[log_length];
+       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);
+       GLint shader_ok;
+       glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
+       if (!shader_ok) {
+               fprintf(stderr, "Failed to compile shader\n");
+               show_info_log(shader);
+               exit(1);
+       }
+       return shader;
+}
+
+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);
+       return buffer;
+}
+
+// initialisation
+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");
+}
+
+// draw a quad
+void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+       glUseProgram(program);
+       
+       // send vertex data to card with given attribute
+       GLfloat vertex_buffer_data[] = {
+               x1, y1,
+               x2, y1,
+               x2, y2,
+               x1, y2,
+       };
+       GLuint vertex_buffer = createArrayBuffer(sizeof(vertex_buffer_data), vertex_buffer_data);
+       glVertexAttribPointer(
+               attributes.position,              /* attribute */
+               2,                                /* size */
+               GL_FLOAT,                         /* type */
+               GL_FALSE,                         /* normalized? */
+               0,                                /* stride */
+               (void*)0                          /* array buffer offset */
+       );
+       glEnableVertexAttribArray(attributes.position);
+       
+       // same with color data
+       GLfloat color_buffer_data[] = {
+               red, green, blue,
+               red, green, blue,
+               red, green, blue,
+               red, green, blue,
+       };
+       GLuint color_buffer = createArrayBuffer(sizeof(color_buffer_data), color_buffer_data);
+       glVertexAttribPointer(
+               attributes.color,              /* attribute */
+               3,                             /* size */
+               GL_FLOAT,                      /* type */
+               GL_FALSE,                      /* normalized? */
+               0,                             /* stride */
+               (void*)0                       /* array buffer offset */
+       );
+       glEnableVertexAttribArray(attributes.color);
+       
+       // draw
+       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+       
+       // cleanup
+       glDeleteBuffers(1, &vertex_buffer);
+       glDeleteBuffers(1, &color_buffer);
+}