]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/grgl2shader.cpp
disable emterpreter for now (too many issues)
[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         "       float alpha1 = texture2D(texture, texCoordVar).a;\n"
122         "       gl_FragColor = vec4(colorVar.rgb, mix(0.0, colorVar.a, alpha1));\n"
123         "}\n";
124
125 static const char f_color_src[] =
126         "precision mediump float;\n"
127         "varying vec4 colorVar;\n"
128         "void main()\n"
129         "{\n"
130         "       gl_FragColor = colorVar;\n"
131         "}\n";
132
133 static const char f_fog_color_src[] =
134         "precision mediump float;\n"
135         "varying vec4 colorVar;\n"
136         "varying vec4 secColorVar;\n"
137         "void main()\n"
138         "{\n"
139         "       gl_FragColor = vec4(mix(secColorVar.rgb, colorVar.rgb, 1.0 - secColorVar.a), colorVar.a);\n"
140         "}\n";
141
142 static const char f_window_src[] =
143         "precision mediump float;\n"
144         "uniform sampler2D texture;\n"
145         "varying vec2 texCoordVar;\n"
146         "void main()\n"
147         "{\n"
148         "       gl_FragColor = texture2D(texture, texCoordVar);\n"
149         "}\n";
150
151
152 static GLuint opengl2_create_shader(const char *src, GLenum type)
153 {
154         GLuint shader;
155         GLint compiled;
156
157         shader = glCreateShader(type);
158
159         if ( !shader ) {
160                 return 0;
161         }
162
163         glShaderSource(shader, 1, &src, NULL);
164
165         glCompileShader(shader);
166
167         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
168
169         if ( !compiled ) {
170                 GLint len = 0;
171
172                 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
173
174                 if (len > 1) {
175                         char *log = (char *) malloc(sizeof(char) * len);
176
177                         glGetShaderInfoLog(shader, len, NULL, log);
178                         nprintf(("OpenGL", "Error compiling shader:\n%s\n", log));
179
180                         free(log);
181                 }
182
183                 glDeleteShader(shader);
184
185                 return 0;
186         }
187
188         return shader;
189 }
190
191 static GLuint opengl2_create_program(GLuint vert, GLuint frag)
192 {
193         GLuint program;
194         GLint linked;
195
196         program = glCreateProgram();
197
198         if ( !program ) {
199                 return 0;
200         }
201
202         glAttachShader(program, vert);
203         glAttachShader(program, frag);
204
205         glBindAttribLocation(program, SDRI_POSITION, "vPosition");
206         glBindAttribLocation(program, SDRI_COLOR, "vColor");
207         glBindAttribLocation(program, SDRI_SEC_COLOR, "vSecColor");
208         glBindAttribLocation(program, SDRI_TEXCOORD, "vTexCoord");
209
210         glLinkProgram(program);
211
212         glGetProgramiv(program, GL_LINK_STATUS, &linked);
213
214         if ( !linked ) {
215                 GLint len = 0;
216
217                 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
218
219                 if (len > 1) {
220                         char *log = (char *) malloc(sizeof(char) * len);
221
222                         glGetProgramInfoLog(program, len, NULL, log);
223                         nprintf(("OpenGL", "Error linking program:\n%s\n", log));
224
225                         free(log);
226                 }
227
228                 glDeleteProgram(program);
229
230                 return 0;
231         }
232
233         return program;
234 }
235
236 void opengl2_shader_use(sdr_prog_t prog)
237 {
238         static sdr_prog_t current = PROG_INVALID;
239
240         if (prog == current) {
241                 return;
242         }
243
244         switch (prog) {
245                 case PROG_TEX:
246                         glUseProgram(tex_prog);
247                         break;
248
249                 case PROG_AABITMAP:
250                         glUseProgram(aabitmap_prog);
251                         break;
252
253                 case PROG_COLOR:
254                         glUseProgram(color_prog);
255                         break;
256
257                 case PROG_WINDOW:
258                         glUseProgram(window_prog);
259                         break;
260
261                 case PROG_TEX_FOG:
262                         glUseProgram(fog_tex_prog);
263                         break;
264
265                 case PROG_COLOR_FOG:
266                         glUseProgram(fog_color_prog);
267                         break;
268
269                 default:
270                         Int3();
271                         break;
272         }
273
274         current = prog;
275 }
276
277 // update window ortho coords
278 void opengl2_shader_update()
279 {
280         GLfloat ortho[16];
281
282         SDL_zero(ortho);
283
284         ortho[0] = 2.0f / GL_viewport_w;
285         ortho[5] = 2.0f / -GL_viewport_h;
286         ortho[10] = -2.0f / 1.0f;
287         ortho[12] = -1.0f;
288         ortho[13] = 1.0f;
289         ortho[14] = -1.0f;
290         ortho[15] = 1.0f;
291
292         opengl2_shader_use(PROG_WINDOW);
293         GLint loc = glGetUniformLocation(window_prog, "vOrtho");
294         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
295 }
296
297 int opengl2_shader_init()
298 {
299         GLuint v_tex = opengl2_create_shader(v_tex_src, GL_VERTEX_SHADER);
300         GLuint v_fog_tex = opengl2_create_shader(v_fog_tex_src, GL_VERTEX_SHADER);
301         GLuint v_color = opengl2_create_shader(v_color_src, GL_VERTEX_SHADER);
302         GLuint v_fog_color = opengl2_create_shader(v_fog_color_src, GL_VERTEX_SHADER);
303         GLuint v_window = opengl2_create_shader(v_window_src, GL_VERTEX_SHADER);
304
305         GLuint f_aabitmap = opengl2_create_shader(f_aabitmap_src, GL_FRAGMENT_SHADER);
306         GLuint f_tex = opengl2_create_shader(f_tex_src, GL_FRAGMENT_SHADER);
307         GLuint f_fog_tex = opengl2_create_shader(f_fog_tex_src, GL_FRAGMENT_SHADER);
308         GLuint f_color = opengl2_create_shader(f_color_src, GL_FRAGMENT_SHADER);
309         GLuint f_fog_color = opengl2_create_shader(f_fog_color_src, GL_FRAGMENT_SHADER);
310         GLuint f_window = opengl2_create_shader(f_window_src, GL_FRAGMENT_SHADER);
311
312         aabitmap_prog = opengl2_create_program(v_tex, f_aabitmap);
313         tex_prog = opengl2_create_program(v_tex, f_tex);
314         fog_tex_prog = opengl2_create_program(v_fog_tex, f_fog_tex);
315         color_prog = opengl2_create_program(v_color, f_color);
316         fog_color_prog = opengl2_create_program(v_fog_color, f_fog_color);
317         window_prog = opengl2_create_program(v_window, f_window);
318
319
320         // set up orthographic projection var
321         // (this should never have to change while game is running)
322         GLfloat ortho[16];
323
324         SDL_zero(ortho);
325
326         ortho[0] = 2.0f / gr_screen.max_w;
327         ortho[5] = 2.0f / -gr_screen.max_h;
328         ortho[10] = -2.0f / 1.0f;
329         ortho[12] = -1.0f;
330         ortho[13] = 1.0f;
331         ortho[14] = -1.0f;
332         ortho[15] = 1.0f;
333
334         GLint loc;
335
336         opengl2_shader_use(PROG_COLOR_FOG);
337         loc = glGetUniformLocation(fog_color_prog, "vOrtho");
338         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
339
340         opengl2_shader_use(PROG_COLOR);
341         loc = glGetUniformLocation(color_prog, "vOrtho");
342         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
343
344         opengl2_shader_use(PROG_TEX_FOG);
345         loc = glGetUniformLocation(fog_tex_prog, "vOrtho");
346         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
347
348         opengl2_shader_use(PROG_AABITMAP);
349         loc = glGetUniformLocation(aabitmap_prog, "vOrtho");
350         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
351
352         opengl2_shader_use(PROG_TEX);
353         loc = glGetUniformLocation(tex_prog, "vOrtho");
354         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
355
356         opengl2_shader_update();
357
358         return 1;
359 }
360
361 void opengl2_shader_cleanup()
362 {
363         if (tex_prog) {
364                 glDeleteProgram(tex_prog);
365                 tex_prog = 0;
366         }
367
368         if (fog_tex_prog) {
369                 glDeleteProgram(fog_tex_prog);
370                 fog_tex_prog = 0;
371         }
372
373         if (aabitmap_prog) {
374                 glDeleteProgram(aabitmap_prog);
375                 aabitmap_prog = 0;
376         }
377
378         if (color_prog) {
379                 glDeleteProgram(color_prog);
380                 color_prog = 0;
381         }
382
383         if (fog_color_prog) {
384                 glDeleteProgram(fog_color_prog);
385                 fog_color_prog = 0;
386         }
387
388         if (window_prog) {
389                 glDeleteProgram(window_prog);
390                 window_prog = 0;
391         }
392 }