atomes 1.3.1
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
d_bonds.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-2026 by CNRS and University of Strasbourg */
15
21
22/*
23* This file: 'd_bonds.c'
24*
25* Contains:
26*
27
28 - The functions to prepare the OpenGL rendering of bond(s) and clone bond(s)
29
30*
31* List of functions:
32
33 int cylinder_vertices (int qual);
34 int cylinder_indices (int qual);
35 int cap_vertices (int qual);
36 int cap_indices (int qual);
37 int find_bond_vertices (gboolean to_pick, int sty, int sa, int sb, int bi, int cap);
38 int create_bond_lists (gboolean to_pick);
39
40 float get_bond_radius (int sty, int ac, int at, int bt, int sel);
41
42 void setup_line_vertice (float * vertices, vec3_t pos, ColRGBA col, float alpha);
43 void setup_cylinder_vertice (float * vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, float delta, float r_sph_a, float r_sph_b);
44 void setup_cap_vertice (float * vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, gboolean sel);
45 void setup_this_bond (int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, atom * at, atom * bt, float al, float * vertices);
46 void prepare_bond (int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, int bid, atom * at, atom * bt, float * vertices);
47 void setup_all_cylinder_vertices (int style, gboolean to_pick, int cap, int bi, float * vertices);
48 void setup_line_vertices (int style, int cap, int bi, int sa, int sb, float * vertices);
49
50 vec4_t rotate_bond (vec3_t a, vec3_t b);
51
52 object_3d * draw_cylinder (int quality, float ra, float rb);
53 object_3d * draw_cylinder_cap (int quality, float rad, gboolean picked);
54
55*/
56
57#include "global.h"
58#include "glview.h"
59#include "dlp_field.h"
60
61extern object_3d * draw_billboard_quad (void);
62/* Sphere radius function (declared in d_atoms.c) — needed to fill clip radii */
63extern float get_sphere_radius (int style, int sp, int ac, int sel);
64
65extern ColRGBA get_atom_color (int i, int j, double al, int picked, gboolean to_picked);
67extern int nbs;
68
77{
78 return 2*qual;
79}
80
89{
90 return 2*(qual + 1);
91}
92
102object_3d * draw_cylinder (int quality, float ra, float rb)
103{
104 int i, j;
105 object_3d * new_cylinder = g_malloc0(sizeof*new_cylinder);
106 new_cylinder -> quality = quality;
107 new_cylinder -> num_vertices = cylinder_vertices (quality);
108 new_cylinder -> vert_buffer_size = 3;
109 new_cylinder -> vertices = allocfloat (3*new_cylinder -> num_vertices);
110 new_cylinder -> num_indices = cylinder_indices (quality);
111 new_cylinder -> ind_buffer_size = 1;
112 new_cylinder -> indices = allocint (cylinder_indices (quality));
113
114 float step = 2.0 * pi / (quality-1);
115 float x, y;
116 j = 0;
117 // Vertex
118 for(i = 0; i < quality; i++)
119 {
120 x = cos (i*step);
121 y = sin (i*step);
122 new_cylinder -> vertices[j] = ra*x;
123 new_cylinder -> vertices[j+1] = ra*y;
124 new_cylinder -> vertices[j+2] = 0.5;
125 j += 3;
126 new_cylinder -> vertices[j] = rb*x;
127 new_cylinder -> vertices[j+1] = rb*y;
128 new_cylinder -> vertices[j+2] = -0.5;
129 j += 3;
130 }
131
132 for (i = 0; i < 2*quality; i++)
133 {
134 new_cylinder -> indices[i] = i % (2*quality-2);
135 }
136
137 return new_cylinder;
138}
139
148{
149 return qual + 1;
150}
151
160{
161 return qual + 2;
162}
163
173object_3d * draw_cylinder_cap (int quality, float rad, gboolean picked)
174{
175 int i, j;
176
177 object_3d * new_cap = g_malloc0(sizeof*new_cap);
178 new_cap -> quality = quality;
179 new_cap -> num_vertices = cap_vertices(quality);
180 new_cap -> vert_buffer_size = 3;
181 new_cap -> vertices = allocfloat (3*new_cap -> num_vertices);
182 new_cap -> num_indices = cap_indices(quality);
183 new_cap -> ind_buffer_size = 1;
184 new_cap -> indices = allocint (new_cap -> num_indices);
185
186 float delta = (picked) ? 0.05 : 0.0;
187 float step = 2.0 * pi / (quality - 1);
188 float x, y;
189 j = 0;
190 // Center
191 new_cap -> vertices[j] = 0.0;
192 new_cap -> vertices[j+1] = 0.0;
193 new_cap -> vertices[j+2] = - delta;
194 j += 3;
195 for(i = 0; i < quality; i++)
196 {
197 x = cos (i*step);
198 y = sin (i*step);
199 new_cap -> vertices[j] = rad*x;
200 new_cap -> vertices[j+1] = rad*y;
201 new_cap -> vertices[j+2] = 0.0 - delta;
202 j += 3;
203 }
204
205 for (i=0; i <= quality; i++)
206 {
207 new_cap -> indices[i] = i % (quality + 1);
208 }
209 return new_cap;
210}
211
221{
222 vec3_t c, f, raxis;
223 c = v3_sub (vec3(b.x, b.y, b.z), vec3(a.x, a.y, a.z));
224 f = vec3 (0.0, 0.0, 1.0);
225 double rangle;
226 raxis = v3_cross (f, c);
227 //rangle = 180.0 / pi * acos(v3_dot(f, c) / v3_length(c));
228 rangle = acos(v3_dot(f, c) / v3_length(c));
229 return axis_to_quat (raxis, rangle);
230}
231
243float get_bond_radius (int sty, int ac, int at, int bt, int sel)
244{
245 if (sty == BALL_AND_STICK)
246 {
247 return plot -> bondrad[at][bt] + 0.05*sel;
248 }
249 else if (sty == CYLINDERS)
250 {
251 return plot -> radall[ac] + 0.05*sel;
252 }
253 else
254 {
255 return plot -> linerad[at][bt] + 4.0*sel;
256 }
257}
258
269void setup_line_vertice (float * vertices, vec3_t pos, ColRGBA col, float alpha)
270{
271 int s = nbs*LINE_BUFF_SIZE;
272 vertices[s] = pos.x;
273 vertices[s+1] = pos.y;
274 vertices[s+2] = pos.z;
275 vertices[s+3] = col.red;
276 vertices[s+4] = col.green;
277 vertices[s+5] = col.blue;
278 vertices[s+6] = col.alpha * alpha;
279 nbs ++;
280}
281
297void setup_cylinder_vertice (float * vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, float delta, float r_sph_a, float r_sph_b)
298{
299 int cbs = (plot -> ray_tracing) ? CYLI_BUFF_SIZE + 2 : CYLI_BUFF_SIZE;
300 int s = nbs*cbs;
301 vertices[s] = (pos_a.x + pos_b.x)/2.0;
302 vertices[s+1] = (pos_a.y + pos_b.y)/2.0;
303 vertices[s+2] = (pos_a.z + pos_b.z)/2.0;
304 vertices[s+3] = v3_length(v3_sub(pos_a, pos_b)) + delta;
305 vertices[s+4] = rad;
306 vec4_t quat = rotate_bond (pos_b, pos_a);
307 vertices[s+5] = quat.w;
308 vertices[s+6] = quat.x;
309 vertices[s+7] = quat.y;
310 vertices[s+8] = quat.z;
311 vertices[s+9] = col.red;
312 vertices[s+10] = col.green;
313 vertices[s+11] = col.blue;
314 vertices[s+12] = col.alpha * alpha;
315 if (r_sph_a > 0.0)
316 {
317 vertices[s+13] = r_sph_a; /* sphere clip radius at pos_a endpoint */
318 vertices[s+14] = r_sph_b; /* sphere clip radius at pos_b endpoint (0.0 for half-bonds) */
319 }
320 nbs ++;
321}
322
336void setup_cap_vertice (float * vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, gboolean sel)
337{
338 int s = nbs*CAPS_BUFF_SIZE;
339 vec3_t dir = (sel) ? v3_norm (v3_sub(pos_a, pos_b)) : vec3(0.0, 0.0, 0.0);
340 vertices[s] = pos_b.x - 0.05*dir.x;
341 vertices[s+1] = pos_b.y - 0.05*dir.y;
342 vertices[s+2] = pos_b.z - 0.05*dir.z;
343 vertices[s+3] = rad;
344 vec4_t quat = rotate_bond (pos_b, pos_a);
345 vertices[s+4] = quat.w;
346 vertices[s+5] = quat.x;
347 vertices[s+6] = quat.y;
348 vertices[s+7] = quat.z;
349 vertices[s+8] = col.red;
350 vertices[s+9] = col.green;
351 vertices[s+10] = col.blue;
352 vertices[s+11] = col.alpha * alpha;
353 nbs ++;
354}
355
357
374void setup_this_bond (int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, atom * at, atom * bt, float al, float * vertices)
375{
376 float alpha = 1.0;
377 float delta = 0.0;
378 float shift[3];
379 int p, q, r;
380 vec3_t pos_a, pos_b;
381 ColRGBA col = get_atom_color (at -> sp, at -> id, 1.0, (picked) ? pi + 1 : 0, to_pick);
382 float rad = get_bond_radius ((to_pick) ? BALL_AND_STICK : (sty == NONE) ? plot -> style : sty, bi, at -> sp, bt -> sp, (picked) ? 1.0 : 0.0);
383 if (picked)
384 {
385 gboolean show_a, show_b;
386 int sta, stb;
387 if (in_movie_encoding && plot -> at_data != NULL)
388 {
389 show_a = plot -> at_data[bt -> id].show[bi];
390 show_b = plot -> at_data[bt -> id].pick[pi];
391 sta = plot -> at_data[at -> id].style;
392 stb = plot -> at_data[bt -> id].style;
393 }
394 else
395 {
396 show_a = bt -> show[bi];
397 show_b = bt -> pick[pi];
398 sta = at -> style;
399 stb = bt -> style;
400 }
401 delta = ((show_a && show_b) && (sta == stb)) ? 0.0 : 0.1;
402 }
403 for (p=0; p<plot -> abc -> extra_cell[0]+1;p++)
404 {
405 for (q=0; q<plot -> abc -> extra_cell[1]+1; q++)
406 {
407 for (r=0; r<plot -> abc -> extra_cell[2]+1; r++)
408 {
409 shift[0]=p*box_gl -> vect[0][0]+q*box_gl -> vect[1][0]+r*box_gl -> vect[2][0];
410 shift[1]=p*box_gl -> vect[0][1]+q*box_gl -> vect[1][1]+r*box_gl -> vect[2][1];
411 shift[2]=p*box_gl -> vect[0][2]+q*box_gl -> vect[1][2]+r*box_gl -> vect[2][2];
412 at_shift (at, shift);
413 at_shift (bt, shift);
414 pos_a = vec3(at -> x, at -> y, at -> z);
415 pos_b = vec3((at -> x + bt -> x)/2.0, (at -> y + bt -> y)/2.0, (at -> z + bt -> z)/2.0);
416 if (to_pick || ((sty == NONE && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || sty == BALL_AND_STICK || sty == CYLINDERS))
417 {
418 if (cap)
419 {
420 setup_cap_vertice (vertices, pos_a, pos_b, col, rad, alpha*al, (plot -> ray_tracing && delta > 0.0) ? TRUE : FALSE);
421 }
422 else
423 {
424 float r_sph = (plot -> ray_tracing) ? get_sphere_radius ((sty == NONE) ? plot -> style : sty, at -> sp, bi, 0) : 0.0f;
425 setup_cylinder_vertice (vertices, pos_a, pos_b, col, rad, (to_pick) ? 1.0 : alpha*al, delta, r_sph, 0.0f);
426 }
427 }
428 else
429 {
430 setup_line_vertice (vertices, pos_a, col, alpha*al);
431 setup_line_vertice (vertices, pos_b, col, alpha*al);
432 }
433 at_unshift (at, shift);
434 at_unshift (bt, shift);
435 alpha = 0.5;
436 }
437 }
438 }
439}
440
457void prepare_bond (int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, int bid, atom * at, atom * bt, float * vertices)
458{
459 if (bi == 0)
460 {
461 setup_this_bond (sty, to_pick, picked, cap, bi, pi, at, bt, 1.0, vertices);
462 }
463 else
464 {
465 atom * tmp_a, * tmp_b;
466 float x, y, z;
467 int sign;
468 sign = 1;
469 if (wingl -> bondid[step][1][bid][0] == at -> id) sign = -1;
470 x = wingl -> clones[step][bid].x;
471 y = wingl -> clones[step][bid].y;
472 z = wingl -> clones[step][bid].z;
473 tmp_a = duplicate_atom (at);
474 tmp_b = duplicate_atom (at);
475 tmp_a -> pick[pi] = bt -> pick[pi];
476 tmp_a -> style = bt -> style;
477 tmp_a -> sp = bt -> sp + proj_sp;
478 tmp_b -> sp += proj_sp;
479 tmp_a -> x += sign * x;
480 tmp_a -> y += sign * y;
481 tmp_a -> z += sign * z;
482 setup_this_bond (sty, to_pick, picked, cap, bi, pi, tmp_b, tmp_a, 0.5, vertices);
485
486 tmp_a = duplicate_atom (bt);
487 tmp_b = duplicate_atom (bt);
488 tmp_a -> pick[pi] = at -> pick[pi];
489 tmp_a -> style = at -> style;
490 tmp_a -> sp = at -> sp + proj_sp;
491 tmp_b -> sp += proj_sp;
492 tmp_a -> id = at -> id;
493 tmp_a -> x -= sign * x;
494 tmp_a -> y -= sign * y;
495 tmp_a -> z -= sign * z;
496 setup_this_bond (sty, to_pick, picked, cap, bi, pi, tmp_a, tmp_b, 0.5, vertices);
499 }
500}
501
514int find_bond_vertices (gboolean to_pick, int sty, int sa, int sb, int bi, int cap)
515{
516 int i, j, k, l, m, n;
517 gboolean show_a, show_b;
518 l = 0;
519 for (i=0; i < wingl -> bonds[step][bi]; i++)
520 {
521 j = wingl -> bondid[step][bi][i][0];
522 k = wingl -> bondid[step][bi][i][1];
523 if (in_movie_encoding && plot -> at_data != NULL)
524 {
525 show_a = plot -> at_data[j].show[bi];
526 m = plot -> at_data[j].style;
527 show_b = plot -> at_data[k].show[bi];
528 n = plot -> at_data[k].style;
529 }
530 else
531 {
532 show_a = proj_gl -> atoms[step][j].show[bi];
533 m = proj_gl -> atoms[step][j].style;
534 show_b = proj_gl -> atoms[step][k].show[bi];
535 n = proj_gl -> atoms[step][k].style;
536 }
537 if (proj_gl -> atoms[step][j].sp == sa && proj_gl -> atoms[step][k].sp == sb)
538 {
539 if (show_a && (m == sty || to_pick))
540 {
541 if (cap)
542 {
543 if (! show_b || n != sty) l += 1 + bi;
544 }
545 else
546 {
547 l += 1 + bi;
548 }
549 }
550 }
551 if (proj_gl -> atoms[step][j].sp == sb && proj_gl -> atoms[step][k].sp == sa)
552 {
553 if (show_b && (n == sty || to_pick))
554 {
555 if (cap)
556 {
557 if (! show_a || m != sty) l += 1 + bi;
558 }
559 else
560 {
561 l += 1 + bi;
562 }
563 }
564 }
565 }
566 return 2*l;
567}
568
580void setup_all_cylinder_vertices (int style, gboolean to_pick, int cap, int bi, float * vertices)
581{
582 int i, j, k, l, m;
583 gboolean show_a, show_b;
584 for (i=0; i < wingl -> bonds[step][bi]; i++)
585 {
586 j = wingl -> bondid[step][bi][i][0];
587 k = wingl -> bondid[step][bi][i][1];
588 if (in_movie_encoding && plot -> at_data != NULL)
589 {
590 show_a = plot -> at_data[j].show[bi];
591 l = plot -> at_data[j].style;
592 show_b = plot -> at_data[k].show[bi];
593 m = plot -> at_data[k].style;;
594 }
595 else
596 {
597 show_a = proj_gl -> atoms[step][j].show[bi];
598 l = proj_gl -> atoms[step][j].style;
599 show_b = proj_gl -> atoms[step][k].show[bi];
600 m = proj_gl -> atoms[step][k].style;
601 }
602 if (show_a && (l == style || to_pick))
603 {
604 if (cap)
605 {
606 if (! show_b || m != style) prepare_bond (style, to_pick, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][j], & proj_gl -> atoms[step][k], vertices);
607 }
608 else
609 {
610 prepare_bond (style, to_pick, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][j], & proj_gl -> atoms[step][k], vertices);
611 }
612 }
613 if (show_b && (m == style || to_pick))
614 {
615 if (cap)
616 {
617 if (! show_a || l != style) prepare_bond (style, to_pick, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][k], & proj_gl -> atoms[step][j], vertices);
618 }
619 else
620 {
621 prepare_bond (style, to_pick, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][k], & proj_gl -> atoms[step][j], vertices);
622 }
623 }
624 }
625}
626
639void setup_line_vertices (int style, int cap, int bi, int sa, int sb, float * vertices)
640{
641 int i, j, k, l, m;
642 gboolean show_a, show_b;
643 for (i=0; i < wingl -> bonds[step][bi]; i++)
644 {
645 j = wingl -> bondid[step][bi][i][0];
646 k = wingl -> bondid[step][bi][i][1];
647 if (in_movie_encoding && plot -> at_data != NULL)
648 {
649 show_a = plot -> at_data[j].show[bi];
650 l = plot -> at_data[j].style;
651 show_b = plot -> at_data[k].show[bi];
652 m = plot -> at_data[k].style;
653 }
654 else
655 {
656 show_a = proj_gl -> atoms[step][j].show[bi];
657 l = proj_gl -> atoms[step][j].style;
658 show_b = proj_gl -> atoms[step][k].show[bi];
659 m = proj_gl -> atoms[step][k].style;
660 }
661 if (proj_gl -> atoms[step][j].sp == sa && proj_gl -> atoms[step][k].sp == sb)
662 {
663 if (show_a && l == style)
664 {
665 prepare_bond (style, FALSE, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][j], & proj_gl -> atoms[step][k], vertices);
666 }
667 }
668 if (proj_gl -> atoms[step][j].sp == sb && proj_gl -> atoms[step][k].sp == sa)
669 {
670 if (show_b && m == style)
671 {
672 prepare_bond (style, FALSE, FALSE, cap, bi, 0, i, & proj_gl -> atoms[step][k], & proj_gl -> atoms[step][j], vertices);
673 }
674 }
675 }
676}
677
685int create_bond_lists (gboolean to_pick)
686{
687 int nshaders = 0;
688 int **** nbonds;
689 int **** ncaps;
690 int nbds[NUM_STYLES];
691 int ncap[NUM_STYLES];
692 object_3d * cyl, * cap;
693 int f, g, h, i, j, k, l, m;
694
695 if (! to_pick)
696 {
698 wingl -> create_shaders[BONDS] = FALSE;
699 }
700
701 g = (plot -> draw_clones) ? 2 : 1;
702
703 nbonds = allocqint (NUM_STYLES, g, proj_sp, proj_sp);
704 if (! to_pick) ncaps = allocqint (NUM_STYLES, g, proj_sp, proj_sp);
705
706 for (f=0; f<NUM_STYLES; f++)
707 {
708 nbds[f] = ncap[f] = 0;
709 k = l = m = 0;
710 if (to_pick || (! f && (plot -> style != SPHERES && plot -> style != PUNT)) || (f && f-1 != SPHERES && f-1 != PUNT))
711 {
712 for (h=0; h<g; h++)
713 {
714 for (i=0; i<proj_sp; i++)
715 {
716 for (j=0; j<proj_sp; j++)
717 {
718 nbonds[f][h][i][j] = find_bond_vertices (to_pick, f-1, i, j, h, 0);
719 k += nbonds[f][h][i][j];
720 if (nbonds[f][h][i][j] > 0) l ++;
721 if (! to_pick && ((! f && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || (f && (f-1 == BALL_AND_STICK || f-1 == CYLINDERS))))
722 {
723 ncaps[f][h][i][j] = find_bond_vertices (to_pick, f-1, i, j, h, 1);
724 m += ncaps[f][h][i][j];
725 }
726 }
727 }
728 }
729 nbds[f] = k;
730 ncap[f] = m;
731 if (to_pick || (((! f && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || (f && (f-1 == BALL_AND_STICK || f-1 == CYLINDERS)))))
732 {
733 if (k > 0)
734 {
735 nshaders ++;
736 if (m > 0 && ! to_pick) nshaders ++;
737 }
738 }
739 else
740 {
741 nshaders += l;
742 }
743 }
744 if (to_pick) break;
745 }
746#ifdef DEBUG
747 g_debug ("Bond LIST:: to_pick= %s, shaders= %d", (to_pick) ? "true" : "false", nshaders);
748#endif
749 if (nshaders == 0) return nshaders;
750 if (! to_pick) wingl -> ogl_glsl[BONDS][step] = g_malloc0(nshaders*sizeof*wingl -> ogl_glsl[BONDS][step]);
751 l = 0;
752 for (f=0; f<NUM_STYLES; f++)
753 {
754 if (nbds[f])
755 {
756 if (to_pick || (! f && (plot -> style == BALL_AND_STICK || plot -> style == CYLINDERS)) || (f && (f-1 == BALL_AND_STICK || f-1 == CYLINDERS)))
757 {
758 cyl = (plot -> ray_tracing) ? draw_billboard_quad () : draw_cylinder (plot -> quality, 1.0, 1.0);
759 cyl -> num_instances = (nbds[f]/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
760 /* Unreal mode: extend instance buffer by 2 floats per instance for sphere clip radii */
761 cyl -> inst_buffer_size = (plot -> ray_tracing) ? CYLI_BUFF_SIZE + 2 : CYLI_BUFF_SIZE;
762 allocate_instances (cyl);
763 nbs = 0;
764 for (h=0; h<g; h++)
765 {
766 setup_all_cylinder_vertices (f-1, to_pick, 0, h, cyl -> instances);
767 if (to_pick && h==0) wingl -> bonds_to_be_picked = wingl -> to_be_picked;
768 }
769 if (! to_pick)
770 {
771 const GLchar * vs_cyl = (plot -> ray_tracing) ? cylinder_vertex_ray : cylinder_vertex;
772 const GLchar * fs_cyl = (plot -> ray_tracing) ? full_color_ray : full_color;
773 /* narray=8 in ray_tracing mode to allocate slots for r_sphere_a/b attributes */
774 int narray_cyl = plot -> ray_tracing ? 8 : 6;
775 wingl -> ogl_glsl[BONDS][step][l] = init_shader_program (BONDS, GLSL_CYLINDERS, vs_cyl, NULL, fs_cyl, GL_TRIANGLE_STRIP, narray_cyl, 1, TRUE, cyl);
776 l ++;
777 if (ncap[f] > 0)
778 {
779 cap = (plot -> ray_tracing) ? draw_billboard_quad () : draw_cylinder_cap (plot -> quality, 1.0, FALSE);
780 cap -> num_instances = (ncap[f]/2) * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
781 cap -> inst_buffer_size = CAPS_BUFF_SIZE;
782 allocate_instances (cap);
783 nbs = 0;
784 for (h=0; h<g; h++)
785 {
786 setup_all_cylinder_vertices (f-1, FALSE, 1, h, cap -> instances);
787 }
788 const GLchar * vs_cap = (plot -> ray_tracing) ? cap_vertex_ray : cap_vertex;
789 GLenum prim_cap = (plot -> ray_tracing) ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN;
790 wingl -> ogl_glsl[BONDS][step][l] = init_shader_program (BONDS, GLSL_CAPS, vs_cap, NULL, fs_cyl, prim_cap, 5, 1, TRUE, cap);
791 l ++;
792 }
793 }
794 else
795 {
796 wingl -> ogl_glsl[PICKS][0][1] = init_shader_program (PICKS, GLSL_CYLINDERS, cylinder_vertex, NULL, full_color, GL_TRIANGLE_STRIP, 6, 1, FALSE, cyl);
797 }
798 }
799 else if ((! f && (plot -> style != SPHERES && plot -> style != PUNT)) || (f && f-1 != SPHERES && f-1 != PUNT))
800 {
801 for (h=0; h<g; h++)
802 {
803 for (i=0; i<proj_sp; i++)
804 {
805 for (j=0; j<proj_sp; j++)
806 {
807 if (nbonds[f][h][i][j])
808 {
809 cyl = g_malloc0(sizeof*cyl);
810 cyl -> vert_buffer_size = LINE_BUFF_SIZE;
811 cyl -> num_vertices = nbonds[f][h][i][j] * (plot -> abc -> extra_cell[0]+1)*(plot -> abc -> extra_cell[1]+1)*(plot -> abc -> extra_cell[2]+1);
812 cyl -> vertices = allocfloat (cyl -> vert_buffer_size*cyl -> num_vertices);
813 nbs = 0;
814 setup_line_vertices (f-1, 0, h, i, j, cyl -> vertices);
815 wingl -> ogl_glsl[BONDS][step][l] = init_shader_program (BONDS, GLSL_LINES, line_vertex, NULL, line_color, GL_LINES, 2, 1, FALSE, cyl);
816 wingl -> ogl_glsl[BONDS][step][l] -> line_width = get_bond_radius (WIREFRAME, h, i+proj_sp*h, j+proj_sp*h, FALSE);
817 l++;
818 }
819 }
820 }
821 }
822 }
823 }
824 if (to_pick) break;
825 }
826 for (f=0; f<NUM_STYLES; f++)
827 {
828 for (h=0; h<g; h++)
829 {
830 for (i=0; i<proj_sp; i++)
831 {
832 g_free (nbonds[f][h][i]);
833 if (! to_pick) g_free (ncaps[f][h][i]);
834 }
835 g_free (nbonds[f][h]);
836 if (! to_pick) g_free (ncaps[f][h]);
837 }
838 g_free (nbonds[f]);
839 if (! to_pick) g_free (ncaps[f]);
840 }
841 g_free (nbonds);
842 if (! to_pick) g_free (ncaps);
843 return nshaders;
844}
float get_sphere_radius(int style, int sp, int ac, int sel)
get an atom sphere radius
Definition d_atoms.c:305
int nbs
Definition d_atoms.c:165
object_3d * draw_billboard_quad()
create a camera-aligned billboard quad proxy for perfect impostors.
Definition d_atoms.c:273
int cylinder_indices(int qual)
return the number of OpenGL indices to render a cylinder
Definition d_bonds.c:88
int create_bond_lists(gboolean to_pick)
prepare bond(s) and clone bond(s) OpenGL rendering
Definition d_bonds.c:685
void setup_cap_vertice(float *vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, gboolean sel)
fill the OpenGL data buffer for a cylinder cap bond (or clone bond) to render
Definition d_bonds.c:336
int find_bond_vertices(gboolean to_pick, int sty, int sa, int sb, int bi, int cap)
find bond(s) and clone bond(s) to render
Definition d_bonds.c:514
int cylinder_vertices(int qual)
return the number of OpenGL vertices to render a cylinder
Definition d_bonds.c:76
int cap_vertices(int qual)
return the number of OpenGL vertices to render a cylinder cap
Definition d_bonds.c:147
object_3d * draw_billboard_quad(void)
create a camera-aligned billboard quad proxy for perfect impostors.
Definition d_atoms.c:273
int vs_bid
Definition d_bonds.c:356
void setup_cylinder_vertice(float *vertices, vec3_t pos_a, vec3_t pos_b, ColRGBA col, float rad, float alpha, float delta, float r_sph_a, float r_sph_b)
fill the OpenGL data buffer for a cylinder bond (or clone bond) to render
Definition d_bonds.c:297
float get_sphere_radius(int style, int sp, int ac, int sel)
get an atom sphere radius
Definition d_atoms.c:305
void setup_this_bond(int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, atom *at, atom *bt, float al, float *vertices)
prepare the OpenGL rendering data of a bond / clone bond
Definition d_bonds.c:374
vec4_t rotate_bond(vec3_t a, vec3_t b)
rotate a bond based on the proper orientation
Definition d_bonds.c:220
void setup_line_vertices(int style, int cap, int bi, int sa, int sb, float *vertices)
prepare line bond(s) and clone bond(s) to render
Definition d_bonds.c:639
void setup_line_vertice(float *vertices, vec3_t pos, ColRGBA col, float alpha)
fill the OpenGL data buffer for a line bond (or clone bond) to render
Definition d_bonds.c:269
object_3d * draw_cylinder_cap(int quality, float rad, gboolean picked)
OpenGL 3D cylinder cap object rendering.
Definition d_bonds.c:173
ColRGBA get_atom_color(int i, int j, double al, int picked, gboolean to_picked)
get atom (or clone) color
Definition d_atoms.c:75
object_3d * draw_cylinder(int quality, float ra, float rb)
OpenGL 3D cylinder object rendering.
Definition d_bonds.c:102
int cap_indices(int qual)
return the number of OpenGL indices to render a cylinder cap
Definition d_bonds.c:159
vec3_t model_position
void setup_all_cylinder_vertices(int style, gboolean to_pick, int cap, int bi, float *vertices)
prepare cylinder bond(s) and clone bond(s) to render
Definition d_bonds.c:580
void prepare_bond(int sty, gboolean to_pick, gboolean picked, int cap, int bi, int pi, int bid, atom *at, atom *bt, float *vertices)
prepare a bond OpenGL rendering
Definition d_bonds.c:457
float get_bond_radius(int sty, int ac, int at, int bt, int sel)
get bond (clone bond) radius
Definition d_bonds.c:243
ColRGBA col
Definition d_measures.c:77
atom_in_selection * tmp_a
Definition d_measures.c:69
atom_in_selection * tmp_b
Definition d_measures.c:69
int * shift
Definition d_measures.c:72
int atoms[NUM_STYLES][2]
int bonds[NUM_STYLES][2]
GtkTreeSelection * sel
Definition datab.c:102
Variable declarations for the creation of the DL_POLY input file(s).
double pi
Definition global.c:202
gboolean in_movie_encoding
Definition global.c:184
int * allocint(int val)
allocate an int * pointer
Definition global.c:301
int **** allocqint(int wal, int xal, int yal, int zal)
allocate an int **** pointer
Definition global.c:364
float * allocfloat(int val)
allocate a float * pointer
Definition global.c:385
Global variable declarations Global convenience function declarations Global data structure defin...
Variable declarations related to the OpenGL window Function declarations related to the OpenGL wind...
image * plot
Definition ogl_draw.c:72
void at_unshift(atom *at, float *shift)
correct atomic coordinates modified to display image in cell replica
Definition ogl_draw.c:514
project * proj_gl
Definition ogl_draw.c:66
glwin * wingl
Definition ogl_draw.c:65
gboolean pick
int proj_sp
Definition ogl_draw.c:67
void at_shift(atom *at, float *shift)
modify atomic coordinates to display image in cell replica
Definition ogl_draw.c:499
box_info * box_gl
Definition ogl_draw.c:70
void cleaning_shaders(glwin *view, int shader)
re-initialize an OpenGL shader
int qual
Definition ogl_draw.c:73
atom * free_atom(atom *at)
free an atom data structure
Definition ogl_draw.c:484
#define NUM_STYLES
Definition glview.h:177
int step
Definition ogl_draw.c:76
atom * duplicate_atom(atom *at)
copy (partially) an atom data structure
Definition ogl_draw.c:449
glsl_program * init_shader_program(int object, int object_id, const GLchar *vertex, const GLchar *geometry, const GLchar *fragment, GLenum type_of_vertices, int narray, int nunif, gboolean lightning, object_3d *obj)
create an OpenGL shader program
@ SPHERES
Definition glview.h:185
@ BALL_AND_STICK
Definition glview.h:182
@ CYLINDERS
Definition glview.h:186
@ WIREFRAME
Definition glview.h:183
@ NONE
Definition glview.h:181
@ PUNT
Definition glview.h:187
@ BONDS
Definition glwin.h:90
@ PICKS
Definition glwin.h:97
double z
Definition ogl_draw.c:63
double y
Definition ogl_draw.c:63
double x
Definition ogl_draw.c:63
const GLchar * full_color
const GLchar * cap_vertex_ray
const GLchar * cylinder_vertex
const GLchar * full_color_ray
const GLchar * cylinder_vertex_ray
const GLchar * line_color
Definition ogl_shaders.c:93
const GLchar * cap_vertex
const GLchar * line_vertex
Definition ogl_shaders.c:80
void allocate_instances(object_3d *object)
allocate the instances buffer of a 3D object
#define LINE_BUFF_SIZE
Definition ogl_shading.h:50
#define CAPS_BUFF_SIZE
Definition ogl_shading.h:52
#define CYLI_BUFF_SIZE
Definition ogl_shading.h:51
@ GLSL_CAPS
Definition ogl_shading.h:42
@ GLSL_LINES
Definition ogl_shading.h:40
@ GLSL_CYLINDERS
Definition ogl_shading.h:41
Definition global.h:964
float y
Definition math_3d.h:130
float x
Definition math_3d.h:130
float z
Definition math_3d.h:130
float w
Definition math_3d.h:149
float y
Definition math_3d.h:149
float x
Definition math_3d.h:149
float z
Definition math_3d.h:149