c14b3a5d89f4823ab11b98900f3c96075e61673c
[gltest.git] / glutil_gl2.cpp
1 /* gltest - small OpenGL tearing test program
2  * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "glutil.h"
22
23 // shaders
24 static const char *vertex_shader_source =
25 "#version 100 \n\
26 attribute vec2 position; \n\
27 attribute vec3 color; \n\
28 varying vec3 frag_color; \n\
29 void main() \n\
30 { \n\
31         frag_color = color; \n\
32         gl_Position = vec4(position * vec2(2) - vec2(1), 0.0, 1.0); \n\
33 }";
34 static const char *fragment_shader_source =
35 "#version 100 \n\
36 varying vec3 frag_color; \n\
37 void main(void) \n\
38 { \n\
39         gl_FragColor = vec4(frag_color, 1.0); \n\
40 }";
41
42
43 // OpenGL IDs (yeah, this is a bad hack... do we care?)
44 static GLuint program;
45 static struct {
46         GLint position;
47         GLint color;
48 } attributes;
49
50 // some local hlper functions
51 static void show_info_log(GLuint object)
52 {
53         GLint log_length;
54         glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
55         char *log = new char[log_length];
56         glGetShaderInfoLog(object, log_length, NULL, log);
57         fprintf(stderr, "%s", log);
58         delete[] log;
59 }
60
61 static GLuint compile_shader(GLenum shader_type, const char *source)
62 {
63         GLuint shader = glCreateShader(shader_type);
64         glShaderSource(shader, 1, &source, NULL);
65         glCompileShader(shader);
66         GLint shader_ok;
67         glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
68         if (!shader_ok) {
69                 fprintf(stderr, "Failed to compile shader\n");
70                 show_info_log(shader);
71                 exit(1);
72         }
73         return shader;
74 }
75
76 static GLuint createArrayBuffer(GLsizeiptr size, GLfloat *data)
77 {
78         GLuint buffer;
79         glGenBuffers(1, &buffer);
80         glBindBuffer(GL_ARRAY_BUFFER, buffer);
81         glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
82         return buffer;
83 }
84
85 // initialisation
86 void initialise2dProjection()
87 {
88         GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source);
89         GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_source);
90         program = glCreateProgram();
91         glAttachShader(program, vertex_shader);
92         glAttachShader(program, fragment_shader);
93         glLinkProgram(program);
94         attributes.position = glGetAttribLocation(program, "position");
95         attributes.color = glGetAttribLocation(program, "color");
96 }
97
98 // draw a quad
99 void drawQuad(GLfloat red, GLfloat green, GLfloat blue, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
100 {
101         glUseProgram(program);
102         
103         // send vertex data to card with given attribute
104         GLfloat vertex_buffer_data[] = {
105                 x1, y1,
106                 x2, y1,
107                 x2, y2,
108                 x1, y2,
109         };
110         GLuint vertex_buffer = createArrayBuffer(sizeof(vertex_buffer_data), vertex_buffer_data);
111         glVertexAttribPointer(
112                 attributes.position,              /* attribute */
113                 2,                                /* size */
114                 GL_FLOAT,                         /* type */
115                 GL_FALSE,                         /* normalized? */
116                 0,                                /* stride */
117                 (void*)0                          /* array buffer offset */
118         );
119         glEnableVertexAttribArray(attributes.position);
120         
121         // same with color data
122         GLfloat color_buffer_data[] = {
123                 red, green, blue,
124                 red, green, blue,
125                 red, green, blue,
126                 red, green, blue,
127         };
128         GLuint color_buffer = createArrayBuffer(sizeof(color_buffer_data), color_buffer_data);
129         glVertexAttribPointer(
130                 attributes.color,              /* attribute */
131                 3,                             /* size */
132                 GL_FLOAT,                      /* type */
133                 GL_FALSE,                      /* normalized? */
134                 0,                             /* stride */
135                 (void*)0                       /* array buffer offset */
136         );
137         glEnableVertexAttribArray(attributes.color);
138         
139         // draw
140         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
141         
142         // cleanup
143         glDeleteBuffers(1, &vertex_buffer);
144         glDeleteBuffers(1, &color_buffer);
145 }