atomes 1.1.16
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
ogl_shaders.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2024 by CNRS and University of Strasbourg */
15
22/*
23* This file: 'ogl_shaders.c'
24*
25* Contains:
26*
27
28 - The OpenGL shaders for the atomes program
29
30*
31*/
32
33#include "global.h"
34
35// Point shaders:
36
37// const GLchar * point_vertex;
38// const GLchar * point_colors;
39
40//#define GLSL(src) "#version 430 core\n" #src
41#define GLSL(src) "#version 150\n" #src
42
43const GLchar * point_vertex = GLSL(
44 uniform mat4 mvp;
45 in vec3 vert;
46 in vec3 offset;
47 in float size;
48 in vec4 vertColor;
49
50 out vec4 vert_color;
51 void main()
52 {
53 vert_color = vertColor;
54 gl_PointSize = size;
55 gl_Position = mvp * vec4(vert + offset, 1.0);
56 }
57);
58
59const GLchar * point_color = GLSL(
60 in vec4 vert_color;
61 out vec4 fragment_color;
62 void main()
63 {
64 /*if(dot(gl_PointCoord-0.5,gl_PointCoord-0.5)>0.25)
65 {
66 discard;
67 }
68 else
69 {*/
70 fragment_color = vert_color;
71 //}
72 }
73);
74
75// Basic line shaders
76
77// const GLchar * line_vertex;
78// const GLchar * line_colors;
79
80const GLchar * line_vertex = GLSL(
81 uniform mat4 mvp;
82 in vec3 vert;
83 in vec4 vertColor;
84
85 out vec4 vert_color;
86 void main()
87 {
88 vert_color = vertColor;
89 gl_Position = mvp * vec4(vert, 1.0);
90 }
91);
92
93const GLchar * axis_line_vertex = GLSL(
94 uniform mat4 mvp;
95 uniform vec4 vertColor;
96 in vec3 vert;
97
98 out vec4 vert_color;
99 void main()
100 {
101 vert_color = vertColor;
102 gl_Position = mvp * vec4(vert, 1.0);
103 }
104);
105
106const GLchar * line_color = GLSL(
107 in vec4 vert_color;
108 out vec4 fragment_color;
109 void main()
110 {
111 fragment_color = vert_color;
112 }
113);
114
115const GLchar * line_stipple = GLSL(
116 layout(lines) in;
117 layout(line_strip, max_vertices=2) out;
118 in vec4 vert_color[];
119 uniform float depth;
120
121 out float line_pos;
122 out vec4 v_color;
123 void main()
124 {
125 vec2 win_pos_0 = gl_in[0].gl_Position.xy;
126 vec2 win_pos_1 = gl_in[1].gl_Position.xy;
127 gl_Position = gl_in[0].gl_Position;
128 line_pos = 0.0;
129 v_color = vert_color[0];
130 EmitVertex();
131 gl_Position = gl_in[1].gl_Position;
132 float psize = 3.0; // No particular reason, just seems right
133 line_pos = psize * length(win_pos_1 - win_pos_0);
134 line_pos *= depth;
135 v_color = vert_color[1];
136 EmitVertex();
137 EndPrimitive();
138 }
139);
140
141const GLchar * angle_vertex = GLSL(
142 uniform mat4 mvp;
143 in vec3 vert;
144 in vec4 vertColor;
145
146 out vec4 vert_color;
147 void main()
148 {
149 vert_color = vertColor;
150 gl_Position = vec4(vert, 1.0);
151 }
152);
153
154const GLchar * angle_stipple = GLSL(
155 layout(triangles) in;
156 layout(line_strip, max_vertices=20) out;
157 in vec4 vert_color[];
158
159 uniform float depth;
160 uniform mat4 mvp;
161 uniform mat4 un_view;
162 uniform mat4 text_proj;
163 uniform vec4 viewp;
164
165 out float line_pos;
166 out vec4 v_color;
167
168 const float PI = 3.14159265359;
169
170 mat4 translate_this (in vec3 coord)
171 {
172 mat4 translate;
173 translate[0] = vec4(1.0, 0.0, 0.0, 0.0);
174 translate[1] = vec4(0.0, 1.0, 0.0, 0.0);
175 translate[2] = vec4(0.0, 0.0, 1.0, 0.0);
176 translate[3][0] = coord.x;
177 translate[3][1] = coord.y;
178 translate[3][2] = coord.z;
179 translate[3][3] = 1.0;
180 return translate;
181 }
182
183 vec3 project (in vec3 coord)
184 {
185 mat4 n_mvp = (mvp * translate_this (coord));
186 vec4 res = n_mvp * vec4(vec3(0.0), 1.0);
187 if (res.w != 0.0)
188 {
189 res.w = 1.0 / res.w;
190 res.x = res.w * res.x + 1.0;
191 res.y = res.w * res.y + 1.0;
192 res.z = res.w * res.z + 1.0;
193 return vec3 (res.x*viewp.z+viewp.x, res.y*viewp.w+viewp.y, res.z);
194 }
195 else
196 {
197 return vec3 (0.0, 0.0, -1.0);
198 }
199 }
200
201 float angle2d (in vec2 at, in vec2 bt, in vec2 ct)
202 {
203 vec2 ab = bt - at;
204 vec2 bc = bt - ct;
205 float theta = dot(ab,bc) / (length(ab) * length(bc));
206 if (theta < -1.0)
207 {
208 return acos (-2.0 - theta);
209 }
210 else if (theta > 1.0)
211 {
212 return acos (2.0 - theta);
213 }
214 else
215 {
216 return acos (theta);
217 }
218 }
219
220 void main()
221 {
222 vec3 pa = project (gl_in[0].gl_Position.xyz);
223 vec3 pb = project (gl_in[1].gl_Position.xyz);
224 vec3 pc = project (gl_in[2].gl_Position.xyz);
225 vec2 pd;
226 pd.x = pb.x + 100.0;
227 pd.y = pb.y;
228 float alpha = angle2d (pa.xy, pb.xy, pd);
229 float beta = angle2d (pc.xy, pb.xy, pd);
230 float theta = angle2d (pa.xy, pb.xy, pc.xy);
231 if (pa.y > pb.y && pc.y > pb.y)
232 {
233 beta = min (alpha, beta);
234 }
235 else if (pa.y < pb.y && pc.y < pb.y)
236 {
237 beta = min (-alpha, -beta);
238 // or beta = - max (alpha, beta);
239 }
240 else
241 {
242 vec2 pe;
243 vec2 pf;
244 pe.y = max(pa.y, pc.y);
245 if (pe.y == pa.y)
246 {
247 pe.x = pa.x;
248 pf.y = pc.y;
249 pf.x = pc.x;
250 }
251 else
252 {
253 pe.x = pc.x;
254 pf.y = pa.y;
255 pf.x = pa.x;
256 }
257 beta = angle2d (pe, pb.xy, pd);
258 alpha = angle2d (pf, pb.xy, pd);
259 if (beta + alpha < PI)
260 {
261 beta -= theta;
262 }
263 }
264
265 float psize = 3.0; // No particular reason, just seems right
266 float tan_factor = tan(theta/10.0);
267 float radial_factor = cos(theta/10.0);
268 float dist = min(length(pb-pa), length(pb-pc)) / 3.0;
269 float x = dist * cos(beta);
270 float y = dist * sin(beta);
271 float tx;
272 float ty;
273
274 vec2 apos;
275 vec2 bpos;
276 v_color = vert_color[0];
277
278 vec4 pos_s = mvp * gl_in[0].gl_Position;
279 vec4 pos_e = mvp * gl_in[1].gl_Position;
280 line_pos = 0.0;
281 gl_Position = pos_s;
282 EmitVertex();
283 float line_save = psize * length(pos_e.xy - pos_s.xy);
284 line_pos = line_save;
285 line_pos *= depth;
286 gl_Position = pos_e;
287 EmitVertex();
288 int i;
289 line_pos = -1.0;
290 EmitVertex();
291 for (i = 0; i < 11; i++)
292 {
293 apos = vec2(x,y);
294 gl_Position = text_proj * (vec4(pb, 1.0) + vec4(apos.x, apos.y, 0.0, 1.0));
295 EmitVertex();
296 if (i == 0)
297 {
298 line_pos = line_save;
299 EmitVertex();
300 }
301 tx = -y;
302 ty = x;
303 x += tx * tan_factor;
304 y += ty * tan_factor;
305 x *= radial_factor;
306 y *= radial_factor;
307 bpos = vec2(x,y);
308 line_pos += psize * length(bpos - apos) / 20.0;
309 }
310 EmitVertex();
311 line_save = line_pos;
312 line_pos = -1.0;
313 EmitVertex();
314 gl_Position = pos_e;
315 EmitVertex();
316 line_pos = line_save;
317 line_pos *= depth;
318 EmitVertex();
319 pos_s = mvp * gl_in[2].gl_Position;
320 line_pos += depth * psize * length(pos_s.xy - pos_e.xy);
321 gl_Position = pos_s;
322 EmitVertex();
323 EndPrimitive();
324 }
325);
326
327const GLchar * line_stipple_color = GLSL(
328 uniform int factor;
329 uniform uint pattern;
330 in float line_pos;
331 in vec4 v_color;
332
333 out vec4 fragment_color;
334 void main()
335 {
336 fragment_color = v_color;
337 if (line_pos == -1.0) discard;
338 uint bit = uint(round(line_pos/factor)) % 16U;
339 if ((pattern & (1U<<bit)) == 0U) discard;
340 }
341);
342
343const GLchar * angle_color = GLSL(
344 uniform int factor;
345 uniform uint pattern;
346 in float line_pos;
347 in vec4 v_color;
348
349 out vec4 fragment_color;
350 void main()
351 {
352 fragment_color = v_color;
353 if (line_pos == -1.0) discard;
354 }
355);
356
357// Triangle shader
358
359const GLchar * full_vertex = GLSL(
360 uniform mat4 mvp;
361 uniform mat4 m_view;
362 in vec3 vert;
363 in vec3 vertNormal;
364 in vec4 vertColor;
365
366 out vec4 surfaceColor;
367 out vec3 surfacePosition;
368 out vec3 surfaceNormal;
369 out vec3 surfaceToCamera;
370 void main ()
371 {
372 surfaceColor = vertColor;
373
374 surfacePosition = vec3(m_view * vec4(vert, 1.0f));
375 surfaceNormal = mat3(m_view) * vertNormal;
376 surfaceToCamera = normalize (- surfacePosition);
377 gl_Position = mvp * vec4(vert, 1.0f);
378 }
379);
380
381const GLchar * full_color = GLSL(
382
383 int PHONG = 1;
384 int BLINN = 2;
385 int COOK_BLINN = 3;
386 int COOK_BECKMANN = 4;
387 int COOK_GGX = 5;
388
389 struct Light {
390 int type;
391 vec3 position;
392 vec3 direction;
393 vec3 intensity;
394 float constant;
395 float linear;
396 float quadratic;
397 float cone_angle;
398 float spot_inner;
399 float spot_outer;
400 };
401
402 struct Material {
403 vec3 albedo;
404 float metallic;
405 float roughness;
406 float back_light;
407 float gamma;
408 float alpha;
409 };
410
411 struct Fog {
412 int mode;
413 int based;
414 float density;
415 vec2 depth;
416 vec3 color;
417 };
418
419 uniform Light AllLights[10];
420 uniform Material mat;
421 uniform Fog fog;
422 uniform int lights_on;
423 uniform int numLights;
424
425 in vec4 surfaceColor;
426 in vec3 surfacePosition;
427 in vec3 surfaceNormal;
428 in vec3 surfaceToCamera;
429
430 out vec4 fragment_color;
431
432 const float PI = 3.14159265359;
433
434 // clamping to 0 - 1 range
435 float saturate (in float value)
436 {
437 return clamp(value, 0.0, 1.0);
438 }
439
440 // phong (lambertian) diffuse term
441 float phong_diffuse()
442 {
443 return (1.0 / PI);
444 }
445
446 // compute Fresnel specular factor for given base specular and product
447 // product could be NdV or VdH depending on used technique
448 vec3 fresnel_factor (in vec3 f0, in float product)
449 {
450 return mix(f0, vec3(1.0), pow(1.01 - product, 5.0));
451 }
452
453 // following functions are copies of UE4
454 // for computing cook-torrance specular lighting terms
455
456 float D_blinn(in float roughness, in float NdH)
457 {
458 float m = roughness * roughness;
459 float m2 = m * m;
460 float n = 2.0 / m2 - 2.0;
461 return (n + 2.0) / (2.0 * PI) * pow(NdH, n);
462 }
463
464 float D_beckmann(in float roughness, in float NdH)
465 {
466 float m = roughness * roughness;
467 float m2 = m * m;
468 float NdH2 = NdH * NdH;
469 return exp((NdH2 - 1.0) / (m2 * NdH2)) / (PI * m2 * NdH2 * NdH2);
470 }
471
472 float D_GGX(in float roughness, in float NdH)
473 {
474 float m = roughness * roughness;
475 float m2 = m * m;
476 float d = (NdH * m2 - NdH) * NdH + 1.0;
477 return m2 / (PI * d * d);
478 }
479
480 float G_schlick(in float roughness, in float NdV, in float NdL)
481 {
482 float k = roughness * roughness * 0.5;
483 float V = NdV * (1.0 - k) + k;
484 float L = NdL * (1.0 - k) + k;
485 return 0.25 / (V * L);
486 }
487
488 // simple phong specular calculation with normalization
489 vec3 phong_specular(in vec3 V, in vec3 L, in vec3 N, in vec3 specular, in float roughness)
490 {
491 vec3 R = reflect(-L, N);
492 float spec = max(0.0, dot(V, R));
493
494 float k = 1.999 / (roughness * roughness);
495
496 return min(1.0, 3.0 * 0.0398 * k) * pow(spec, min(10000.0, k)) * specular;
497 }
498
499 // simple blinn specular calculation with normalization
500 vec3 blinn_specular(in float NdH, in vec3 specular, in float roughness)
501 {
502 float k = 1.999 / (roughness * roughness);
503
504 return min(1.0, 3.0 * 0.0398 * k) * pow(NdH, min(10000.0, k)) * specular;
505 }
506
507 // cook-torrance specular calculation
508 vec3 cooktorrance_specular (in int cook, in float NdL, in float NdV, in float NdH, in vec3 specular, in float roughness)
509 {
510 float D;
511 if (cook == COOK_BLINN)
512 {
513 D = D_blinn(roughness, NdH);
514 }
515 else if (cook == COOK_BECKMANN)
516 {
517 D = D_beckmann(roughness, NdH);
518 }
519 else if (cook == COOK_GGX)
520 {
521 D = D_GGX(roughness, NdH);
522 }
523
524 float G = G_schlick(roughness, NdV, NdL);
525
526 float rim = mix(1.0 - roughness * mat.back_light * 0.9, 1.0, NdV);
527
528 return (1.0 / rim) * specular * G * D;
529 }
530
531 vec3 Apply_lighting_model (in int model, in Light light, in vec3 specular)
532 {
533 vec3 v_pos = surfacePosition;
534 // L, V, H vectors
535 vec3 L;
536 float A;
537 float I = 1.0;
538 if (light.type == 0)
539 {
540 // Directional light
541 L = normalize (-light.direction);
542 A = 1.0;
543 }
544 else
545 {
546 vec3 L = light.position - v_pos;
547 float dist = length (L);
548 L = normalize(L);
549 A = 1.0 / (light.constant + light.linear*dist + light.quadratic*dist*dist);
550 if (light.type == 2)
551 {
552 float theta = dot(L, normalize(light.position-light.direction));
553 if(theta > light.cone_angle)
554 {
555 float epsilon = light.spot_inner - light.spot_outer;
556 I = saturate((theta - light.spot_outer) / epsilon);
557 }
558 else
559 {
560 return vec3(0.0001);
561 }
562 }
563 }
564 vec3 V = normalize(-v_pos);
565 vec3 H = normalize(L + V);
566 vec3 N = surfaceNormal;
567
568 // compute material reflectance
569 float NdL = max(0.0, dot(N, L));
570 float NdV = max(0.001, dot(N, V));
571 float NdH = max(0.001, dot(N, H));
572 float HdV = max(0.001, dot(H, V));
573 float LdV = max(0.001, dot(L, V));
574
575 // fresnel term is common for any, except phong
576 // so it will be calculated inside ifdefs
577 vec3 specfresnel;
578 vec3 specref;
579 if (model == PHONG)
580 {
581 // specular reflectance with PHONG
582 specfresnel = fresnel_factor (specular, NdV);
583 specref = phong_specular (V, L, N, specfresnel, mat.roughness);
584 }
585 else if (model == BLINN)
586 {
587 // specular reflectance with BLINN
588 specfresnel = fresnel_factor (specular, HdV);
589 specref = blinn_specular (NdH, specfresnel, mat.roughness);
590 }
591 else
592 {
593 // specular reflectance with COOK-TORRANCE
594 specfresnel = fresnel_factor(specular, HdV);
595 specref = cooktorrance_specular(model, NdL, NdV, NdH, specfresnel, mat.roughness);
596 }
597
598 specref *= vec3(NdL);
599
600 // diffuse is common for any model
601 vec3 diffref = (vec3(1.0) - specfresnel) * phong_diffuse() * NdL;
602
603 // compute lighting
604 vec3 reflected_light = vec3(0);
605 vec3 diffuse_light = vec3(0); // initial value == constant ambient light
606
607 // point light
608 vec3 light_color = light.intensity * A * I;
609 reflected_light += specref * light_color;
610 diffuse_light += diffref * light_color;
611
612 // final result
613 return diffuse_light * mix(mat.albedo, vec3(0.0), mat.metallic) + reflected_light;
614 }
615
616 vec3 Apply_fog (in vec3 lightColor)
617 {
618 //distance
619 float dist = 0.0;
620 float fogFactor = 0.0;
621
622 //compute distance used in fog equations
623 if (fog.based == 0)
624 {
625 //plane based
626 dist = abs (surfacePosition.z);
627 }
628 else
629 {
630 //range based
631 dist = length (surfacePosition);
632 }
633
634 if (fog.mode == 1) // linear fog
635 {
636 fogFactor = (fog.depth.x - dist)/(fog.depth.y - fog.depth.x);
637 }
638 else if (fog.mode == 2) // exponential fog
639 {
640 fogFactor = 1.0 / exp (dist * fog.density);
641 }
642 else
643 {
644 fogFactor = 1.0 / exp((dist * fog.density)* (dist * fog.density));
645 }
646 fogFactor = saturate (fogFactor);
647 return mix (fog.color, lightColor, fogFactor);
648 }
649
650 void main ()
651 {
652 // Properties
653 vec3 color;
654 float alpha;
655 if (lights_on == 0)
656 {
657 color = vec3(1.0);
658 alpha = surfaceColor.w;
659 }
660 else
661 {
662 // mix between metal and non-metal material, for non-metal
663 // constant base specular factor of 0.04 grey is used
664 vec3 specular = mix(vec3(0.04), mat.albedo, mat.metallic);
665 color = vec3(0.0);
666 for(int i = 0; i < numLights; i++)
667 {
668 color += Apply_lighting_model (lights_on, AllLights[i], specular);
669 }
670 color = pow(color, vec3(1.0/mat.gamma));
671 alpha = surfaceColor.w * mat.alpha;
672 }
673 if (fog.mode > 0)
674 {
675 fragment_color = vec4 (Apply_fog(surfaceColor.xyz*color), alpha);
676 }
677 else
678 {
679 fragment_color = vec4 (surfaceColor.xyz*color, alpha);
680 }
681 }
682);
683
684// Sphere
685
686const GLchar * sphere_vertex = GLSL(
687 uniform mat4 mvp;
688 uniform mat4 m_view;
689
690 in vec3 vert;
691 in vec3 offset;
692 in vec4 vertColor;
693 in float radius;
694
695 out vec4 surfaceColor;
696 out vec3 surfacePosition;
697 out vec3 surfaceNormal;
698 out vec3 surfaceToCamera;
699 void main ()
700 {
701 surfaceColor = vertColor;
702 vec4 pos = vec4 (radius*vert + offset, 1.0);
703 surfacePosition = vec3(m_view * pos);
704 surfaceNormal = mat3(m_view) * vert;
705 surfaceToCamera = normalize (- surfacePosition);
706 gl_PointSize = 1.0;
707 gl_Position = mvp * pos;
708 }
709);
710
711const GLchar * axis_sphere_vertex = GLSL(
712 uniform mat4 mvp;
713 uniform mat4 m_view;
714 uniform vec4 vertColor;
715
716 in vec3 vert;
717 in vec3 vertNormal;
718
719 out vec4 surfaceColor;
720 out vec3 surfacePosition;
721 out vec3 surfaceNormal;
722 out vec3 surfaceToCamera;
723 void main ()
724 {
725 surfaceColor = vertColor;
726 vec4 pos = vec4(vert, 1.0);
727 surfacePosition = vec3(m_view * pos);
728 surfaceNormal = mat3(m_view) * vertNormal;
729 surfaceToCamera = normalize (- surfacePosition);
730 gl_PointSize = 1.0;
731 gl_Position = mvp * pos;
732 }
733);
734
735// Cylinder
736
737const GLchar * gs_cylinder_vertex = GLSL(
738 in vec3 vert;
739 in vec4 vertColor;
740 out vec4 vertCol;
741 void main ()
742 {
743 vertCol = vertColor;
744 gl_Position = vec4(vert, 1.0);
745 }
746);
747
748const GLchar * cylinder_vertex = GLSL(
749 uniform mat4 mvp;
750 uniform mat4 m_view;
751 in vec4 quat;
752 in float height;
753 in float radius;
754 in vec3 offset;
755 in vec3 vert;
756 in vec4 vertColor;
757
758 out vec4 surfaceColor;
759 out vec3 surfacePosition;
760 out vec3 surfaceNormal;
761 out vec3 surfaceToCamera;
762
763 vec3 rotate_this (in vec3 v, in vec4 quat)
764 {
765 vec3 u = vec3(quat.x, quat.y, quat.z);
766 float s = quat.w;
767 return 2.0 * dot(u,v) * u + (s*s - dot(u,u)) * v + 2.0 * s * cross (u,v);
768 }
769
770 void main ()
771 {
772 surfaceColor = vertColor;
773 vec3 pos = vec3(radius*vert.x, radius*vert.y, height*vert.z);
774 vec3 norm = normalize (vec3(vert.x, vert.y, 0.0));
775 if (quat.w != 0.0)
776 {
777 pos = rotate_this (pos, quat);
778 norm = rotate_this (norm, quat);
779 }
780 pos += offset;
781 surfacePosition = vec3(m_view * vec4(pos,1.0));
782 surfaceNormal = mat3(m_view) * norm;
783 surfaceToCamera = normalize (- surfacePosition);
784 gl_Position = mvp * vec4(pos,1.0);
785 }
786);
787
788const GLchar * cone_vertex = GLSL(
789 uniform mat4 mvp;
790 uniform mat4 m_view;
791 in vec4 quat;
792 in float height;
793 in float radius;
794 in vec3 offset;
795 in vec3 vert;
796 in vec4 vertColor;
797
798 out vec4 surfaceColor;
799 out vec3 surfacePosition;
800 out vec3 surfaceNormal;
801 out vec3 surfaceToCamera;
802
803 vec3 rotate_this (in vec3 v, in vec4 quat)
804 {
805 vec3 u = vec3(quat.x, quat.y, quat.z);
806 float s = quat.w;
807 return 2.0 * dot(u,v) * u + (s*s - dot(u,u)) * v + 2.0 * s * cross (u,v);
808 }
809
810 void main ()
811 {
812 surfaceColor = vertColor;
813 vec3 pos = vec3(radius*vert.x, radius*vert.y, height*vert.z);
814 // The normal calculation changes / cylinders
815 float B = sqrt(radius*radius + height*height);
816 vec3 norm = vec3(height*vert.x/B, height*vert.y/B, radius/B);
817 if (quat.w != 0.0)
818 {
819 pos = rotate_this (pos, quat);
820 norm = rotate_this (norm, quat);
821 }
822 pos += offset;
823 surfacePosition = vec3(m_view * vec4(pos,1.0));
824 surfaceNormal = mat3(m_view) * norm;
825 surfaceToCamera = normalize (- surfacePosition);
826 gl_Position = mvp * vec4(pos,1.0);
827 }
828);
829
830const GLchar * cap_vertex = GLSL(
831 uniform mat4 mvp;
832 uniform mat4 m_view;
833 in vec4 quat;
834 in float radius;
835 in vec3 offset;
836 in vec3 vert;
837 in vec4 vertColor;
838
839 out vec4 surfaceColor;
840 out vec3 surfacePosition;
841 out vec3 surfaceNormal;
842 out vec3 surfaceToCamera;
843
844 vec3 rotate_this (in vec3 v, in vec4 quat)
845 {
846 vec3 u = vec3(quat.x, quat.y, quat.z);
847 float s = quat.w;
848 return 2.0 * dot(u,v) * u + (s*s - dot(u,u)) * v + 2.0 * s * cross (u,v);
849 }
850
851 void main ()
852 {
853 surfaceColor = vertColor;
854 vec3 pos = vec3(radius*vert.x, radius*vert.y, vert.z);
855 vec3 norm = vec3(0.0, 0.0, -1.0);
856 if (quat.w != 0.0)
857 {
858 pos = rotate_this (pos, quat);
859 norm = rotate_this (norm, quat);
860 }
861 pos += offset;
862 surfacePosition = vec3(m_view * vec4(pos,1.0));
863 surfaceNormal = mat3(m_view) * norm;
864 surfaceToCamera = normalize (- surfacePosition);
865 gl_Position = mvp * vec4(pos,1.0);
866 }
867);
868
869const GLchar * gs_cylinder_geom = GLSL(
870
871 layout (lines) in;
872 layout (triangle_strip, max_vertices=64) out;
873
874 uniform mat4 mvp;
875 uniform mat4 m_view;
876 uniform int quality;
877 uniform float radius;
878
879 in vec4 vertCol[];
880
881 out vec4 surfaceColor;
882 out vec3 surfacePosition;
883 out vec3 surfaceNormal;
884 out vec3 surfaceToCamera;
885
886 float pi = 3.141592653;
887
888 vec3 create_perp (in vec3 axis)
889 {
890 vec3 u = vec3(0.0, 0.0, 1.0);
891 vec3 v = vec3(0.0, 1.0, 0.0);
892 vec3 res = cross(u, axis);
893 if (length(res) == 0.0)
894 {
895 res = cross (v, axis);
896 }
897 return res;
898 }
899
900 void main()
901 {
902
903 vec3 v1 = gl_in[0].gl_Position.xyz;
904 vec3 v2 = gl_in[1].gl_Position.xyz;
905 vec3 axis = normalize(v2 - v1);
906 vec3 perp_x = create_perp (axis);
907 vec3 perp_y = cross (axis, perp_x);
908 float step = 2.0 * pi / float(quality - 1);
909 for(int i=0; i<quality; i++)
910 {
911 float a = i * step;
912 float ca = cos(a);
913 float sa = sin(a);
914
915 vec3 normal = normalize(ca*perp_x + sa*perp_y);
916 vec3 p1 = v1 + radius * normal;
917 vec3 p2 = v2 + radius * normal;
918
919 surfaceNormal = mat3(m_view) * normal;
920 gl_Position = mvp * vec4(p1, 1.0);
921
922 surfacePosition = vec3(m_view * vec4(p1, 1.0));
923 surfaceToCamera = normalize (- surfacePosition);
924 surfaceColor = vertCol[0];
925 EmitVertex();
926
927 gl_Position = mvp * vec4 (p2, 1.0);
928 surfacePosition = vec3(m_view * vec4(p2, 1.0));
929 surfaceToCamera = normalize (- surfacePosition);
930 surfaceColor = vertCol[1];
931 EmitVertex();
932 }
933 EndPrimitive();
934 }
935);
936
937// Axis cylinder
938
939const GLchar * axis_cylinder_geom = GLSL(
940
941 layout (lines) in;
942 layout (triangle_strip, max_vertices=64) out;
943
944 uniform mat4 mvp;
945 uniform mat4 m_view;
946 uniform float radius;
947
948 out vec3 surfacePosition;
949 out vec3 surfaceNormal;
950 out vec3 surfaceToCamera;
951
952 float pi = 3.141592653;
953
954 vec3 create_perp (in vec3 axis)
955 {
956 vec3 u = vec3(0.0, 0.0, 1.0);
957 vec3 v = vec3(0.0, 1.0, 0.0);
958 vec3 res = cross(u, axis);
959 if (length(res) == 0.0)
960 {
961 res = cross (v, axis);
962 }
963 return res;
964 }
965
966 void main()
967 {
968
969 vec3 v1 = gl_in[0].gl_Position.xyz;
970 vec3 v2 = gl_in[1].gl_Position.xyz;
971 float r1 = gl_in[0].gl_Position.w;
972 float r2 = gl_in[1].gl_Position.w;
973 vec3 axis = normalize(v2 - v1);
974 vec3 perp_x = create_perp (axis);
975 vec3 perp_y = cross (axis, perp_x);
976 float step = 2.0 * pi / float(32 - 1);
977 for(int i=0; i<32; i++)
978 {
979 float a = i * step;
980 float ca = cos(a);
981 float sa = sin(a);
982
983 vec3 normal = normalize(ca*perp_x + sa*perp_y);
984 vec3 p1 = v1 + r1 * normal;
985 vec3 p2 = v2 + r2 * normal;
986
987 surfaceNormal = mat3(m_view) * normal;
988 gl_Position = mvp * vec4(p1, 1.0);
989
990 surfacePosition = vec3(m_view * vec4(p1, 1.0));
991 surfaceToCamera = normalize (- surfacePosition);
992 EmitVertex();
993
994 gl_Position = mvp * vec4 (p2, 1.0);
995 surfacePosition = vec3(m_view * vec4(p2, 1.0));
996 surfaceToCamera = normalize (- surfacePosition);
997 EmitVertex();
998 }
999 EndPrimitive();
1000 }
1001);
1002
1003// Tetrahedra
1004
1005const GLchar * polyedron_vertex = GLSL(
1006 in vec4 vert;
1007 in vec4 vertColor;
1008
1009 out vec4 surfaceColor;
1010 void main ()
1011 {
1012 surfaceColor = vertColor;
1013 gl_Position = vert;
1014 }
1015);
1016
1017const GLchar * polyedron_geom = GLSL(
1018
1019 layout (triangles) in;
1020 layout (triangle_strip, max_vertices=3) out;
1021
1022 uniform mat4 mvp;
1023 uniform mat4 m_view;
1024
1025 out vec3 surfacePosition;
1026 out vec3 surfaceNormal;
1027 out vec3 surfaceToCamera;
1028
1029 float pi = 3.141592653;
1030
1031 vec3 get_triangle_normal (in vec3 v1, in vec3 v2, in vec3 v3)
1032 {
1033 vec3 edge_a = v3 - v1;
1034 vec3 edge_b = v2 - v1;
1035 return normalize(cross(edge_a, edge_b));
1036 }
1037
1038 void main()
1039 {
1040 vec3 v[3];
1041 int i;
1042 for (i=0; i<3; i++)
1043 {
1044 v[i] = gl_in[i].gl_Position.xyz;
1045 }
1046 float sign = gl_in[0].gl_Position.w;
1047 vec3 normal = sign * get_triangle_normal(v[0], v[1], v[2]);
1048 surfaceNormal = mat3(m_view) * normal;
1049 for (i=0; i<3; i++)
1050 {
1051 gl_Position = mvp * vec4(v[i], 1.0);
1052 surfacePosition = vec3(m_view * vec4(v[i], 1.0));
1053 surfaceToCamera = normalize (- surfacePosition);
1054 EmitVertex();
1055 }
1056 EndPrimitive();
1057 }
1058);
1059
1060const GLchar * polyedron_color = GLSL(
1061
1062 int PHONG = 1;
1063 int BLINN = 2;
1064 int COOK_TORRANCE = 3;
1065 int COOK_BLINN = 3;
1066 int COOK_BECKMANN = 4;
1067 int COOK_GGX = 5;
1068
1069 struct Light {
1070 int type;
1071 vec3 position;
1072 vec3 direction;
1073 vec3 intensity;
1074 float constant;
1075 float linear;
1076 float quadratic;
1077 float cone_angle;
1078 float spot_inner;
1079 float spot_outer;
1080 };
1081
1082 struct Material {
1083 vec3 albedo;
1084 float metallic;
1085 float roughness;
1086 float back_light;
1087 float gamma;
1088 float alpha;
1089 };
1090
1091 struct Fog {
1092 int mode;
1093 int based;
1094 float density;
1095 vec2 depth;
1096 vec3 color;
1097 };
1098
1099 uniform Light AllLights[10];
1100 uniform Material mat;
1101 uniform Fog fog;
1102 uniform int lights_on;
1103 uniform int numLights;
1104 uniform vec4 vertColor;
1105
1106 in vec3 surfacePosition;
1107 in vec3 surfaceNormal;
1108 in vec3 surfaceToCamera;
1109
1110 out vec4 fragment_color;
1111
1112 const float PI = 3.14159265359;
1113
1114 // clamping to 0 - 1 range
1115 float saturate (in float value)
1116 {
1117 return clamp(value, 0.0, 1.0);
1118 }
1119
1120 // phong (lambertian) diffuse term
1121 float phong_diffuse()
1122 {
1123 return (1.0 / PI);
1124 }
1125
1126 // compute fresnel specular factor for given base specular and product
1127 // product could be NdV or VdH depending on used technique
1128 vec3 fresnel_factor (in vec3 f0, in float product)
1129 {
1130 return mix(f0, vec3(1.0), pow(1.01 - product, 5.0));
1131 }
1132
1133 // following functions are copies of UE4
1134 // for computing cook-torrance specular lighting terms
1135
1136 float D_blinn(in float roughness, in float NdH)
1137 {
1138 float m = roughness * roughness;
1139 float m2 = m * m;
1140 float n = 2.0 / m2 - 2.0;
1141 return (n + 2.0) / (2.0 * PI) * pow(NdH, n);
1142 }
1143
1144 float D_beckmann(in float roughness, in float NdH)
1145 {
1146 float m = roughness * roughness;
1147 float m2 = m * m;
1148 float NdH2 = NdH * NdH;
1149 return exp((NdH2 - 1.0) / (m2 * NdH2)) / (PI * m2 * NdH2 * NdH2);
1150 }
1151
1152 float D_GGX(in float roughness, in float NdH)
1153 {
1154 float m = roughness * roughness;
1155 float m2 = m * m;
1156 float d = (NdH * m2 - NdH) * NdH + 1.0;
1157 return m2 / (PI * d * d);
1158 }
1159
1160 float G_schlick(in float roughness, in float NdV, in float NdL)
1161 {
1162 float k = roughness * roughness * 0.5;
1163 float V = NdV * (1.0 - k) + k;
1164 float L = NdL * (1.0 - k) + k;
1165 return 0.25 / (V * L);
1166 }
1167
1168 // simple phong specular calculation with normalization
1169 vec3 phong_specular(in vec3 V, in vec3 L, in vec3 N, in vec3 specular, in float roughness)
1170 {
1171 vec3 R = reflect(-L, N);
1172 float spec = max(0.0, dot(V, R));
1173
1174 float k = 1.999 / (roughness * roughness);
1175
1176 return min(1.0, 3.0 * 0.0398 * k) * pow(spec, min(10000.0, k)) * specular;
1177 }
1178
1179 // simple blinn specular calculation with normalization
1180 vec3 blinn_specular(in float NdH, in vec3 specular, in float roughness)
1181 {
1182 float k = 1.999 / (roughness * roughness);
1183
1184 return min(1.0, 3.0 * 0.0398 * k) * pow(NdH, min(10000.0, k)) * specular;
1185 }
1186
1187 // cook-torrance specular calculation
1188 vec3 cooktorrance_specular (in int cook, in float NdL, in float NdV, in float NdH, in vec3 specular, in float roughness)
1189 {
1190 float D;
1191 if (cook == COOK_BLINN)
1192 {
1193 D = D_blinn(roughness, NdH);
1194 }
1195 else if (cook == COOK_BECKMANN)
1196 {
1197 D = D_beckmann(roughness, NdH);
1198 }
1199 else if (cook == COOK_GGX)
1200 {
1201 D = D_GGX(roughness, NdH);
1202 }
1203
1204 float G = G_schlick(roughness, NdV, NdL);
1205
1206 float rim = mix(1.0 - roughness * mat.back_light * 0.9, 1.0, NdV);
1207
1208 return (1.0 / rim) * specular * G * D;
1209 }
1210
1211 vec3 Apply_lighting_model (in int model, in Light light, in vec3 specular)
1212 {
1213 vec3 v_pos = surfacePosition;
1214 // L, V, H vectors
1215 vec3 L;
1216 float A;
1217 float I = 1.0;
1218 if (light.type == 0)
1219 {
1220 // Directional light
1221 L = normalize (-light.direction);
1222 A = 1.0;
1223 }
1224 else
1225 {
1226 vec3 L = light.position - v_pos;
1227 float dist = length (L);
1228 L = normalize(L);
1229 A = 1.0 / (light.constant + light.linear*dist + light.quadratic*dist*dist);
1230 if (light.type == 2)
1231 {
1232 float theta = dot(L, normalize(light.position-light.direction));
1233 if(theta > light.cone_angle)
1234 {
1235 float epsilon = light.spot_inner - light.spot_outer;
1236 I = saturate((theta - light.spot_outer) / epsilon);
1237 }
1238 else
1239 {
1240 return vec3(0.0001);
1241 }
1242 }
1243 }
1244 vec3 V = normalize(-v_pos);
1245 vec3 H = normalize(L + V);
1246 vec3 N = surfaceNormal;
1247
1248 // compute material reflectance
1249 float NdL = max(0.0, dot(N, L));
1250 float NdV = max(0.001, dot(N, V));
1251 float NdH = max(0.001, dot(N, H));
1252 float HdV = max(0.001, dot(H, V));
1253 float LdV = max(0.001, dot(L, V));
1254
1255 // fresnel term is common for any, except phong
1256 // so it will be calculated inside ifdefs
1257 vec3 specfresnel;
1258 vec3 specref;
1259 if (model == PHONG)
1260 {
1261 // specular reflectance with PHONG
1262 specfresnel = fresnel_factor (specular, NdV);
1263 specref = phong_specular (V, L, N, specfresnel, mat.roughness);
1264 }
1265 else if (model == BLINN)
1266 {
1267 // specular reflectance with BLINN
1268 specfresnel = fresnel_factor (specular, HdV);
1269 specref = blinn_specular (NdH, specfresnel, mat.roughness);
1270 }
1271 else
1272 {
1273 // specular reflectance with COOK-TORRANCE
1274 specfresnel = fresnel_factor(specular, HdV);
1275 specref = cooktorrance_specular(model, NdL, NdV, NdH, specfresnel, mat.roughness);
1276 }
1277
1278 specref *= vec3(NdL);
1279
1280 // diffuse is common for any model
1281 vec3 diffref = (vec3(1.0) - specfresnel) * phong_diffuse() * NdL;
1282
1283 // compute lighting
1284 vec3 reflected_light = vec3(0);
1285 vec3 diffuse_light = vec3(0); // initial value == constant ambient light
1286
1287 // point light
1288 vec3 light_color = light.intensity * A * I;
1289 reflected_light += specref * light_color;
1290 diffuse_light += diffref * light_color;
1291
1292 // final result
1293 return diffuse_light * mix(mat.albedo, vec3(0.0), mat.metallic) + reflected_light;
1294 }
1295
1296 vec3 Apply_fog (in vec3 lightColor)
1297 {
1298 //distance
1299 float dist = 0.0;
1300 float fogFactor = 0.0;
1301
1302 //compute distance used in fog equations
1303 if (fog.based == 0)
1304 {
1305 //plane based
1306 dist = abs (surfacePosition.z);
1307 }
1308 else
1309 {
1310 //range based
1311 dist = length (surfacePosition);
1312 }
1313
1314 if (fog.mode == 1) // linear fog
1315 {
1316 fogFactor = (fog.depth.x - dist)/(fog.depth.y - fog.depth.x);
1317 }
1318 else if (fog.mode == 2) // exponential fog
1319 {
1320 fogFactor = 1.0 / exp (dist * fog.density);
1321 }
1322 else
1323 {
1324 fogFactor = 1.0 / exp((dist * fog.density)* (dist * fog.density));
1325 }
1326 fogFactor = saturate (fogFactor);
1327 return mix (fog.color, lightColor, fogFactor);
1328 }
1329
1330 void main()
1331 {
1332 // Properties
1333 vec3 color;
1334 float alpha;
1335 if (lights_on == 0)
1336 {
1337 color = vec3(1.0);
1338 alpha = vertColor.w;
1339 }
1340 else
1341 {
1342 // mix between metal and non-metal material, for non-metal
1343 // constant base specular factor of 0.04 grey is used
1344 vec3 specular = mix(vec3(0.04), mat.albedo, mat.metallic);
1345 color = vec3(0.0);
1346 for(int i = 0; i < numLights; i++)
1347 {
1348 color += Apply_lighting_model (lights_on, AllLights[i], specular);
1349 }
1350 color = pow(color, vec3(1.0/mat.gamma));
1351 alpha = vertColor.w * mat.alpha;
1352 }
1353 if (fog.mode > 0)
1354 {
1355 fragment_color = vec4 (Apply_fog(vertColor.xyz*color), alpha);
1356 }
1357 else
1358 {
1359 fragment_color = vec4 (vertColor.xyz*color, alpha);
1360 }
1361 }
1362);
1363
1364
1365const GLchar * pick_color = GLSL(
1366 in vec4 vert_color;
1367 out uvec4 fragment_color;
1368 void main()
1369 {
1370 fragment_color = uvec4(vert_color);
1371 }
1372);
1373
1374const GLchar * string_vertex = GLSL(
1375 uniform mat4 mvp;
1376 uniform mat4 un_view;
1377 uniform mat4 text_proj;
1378 uniform vec4 viewp;
1379 uniform vec4 pos_shift;
1380 in vec2 vert;
1381 in vec2 tcoord;
1382 in vec3 offset;
1383 out float angle;
1384
1385 out vec2 text_coords;
1386 mat4 translate_this (in vec3 coord)
1387 {
1388 mat4 translate;
1389 translate[0] = vec4(1.0, 0.0, 0.0, 0.0);
1390 translate[1] = vec4(0.0, 1.0, 0.0, 0.0);
1391 translate[2] = vec4(0.0, 0.0, 1.0, 0.0);
1392 translate[3][0] = coord.x;
1393 translate[3][1] = coord.y;
1394 translate[3][2] = coord.z;
1395 translate[3][3] = 1.0;
1396
1397 return translate;
1398 }
1399
1400 vec4 project (in vec3 coord)
1401 {
1402 mat4 n_mvp = ((mvp * translate_this (coord)) * un_view) * translate_this (pos_shift.xyz);
1403 vec4 res = n_mvp * vec4(vec3(0.0), 1.0);
1404 if (res.w != 0.0)
1405 {
1406 res.w = 1.0 / res.w;
1407 res.x = res.w * res.x + 1.0;
1408 res.y = res.w * res.y + 1.0;
1409 res.z = res.w * res.z + 1.0;
1410 return vec4 (res.x*viewp.z+viewp.x, res.y*viewp.w+viewp.y, pos_shift.w*res.z, 1.0);
1411 }
1412 else
1413 {
1414 return vec4 (0.0, 0.0, -1.0, 0.0);
1415 }
1416 }
1417
1418 void main()
1419 {
1420 text_coords = tcoord;
1421 vec4 pos = project (offset) + vec4(vert, 0.0, 1.0);
1422 gl_Position = text_proj * pos;
1423 }
1424);
1425
1426const GLchar * angstrom_vertex = GLSL(
1427 uniform mat4 mvp;
1428 uniform mat4 un_view;
1429 uniform mat4 text_proj;
1430 uniform vec4 viewp;
1431 uniform vec4 pos_shift;
1432 uniform int tilted;
1433
1434 in vec2 vert;
1435 in vec2 tcoord;
1436 in vec3 offset;
1437 in vec3 at_a;
1438 in vec3 at_b;
1439
1440 out vec2 text_coords;
1441
1442 float angle2d (in vec2 at, in vec2 bt, in vec2 ct)
1443 {
1444 vec2 ab = bt - at;
1445 vec2 bc = bt - ct;
1446 float theta = dot(ab,bc) / (length(ab) * length(bc));
1447 if (theta < -1.0)
1448 {
1449 return acos (-2.0 - theta);
1450 }
1451 else if (theta > 1.0)
1452 {
1453 return acos (2.0 - theta);
1454 }
1455 else
1456 {
1457 return acos (theta);
1458 }
1459 }
1460
1461 mat4 rotate_this_z (in float theta)
1462 {
1463 return mat4 ( vec4( cos(theta), sin(theta), 0.0, 0.0),
1464 vec4(-sin(theta), cos(theta), 0.0, 0.0),
1465 vec4( 0.0, 0.0, 1.0, 0.0),
1466 vec4( 0.0, 0.0, 0.0, 1.0));
1467 }
1468
1469 mat4 translate_this (in vec3 coord)
1470 {
1471 mat4 translate;
1472 translate[0] = vec4(1.0, 0.0, 0.0, 0.0);
1473 translate[1] = vec4(0.0, 1.0, 0.0, 0.0);
1474 translate[2] = vec4(0.0, 0.0, 1.0, 0.0);
1475 translate[3][0] = coord.x;
1476 translate[3][1] = coord.y;
1477 translate[3][2] = coord.z;
1478 translate[3][3] = 1.0;
1479
1480 return translate;
1481 }
1482
1483 vec4 project (in vec3 coord, vec4 shift)
1484 {
1485 mat4 n_mvp = mvp * translate_this (coord) * un_view;
1486 vec4 res = n_mvp * vec4(vec3(0.0), 1.0);
1487 res = translate_this (vec3(shift.x/viewp.z, shift.y/viewp.w, shift.z)) * res;
1488 if (res.w != 0.0)
1489 {
1490 res.w = 1.0 / res.w;
1491 res.x = res.w * res.x + 1.0;
1492 res.y = res.w * res.y + 1.0;
1493 res.z = res.w * res.z + 1.0;
1494 return vec4 (res.x*viewp.z+viewp.x, res.y*viewp.w+viewp.y, shift.w*res.z, 1.0);
1495 }
1496 else
1497 {
1498 return vec4 (0.0, 0.0, -1.0, 0.0);
1499 }
1500 }
1501
1502 void main()
1503 {
1504 text_coords = tcoord;
1505 float rot_angle = 0.0;
1506 vec4 shift = pos_shift;
1507 if (tilted > 0)
1508 {
1509 vec3 pos_a = project (at_a, vec4(0.0)).xyz;
1510 vec3 pos_b = project (at_b, vec4(0.0)).xyz;
1511 vec2 pa;
1512 vec2 pb;
1513 vec2 pc;
1514 pa.y = max(pos_a.y, pos_b.y);
1515 if (pa.y == pos_a.y)
1516 {
1517 pa.x = pos_a.x;
1518 pb.x = pos_b.x;
1519 pb.y = pos_b.y;
1520 }
1521 else
1522 {
1523 pa.x = pos_b.x;
1524 pb.x = pos_a.x;
1525 pb.y = pos_a.y;
1526 }
1527 pc.x = pa.x;
1528 pc.y = pb.y;
1529 rot_angle = - angle2d (pa, pb, pc);
1530 if (pa.x < pb.x)
1531 {
1532 rot_angle = -rot_angle;
1533 shift.x = -shift.x;
1534 }
1535 }
1536 vec4 pos;
1537 if (rot_angle != 0.0)
1538 {
1539 pos = project(offset, shift) + vec4(vert, 0.0, 1.0) * rotate_this_z(rot_angle);
1540 }
1541 else
1542 {
1543 pos = project(offset, shift) + vec4(vert, 0.0, 1.0);
1544 }
1545 gl_Position = text_proj * pos;
1546 }
1547);
1548
1549const GLchar * degree_vertex = GLSL(
1550 uniform mat4 mvp;
1551 uniform mat4 un_view;
1552 uniform mat4 text_proj;
1553 uniform vec4 viewp;
1554 uniform vec4 pos_shift;
1555 uniform int tilted;
1556
1557 in vec2 vert;
1558 in vec2 tcoord;
1559 in vec3 offset;
1560 in vec3 at_a;
1561 in vec3 at_b;
1562 in vec3 at_c;
1563
1564 const float PI = 3.14159265359;
1565
1566 out vec2 text_coords;
1567
1568 float angle2d (in vec2 at, in vec2 bt, in vec2 ct)
1569 {
1570 vec2 ab = bt - at;
1571 vec2 bc = bt - ct;
1572 float theta = dot(ab,bc) / (length(ab) * length(bc));
1573 if (theta < -1.0)
1574 {
1575 return acos (-2.0 - theta);
1576 }
1577 else if (theta > 1.0)
1578 {
1579 return acos (2.0 - theta);
1580 }
1581 else
1582 {
1583 return acos (theta);
1584 }
1585 }
1586
1587 mat4 rotate_this_z (in float theta)
1588 {
1589 return mat4 ( vec4( cos(theta), sin(theta), 0.0, 0.0),
1590 vec4(-sin(theta), cos(theta), 0.0, 0.0),
1591 vec4( 0.0, 0.0, 1.0, 0.0),
1592 vec4( 0.0, 0.0, 0.0, 1.0));
1593 }
1594
1595 mat4 translate_this (in vec3 coord)
1596 {
1597 mat4 translate;
1598 translate[0] = vec4(1.0, 0.0, 0.0, 0.0);
1599 translate[1] = vec4(0.0, 1.0, 0.0, 0.0);
1600 translate[2] = vec4(0.0, 0.0, 1.0, 0.0);
1601 translate[3][0] = coord.x;
1602 translate[3][1] = coord.y;
1603 translate[3][2] = coord.z;
1604 translate[3][3] = 1.0;
1605
1606 return translate;
1607 }
1608
1609 vec4 project (in vec3 coord, vec4 shift)
1610 {
1611 mat4 n_mvp = mvp * translate_this (coord) * un_view;
1612 vec4 res = n_mvp * vec4(vec3(0.0), 1.0);
1613 res = translate_this (vec3(shift.x/viewp.z, shift.y/viewp.w, shift.z)) * res;
1614 if (res.w != 0.0)
1615 {
1616 res.w = 1.0 / res.w;
1617 res.x = res.w * res.x + 1.0;
1618 res.y = res.w * res.y + 1.0;
1619 res.z = res.w * res.z + 1.0;
1620 return vec4 (res.x*viewp.z+viewp.x, res.y*viewp.w+viewp.y, shift.w*res.z, 1.0);
1621 }
1622 else
1623 {
1624 return vec4 (0.0, 0.0, -1.0, 0.0);
1625 }
1626 }
1627
1628 void main()
1629 {
1630 text_coords = tcoord;
1631 float rot_angle = 0.0;
1632 vec4 shift = pos_shift;
1633 vec3 pos_a = project (at_a, vec4(0.0)).xyz;
1634 vec3 pos_b = project (at_b, vec4(0.0)).xyz;
1635 vec3 pos_c = project (at_c, vec4(0.0)).xyz;
1636 vec2 pa = pos_a.xy;
1637 vec2 pb = pos_b.xy;
1638 vec2 pc = pos_c.xy;
1639 vec2 pd;
1640 float theta = angle2d (pa, pb, pc);
1641 pd.x = pb.x + 100.0;
1642 pd.y = pb.y;
1643 float alpha;
1644 float beta;
1645 float gamma;
1646 vec2 sign;
1647 sign.x = 1.0;
1648 sign.y = 1.0;
1649
1650 beta = angle2d (pa, pb, pd);
1651 alpha = angle2d (pc, pb, pd);
1652 if (pa.y > pb.y && pc.y > pb.y)
1653 {
1654 gamma = min (alpha, beta);
1655 }
1656 else if (pa.y < pb.y && pc.y < pb.y)
1657 {
1658 gamma = min (-alpha, -beta);
1659 }
1660 else
1661 {
1662 vec2 pe;
1663 vec2 pf;
1664 pe.y = max(pa.y, pc.y);
1665 if (pe.y == pa.y)
1666 {
1667 pe.x = pa.x;
1668 pf.y = pc.y;
1669 pf.x = pc.x;
1670 }
1671 else
1672 {
1673 pe.x = pc.x;
1674 pf.y = pa.y;
1675 pf.x = pa.x;
1676 }
1677 beta = angle2d (pe, pb, pd);
1678 gamma = beta;
1679 alpha = angle2d (pf, pb, pd);
1680 if (beta + alpha < PI)
1681 {
1682 gamma -= theta;
1683 }
1684 }
1685 rot_angle = PI/2.0 - gamma - theta/2.0;
1686 vec3 a = at_b + ((at_a - at_b)/3.0 + (at_c - at_b)/3.0)/2.0;
1687 vec4 b = project (a, shift);
1688 float dist = min(length(pb-pa), length(pb-pc)) / 3.0;
1689 float x = pb.x + (shift.x+dist) * sin(rot_angle);
1690 float y = pb.y + (shift.y+dist) * cos(rot_angle);
1691 if (pa.y < pb.y && pc.y < pb.y)
1692 {
1693 gamma = - max (alpha, beta);
1694 }
1695 else if (pa.y > pb.y || pc.y > pb.y)
1696 {
1697 gamma += PI;
1698 }
1699 rot_angle = PI/2.0 - gamma - theta/2.0;
1700 vec3 c = vec3(x, y, b.z);
1701 vec4 pos = vec4(c, 1.0);
1702 if (tilted > 0)
1703 {
1704 rot_angle += PI;
1705 pos += vec4(vert, 0.0, 1.0) * rotate_this_z(rot_angle);
1706 }
1707 else
1708 {
1709 pos += vec4(vert, 0.0, 1.0);
1710 }
1711 gl_Position = text_proj * pos;
1712 }
1713);
1714
1715const GLchar * string_color = GLSL(
1716 uniform sampler2DRect tex;
1717 uniform vec4 vert_color;
1718 uniform vec4 viewp;
1719 uniform int tilted;
1720 in vec2 text_coords;
1721
1722 out vec4 fragment_color;
1723 void main()
1724 {
1725 vec2 coords = text_coords;
1726 fragment_color = vert_color * vec4(1.0, 1.0, 1.0, texture (tex, text_coords).r);
1727 }
1728);
1729
1730const GLchar * string_color_2d = GLSL(
1731 uniform sampler2DRect tex;
1732 uniform vec4 vert_color;
1733 in vec2 text_coords;
1734
1735 out vec4 fragment_color;
1736 void main()
1737 {
1738 vec4 sampled = vec4(1.0, 1.0, 1.0, texture (tex, text_coords).r);
1739 fragment_color = vert_color * sampled;
1740 }
1741);
void translate(project *this_proj, int status, int axis, vec3_t trans)
translate
Definition atom_move.c:230
gchar * axis[3]
Definition w_axis.c:65
PangoLayout * layout
Definition curve.c:79
double dist
Definition d_measures.c:73
int * shift
Definition d_measures.c:72
vec3_t get_triangle_normal(vec3_t v1, vec3_t v2, vec3_t v3)
compute triangle normal vector
Definition d_poly.c:101
double *** cross
Definition dlp_edit.c:418
double pi
Definition global.c:195
Global variable declarations Global convenience function declarations Global data structure defin...
struct project project
data structure for the 'atomes' project
Definition global.h:935
#define min(a, b)
Definition global.h:81
#define max(a, b)
Definition global.h:80
int step
Definition ogl_draw.c:70
struct angle angle
Definition glwin.h:112
int main(int argc, char *argv[])
initialization of the atomes program
Definition main.c:642
double precision, dimension(3) rim
double precision p1
double precision p2
double y
Definition ogl_draw.c:57
double x
Definition ogl_draw.c:57
const GLchar * full_color
const GLchar * gs_cylinder_vertex
const GLchar * string_color_2d
const GLchar * string_vertex
const GLchar * line_stipple_color
const GLchar * axis_sphere_vertex
const GLchar * angle_stipple
const GLchar * angle_vertex
const GLchar * polyedron_vertex
const GLchar * gs_cylinder_geom
const GLchar * pick_color
const GLchar * polyedron_geom
const GLchar * polyedron_color
const GLchar * cylinder_vertex
const GLchar * string_color
const GLchar * full_vertex
const GLchar * line_color
const GLchar * line_stipple
const GLchar * cap_vertex
const GLchar * axis_cylinder_geom
#define GLSL(src)
Definition ogl_shaders.c:41
const GLchar * angle_color
const GLchar * line_vertex
Definition ogl_shaders.c:80
const GLchar * sphere_vertex
const GLchar * point_vertex
Definition ogl_shaders.c:43
const GLchar * axis_line_vertex
Definition ogl_shaders.c:93
const GLchar * cone_vertex
const GLchar * degree_vertex
const GLchar * point_color
Definition ogl_shaders.c:59
const GLchar * angstrom_vertex
Definition glwin.h:222
int based
Definition glwin.h:224
int mode
Definition glwin.h:223
vec3_t color
Definition glwin.h:227
float density
Definition glwin.h:225
float depth[2]
Definition glwin.h:226
Definition glwin.h:181
vec3_t direction
Definition glwin.h:186
int type
Definition glwin.h:182
vec3_t position
Definition glwin.h:185
vec3_t intensity
Definition glwin.h:187
vec3_t albedo
Definition glwin.h:200
int b
Definition tab-1.c:95
int c
Definition tab-1.c:95
int d
Definition tab-1.c:95
int a
Definition tab-1.c:95
GtkWidget * res[2]
Definition w_encode.c:212