]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/grgl2shader.cpp
rendering functions mostly done; more complete shader setup
[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 tmapper_prog = 0;
18 static GLuint aabitmap_prog = 0;
19 static GLuint lines_prog = 0;
20
21 static const char v_generic_tex_src[] =
22         "uniform mat4 vOrtho;\n"
23         "attribute vec4 vPosition;\n"
24         "attribute vec4 vColor;\n"
25         "attribute vec4 vSecColor;\n"
26         "attribute vec2 vTexCoord;\n"
27         "varying vec4 colorVar;\n"
28         "varying vec4 secColorVar;\n"
29         "varying vec2 texCoordVar;\n"
30         "void main()\n"
31         "{\n"
32         "       gl_Position = vOrtho * vPosition;\n"
33         "       colorVar = vColor;\n"
34         "       secColorVar = vSecColor;\n"
35         "       texCoordVar = vTexCoord;\n"
36         "}\n";
37
38 static const char v_lines_src[] =
39         "uniform mat4 vOrtho;\n"
40         "attribute vec4 vPosition;\n"
41         "attribute vec4 vColor;\n"
42         "varying vec4 colorVar;\n"
43         "void main()\n"
44         "{\n"
45         "       gl_Position = vOrtho * vPosition;\n"
46         "       colorVar = vColor;\n"
47         "}\n";
48
49 static const char f_tmapper_src[] =
50         "precision mediump float;\n"
51         "uniform sampler2D texture;\n"
52         "varying vec4 colorVar;\n"
53         "varying vec4 secColorVar;\n"
54         "varying vec2 texCoordVar;\n"
55         "void main()\n"
56         "{\n"
57         "       vec4 base_color = colorVar * texture2D(texture, texCoordVar);\n"
58         "       gl_FragColor = vec4(mix(secColorVar.rgb, base_color.rgb, 1.0 - secColorVar.a), base_color.a);\n"
59         "}\n";
60
61 static const char f_aabitmap_src[] =
62         "precision mediump float;\n"
63         "uniform sampler2D texture;\n"
64         "varying vec4 colorVar;\n"
65         "varying vec2 texCoordVar;\n"
66         "void main()\n"
67         "{\n"
68         "       gl_FragColor = colorVar * texture2D(texture, texCoordVar).aaaa;\n"
69         "}\n";
70
71 static const char f_lines_src[] =
72         "precision mediump float;\n"
73         "varying vec4 colorVar;\n"
74         "void main()\n"
75         "{\n"
76         "       gl_FragColor = colorVar;\n"
77         "}\n";
78
79
80
81 static GLuint opengl2_create_shader(const char *src, GLenum type)
82 {
83         GLuint shader;
84         GLint compiled;
85
86         shader = glCreateShader(type);
87
88         if ( !shader ) {
89                 return 0;
90         }
91
92         glShaderSource(shader, 1, &src, NULL);
93
94         glCompileShader(shader);
95
96         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
97
98         if ( !compiled ) {
99                 GLint len = 0;
100
101                 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
102
103                 if (len > 1) {
104                         char *log = (char *) malloc(sizeof(char) * len);
105
106                         glGetShaderInfoLog(shader, len, NULL, log);
107                         nprintf(("OpenGL", "Error compiling shader:\n%s\n", log));
108
109                         free(log);
110                 }
111
112                 glDeleteShader(shader);
113
114                 return 0;
115         }
116
117         return shader;
118 }
119
120 static GLuint opengl2_create_program(GLuint vert, GLuint frag)
121 {
122         GLuint program;
123         GLint linked;
124
125         program = glCreateProgram();
126
127         if ( !program ) {
128                 return 0;
129         }
130
131         glAttachShader(program, vert);
132         glAttachShader(program, frag);
133
134         glBindAttribLocation(program, SDRI_POSITION, "vPosition");
135         glBindAttribLocation(program, SDRI_COLOR, "vColor");
136         glBindAttribLocation(program, SDRI_SEC_COLOR, "vSecColor");
137         glBindAttribLocation(program, SDRI_TEXCOORD, "vTexCoord");
138
139         glLinkProgram(program);
140
141         glGetProgramiv(program, GL_LINK_STATUS, &linked);
142
143         if ( !linked ) {
144                 GLint len = 0;
145
146                 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
147
148                 if (len > 1) {
149                         char *log = (char *) malloc(sizeof(char) * len);
150
151                         glGetProgramInfoLog(program, len, NULL, log);
152                         nprintf(("OpenGL", "Error linking program:\n%s\n", log));
153
154                         free(log);
155                 }
156
157                 glDeleteProgram(program);
158
159                 return 0;
160         }
161
162         return program;
163 }
164
165 void opengl2_shader_use(sdr_prog_t prog)
166 {
167         static sdr_prog_t current = PROG_INVALID;
168
169         if (prog == current) {
170                 return;
171         }
172
173         switch (prog) {
174                 case PROG_TMAPPER:
175                         glUseProgram(tmapper_prog);
176                         break;
177
178                 case PROG_AABITMAP:
179                         glUseProgram(aabitmap_prog);
180                         break;
181
182                 case PROG_LINES:
183                         glUseProgram(lines_prog);
184                         break;
185
186                 default:
187                         Int3();
188                         break;
189         }
190
191         current = prog;
192 }
193
194 int opengl2_shader_init()
195 {
196         GLuint v_generic_tex = opengl2_create_shader(v_generic_tex_src, GL_VERTEX_SHADER);
197         GLuint v_lines = opengl2_create_shader(v_lines_src, GL_VERTEX_SHADER);
198
199         GLuint f_tmapper = opengl2_create_shader(f_tmapper_src, GL_FRAGMENT_SHADER);
200         GLuint f_aabitmap = opengl2_create_shader(f_aabitmap_src, GL_FRAGMENT_SHADER);
201         GLuint f_lines = opengl2_create_shader(f_lines_src, GL_FRAGMENT_SHADER);
202
203         tmapper_prog = opengl2_create_program(v_generic_tex, f_tmapper);
204         aabitmap_prog = opengl2_create_program(v_generic_tex, f_aabitmap);
205         lines_prog = opengl2_create_program(v_lines, f_lines);
206
207
208         GLfloat ortho[16];
209
210         SDL_zero(ortho);
211
212         ortho[0] = 2.0f / gr_screen.max_w;
213         ortho[5] = 2.0f / -gr_screen.max_h;
214         ortho[10] = -2.0f / 1.0f;
215         ortho[12] = -1.0f;
216         ortho[13] = 1.0f;
217         ortho[14] = -1.0f;
218         ortho[15] = 1.0f;
219
220         GLint loc;
221
222         opengl2_shader_use(PROG_LINES);
223         loc = glGetUniformLocation(lines_prog, "vOrtho");
224         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
225
226         opengl2_shader_use(PROG_AABITMAP);
227         loc = glGetUniformLocation(aabitmap_prog, "vOrtho");
228         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
229
230         opengl2_shader_use(PROG_TMAPPER);
231         loc = glGetUniformLocation(tmapper_prog, "vOrtho");
232         glUniformMatrix4fv(loc, 1, GL_FALSE, ortho);
233
234         return 1;
235 }
236
237 void opengl2_shader_cleanup()
238 {
239         if (tmapper_prog) {
240                 glDeleteProgram(tmapper_prog);
241                 tmapper_prog = 0;
242         }
243
244         if (aabitmap_prog) {
245                 glDeleteProgram(aabitmap_prog);
246                 aabitmap_prog = 0;
247         }
248
249         if (lines_prog) {
250                 glDeleteProgram(lines_prog);
251                 lines_prog = 0;
252         }
253 }