OpenCPN Partial API docs
Loading...
Searching...
No Matches
shaders.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 *
5 ***************************************************************************
6 * Copyright (C) 2017 by David S. Register *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22 **************************************************************************/
23
24#include "shaders.h"
25
26#if defined(USE_ANDROID_GLES2) || defined(ocpnUSE_GLSL)
27
28#ifdef USE_ANDROID_GLES2
29#include <GLES2/gl2.h>
30#include "qdebug.h"
31#endif
32
33#ifdef USE_ANDROID_GLES2
34const GLchar* preamble =
35"\n";
36#else
37const GLchar* preamble =
38"#version 120\n"
39"#define precision\n"
40"#define lowp\n"
41"#define mediump\n"
42"#define highp\n";
43#endif
44
45
46// Simple colored triangle shader
47
48static const GLchar* color_tri_vertex_shader_source =
49 "attribute vec2 position;\n"
50 "uniform mat4 MVMatrix;\n"
51 "uniform mat4 TransformMatrix;\n"
52 "uniform vec4 color;\n"
53 "varying vec4 fragColor;\n"
54 "void main() {\n"
55 " fragColor = color;\n"
56 " gl_Position = MVMatrix * TransformMatrix * vec4(position, 0.0, 1.0);\n"
57 "}\n";
58
59static const GLchar* color_tri_fragment_shader_source =
60 "precision lowp float;\n"
61 "varying vec4 fragColor;\n"
62 "void main() {\n"
63 " gl_FragColor = fragColor;\n"
64 "}\n";
65
66// Simple 2D texture shader
67static const GLchar* texture_2D_vertex_shader_source =
68 "attribute vec2 aPos;\n"
69 "attribute vec2 aUV;\n"
70 "uniform mat4 MVMatrix;\n"
71 "uniform mat4 TransformMatrix;\n"
72 "varying vec2 varCoord;\n"
73 "void main() {\n"
74 " gl_Position = MVMatrix * TransformMatrix * vec4(aPos, 0.0, 1.0);\n"
75 " varCoord = aUV;\n"
76 "}\n";
77
78static const GLchar* texture_2D_fragment_shader_source =
79 "precision lowp float;\n"
80 "uniform sampler2D uTex;\n"
81 "varying vec2 varCoord;\n"
82 "void main() {\n"
83 " gl_FragColor = texture2D(uTex, varCoord);\n"
84 "}\n";
85
86// Circle shader
87
88static const GLchar* circle_filled_vertex_shader_source =
89 "precision highp float;\n"
90 "attribute vec2 aPos;\n"
91 "uniform mat4 MVMatrix;\n"
92 "uniform mat4 TransformMatrix;\n"
93 "void main() {\n"
94 " gl_Position = MVMatrix * TransformMatrix * vec4(aPos, 0.0, 1.0);\n"
95 "}\n";
96
97static const GLchar* circle_filled_fragment_shader_source =
98 "precision highp float;\n"
99 "uniform float border_width;\n"
100 "uniform float circle_radius;\n"
101 "uniform vec4 circle_color;\n"
102 "uniform vec4 border_color;\n"
103 "uniform vec2 circle_center;\n"
104 "void main(){\n"
105 "float d = distance(gl_FragCoord.xy, circle_center);\n"
106 "if (d < (circle_radius - border_width)) { gl_FragColor = circle_color; }\n"
107 "else if (d < circle_radius) { gl_FragColor = border_color; }\n"
108 "else { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }\n"
109 "}\n";
110
111// Alpha 2D texture shader
112static const GLchar* texture_2DA_vertex_shader_source =
113 "attribute vec2 aPos;\n"
114 "attribute vec2 aUV;\n"
115 "uniform mat4 MVMatrix;\n"
116 "uniform mat4 TransformMatrix;\n"
117 "varying vec2 varCoord;\n"
118 "void main() {\n"
119 " gl_Position = MVMatrix * TransformMatrix * vec4(aPos, 0.0, 1.0);\n"
120 " varCoord = aUV;\n"
121 "}\n";
122
123static const GLchar* texture_2DA_fragment_shader_source =
124 "precision lowp float;\n"
125 "uniform sampler2D uTex;\n"
126 "varying vec2 varCoord;\n"
127 "uniform vec4 color;\n"
128 "void main() {\n"
129 " gl_FragColor = texture2D(uTex, varCoord) + color;\n"
130 "}\n";
131
132
133//https://vitaliburkov.wordpress.com/2016/09/17/simple-and-fast-high-quality-antialiased-lines-with-opengl/
134static const GLchar* AALine_vertex_shader_source =
135 "uniform vec2 uViewPort; //Width and Height of the viewport\n"
136 "varying vec2 vLineCenter;\n"
137 "attribute vec2 position;\n"
138 "uniform mat4 MVMatrix;\n"
139 "uniform mat4 TransformMatrix;\n"
140 "void main()\n"
141 "{\n"
142 " vec4 pp = MVMatrix * vec4(position, 0.0, 1.0);\n"
143 " gl_Position = pp;\n"
144 " vec2 vp = uViewPort;\n"
145 " vLineCenter = 0.5*(pp.xy + vec2(1, 1))*vp;\n"
146 "}\n";
147
148
149static const GLchar* AALine_fragment_shader_source =
150 "precision mediump float;\n"
151 "uniform float uLineWidth;\n"
152 "uniform vec4 color;\n"
153 "uniform float uBlendFactor; //1.5..2.5\n"
154 "varying vec2 vLineCenter;\n"
155 "void main()\n"
156 "{\n"
157 " vec4 col = color;\n"
158 " float d = length(vLineCenter-gl_FragCoord.xy);\n"
159 " float w = uLineWidth;\n"
160 " if (d>w)\n"
161 " col.w = 0.0;\n"
162 " else{\n"
163 " if(float((w/2-d)/(w/2)) < .5){\n"
164 " //col.w *= pow(float((w-d)/w), uBlendFactor);\n"
165 " col.w *= pow(float((w/2-d)/(w/2)), uBlendFactor);\n"
166 " }\n"
167 " }\n"
168 " gl_FragColor = col;\n"
169 "}\n";
170
171// Ring shader
172
173static const GLchar *ring_vertex_shader_source =
174 "precision highp float;\n"
175 "attribute vec2 aPos;\n"
176 "uniform mat4 MVMatrix;\n"
177 "uniform mat4 TransformMatrix;\n"
178 "void main() {\n"
179 " gl_Position = MVMatrix * TransformMatrix * vec4(aPos, 0.0, 1.0);\n"
180 "}\n";
181
182static const GLchar *ring_fragment_shader_source =
183 "precision highp float;\n"
184 "uniform float border_width;\n"
185 "uniform float circle_radius;\n"
186 "uniform float ring_width;\n"
187 "uniform vec4 circle_color;\n"
188 "uniform vec4 border_color;\n"
189 "uniform vec2 circle_center;\n"
190 "uniform float sector_1;\n"
191 "uniform float sector_2;\n"
192
193 "void main(){\n"
194 "const float PI = 3.14159265358979323846264;\n"
195 "bool bdraw = false;\n"
196
197 "float angle = atan(gl_FragCoord.y-circle_center.y, "
198 "gl_FragCoord.x-circle_center.x);\n"
199 "angle = PI/2.0 - angle;\n"
200 "if(angle < 0.0) angle += PI * 2.0;\n"
201
202 "if(sector_2 > PI * 2.0){\n"
203 " if((angle > sector_1) && (angle < (PI * 2.0) )){\n"
204 " bdraw = true;\n"
205 " }\n"
206 " if(angle < sector_2 - (PI * 2.0)){\n"
207 " bdraw = true;\n"
208 " }\n"
209 "} else {\n"
210 " if((angle > sector_1) && (angle < sector_2)){\n"
211 " bdraw = true;\n"
212 " }\n"
213 "}\n"
214
215 "if(bdraw){\n"
216 " float d = distance(gl_FragCoord.xy, circle_center);\n"
217 " if (d > circle_radius) {\n"
218 " discard;\n"
219 " } else if( d > (circle_radius - border_width)) {\n"
220 " gl_FragColor = border_color;\n"
221 " } else if( d > (circle_radius - border_width - ring_width)) {\n"
222 " gl_FragColor = circle_color;\n"
223 " } else if( d > (circle_radius - border_width - ring_width - "
224 "border_width)) {\n"
225 " gl_FragColor = border_color;\n"
226 " } else {\n"
227 " discard;\n"
228 " }\n"
229 "} else{\n"
230 " discard;\n"
231 "}\n"
232 "}\n";
233
234GLShaderProgram *pAALine_shader_program[2];
235GLShaderProgram *pcolor_tri_shader_program[2];
236GLShaderProgram *ptexture_2D_shader_program[2];
237GLShaderProgram *pcircle_filled_shader_program[2];
238GLShaderProgram *ptexture_2DA_shader_program[2];
239GLShaderProgram *pring_shader_program[2];
240
241
242bool bShadersLoaded[2];
243
244bool loadShaders(int index) {
245 // Are the shaders ready?
246 if (bShadersLoaded[index]) {
247 reConfigureShaders(index);
248 return true;
249 }
250
251 bool ret_val = true;
252 GLint success;
253
254
255 // Simple colored triangle shader
256 if (!pcolor_tri_shader_program[index]) {
257 GLShaderProgram *shaderProgram = new GLShaderProgram;
258 shaderProgram->addShaderFromSource(color_tri_vertex_shader_source, GL_VERTEX_SHADER);
259 shaderProgram->addShaderFromSource(color_tri_fragment_shader_source, GL_FRAGMENT_SHADER);
260 shaderProgram->linkProgram();
261
262 if (shaderProgram->isOK())
263 pcolor_tri_shader_program[index] = shaderProgram;
264 }
265
266 if (!ptexture_2D_shader_program[index]) {
267 GLShaderProgram *shaderProgram = new GLShaderProgram;
268 shaderProgram->addShaderFromSource(texture_2D_vertex_shader_source, GL_VERTEX_SHADER);
269 shaderProgram->addShaderFromSource(texture_2D_fragment_shader_source, GL_FRAGMENT_SHADER);
270 shaderProgram->linkProgram();
271
272 if (shaderProgram->isOK())
273 ptexture_2D_shader_program[index] = shaderProgram;
274 }
275
276 if (!pcircle_filled_shader_program[index]) {
277 GLShaderProgram *shaderProgram = new GLShaderProgram;
278 shaderProgram->addShaderFromSource(circle_filled_vertex_shader_source, GL_VERTEX_SHADER);
279 shaderProgram->addShaderFromSource(circle_filled_fragment_shader_source, GL_FRAGMENT_SHADER);
280 shaderProgram->linkProgram();
281
282 if (shaderProgram->isOK())
283 pcircle_filled_shader_program[index] = shaderProgram;
284 }
285
286 if (!ptexture_2DA_shader_program[index]) {
287 GLShaderProgram *shaderProgram = new GLShaderProgram;
288 shaderProgram->addShaderFromSource(texture_2DA_vertex_shader_source, GL_VERTEX_SHADER);
289 shaderProgram->addShaderFromSource(texture_2DA_fragment_shader_source, GL_FRAGMENT_SHADER);
290 shaderProgram->linkProgram();
291
292 if (shaderProgram->isOK())
293 ptexture_2DA_shader_program[index] = shaderProgram;
294 }
295
296 if (!pAALine_shader_program[index]) {
297 GLShaderProgram *shaderProgram = new GLShaderProgram;
298 shaderProgram->addShaderFromSource(AALine_fragment_shader_source, GL_FRAGMENT_SHADER);
299 shaderProgram->addShaderFromSource(AALine_vertex_shader_source, GL_VERTEX_SHADER);
300 shaderProgram->linkProgram();
301
302 if (shaderProgram->isOK())
303 pAALine_shader_program[index] = shaderProgram;
304 }
305
306 // ring shader
307 if (!pring_shader_program[index]) {
308 GLShaderProgram *shaderProgram = new GLShaderProgram;
309 shaderProgram->addShaderFromSource(ring_fragment_shader_source, GL_FRAGMENT_SHADER);
310 shaderProgram->addShaderFromSource(ring_vertex_shader_source, GL_VERTEX_SHADER);
311 shaderProgram->linkProgram();
312
313 if (shaderProgram->isOK())
314 pring_shader_program[index] = shaderProgram;
315 }
316
317 bShadersLoaded[index] = true;
318 reConfigureShaders(index);
319
320 return ret_val;
321}
322
323void reConfigureShaders(int index) {
324}
325
326void unloadShaders() {
327 bShadersLoaded[0] = bShadersLoaded[1] = false;
328}
329
330GLShaderProgram *GetStaticTriShader() {
331 GLShaderProgram *shaderProgram = new GLShaderProgram;
332 shaderProgram->addShaderFromSource(color_tri_vertex_shader_source, GL_VERTEX_SHADER);
333 shaderProgram->addShaderFromSource(color_tri_fragment_shader_source, GL_FRAGMENT_SHADER);
334 shaderProgram->linkProgram();
335
336 if (shaderProgram->isOK())
337 return shaderProgram;
338 else
339 return NULL;
340}
341
342
343#endif