]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/grgl2shader.cpp
add gr_stream_*() for movie playback
[taylor/freespace2.git] / src / graphics / grgl2shader.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 #include "SDL_opengles2.h"
10
11 #include "pstypes.h"
12 #include "gropengl.h"
13 #include "gropenglinternal.h"
14 #include "grgl2.h"
15
16
17 static GLuint tex_prog = 0;
18 static GLuint fog_tex_prog = 0;
19 static GLuint aabitmap_prog = 0;
20 static GLuint color_prog = 0;
21 static GLuint fog_color_prog = 0;
22 static GLuint window_prog = 0;
23
24
25 static const char v_tex_src[] =
26         "uniform mat4 vOrtho;\n"
27         "attribute vec4 vPosition;\n"
28         "attribute vec4 vColor;\n"
29         "attribute vec2 vTexCoord;\n"
30         "varying vec4 colorVar;\n"
31         "varying vec2 texCoordVar;\n"
32         "void main()\n"
33         "{\n"
34         "       gl_Position = vOrtho * vPosition;\n"
35         "       colorVar = vColor;\n"
36         "       texCoordVar = vTexCoord;\n"
37         "}\n";
38
39 static const char v_fog_tex_src[] =
40         "uniform mat4 vOrtho;\n"
41         "attribute vec4 vPosition;\n"
42         "attribute vec4 vColor;\n"
43         "attribute vec4 vSecColor;\n"
44         "attribute vec2 vTexCoord;\n"
45         "varying vec4 colorVar;\n"
46         "varying vec4 secColorVar;\n"
47         "varying vec2 texCoordVar;\n"
48         "void main()\n"
49         "{\n"
50         "       gl_Position = vOrtho * vPosition;\n"
51         "       colorVar = vColor;\n"
52         "       secColorVar = vSecColor;\n"
53         "       texCoordVar = vTexCoord;\n"
54         "}\n";
55
56 static const char v_color_src[] =
57         "uniform mat4 vOrtho;\n"
58         "attribute vec4 vPosition;\n"
59         "attribute vec4 vColor;\n"
60         "varying vec4 colorVar;\n"
61         "void main()\n"
62         "{\n"
63         "       gl_Position = vOrtho * vPosition;\n"
64         "       colorVar = vColor;\n"
65         "}\n";
66
67 static const char v_fog_color_src[] =
68         "uniform mat4 vOrtho;\n"
69         "attribute vec4 vPosition;\n"
70         "attribute vec4 vColor;\n"
71         "attribute vec4 vSecColor;\n"
72         "varying vec4 colorVar;\n"
73         "varying vec4 secColorVar;\n"
74         "void main()\n"
75         "{\n"
76         "       gl_Position = vOrtho * vPosition;\n"
77         "       colorVar = vColor;\n"
78         "       secColorVar = vSecColor;\n"
79         "}\n";
80
81 static const char v_window_src[] =
82         "uniform mat4 vOrtho;\n"
83         "attribute vec4 vPosition;\n"
84         "attribute vec2 vTexCoord;\n"
85         "varying vec2 texCoordVar;\n"
86         "void main()\n"
87         "{\n"
88         "       gl_Position = vOrtho * vPosition;\n"
89         "       texCoordVar = vTexCoord;\n"
90         "}\n";
91
92 static const char f_tex_src[] =
93         "precision mediump float;\n"
94         "uniform sampler2D texture;\n"
95         "varying vec4 colorVar;\n"
96         "varying vec2 texCoordVar;\n"
97         "void main()\n"
98         "{\n"
99         "       gl_FragColor = colorVar * texture2D(texture, texCoordVar);\n"
100         "}\n";
101
102 static const char f_fog_tex_src[] =
103         "precision mediump float;\n"
104         "uniform sampler2D texture;\n"
105         "varying vec4 colorVar;\n"
106         "varying vec4 secColorVar;\n"
107         "varying vec2 texCoordVar;\n"
108         "void main()\n"
109         "{\n"
110         "       vec4 base_color = colorVar * texture2D(texture, texCoordVar);\n"
111         "       gl_FragColor = vec4(mix(secColorVar.rgb, base_color.rgb, 1.0 - secColorVar.a), base_color.a);\n"
112         "}\n";
113
114 static const char f_aabitmap_src[] =
115         "precision mediump float;\n"
116         "uniform sampler2D texture;\n"
117         "varying vec4 colorVar;\n"
118         "varying vec2 texCoordVar;\n"
119         "void main()\n"
120         "{\n"
121         "       gl_FragColor = colorVar * texture2D(texture, texCoordVar).aaaa;\n"
122         "}\n";
123
124 static const char f_color_src[] =
125         "precision mediump float;\n"
126         "varying vec4 colorVar;\n"
127         "void main()\n"
128         "{\n"
129         "       gl_FragColor = colorVar;\n"
130         "}\n";
131
132 static const char f_fog_color_src[] =
133         "precision mediump float;\n"
134         "varying vec4 colorVar;\n"
135         "varying vec4 secColorVar;\n"
136         "void main()\n"
137         "{\n"
138         "       gl_FragColor = vec4(mix(secColorVar.rgb, colorVar.rgb, 1.0 - secColorVar.a), colorVar.a);\n"
139         "}\n";
140
141 static const char f_window_src[] =
142         "precision mediump float;\n"
143         "uniform sampler2D texture;\n"
144         "varying vec2 texCoordVar;\n"
145         "void main()\n"
146         "{\n"
147         "       gl_FragColor = texture2D(texture, texCoordVar);\n"
148         "}\n";
149
150
151 static GLuint opengl2_create_shader(const char *src, GLenum type)
152 {
153         GLuint shader;
154         GLint compiled;
155
156         shader = glCreateShader(type);
157
158         if ( !shader ) {
159                 return 0;
160         }
161
162         glShaderSource(shader, 1, &src, NULL);
163
164         glCompileShader(shader);
165
166         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
167
168         if ( !compiled ) {
169                 GLint len = 0;
170
171                 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
172
173                 if (len > 1) {
174                         char *log = (char *) malloc(sizeof(char) * len);
175
176                         glGetShaderInfoLog(shader, len, NULL, log);
177                         nprintf(("OpenGL", "Error compiling shader:\n%s\n", log));
178
179                         free(log);
180                 }
181
182                 glDeleteShader(shader);
183
184                 return 0;
185         }
186
187         return shader;
188 }
189
190 static GLuint opengl2_create_program(GLuint vert, GLuint frag)
191 {
192         GLuint program;
193         GLint linked;
194
195         program = glCreateProgram();
196
197         if ( !program ) {
198                 return 0;
199         }
200
201         glAttachShader(program, vert);
202         glAttachShader(program, frag);
203
204         glBindAttribLocation(program, SDRI_POSITION, "vPosition");
205         glBindAttribLocation(program, SDRI_COLOR, "vColor");
206         glBindAttribLocation(program, SDRI_SEC_COLOR, "vSecColor");
207         glBindAttribLocation(program, SDRI_TEXCOORD, "vTexCoord");
208
209         glLinkProgram(program);
210
211         glGetProgramiv(program, GL_LINK_STATUS, &linked);
212
213         if ( !linked ) {
214                 GLint len = 0;
215
216                 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
217
218                 if (len > 1) {
219                         char *log = (char *) malloc(sizeof(char) * len);
220
221                         glGetProgramInfoLog(program, len, NULL, log);
222                         nprintf(("OpenGL", "Error linking program:\n%s\n", log));
223
224                         free(log);
225                 }
226
227                 glDeleteProgram(program);
228
229                 return 0;
230         }
231
232         return program;
233 }
234
235 void opengl2_shader_use(sdr_prog_t prog)
236 {
237         static sdr_prog_t current = PROG_INVALID;
238
239         if (prog == current) {
240                 return;
241         }
242
243         switch (prog) {
244                 case PROG_TEX:
245                         glUseProgram(tex_prog);
246                         break;
247
248                 case PROG_AABITMAP:
249                         glUseProgram(aabitmap_prog);
250                         break;
251
252                 case PROG_COLOR:
253                         glUseProgram(color_prog);
254                         break;
255
256                 case PROG_WINDOW:
257                         glUseProgram(window_prog);
258                         break;
259
260                 case PROG_TEX_FOG:
261                         glUseProgram(fog_tex_prog);
262                         break;
263
264                 case PROG_COLOR_FOG:
265                         glUseProgram(fog_color_prog);
266                         break;
267
268                 default:
269                         Int3();
270                         break;
271         }
272
273         current = prog;
274 }
275
276 // update window ortho coords
277 void opengl2_shader_update()
278 {
279         GLfloat ortho[16];
280
281         SDL_zero(ortho);
282
283         ortho[0] = 2.0f / GL_viewport_w;
284         ortho[5] = 2.0f / -GL_viewport_h;
285         ortho[10] = -2.0f / 1.0f;
286         ortho[12] = -1.0f;
287         ortho[13] = 1.0f;
288         ortho[14] = -1.0f;
289         ortho[15] = 1.0f;
290
291         opengl2_shader_use(PROG_WINDOW);
292         GLint loc = glGetUniformLocation(window_prog, "vOrtho");
293         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
294 }
295
296 int opengl2_shader_init()
297 {
298         GLuint v_tex = opengl2_create_shader(v_tex_src, GL_VERTEX_SHADER);
299         GLuint v_fog_tex = opengl2_create_shader(v_fog_tex_src, GL_VERTEX_SHADER);
300         GLuint v_color = opengl2_create_shader(v_color_src, GL_VERTEX_SHADER);
301         GLuint v_fog_color = opengl2_create_shader(v_fog_color_src, GL_VERTEX_SHADER);
302         GLuint v_window = opengl2_create_shader(v_window_src, GL_VERTEX_SHADER);
303
304         GLuint f_aabitmap = opengl2_create_shader(f_aabitmap_src, GL_FRAGMENT_SHADER);
305         GLuint f_tex = opengl2_create_shader(f_tex_src, GL_FRAGMENT_SHADER);
306         GLuint f_fog_tex = opengl2_create_shader(f_fog_tex_src, GL_FRAGMENT_SHADER);
307         GLuint f_color = opengl2_create_shader(f_color_src, GL_FRAGMENT_SHADER);
308         GLuint f_fog_color = opengl2_create_shader(f_fog_color_src, GL_FRAGMENT_SHADER);
309         GLuint f_window = opengl2_create_shader(f_window_src, GL_FRAGMENT_SHADER);
310
311         aabitmap_prog = opengl2_create_program(v_tex, f_aabitmap);
312         tex_prog = opengl2_create_program(v_tex, f_tex);
313         fog_tex_prog = opengl2_create_program(v_fog_tex, f_fog_tex);
314         color_prog = opengl2_create_program(v_color, f_color);
315         fog_color_prog = opengl2_create_program(v_fog_color, f_fog_color);
316         window_prog = opengl2_create_program(v_window, f_window);
317
318
319         // set up orthographic projection var
320         // (this should never have to change while game is running)
321         GLfloat ortho[16];
322
323         SDL_zero(ortho);
324
325         ortho[0] = 2.0f / gr_screen.max_w;
326         ortho[5] = 2.0f / -gr_screen.max_h;
327         ortho[10] = -2.0f / 1.0f;
328         ortho[12] = -1.0f;
329         ortho[13] = 1.0f;
330         ortho[14] = -1.0f;
331         ortho[15] = 1.0f;
332
333         GLint loc;
334
335         opengl2_shader_use(PROG_COLOR_FOG);
336         loc = glGetUniformLocation(fog_color_prog, "vOrtho");
337         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
338
339         opengl2_shader_use(PROG_COLOR);
340         loc = glGetUniformLocation(color_prog, "vOrtho");
341         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
342
343         opengl2_shader_use(PROG_TEX_FOG);
344         loc = glGetUniformLocation(fog_tex_prog, "vOrtho");
345         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
346
347         opengl2_shader_use(PROG_AABITMAP);
348         loc = glGetUniformLocation(aabitmap_prog, "vOrtho");
349         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
350
351         opengl2_shader_use(PROG_TEX);
352         loc = glGetUniformLocation(tex_prog, "vOrtho");
353         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
354
355         opengl2_shader_update();
356
357         return 1;
358 }
359
360 void opengl2_shader_cleanup()
361 {
362         if (tex_prog) {
363                 glDeleteProgram(tex_prog);
364                 tex_prog = 0;
365         }
366
367         if (fog_tex_prog) {
368                 glDeleteProgram(fog_tex_prog);
369                 fog_tex_prog = 0;
370         }
371
372         if (aabitmap_prog) {
373                 glDeleteProgram(aabitmap_prog);
374                 aabitmap_prog = 0;
375         }
376
377         if (color_prog) {
378                 glDeleteProgram(color_prog);
379                 color_prog = 0;
380         }
381
382         if (fog_color_prog) {
383                 glDeleteProgram(fog_color_prog);
384                 fog_color_prog = 0;
385         }
386
387         if (window_prog) {
388                 glDeleteProgram(window_prog);
389                 window_prog = 0;
390         }
391 }