1
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright by Schrodinger, LLC
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #ifndef _H_CGO
18 #define _H_CGO
19
20 #include"Base.h"
21 #include"Ray.h"
22 #include"Setting.h"
23 #include"os_gl.h"
24 #include"os_gl_cgo.h"
25 #include"Rep.h"
26 #include"MemoryDebug.h"
27 #include <vector>
28 #include <unordered_map>
29 #include <typeinfo>
30 #include <type_traits>
31 #include <memory>
32 #include "GenericBuffer.h"
33 #include <set>
34 #include <glm/vec3.hpp>
35 #include <glm/vec4.hpp>
36
37 /* Compiled Graphics Library for simple graphics objects
38 in floating point three-space, with the goal of achieving
39 quick and easy rendering in multiple environments without the
40 headaches of OpenGL arrays.
41
42 */
43
44 #define CGO_read_int(p) (*((int*)((p)++)))
45 #define CGO_get_int(p) (*((int*)(p)))
46 #define CGO_get_uint(p) (uint)(*((uint*)(p)))
47 #define CGO_write_int(p,i) ((*((int*)(p++)))=(i))
48 #define CGO_write_uint(p,i) ((*((uint*)(p++)))=(i))
49 #define CGO_put_int(p,i) ((*((int*)(p)))=(i))
50 #define CGO_put_uint(p,i) ((*((uint*)(p)))=(i))
51
CLIP_COLOR_VALUE(float cv)52 inline uchar CLIP_COLOR_VALUE(float cv){ return ((cv>1.f) ? 255 : (cv < 0.f) ? 0 : pymol_roundf(cv * 255) ); }
CONVERT_COLOR_VALUE(unsigned char cv)53 inline float CONVERT_COLOR_VALUE(unsigned char cv) { return ((cv>255) ? 1.f : (cv < 0) ? 0.f : (cv / 255.f) ); }
54
55 // normal values are mapped between { -1, 1 } to { 0, 255 },
56 // the values are mapped: { -1/128, -.5/192, 0./255, .5/63, 1./127 }
CLIP_NORMAL_VALUE(float cv)57 inline uchar CLIP_NORMAL_VALUE(float cv){ return ((cv>1.f) ? 127 :
58 (cv < -1.f) ? 128 :
59 pymol_roundf(((cv + 1.f)/2.f) * 255) - 128 ); }
60
61 /* Supported functions:
62 * stop
63 * null
64 * begin
65 GL_POINTS,
66 GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP,
67 GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
68 * end
69 * vertex
70 * normal
71 * color
72 * sphere * currently for ray-tracing only
73 * triangle * currently for ray-tracing only
74 * cylinder * currently for ray-tracing only
75 * linewidth
76 * primwidth * ray-tracing
77 */
78
79 /* instructions and data segment sizes */
80
81 #define CGO_STOP 0x00
82 #define CGO_STOP_SZ 0
83 #define CGO_NULL 0x01
84 #define CGO_NULL_SZ 0
85 #define CGO_BEGIN 0x02
86 #define CGO_BEGIN_SZ 1
87 #define CGO_END 0x03
88 #define CGO_END_SZ 0
89 #define CGO_VERTEX 0x04
90 #define CGO_VERTEX_SZ 3
91 #define CGO_NORMAL 0x05
92 #define CGO_NORMAL_SZ 3
93 #define CGO_COLOR 0x06
94 #define CGO_COLOR_SZ 3
95 #define CGO_SPHERE 0x07
96 #define CGO_SPHERE_SZ 4
97 #define CGO_TRIANGLE 0x08
98 #define CGO_TRIANGLE_SZ 27
99 #define CGO_CYLINDER 0x09
100 #define CGO_CYLINDER_SZ 13
101 // CGO_LINEWIDTH, CGO_WIDTHSCALE, CGO_DOTWIDTH work only on ray tracing
102 #define CGO_LINEWIDTH 0x0A
103 #define CGO_LINEWIDTH_SZ 1
104 #define CGO_WIDTHSCALE 0x0B
105 #define CGO_WIDTHSCALE_SZ 1
106
107 #define CGO_ENABLE 0x0C
108 #define CGO_ENABLE_SZ 1
109 #define CGO_DISABLE 0x0D
110 #define CGO_DISABLE_SZ 1
111 #define CGO_SAUSAGE 0x0E
112 #define CGO_SAUSAGE_SZ 13
113 #define CGO_CUSTOM_CYLINDER 0x0F
114 #define CGO_CUSTOM_CYLINDER_SZ 15
115
116 #define CGO_DOTWIDTH 0x10
117 #define CGO_DOTWIDTH_SZ 1
118
119 #define CGO_ALPHA_TRIANGLE 0x11
120 #define CGO_ALPHA_TRIANGLE_SZ 35
121 #define CGO_ELLIPSOID 0x12
122 #define CGO_ELLIPSOID_SZ 13
123 #define CGO_FONT 0x13
124 #define CGO_FONT_SZ 3 /* size, face, style */
125 #define CGO_FONT_SCALE 0x14
126 #define CGO_FONT_SCALE_SZ 2
127 #define CGO_FONT_VERTEX 0x15
128 #define CGO_FONT_VERTEX_SZ 3 /* principle axes (zeros -> use camera x y z */
129
130 // CGO_FONT_AXES not used
131 #define CGO_FONT_AXES 0x16
132 #define CGO_FONT_AXES_SZ 9 /* principle axes (zeros -> use camera x y z */
133
134 #define CGO_CHAR 0x17
135 #define CGO_CHAR_SZ 1
136 #define CGO_INDENT 0x18
137 #define CGO_INDENT_SZ 2
138 #define CGO_ALPHA 0x19
139 #define CGO_ALPHA_SZ 1
140 #define CGO_QUADRIC 0x1A
141 #define CGO_QUADRIC_SZ 14
142 #define CGO_CONE 0x1B
143 #define CGO_CONE_SZ 16
144 #define CGO_RESET_NORMAL 0x1E
145 #define CGO_RESET_NORMAL_SZ 1
146 #define CGO_PICK_COLOR 0x1F
147 #define CGO_PICK_COLOR_SZ 2
148
149
150 /* CGO_DRAW_ARRAYS : operation that calls glDrawArrays with all arrays in memory
151 (i.e., stored in the CGO array). There can be up to 4 arrays (vertex, normal, color,
152 and pick color array, where each are stored using GL_FLOAT array (except for the pick
153 color array, which is GL_UNSIGNED_BYTE, because the 2nd 2/3rds of the array is used to
154 store atom/bond picking information. Also, the color array is stored using 4 floats,
155 since glColorPointer() requires having 4 as an argument for OpenGLES.
156 - mode : GL Mode that is used
157 - arrays : which arrays that are used (bitmask on CGO_<type>_ARRAY, where <type>
158 can be VERTEX, NORMAL, COLOR, or PICK_COLOR)
159 - narrays : number of arrays specified in arrays
160 - nverts : number of total vertices specified in arrays
161 - each GL_FLOAT array specified in order
162 */
163 #define CGO_DRAW_ARRAYS 0x1C
164 /* CGO_DRAW_BUFFERS_INDEXED : operation that uses glDrawArrays with VBOs. It also
165 has a dynamic length since it holds the picking information (atom/bond) for each vertex,
166 as well as space for picking to use when drawing colors (since colors are dynamically generated
167 for each atom/bond value).
168 - mode : GL Mode that is used
169 - arrays : which arrays that are used (bitmask on CGO_<type>_ARRAY, where <type>
170 can be VERTEX, NORMAL, COLOR, or PICK_COLOR)
171 - narrays : number of arrays specified in arrays
172 - nverts : number of total vertices specified in arrays
173 - bufs[5] : each VBO id in order (if used, VERTEX, NORMAL, COLOR, PICK_COLOR), plus the
174 vertex index array that specifies all vertices.
175 */
176 #define CGO_DRAW_BUFFERS_INDEXED 0x21
177
178 /* CGO_BOUNDING_BOX : operation that allows the extent to be expanded. Since the geometry
179 data is not kept in the CGO object for VBO objects (only on the card), this object allows
180 the bounding box of the object to be saved in the CGO. This is used in the CGOGetExtent(),
181 typically when the view is being automatically set, but can be used for other things.
182 */
183 #define CGO_BOUNDING_BOX 0x22
184 #define CGO_BOUNDING_BOX_SZ 6
185
186 #define CGO_DRAW_BUFFERS_NOT_INDEXED 0x23
187
188 #define CGO_SPECIAL 0x24
189 #define CGO_SPECIAL_SZ 1
190
191 #define CGO_DRAW_CYLINDER_BUFFERS 0x25
192
193 #define CGO_SHADER_CYLINDER 0x26
194 #define CGO_SHADER_CYLINDER_SZ 8
195
196 #define CGO_SHADER_CYLINDER_WITH_2ND_COLOR 0x27
197 #define CGO_SHADER_CYLINDER_WITH_2ND_COLOR_SZ 13
198
199 #define CGO_DRAW_SPHERE_BUFFERS 0x28
200
201 #define CGO_ACCESSIBILITY 0x29
202 #define CGO_ACCESSIBILITY_SZ 1
203
204 #define CGO_DRAW_TEXTURE 0x2A
205 #define CGO_DRAW_TEXTURE_SZ 13
206
207 #define CGO_DRAW_TEXTURES 0x2B
208
209 #define CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS 0x2C
210
211 #define CGO_TEX_COORD 0x2D
212 #define CGO_TEX_COORD_SZ 2
213
214
215 #define CGO_DRAW_LABEL 0x2E
216 #define CGO_DRAW_LABEL_SZ 20
217
218 #define CGO_DRAW_LABELS 0x2F
219
220 #define CGO_DRAW_CONNECTOR 0x30
221 #define CGO_DRAW_CONNECTOR_SZ 25
222
223 #define CGO_DRAW_CONNECTORS 0x31
224
225 #define CGO_DRAW_TRILINES 0x32
226 #define CGO_DRAW_TRILINES_SZ 2
227
228 #define CGO_UNIFORM3F 0x33
229 #define CGO_UNIFORM3F_SZ 4
230 #define CGO_UNIFORM3F_HEADER 4
231
232 #define CGO_SPECIAL_WITH_ARG 0x34
233 #define CGO_SPECIAL_WITH_ARG_SZ 2
234
235 #define CGO_LINE 0x35
236 #define CGO_LINE_SZ 6
237 #define CGO_SPLITLINE 0x36
238 #define CGO_SPLITLINE_SZ 9
239
240 #define CGO_DRAW_CUSTOM 0x37
241
242 #define CGO_VERTEX_ATTRIB_3F 0x38
243 #define CGO_VERTEX_ATTRIB_4UB 0x39
244 #define CGO_VERTEX_ATTRIB_1F 0x3A
245
246 #define CGO_MASK_ATTRIBUTE_IF_PICKING 0x3B
247 #define CGO_BIND_VBO_FOR_PICKING 0x3C
248
249 #define CGO_VERTEX_BEGIN_LINE_STRIP 0x3D
250 #define CGO_VERTEX_BEGIN_LINE_STRIP_SZ 3
251
252 #define CGO_INTERPOLATED 0x3E
253 #define CGO_INTERPOLATED_SZ 1
254
255 #define CGO_VERTEX_CROSS 0x3F
256 #define CGO_VERTEX_CROSS_SZ 3
257
258 #define CGO_VERTEX_ATTRIB_4UB_IF_PICKING 0x40
259
260 #define CGO_CUSTOM_CYLINDER_ALPHA 0x41
261
262 #define CGO_LIGHTING 0x0B50
263
264 #define CGO_VERTEX_ARRAY 0x01
265 #define CGO_NORMAL_ARRAY 0x02
266 #define CGO_COLOR_ARRAY 0x04
267 #define CGO_PICK_COLOR_ARRAY 0x08
268 #define CGO_ACCESSIBILITY_ARRAY 0x10
269 #define CGO_TEX_COORD_ARRAY 0x20
270
271 extern int CGO_sz[];
272 size_t CGO_sz_size();
273
274 // CGOs are floating point arrays so we need to work with sizes in terms of floats
275 template <typename T>
fsizeof()276 static size_t fsizeof() { return sizeof(T) / sizeof(float); }
277
278 struct ObjectGadgetRamp;
279
280 class CGO;
281
282 // These are only the optimized operations
283 namespace cgo {
284 namespace draw {
285 struct begin {
286 static const int op_code = CGO_BEGIN;
287 int mode;
beginbegin288 begin(int mode) : mode(mode) {}
289 };
290
291 struct enable {
292 static const int op_code = CGO_ENABLE;
293 int mode;
enableenable294 enable(int mode) : mode(mode) {}
295 };
296
297 struct disable {
298 static const int op_code = CGO_DISABLE;
299 int mode;
disabledisable300 disable(int mode) : mode(mode) {}
301 };
302
303 struct trilines {
304 static const int op_code = CGO_DRAW_TRILINES;
305 unsigned nverts;
306 unsigned buffer; // GLuint
trilinestrilines307 trilines(unsigned nverts, unsigned buffer) : nverts(nverts), buffer(buffer) {}
308 };
309
310 struct op_with_data {
311 float * floatdata { nullptr };
set_dataop_with_data312 void set_data(float * data) { floatdata = data; };
get_dataop_with_data313 float * get_data() { return floatdata; };
get_dataop_with_data314 const float * get_data() const { return floatdata; };
315 virtual int get_data_length() const = 0;
~op_with_dataop_with_data316 virtual ~op_with_data() {}
317 };
318
319 struct op_with_draw_buffers {
320 };
321
322 struct arrays : op_with_data {
323 static const int op_code = CGO_DRAW_ARRAYS;
arraysarrays324 arrays(int _mode, short _arrays, int _nverts) :
325 mode(_mode), arraybits(_arrays), narrays(0), nverts(_nverts) {
326 short bit;
327 for (bit = 0; bit < 4; bit++){
328 if ((1 << bit) & arraybits){
329 narrays+=3;
330 }
331 }
332 if (arraybits & CGO_ACCESSIBILITY_ARRAY) narrays++;
333 if (arraybits & CGO_COLOR_ARRAY) narrays++;
334 };
335 int mode;
336 int arraybits;
337 int narrays;
338 int nverts;
get_data_lengtharrays339 int get_data_length() const { return narrays * nverts; };
340 };
341
342 struct buffers_indexed : op_with_data, op_with_draw_buffers {
343 static const int op_code = CGO_DRAW_BUFFERS_INDEXED;
344 buffers_indexed(int _mode, short _arrays, int _nindices,
345 int _nverts, size_t _vboid, size_t _iboid, int _n_data, size_t _pickvboid = 0) :
modebuffers_indexed346 mode(_mode), arraybits(_arrays), narrays(0), nindices(_nindices),
347 nverts(_nverts), vboid(_vboid), iboid(_iboid)
348 , pickvboid(_pickvboid)
349 , pickcolorsset(0)
350 , n_data(_n_data)
351 {
352 short bit;
353 for (bit = 0; bit < 4; bit++){
354 if ((1 << bit) & arraybits){
355 narrays++;
356 }
357 }
358 if (arraybits & CGO_ACCESSIBILITY_ARRAY) narrays++;
359 if (arraybits & CGO_COLOR_ARRAY) narrays++;
360 }
361 int mode;
362 int arraybits;
363 int narrays;
364 int nindices;
365 int nverts;
366 size_t vboid;
367 size_t iboid;
368 size_t pickvboid;
369 int pickcolorsset;
370 int n_data;
get_data_lengthbuffers_indexed371 int get_data_length() const { return nverts * 3 + n_data; };
372 };
373
374 struct sphere_buffers : op_with_data, op_with_draw_buffers {
375 static const int op_code = CGO_DRAW_SPHERE_BUFFERS;
sphere_bufferssphere_buffers376 sphere_buffers(int _num_spheres, int _ub_flags,
377 size_t _vboid, size_t _pickvboid) :
378 num_spheres(_num_spheres), ub_flags(_ub_flags),
379 vboid(_vboid), pickvboid(_pickvboid), pickcolorsset(0) {}
380 int num_spheres;
381 int ub_flags;
382 size_t vboid;
383 size_t pickvboid;
384 int pickcolorsset;
get_data_lengthsphere_buffers385 int get_data_length() const { return num_spheres * 2; };
386 };
387
388 struct cylinder_buffers : op_with_data, op_with_draw_buffers {
389 static const int op_code = CGO_DRAW_CYLINDER_BUFFERS;
cylinder_bufferscylinder_buffers390 cylinder_buffers(int _num_cyl, int _alpha, size_t _vboid,
391 size_t _iboid, size_t _pickvboid) :
392 num_cyl(_num_cyl), alpha(_alpha), vboid(_vboid),
393 iboid(_iboid), pickvboid(_pickvboid), pickcolorsset(0) {
394 }
395 int num_cyl;
396 int alpha;
397 size_t vboid;
398 size_t iboid;
399 size_t pickvboid;
400 int pickcolorsset;
get_data_lengthcylinder_buffers401 int get_data_length() const { return num_cyl * 2 * 2; };
402 };
403
404 struct textures : op_with_data, op_with_draw_buffers {
405 static const int op_code = CGO_DRAW_TEXTURES;
texturestextures406 textures(int _ntextures, size_t _vboid) : ntextures(_ntextures), vboid(_vboid) { }
407 int ntextures;
408 size_t vboid;
get_data_lengthtextures409 int get_data_length() const { return ntextures * 18; };
410 };
411
412 struct screen_textures : op_with_draw_buffers {
413 static const int op_code = CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS;
screen_texturesscreen_textures414 screen_textures(int _nverts, size_t _vboid) : nverts(_nverts),
415 vboid(_vboid) {};
416 int nverts;
417 size_t vboid;
418 };
419
420 struct buffers_not_indexed : op_with_data, op_with_draw_buffers {
421 static const int op_code = CGO_DRAW_BUFFERS_NOT_INDEXED;
422 buffers_not_indexed(int _mode, int _arrays, int _nverts,
423 size_t _vboid, size_t _pickvboid = 0) :
modebuffers_not_indexed424 mode(_mode), arraybits(_arrays), narrays(0), nverts(_nverts),
425 vboid(_vboid), pickvboid(_pickvboid), pickcolorsset(0) {
426 for (short bit = 0; bit < 4; bit++){
427 if ((1 << bit) & arraybits){
428 narrays++;
429 }
430 }
431 if (arraybits & CGO_ACCESSIBILITY_ARRAY) narrays++;
432 if (arraybits & CGO_COLOR_ARRAY) narrays++;
433 };
434 int mode;
435 int arraybits;
436 int narrays;
437 int nverts;
438 size_t vboid;
439 size_t pickvboid;
440 int pickcolorsset;
get_data_lengthbuffers_not_indexed441 int get_data_length() const { return nverts * 3; };
442 };
443
444 struct label {
445 using vec3 = glm::vec3;
446 using vec4 = glm::vec4;
447 static const int op_code = CGO_DRAW_LABEL;
labellabel448 label(const vec3& _world_pos, const vec3& _screen_world_offset, const vec3& _screen_min,
449 const vec3& _screen_max, const vec4& _text_extent, float _relative_mode,
450 const vec3& _target_pos) :
451 world_pos(_world_pos), screen_world_offset(_screen_world_offset), screen_min(_screen_min),
452 screen_max(_screen_max), text_extent(_text_extent), relative_mode(_relative_mode),
453 target_pos(_target_pos) {}
454 vec3 world_pos;
455 vec3 screen_world_offset;
456 vec3 screen_min;
457 vec3 screen_max;
458 vec4 text_extent;
459 float relative_mode;
460 vec3 target_pos;
461 };
462
463 struct labels : op_with_data, op_with_draw_buffers {
464 static const int op_code = CGO_DRAW_LABELS;
labelslabels465 labels(int _ntextures, size_t _vboid, size_t _pickvboid) :
466 vboid(_vboid)
467 , pickvboid(_pickvboid)
468 , ntextures(_ntextures)
469 , pickcolorsset(0)
470 {}
471 size_t vboid;
472 size_t pickvboid;
473 int ntextures;
474 int pickcolorsset;
get_data_lengthlabels475 int get_data_length() const { return ntextures * 18; };
476 };
477
478 struct connectors : op_with_draw_buffers {
479 static const int op_code = CGO_DRAW_CONNECTORS;
connectorsconnectors480 connectors(int _nconnectors, size_t _vboid) :
481 nconnectors(_nconnectors), vboid(_vboid) {};
482 int nconnectors;
483 size_t vboid;
484 };
485
486 struct line {
487 static const int op_code = CGO_LINE;
lineline488 line(const float *v1, const float *v2) {
489 copy3f(v1, vertex1);
490 copy3f(v2, vertex2);
491 };
492 float vertex1[3], vertex2[3];
493 };
494 struct splitline {
495 static const int op_code = CGO_SPLITLINE;
496
497 static const unsigned char interpolation = 0x01; // ramp/interpolation
498 static const unsigned char no_split_for_pick = 0x02;
499 static const unsigned char equal_colors = 0x04;
splitlinesplitline500 splitline(const float *v1, const float *v2, const float *color2arg,
501 unsigned int index_2nd, int bond_2nd,
502 bool isRamped, bool same_pick, bool eq_colors) :
503 index(index_2nd), bond(bond_2nd) {
504 copy3f(v1, vertex1);
505 copy3f(v2, vertex2);
506 color2[0] = CLIP_COLOR_VALUE(color2arg[0]);
507 color2[1] = CLIP_COLOR_VALUE(color2arg[1]);
508 color2[2] = CLIP_COLOR_VALUE(color2arg[2]);
509 flags = (isRamped ? cgo::draw::splitline::interpolation : 0x00) |
510 (same_pick ? cgo::draw::splitline::no_split_for_pick : 0x00) |
511 (eq_colors ? cgo::draw::splitline::equal_colors : 0x00);
512 };
513 float vertex1[3], vertex2[3];
514 unsigned char color2[3];
515 unsigned char flags; // interpolation | no_split_for_pick | equal_colors
516 unsigned int index;
517 int bond;
518 };
519
520 struct mask_attribute_if_picking : op_with_draw_buffers {
521 static const int op_code = CGO_MASK_ATTRIBUTE_IF_PICKING;
mask_attribute_if_pickingmask_attribute_if_picking522 mask_attribute_if_picking(int _attr_lookup_idx, size_t _vboid) {
523 attr_lookup_idx = _attr_lookup_idx;
524 vboid = _vboid;
525 };
526 int attr_lookup_idx;
527 size_t vboid;
528 };
529
530 struct bind_vbo_for_picking : op_with_draw_buffers {
531 static const int op_code = CGO_BIND_VBO_FOR_PICKING;
bind_vbo_for_pickingbind_vbo_for_picking532 bind_vbo_for_picking(size_t _vboid, int _which_attr_idx, int _npickattrs) {
533 vboid = _vboid;
534 which_attr_idx = _which_attr_idx;
535 npickattrs = _npickattrs;
536 };
537 size_t vboid;
538 int which_attr_idx;
539 int npickattrs;
540 };
541
542 struct custom : op_with_data, op_with_draw_buffers {
543 static const int op_code = CGO_DRAW_CUSTOM;
544 custom(int _mode, int _nverts, size_t _vboid, size_t _pickvboid,
545 int _vertsperpickinfo = 1, int _npickbufs = 1, size_t _iboid = 0,
546 int _nindices = 0)
modecustom547 : mode(_mode), nverts(_nverts), vboid(_vboid), pickvboid(_pickvboid),
548 pickcolorsset(0), iboid(_iboid), nindices(_nindices),
549 npickbufs(_npickbufs), vertsperpickinfo(_vertsperpickinfo){};
550 int mode;
551 int nverts;
552 size_t vboid;
553 size_t pickvboid;
554 int pickcolorsset;
555 size_t iboid;
556 int nindices;
557 int npickbufs;
558 int vertsperpickinfo;
get_data_lengthcustom559 int get_data_length() const { return npickbufs*nverts*2/vertsperpickinfo; };
560 };
561
562 struct vertex_attribute_3f {
563 static const int op_code = CGO_VERTEX_ATTRIB_3F;
vertex_attribute_3fvertex_attribute_3f564 vertex_attribute_3f(int _attr_lookup_idx, void *v) {
565 attr_lookup_idx = _attr_lookup_idx;
566 copy3f((float*)v, values);
567 };
568 int attr_lookup_idx;
569 float values[3];
570 };
571
572 struct vertex_attribute_4ub {
573 static const int op_code = CGO_VERTEX_ATTRIB_4UB;
vertex_attribute_4ubvertex_attribute_4ub574 vertex_attribute_4ub(int _attr_lookup_idx, void *_ubdata) {
575 attr_lookup_idx = _attr_lookup_idx;
576 memcpy(ubdata, _ubdata, 4);
577 };
578 int attr_lookup_idx;
579 unsigned char ubdata[4];
580 };
581
582 struct vertex_attribute_4ub_if_picking {
583 static const int op_code = CGO_VERTEX_ATTRIB_4UB_IF_PICKING;
vertex_attribute_4ub_if_pickingvertex_attribute_4ub_if_picking584 vertex_attribute_4ub_if_picking(int _attr_lookup_idx, void *_ubdata) {
585 attr_lookup_idx = _attr_lookup_idx;
586 memcpy(ubdata, _ubdata, 4);
587 };
588 int attr_lookup_idx;
589 unsigned char ubdata[4];
590 };
591
592 struct vertex_attribute_1f {
593 static const int op_code = CGO_VERTEX_ATTRIB_1F;
vertex_attribute_1fvertex_attribute_1f594 vertex_attribute_1f(int _attr_lookup_idx, float v) {
595 attr_lookup_idx = _attr_lookup_idx;
596 value = v;
597 };
598 int attr_lookup_idx;
599 float value;
600 };
601
602 struct shadercylinder {
603 static const int op_code = CGO_SHADER_CYLINDER;
shadercylindershadercylinder604 shadercylinder(const float *_origin, const float *_axis, const float _tube_size, int _cap) :
605 tube_size(_tube_size), cap(_cap) {
606 copy3f(_origin, origin);
607 copy3f(_axis, axis);
608 };
609 float origin[3], axis[3], tube_size;
610 int cap;
611 };
612
613 struct shadercylinder2ndcolor {
614 static const int op_code = CGO_SHADER_CYLINDER_WITH_2ND_COLOR;
615 shadercylinder2ndcolor(CGO *I, const float *_origin, const float *_axis, const float _radius,
616 int _cap, const float *_color2, Pickable *pickcolor2 = NULL,
617 const float alpha = -1.f);
618 float origin[3], axis[3], tube_size;
619 int cap;
620 float color2[3];
621 unsigned int pick_color_index;
622 int pick_color_bond;
623 float alpha;
624 };
625
626 struct sausage {
627 static const int op_code = CGO_SAUSAGE;
sausagesausage628 sausage(const float *_vertex1, const float *_vertex2, const float _radius, const float *_color1, const float *_color2) :
629 radius(_radius) {
630 copy3f(_vertex1, vertex1);
631 copy3f(_vertex2, vertex2);
632 copy3f(_color1, color1);
633 copy3f(_color2, color2);
634 };
635 float vertex1[3], vertex2[3], radius, color1[3], color2[3];
636 };
637
638 struct cylinder {
639 static const int op_code = CGO_CYLINDER;
cylindercylinder640 cylinder(const float *_vertex1, const float *_vertex2, const float _radius, const float *_color1, const float *_color2) :
641 radius(_radius) {
642 copy3f(_vertex1, vertex1);
643 copy3f(_vertex2, vertex2);
644 copy3f(_color1, color1);
645 copy3f(_color2, color2);
646 };
647 float vertex1[3], vertex2[3], radius, color1[3], color2[3];
648 };
649
650 struct custom_cylinder {
651 static const int op_code = CGO_CUSTOM_CYLINDER;
custom_cylindercustom_cylinder652 custom_cylinder(const float *_vertex1, const float *_vertex2, const float _radius, const float *_color1, const float *_color2, const float _cap1, const float _cap2) :
653 radius(_radius), cap1(_cap1), cap2(_cap2) {
654 copy3f(_vertex1, vertex1);
655 copy3f(_vertex2, vertex2);
656 copy3f(_color1, color1);
657 copy3f(_color2, color2);
658 };
659 float vertex1[3], vertex2[3], radius, color1[3], color2[3];
660 float cap1, cap2;
661 };
662
663 struct custom_cylinder_alpha {
664 static const int op_code = CGO_CUSTOM_CYLINDER_ALPHA;
custom_cylinder_alphacustom_cylinder_alpha665 custom_cylinder_alpha(const float *_vertex1, const float *_vertex2, const float _radius, const float *_color1, const float *_color2,
666 const float _alpha1, const float _alpha2,
667 const float _cap1, const float _cap2) :
668 radius(_radius), cap1(_cap1), cap2(_cap2) {
669 copy3f(_vertex1, vertex1);
670 copy3f(_vertex2, vertex2);
671 copy3f(_color1, color1);
672 copy3f(_color2, color2);
673 color1[3] = _alpha1;
674 color2[3] = _alpha2;
675 };
676 float vertex1[3], vertex2[3], radius, color1[4], color2[4];
677 float cap1, cap2;
678 };
679 };
680 };
681
682 class CGO {
683 public:
684 CGO(PyMOLGlobals* G, int size = 0);
685 ~CGO();
686
687 PyMOLGlobals *G { nullptr };
688 float *op { nullptr };
689 size_t c = 0;
690 bool z_flag = false;
691 float z_min { 0 }, z_max { 0 };
692 float z_vector[3];
693 float alpha { 1.f };
694 int *i_start { 0 }, i_size { 0 };
695 unsigned int current_pick_color_index { 0 };
696 int current_pick_color_bond { cPickableNoPick };
697 float current_accessibility { 1.f };
698 float normal[3]{0.f, 0.f, 1.f};
699 float color[3]{};
700 float texture[2];
701 uchar pickColor[4]{0, 0, 0, 0xff};
702 bool has_begin_end { false };
703 bool has_draw_buffers { false }, has_draw_cylinder_buffers { false }, has_draw_sphere_buffers { false };
704 bool use_shader { false }, cgo_shader_ub_color { false }, cgo_shader_ub_normal { false };
705 bool debug { false };
706 bool no_pick { false };
707 short render_alpha { 0 }; // 1 : render CGOSetZVector/CGORenderGLAlpha only
708 // 2 : render both CGOSetZVector/CGORenderGLAlpha and rest of object
709 // calcDepth=1 by default
710 short sphere_quality { 0 }; // quality of spheres when simplified or rendered in immediate mode
711 bool interpolated { false };
712 /***********************************************************************
713 * CGO iterator
714 *
715 * for (auto it = cgo->begin(); !it.is_stop(); ++it) {
716 * auto pc = it.data();
717 * int op = it.op_code();
718 * ...
719 * }
720 ***********************************************************************/
721
722 class const_iterator {
723 protected:
724 const float * m_pc;
725 const float * m_stop;
726 public:
op_code()727 unsigned op_code() const {
728 return *reinterpret_cast<const unsigned*>(m_pc);
729 }
730 operator int() const { return op_code(); }
731
data()732 const float * data() const { return m_pc + 1; }
733
734 template <typename T>
cast()735 const T * cast() const { return reinterpret_cast<const T *>(m_pc + 1); }
736
const_iterator(const CGO * cgo)737 const_iterator(const CGO * cgo) {
738 m_pc = cgo->op;
739 m_stop = cgo->op + cgo->c;
740 }
741
742 const_iterator& operator++();
743
is_stop()744 bool is_stop() const {
745 return m_pc == m_stop || op_code() == CGO_STOP;
746 }
747 };
748
749 class iterator : public const_iterator {
750 public:
iterator(CGO * cgo)751 iterator(CGO * cgo) : const_iterator(cgo) {}
data()752 float * data() { return const_cast<float*>(m_pc + 1); }
cast()753 template <typename T> T* cast() { return reinterpret_cast<T*>(data()); }
754 };
755
begin()756 const_iterator begin() const { return this; }
begin()757 iterator begin() { return this; }
758
759 /***********************************************************************
760 * This is the add function, the signature may look weird but it's
761 * common c++11 perfect forwarding. This function passes the constructor
762 * arguments into the function. Meaning it is used like:
763 * cgo.add<cgo::draw::arrays>(mode, arrays, nverts);
764 ***********************************************************************/
add(TArgs &&...args)765 template <typename T, typename... TArgs> float * add(TArgs&&... args) {
766 int size = fsizeof<T>() + 1;
767 float * at = add_to_buffer(size);
768 // write the op code
769 CGO_write_int(at, T::op_code);
770 // call the type constructor in place forwarding the args to the constructor
771 T * sp = new (at) T(std::forward<TArgs>(args)...);
772
773 if (std::is_base_of<cgo::draw::op_with_draw_buffers, T>::value) {
774 has_draw_buffers = true;
775 }
776
777 if (std::is_base_of<cgo::draw::op_with_data, T>::value) {
778 auto ptr = reinterpret_cast<cgo::draw::op_with_data *>(sp);
779 // set the buffer data flag
780 // create the floating point data for this type
781 auto data_len = ptr->get_data_length();
782 if (data_len) {
783 ptr->set_data(allocate_in_data_heap(data_len));
784 return ptr->get_data();
785 }
786 }
787
788 // this op does not have dynamic data, but since the caller knows
789 // then we return the allocated pointer, so that the caller can determine
790 // whether this was successful or not.
791 return at;
792 }
793
794 // Appends the source CGO onto this CGO
795 int append(const CGO * source, bool stopAtEnd);
796 void move_append(CGO * source);
797 void free_append(CGO * &source);
798
799 // Allocates in our CGO data pool
allocate_in_data_heap(size_t size)800 float * allocate_in_data_heap(size_t size) {
801 std::unique_ptr<float[]> uni(new float[size]);
802 float * ptr = uni.get();
803 _data_heap.emplace_back(std::move(uni));
804 return ptr;
805 }
806
807 // templated by the op type
copy_op_from(const float * pc)808 template <typename T> void copy_op_from(const float * pc) {
809 // copy the op
810 const size_t op_size = fsizeof<T>() + 1; // + 1 is the op
811 float * at = add_to_buffer(op_size);
812 memcpy(at, (pc - 1), op_size * 4);
813
814 if (std::is_base_of<cgo::draw::op_with_draw_buffers, T>::value) {
815 has_draw_buffers = true;
816 }
817
818 if (std::is_base_of<cgo::draw::op_with_data, T>::value) {
819 // copy the float data
820 float * vals { nullptr };
821 auto ptr = reinterpret_cast<const cgo::draw::op_with_data*>(pc);
822 int data_len = ptr->get_data_length();
823 if (data_len) {
824 vals = allocate_in_data_heap(data_len);
825 memcpy(vals, ptr->get_data(), data_len * 4);
826 }
827 auto spop = reinterpret_cast<cgo::draw::op_with_data *>(at + 1);
828 spop->set_data( vals );
829 }
830 }
831
832 // Our CGO_add, allocates size bytes at end of cgo buffer
add_to_buffer(int size)833 float * add_to_buffer(int size) {
834 float * at { nullptr };
835 VLACheck(op, float, size + c);
836 if (!op)
837 return nullptr;
838 at = op + c;
839 c += size;
840 return at;
841 }
842
843 /***********************************************************************
844 * This function adds to the end of this CGO the cgo op that exists in
845 * the float. This function will also increment the pointer passed to it
846 * by the size of the operation.
847 ***********************************************************************/
848 void add_to_cgo(int, const float*);
849
850 // Pretty prints a table with the layout of this CGO
851 void print_table() const;
852
853 private:
854 std::vector<std::unique_ptr<float[]>> _data_heap;
855 };
856
857 int CGORendererInit(PyMOLGlobals * G);
858 void CGORendererFree(PyMOLGlobals * G);
859 #define CGONew new CGO
860 #define CGONewSized CGONew
861 int CGOGetExtent(const CGO * I, float *mn, float *mx);
862 int CGOHasNormals(const CGO * I);
863
864 void CGOFree(CGO * &I, bool withVBOs=true);
865 #define CGOFreeWithoutVBOs(I) CGOFree(I, false)
866
867 CGO *CGODrawText(const CGO * I, int est, float *camera);
868
869 CGO *CGOSimplify(const CGO * I, int est, short sphere_quality = -1, bool stick_round_nub = true);
870 CGO *CGOSimplifyNoCompress(const CGO * I, int est, short sphere_quality = -1, bool stick_round_nub = true);
871
872 // -1 - no lines, 0 - some no interpolation, 1 - all interpolation, 2 - all no interpolation
873 bool CGOCombineBeginEnd(CGO ** I, bool do_not_split_lines = false);
874 CGO *CGOCombineBeginEnd(const CGO * I, int est, bool do_not_split_lines = false);
875
876 void CGOFreeVBOs(CGO *I);
877
878 CGO *CGOOptimizeToVBOIndexed(CGO * I, int est=0, const float *color=NULL, bool addshaders=true, bool embedTransparencyInfo=false);
879 #define CGOOptimizeToVBOIndexedWithColorEmbedTransparentInfo(I, est, color, addshaders) CGOOptimizeToVBOIndexed(I, est, color, addshaders, true)
880 #define CGOOptimizeToVBOIndexedWithColor CGOOptimizeToVBOIndexed
881 #define CGOOptimizeToVBOIndexedNoShader(I, est) CGOOptimizeToVBOIndexed(I, est, NULL, false)
882
883 bool CGOOptimizeToVBONotIndexed(CGO ** I);
884 CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders=true, float **returnedData=NULL);
885
886 #define CGOOptimizeToVBONotIndexedWithReturnedData CGOOptimizeToVBONotIndexed
887 #define CGOOptimizeToVBONotIndexedNoShader(I, est) CGOOptimizeToVBONotIndexed(I, est, false)
888
889
890 CGO *CGOOptimizeSpheresToVBONonIndexed(const CGO * I, int est=0, bool addshaders=false, CGO *leftOverCGO=NULL);
891 #define CGOOptimizeSpheresToVBONonIndexedNoShader(I, est) CGOOptimizeSpheresToVBONonIndexed(I, est, false, NULL)
892
893 int CGOCheckComplex(CGO * I);
894 int CGOPreloadFonts(CGO * I);
895
896 int CGOCheckForText(CGO * I);
897
898 int CGOFromFloatArray(CGO * I, const float *src, int len);
899
900 int CGOBegin(CGO * I, int mode);
901 int CGOEnd(CGO * I);
902
903 int CGOSphere(CGO * I, const float *v1, float r);
904 int CGOEllipsoid(CGO * I, const float *v1, float r, const float *n1, const float *n2, const float *n3);
905 int CGOQuadric(CGO * I, const float *v1, float r, const float *p); /* NOT WORKING YET */
906 int CGOVertex(CGO * I, float v1, float v2, float v3);
907 int CGOVertexv(CGO * I, const float *v);
908 int CGOVertexCrossv(CGO * I, const float *v);
909 int CGOVertexBeginLineStripv(CGO * I, const float *v);
910 int CGOInterpolated(CGO * I, const bool interp);
911 int CGOAlpha(CGO * I, float alpha);
912 int CGOColor(CGO * I, float v1, float v2, float v3);
913 int CGOColorv(CGO * I, const float *v);
914 int CGOTexCoord2f(CGO * I, float v1, float v2);
915 int CGONormal(CGO * I, float v1, float v2, float v3);
916 int CGONormalv(CGO * I, const float *v);
917 int CGOResetNormal(CGO * I, int mode);
918 int CGOLinewidth(CGO * I, float v);
919 int CGOSpecial(CGO * I, int v);
920 // all pre-processor definitions for CGOSpecial ops
921 enum {
922 LINEWIDTH_DYNAMIC_WITH_SCALE = 1,
923 LINEWIDTH_DYNAMIC_MESH,
924 POINTSIZE_DYNAMIC_DOT_WIDTH,
925 LINEWIDTH_DYNAMIC_WITH_SCALE_RIBBON,
926 LINEWIDTH_DYNAMIC_WITH_SCALE_DASH,
927 CYLINDERWIDTH_DYNAMIC_MESH,
928 LINEWIDTH_WITH_SCALE,
929 DOTSIZE_WITH_SPHERESCALE,
930 MESH_WIDTH_FOR_SURFACES,
931 CYLINDER_WIDTH_FOR_DISTANCES,
932 CYLINDER_WIDTH_FOR_RIBBONS,
933 DOT_WIDTH_FOR_DOTS,
934 DOT_WIDTH_FOR_DOT_SPHERES,
935 CYLINDER_WIDTH_FOR_NONBONDED,
936 CYLINDER_WIDTH_FOR_REPWIRE,
937 CYLINDER_WIDTH_FOR_REPWIRE_VARWIDTH,
938 ENABLE_BACK_FACES_IF_NOT_TWO_SIDED,
939 DISABLE_BACK_FACES_IF_NOT_TWO_SIDED,
940 SET_SURFACE_UNIFORMS,
941 SET_ALIGNMENT_UNIFORMS_ATTRIBS,
942 LINEWIDTH_FOR_LINES,
943 SET_LABEL_SCALE_UNIFORMS
944 };
945
946 int CGOSpecialWithArg(CGO * I, int v, float arg);
947 #define SPHERE_MODE_OPS 1
948 #define LINE_LIGHTING 2
949
950 int CGODotwidth(CGO * I, float v);
951 int CGOChar(CGO * I, char c);
952 int CGOFontVertex(CGO * I, float x, float y, float z);
953 int CGOFontVertexv(CGO * I, const float *v);
954 int CGOFontScale(CGO * I, float v1, float v2);
955 int CGOIndent(CGO * I, char c, float dir);
956 int CGOWrite(CGO * I, const char *str);
957 int CGOWriteLeft(CGO * I, const char *str);
958 int CGOWriteIndent(CGO * I, const char *str, float indent);
959
960 #define CGODrawArrays(this, ...) (this)->add<cgo::draw::arrays>(__VA_ARGS__)
961 #define CGOCustomCylinderv(this, ...) (this)->add<cgo::draw::custom_cylinder>(__VA_ARGS__)
962 #define CGOShaderCylinder(this, ...) (this)->add<cgo::draw::shadercylinder>(__VA_ARGS__)
963 #define CGOCylinderv(this, ...) (this)->add<cgo::draw::cylinder>(__VA_ARGS__)
964
965 int CGOBoundingBox(CGO *I, const float *min, const float *max);
966 int CGOAccessibility(CGO * I, const float a);
967
968 int CGODrawTexture(CGO *I, int texture_id, float *worldPos, float *screenMin, float *screenMax, float *textExtent);
969 int CGODrawLabel(CGO *I, int texture_id, float *targetPos, float *worldPos, float *screenWorldOffset, float *screenMin, float *screenMax, float *textExtent, short relativeMode);
970 int CGODrawConnector(CGO *I, float *targetPt3d, float *labelCenterPt3d, float text_width, float text_height, float *screenOffset, float *screenWorldOffset, float *connectorColor, short relativeMode, int draw_bkgrd, float bkgrd_transp, float *bkgrd_color, float rel_ext_length, float connectorWidth);
971 CGO *CGOOptimizeLabels(const CGO * I, int est, bool addshaders=false);
972 CGO *CGOOptimizeTextures(const CGO * I, int est);
973 CGO *CGOExpandDrawTextures(const CGO * I, int est);
974 CGO *CGOOptimizeConnectors(const CGO * I, int est);
975
976 /*void CGOFontScale(CGO *I,float v);
977 void CGOFont(CGO *I,float size,int face,int style);*/
978
979 void CGORoundNub(CGO * I,
980 const float *v1, // cap center
981 const float *p0, // normal along axis
982 const float *p1, // x coord in cap space
983 const float *p2, // y coord in cap space
984 int direction, // 1 or -1
985 int nEdge, // "quality"
986 float size);
987
988 int CGOEnable(CGO * I, int mode);
989 int CGODisable(CGO * I, int mode);
990
991 int CGOStop(CGO * I);
992
993 int CGOConev(CGO * I, const float *p1, const float *p2, float r1, float r2, const float *c1, const float *c2,
994 float cap1, float cap2);
995
996 int CGOAlphaTriangle(CGO * I,
997 const float *v1, const float *v2, const float *v3,
998 const float *n1, const float *n2, const float *n3,
999 const float *c1, const float *c2, const float *c3,
1000 float a1, float a2, float a3, int reverse);
1001 void CGOSetZVector(CGO * I, float z0, float z1, float z2);
1002 struct GadgetSet;
1003 void CGORenderGLPicking(CGO * I, RenderInfo *info,
1004 PickContext * context, CSetting * set1, CSetting * set2, Rep *rep=NULL);
1005 void CGORenderGL(CGO * I, const float *color, CSetting * set1, CSetting * set2,
1006 RenderInfo * info, Rep *rep);
1007 void CGORenderGLAlpha(CGO * I, RenderInfo * info, bool calcDepth);
1008 int CGORenderRay(CGO * I, CRay * ray, RenderInfo * info, const float *color, ObjectGadgetRamp *ramp, CSetting * set1, CSetting * set2);
1009 void CGOReset(CGO * I);
1010
1011 void CGOSetUseShader(CGO *I, int use_shader);
1012
1013 PyObject *CGOAsPyList(CGO * I);
1014 CGO *CGONewFromPyList(PyMOLGlobals * G, PyObject * list, int version, bool shouldCombine=true);
1015 int CGOPickColor(CGO * I, unsigned int index, int bond);
1016
1017 const cgo::draw::buffers_not_indexed* CGOGetNextDrawBufferedNotIndex(
1018 const CGO*);
1019
1020 float *CGOGetNextOp(float *cgo_op, int optype);
1021
1022 int CGOAppend(CGO *dest, const CGO *source, bool stopAtEnd=true);
CGOAppendNoStop(CGO * dest,const CGO * source)1023 inline int CGOAppendNoStop(CGO *dest, const CGO *source) {
1024 return CGOAppend(dest, source, false);
1025 }
1026
1027 int CGOCountNumberOfOperationsOfType(const CGO *I, int op);
1028 int CGOCountNumberOfOperationsOfTypeN(const CGO *I, const std::set<int> &optype);
1029 int CGOCountNumberOfOperationsOfTypeN(const CGO *I, const std::map<int, int> &optype);
1030 bool CGOHasOperations(const CGO *I);
1031 bool CGOHasOperationsOfType(const CGO *I, int optype);
1032 bool CGOHasOperationsOfTypeN(const CGO *I, const std::set<int> &optype);
1033 bool CGOHasCylinderOperations(const CGO *I);
1034 bool CGOHasSphereOperations(const CGO *I);
1035 bool CGOFilterOutCylinderOperationsInto(const CGO *I, CGO *cgo);
1036
1037 bool CGOCheckWhetherToFree(PyMOLGlobals * G, CGO *I);
1038
1039 CGO *CGOConvertLinesToShaderCylinders(const CGO * I, int est);
1040 CGO *CGOSplitUpLinesForPicking(const CGO * I);
1041 CGO *CGOConvertLinesToTrilines(const CGO * I, bool addshaders=true);
1042 CGO *CGOConvertToLabelShader(const CGO *I, CGO * addTo);
1043
1044 void CGOChangeShadersTo(CGO *I, int frommode, int tomode);
1045 void CGOCountNumVerticesDEBUG(const CGO *I);
1046 CGO *CGOOptimizeScreenTexturesAndPolygons(CGO * I, int est);
1047 CGO *CGOColorByRamp(PyMOLGlobals * G, const CGO *I, ObjectGadgetRamp *ramp, int state, CSetting * set1);
1048
1049 #define CGOLineAsTriangleStrips(CGO, minx, miny, maxx, maxy) \
1050 CGOBegin(CGO, GL_TRIANGLE_STRIP); \
1051 CGOVertex(CGO, minx, miny, 0.f); \
1052 CGOVertex(CGO, minx, maxy+1, 0.f); \
1053 CGOVertex(CGO, minx+1, miny, 0.f); \
1054 CGOVertex(CGO, minx+1, maxy+1, 0.f); \
1055 CGOEnd(CGO); \
1056 CGOBegin(CGO, GL_TRIANGLE_STRIP); \
1057 CGOVertex(CGO, minx, maxy, 0.f); \
1058 CGOVertex(CGO, minx, maxy+1, 0.f); \
1059 CGOVertex(CGO, maxx, maxy, 0.f); \
1060 CGOVertex(CGO, maxx, maxy+1, 0.f); \
1061 CGOEnd(CGO); \
1062 CGOBegin(CGO, GL_TRIANGLE_STRIP); \
1063 CGOVertex(CGO, maxx, miny, 0.f); \
1064 CGOVertex(CGO, maxx, maxy+1, 0.f); \
1065 CGOVertex(CGO, maxx+1, miny, 0.f); \
1066 CGOVertex(CGO, maxx+1, maxy+1, 0.f); \
1067 CGOEnd(CGO); \
1068 CGOBegin(CGO, GL_TRIANGLE_STRIP); \
1069 CGOVertex(CGO, minx, miny, 0.f); \
1070 CGOVertex(CGO, minx, miny+1, 0.f); \
1071 CGOVertex(CGO, maxx, miny, 0.f); \
1072 CGOVertex(CGO, maxx, miny+1, 0.f); \
1073 CGOEnd(CGO);
1074
1075 int CGOHasTransparency(const CGO *I, bool checkTransp=true, bool checkOpaque=false);
1076 #define CGOHasOpaque(I) CGOHasTransparency(I, false, true)
1077
1078 CGO *CGOConvertTrianglesToAlpha(const CGO * I);
1079 CGO *CGOGenerateNormalsForTriangles(const CGO * I);
1080
1081 bool CGOHasAnyTriangleVerticesWithoutNormals(const CGO *I, bool checkTriangles=true);
1082 #define CGOHasAnyLineVerticesWithoutNormals(I) CGOHasAnyTriangleVerticesWithoutNormals(I, false)
1083
1084 CGO* CGOTurnLightingOnLinesOff(const CGO* I, bool use_shader);
CGOTurnLightingOnLinesOff(const CGO * I)1085 inline CGO* CGOTurnLightingOnLinesOff(const CGO* I)
1086 {
1087 return CGOTurnLightingOnLinesOff(I, I->use_shader);
1088 }
1089
1090 // returns offset of floats in CGO array
1091 int CGOUniform3f(CGO *I, int uniform_id, const float *value);
1092
1093 CGO *CGOConvertSpheresToPoints(const CGO *I);
1094
1095 #ifdef _PYMOL_ARB_SHADERS
1096 void CGORenderSpheresARB(RenderInfo *info, const CGO *I, const float *fog_info);
1097 #endif
1098
1099 CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc &pickData, int mode, const VertexBuffer::buffer_layout layout=VertexBuffer::INTERLEAVED, bool check_attr_for_data=true, int *idx_array=NULL, int nindicesperfrag=0, int nfragspergroup = 1);
1100
1101 bool CGOCheckSplitLineInterpolationIsSame(const CGO *I, bool &interp_value);
1102
1103 CGO *CGOConvertToTrilinesShader(const CGO *I, CGO *addTo, bool add_color=true);
1104 CGO *CGOConvertToLinesShader(const CGO *I, CGO *addTo, bool add_color=true);
1105
1106 CGO *CGOConvertLinesToCylinderShader(const CGO *I, CGO *addTo, bool add_color = true);
1107 CGO *CGOConvertCrossesToCylinderShader(const CGO *I, CGO *addTo, float cross_size);
1108 CGO *CGOConvertCrossesToLinesShader(const CGO *I, CGO *addTo, float cross_size);
1109 CGO *CGOConvertCrossesToTrilinesShader(const CGO *I, CGO *addTo, float cross_size);
1110 CGO *CGOConvertShaderCylindersToCylinderShader(const CGO *I, CGO *addTo);
1111
1112 void AssignNewPickColor(CGO* cgo, PickColorManager*, unsigned char* color,
1113 const PickContext* context, unsigned int index, int bond);
1114
1115 #endif
1116