HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_Geometry.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RE_Geometry.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  *
10  * This class acts as a wrapper around multiple RE_VertexArray objects,
11  * similar to the way a framebuffer object contains multiple textures.
12  * Arrays can be attached to various attachments points, representing
13  * different vertex attribute data
14  *
15  */
16 #ifndef RE_GEOMETRY_H
17 #define RE_GEOMETRY_H
18 
19 #include "RE_API.h"
20 #include "RE_Types.h"
21 #include "RE_Texture.h"
22 #include "RE_CachedObject.h"
23 
24 #include <UT/UT_NonCopyable.h>
25 #include <UT/UT_String.h>
26 #include <UT/UT_StringArray.h>
27 #include <UT/UT_SymbolTable.h>
28 #include <UT/UT_ValArray.h>
29 #include <iosfwd>
30 
31 class RE_ElementArray;
32 class RE_Render;
33 class RE_Shader;
34 class RE_VertexState;
35 class RE_VertexArray;
36 class RE_VertexMap;
37 class re_Attrib;
38 class re_Connectivity;
39 class re_InstanceGroup;
40 
41 #define RE_GEO_POINTS_IDX 0
42 #define RE_GEO_WIRE_IDX 2
43 #define RE_GEO_SHADED_IDX 4
44 
45 #define RE_GEO_ALL_SHADED 0x40000000
46 
47 /// @brief A collection of vertex arrays defining a geometry object.
48 /// This class acts as a wrapper around multiple RE_VertexArray objects,
49 /// similar to the way a framebuffer object contains multiple textures.
50 /// Arrays can be attached to various attachments points, representing
51 /// different vertex attribute data
53 {
54 public:
55  RE_Geometry(int num_points = 0,
56  bool use_buffer_object = true);
57  ~RE_Geometry();
58 
60 
61  /// Returns the amount of main memory (NOT graphics memory!)
62  /// owned by this RE_Geometry.
63  int64 getMemoryUsage(bool inclusive) const;
64 
65  /// @brief Choose between buffer objects and client arrays
66  /// By default, buffer objects are used if supported. This allows you to
67  /// turn them off and use vertex arrays. This is useful if the geometry
68  /// information is throw-away. If called when vertex arrays are attached,
69  /// they will be cleared (and possibly deleted)
70  void useBufferObjects(bool use_buf = true);
71 
72  /// @brief Optimize this geometry with vertex array objects.
73  /// Use an RE_VertexState (and GL Vertex Array Objects) to contain vertex
74  /// arrays. Requires RE_EXT_VERTEX_ARRAY_OBJECT.
75  void useVertexState(bool use_state = true);
76 
77  /// Clears all the attached buffers, and removes them from the cache.
78  void purgeBuffers();
79 
80  /// @brief Number of points in the geometry.
81  /// Number of points for the arrays declared as RE_ARRAY_POINT. This will
82  /// clear the data in all point arrays and reset the connectivty.
83  //@{
84  bool setNumPoints(int num);
85  int getNumPoints() const { return myNumPoints; }
86  //@}
87 
88  /// Sets the number of elements in arrays declared as RE_ARRAY_VERTEX.
89  //@{
90  bool setNumVertices(int num);
91  int getNumVertices() const { return myNumVertices; }
92  //@}
93 
94  /// Sets the number of elements in arrays declared as RE_ARRAY_PRIMITIVE.
95  //@{
96  bool setNumPrimitives(int num);
97  int getNumPrimitives() const { return myNumPrimitives; }
98  //@}
99 
100  /// @brief Calulcate the number of points required for some primitives
101  /// This will ensure that the buffer is big enough to hold enough vertices
102  /// for the given number of primitives of the specified type. The buffer
103  /// size can be reduced if 'shrink_if_smaller' is true, otherwise this will
104  /// only increase the size of the buffer if needed. If 'shader' is given,
105  /// it will check if the shader has a geometry shader and modify the
106  /// number of vertices by the output primitive type and maximum #vertices.
107  /// Shaders without a geometry shader will have no effect (as if nullptr).
108  /// For transform feedback, only POINTS, LINES or TRIANGLES are ever
109  /// produced.
110  void resizePointsToFit(RE_PrimType primtype,
111  int num_primitives,
112  bool shrink_if_smaller,
113  RE_Shader *shader = nullptr);
114 
115  /// @brief Create buffers for all attached arrays
116  /// When the above methods are called with attached arrays, these arrays
117  /// might have their storage freed. This call will ensure that all arrays
118  /// are initialized.
119  void initialize(RE_Render *r);
120 
121  // ---------------------------------------------------------------------
122  /// @name Generic Vertex Attributes
123  /// GL3 shaders use generic vertex attributes, which are identified by name.
124  /// GL2 shaders can use a few generic vertex attributes along with the fixed
125  /// builtin attributes. Generic attributes must be used for instanced,
126  /// primitive or vertex atttributes.
127  //@{
128 
129  /// place all attributes in a stashed list, which clears them externally
130  /// but keeps them available internally. If createAttribute() or
131  /// findCached...() are called, attributes will be fetched from the stashed
132  /// list. This should not be called without a clearStashedAttributes()
133  /// pairing it, nor called twice in a row.
134  void stashAttributes();
135 
136  /// Remove all remaining stashed attributes. If purge is true, remove them
137  /// from the GL cache as well.
138  int clearStashedAttributes(bool purge_from_cache);
139 
140  /// fetch stashed attribute 'name', placing it back into the geometry's list
141  RE_VertexArray *recallStashedAttribute(const char *name);
142 
143  /// fetch stashed attribute 'name', but only if it is a const buffer.
144  RE_VertexArray *recallStashedVaryingAttribute(const char *attrib_name);
145 
146  /// fetch stashed attribute 'name', but only if it is a const buffer.
147  RE_VertexArray *recallStashedConstAttribute(const char *attrib_name);
148 
149  /// fetch stashed attribute 'name' from the stash list, removing it from
150  /// the list and returning it if found. This does not place it back in the
151  /// geometry's list of attributes.
152  RE_VertexArray *fetchStashedAttribute(const char *name);
153 
154  bool hasStashedAttribute(const char *name);
155 
156 
157  /// @brief Create a generic vertex attribute attached to 'attrib_name'
158  /// Attributes are referenced by name, rather than buffer type. Array size
159  /// is required if array type is RANDOM or INSTANCED.
160  RE_VertexArray *createAttribute(
161  RE_Render *r,
162  const char *attrib_name,
163  RE_GPUType data_format,
164  int vectorsize,
165  const void *data,
167  int array_size = 0,
169  const char *cache_prefix = nullptr,
170  int capacity = -1);
171 
172  /// @brief Create an instanced vertex attribute attached to 'attrib_name'
173  /// Create an attribute which advances once every 'instance_stride'
174  /// instances rather than once per vertex. RE_EXT_INSTANCED_ARRAYS is
175  /// required, and an instanced drawing method must be used (or it acts as a
176  /// uniform).
177  RE_VertexArray *createInstancedAttribute(RE_Render *r,
178  const char *attrib_name,
179  RE_GPUType data_format,
180  int vectorsize,
181  int instance_stride,
182  int num_instances,
183  const void *data,
184  const char *cache_prefix
185  = nullptr,
186  int capacity = -1);
187  /// @brief Create a constant attribute value
188  /// Only RE_GPU_FLOAT32 and _FLOAT64 are supported for constant data.
189  /// The 'data' point must hold at least 1 element (sizeof(type)*vectorsize).
190  RE_VertexArray *createConstAttribute(RE_Render *r,
191  const char *attrib_name,
192  RE_GPUType data_format,
193  int vectorsize,
194  const void *data);
195 
196  /// @brief Create a constant attribute if varying attribute is not found
197  /// Ensures that there is at least a constant attribute value available if
198  /// the attribute doesn't exist already. Only returns an array if one was
199  /// created.
200  RE_VertexArray *assignAttributeDefault(RE_Render *r,
201  const char *attrib_name,
202  RE_GPUType data_format,
203  int vectorsize,
204  const void *default_value);
205 
206  /// Attach an existing attribute using its name as the binding
207  bool attachAttribute(RE_VertexArray *attrib);
208  /// Detatch an attribute from this object by name
209  RE_VertexArray *detachAttribute(const char *name);
210 
211  /// @brief Delete an attached vertex attribute by name
212  /// delete the RE_VertexArray, and if purge_cache is true, remove the
213  /// underlying data buffer from the GL cache.
214  bool clearAttribute(const char *name,
215  bool purge_cache=false);
216 
217  /// @brief Delete an attached vertex attribute by index
218  /// delete the RE_VertexArray, and if purge_cache is true, remove the
219  /// underlying data buffer from the GL cache.
220  bool clearAttributeByIndex(int i,
221  bool purge_cache=false);
222 
223  /// Fetch an attribute by name
224  RE_VertexArray *getAttribute(const char *name) const;
225 
226  /// Return an attribute's index byattribute name. Can change if attributes
227  /// are removed or added.
228  int getAttributeIndex(const char *name) const;
229 
230  /// Fetch an attribute by known type
231  RE_VertexArray *getAttribute(RE_GenericAttribID attrib_id) const;
232 
233  /// Return the number of generic attributes currently attached.
234  int getNumAttributes() const;
235 
236  /// Return currently attached vertex attribute 'i'
237  RE_VertexArray *getAttributeByIndex(int i) const;
238 
239  /// Return a vertex map representing the layout locations of the attributes
240  const RE_VertexMap *getVertexMap() const { return myVertexMap; }
241 
242  //@}
243 
244  // ---------------------------------------------------------------------
245  /// @name Addressable attributes
246  /// Addressable attributes allow you to use buffers, but sample them like
247  /// textures using texelFetch on samplerBuffer uniforms. Only buffer objects
248  /// are supported.
249  //@{
250 
251  /// @brief Create a randomly addressable attribute (texture buffer object)
252  /// Attributes can be stored in texture buffers, and accessed out of
253  /// the normal vertex flow, such as for vertex or primitive attributes.
254  /// Unlike normal attributes, addressable attributes can have a different
255  /// array size than the RE_Geometry's number of vertices.
256  RE_VertexArray *createAddressableAttribute(RE_Render *r,
257  const char *attrib_name,
258  int length,
259  RE_GPUType data_format,
260  int vectorsize,
261  const void *data,
262  RE_ArrayType atype
263  = RE_ARRAY_RANDOM,
264  const char *cache_prefix
265  = nullptr);
266  /// Create a randomly addressable attribute from an existing vertex array
267  RE_Texture *createAddressableAttribute(RE_Render *r,
268  const char *attrib_name,
270 
271  /// Fetch an addressable attribute by name
272  RE_VertexArray *getAddressableAttribute(const char *attrib_name) const;
273 
274  /// Return the index of the named addressable attribute, or -1 if not found
275  int getAddressableAttributeIndex(const char *attrib_name)
276  const;
277 
278  /// Delete the addressable attribute named 'attrib_name'
279  void clearAddressableAttribute(const char *attrib_name);
280 
281  /// Return the number of addressable attributes
283  { return myTextureAttributes.entries(); }
284 
285  /// Return the texture buffer object representing addressable attribute 'i'
287  { return myBufferTextures(index); }
288  /// Return the vertex arrayrepresenting addressable attribute 'i'
290  { return myTextureAttributes(index); }
291 
292  //@}
293 
294  // ---------------------------------------------------------------------
295  /// Caching @n
296 
297  /// Use caching for all vertex and element arrays stored by this object.
298  /// If any vertex arrays are attached, they are cleared unless the name
299  /// matches the previous cache name.
300  //@{
301 
302  /// @brief Set the base cache name.
303  /// Attribute names will be concatenated to the base name to form the full
304  /// cache name. Passing nullptr will disable caching. Returns true if the
305  /// cachename changed, in which case all existing buffers will be purged
306  /// from the cache.
307  bool cacheBuffers(const char *name);
308 
309  /// Return the base cache name.
310  const char *getCacheName() const { return myCacheName; }
311 
312  /// Check if this geometry object is caching.
313  bool isCaching() const { return myCacheName.isstring(); }
314 
315  /// Remove all buffers from the cache when this geometry object is deleted.
316  void purgeOnDelete(bool purge = true)
317  { myPurgeOnDelete = purge; }
318 
319  /// set the cache version for all arrays attached to this geometry object.
320  void setCacheVersion(RE_CacheVersion v);
321 
322  /// @brief Assign a cache tag to monitor cache changes on this object
323  /// The tag will be bumped if this or any of its vertex buffers are removed
324  /// from the cache.
325  void setCacheTag(RE_CacheTagHandle h);
326 
327  /// @brief Find an attribute or array in the GL cache, possibly creating it
328  /// Returns the cached array, if it exists, for the array named
329  /// 'attrib_name'. The name may be one of the gl-builtin attributes, like
330  /// gl_Position or gl_Color. 'array_size' is the size of an INSTANCE or
331  /// RANDOM array_type.
332  RE_VertexArray *findCachedAttrib(
333  RE_Render *r,
334  const char *attrib_name,
335  RE_GPUType data_format,
336  int vectorsize,
337  RE_ArrayType array_type,
338  bool create_if_missing = false,
339  int random_array_size = -1,
340  const RE_CacheVersion *cv = nullptr,
342  const char *cache_prefix = nullptr,
343  int capacity = -1);
344 
345  /// @brief Find an instanced attribute in the GL cache, possibly creating
346  /// it. The instance_step parameter defines how often the attribute
347  /// is advanced when the instance ID changes - 1 is once per instance.
348  RE_VertexArray *findCachedInstancedAttrib(
349  RE_Render *r,
350  const char *attrib_name,
351  RE_GPUType data_format,
352  int vectorsize,
353  int instance_step,
354  int array_size,
355  bool create_if_missing=false,
356  const RE_CacheVersion *v = nullptr,
358  const char *cache_prefix = nullptr,
359  int capacity = -1);
360 
361 
362  //@}
363 
364  // ---------------------------------------------------------------------
365  /// @name Instance groups
366  /// Instance groups allow for rendering of the geometry with different
367  /// attributes, generally InstanceTransform, but others can be overriden
368  /// as well. The base (default) group is instance group 0. Higher groups
369  /// will substitute their attributes for the ones in instance group 0. Note
370  /// that the attribute need not exist in the base group to be overriden.
371  /// If an attribute is not overriden, the base group attribute is used.
372 
373  /// Create a new instance group. instance_group must be a positive int.
374  void createInstanceGroup(int instance_group);
375 
376  /// Remove an existing instance group. Will not remove any attached
377  /// attribute to that group, but the instance group can no longer be
378  /// rendered.
379  void removeInstanceGroup(int instance_group);
380 
381  /// Returns true if the specified instance group exists.
382  bool hasInstanceGroup(int instance_group) const;
383 
385  { return myInstanceGroups.entries(); }
386 
387  /// Use nested instancing, rather than flattening data into arrays of
388  /// length N*M (for M instances nested within N instances). This requires
389  /// data arrays of size N+M. Element 0 contains the count of the instances
390  /// in the topmost level (N). Up to 9 levels are supported.
391  /// Instance indices are still expected in the range [0, N*M)
392  void setInstanceGroupNesting(int instance_group,
393  const UT_IntArray &count_per_level);
394  void clearInstanceGroupNesting(int instance_group);
395 
396  /// For instanced drawing, create indirection list to render only some of
397  /// the instances. The base instance group can also be indexed.
398  void setInstanceGroupIndexList(RE_Render *r,
399  int instance_group,
400  bool trivial,
401  const UT_IntArray *indices
402  = nullptr,
403  int max_capacity = -1);
404 
405  /// Set to draw a single instance in the group.
406  void setInstanceGroupConstIndex(RE_Render *r,
407  int instance_group,
408  int instance_to_draw);
409 
410  /// Set to draw all instances (based on the # transforms).
411  void setInstanceGroupDrawEverything(RE_Render *r,
412  int instance_group);
413  /// Draw none of the instances.
414  void setInstanceGroupDrawNothing(RE_Render *r,
415  int instance_group);
416 
417 
418  /// Create a constant for an attribute in 'instance_group'.
419  RE_VertexArray *createConstInstanceGroupAttrib(RE_Render *r,
420  int instance_group,
421  const char *name,
422  RE_GPUType data_format,
423  int vectorsize,
424  const void *data);
425 
426  /// Create a constant transform for an instance group.
427  void setConstInstanceGroupTransform(int instance_group,
428  const UT_Matrix4D &xform,
429  bool remove_instanced_xform);
430  void setConstInstanceGroupTransform(int instance_group,
431  const UT_Matrix4F &xform,
432  bool remove_instanced_xform);
433 
434  /// set instance group to use the same const transform as another
435  void copyConstInstanceGroupTransform(int instance_group,
436  int src_instance_group);
437 
438 
439  /// @brief Find an instance-group attribute in the cache
440  /// Creates an instanced attribute for an instance-group, which overrides
441  /// the base attribute on the RE_Geometry. instance_group zero is the base
442  /// level ("Cd"), all other groups have the group appended ("Cd1" for
443  /// group 1). When drawn with drawInstanceGroup(), attributes in the
444  /// specified instance group will be used (if present) instead of the base
445  /// attributes.
446  RE_VertexArray *findCachedInstanceGroupAttrib(RE_Render *r,
447  int instance_group,
448  const char *name,
449  RE_GPUType data_type,
450  int vector_size,
451  int instance_step,
452  int num_instances,
453  bool create=false,
454  const RE_CacheVersion *v
455  = nullptr,
458  const char *view_name
459  = nullptr,
460  int capacity = -1);
461 
462  /// Return the attribute in the instance group with type 'attrib_id', or
463  /// if it's not a known type, by name.
464  RE_VertexArray *getInstanceGroupAttrib(int instance_group,
465  RE_GenericAttribID attrib_id,
466  const char *name);
467  /// Remove and delete the array.
468  bool clearInstanceGroupAttrib(int instance_group,
469  RE_GenericAttribID attrib_id,
470  const char *name);
471 
472  /// This is the same as getInstanceGroupAttrib(), but it used mainly by
473  /// RE_Shader to do additional prep on the attrib.
474  RE_VertexArray *getInstanceGroupTextureBufferForShader(RE_Render *r,
475  RE_Shader *sh,
476  int instance_group,
477  RE_GenericAttribID attr_id,
478  const char *name);
479 
480  /// Returns the number of instances to be drawn in an instance group.
481  int getInstanceGroupCount(int instance_group) const;
482 
483  /// Return a full instance group name based on an original base attrib name
484  static void getInstanceGroupName(UT_WorkBuffer &inst_name,
485  const char *base_name,
486  int instance_group);
487 
488  /// Return a full instance group name based on the known attribute type
489  static void getInstanceGroupName(UT_WorkBuffer &inst_name,
490  RE_GenericAttribID attrib_type,
491  int instance_group);
492 
493  // ---------------------------------------------------------------------
494  /// Primitive Connectivity @n
495 
496  /// These methods allow you to set up and cache primitive connectivity.
497  /// Each bit of primitive connectivity is added to a named group, like
498  /// 'wireframe' or 'shaded'. A connectivity group can have multiple
499  /// types of primitives or materials. Groups are indexed, using int ids.
500  /// You can pass an optional material to each set of connected prims. If
501  /// the material is null, it will use the last used material (which may be
502  /// the material of earlier connected primitives). Materials are not owned
503  /// by this class; the element arrays are. If 'replace' is true, any
504  /// previous connectivity established with the name 'connect_group'
505  /// will be removed and replaced with the new connectivity.
506  //@{
507 
508  /// Connect all primitives and place them in indexed group 'connect_index'
509  int connectAllPrims(RE_Render *r,
510  int connect_index,
511  RE_PrimType prim,
512  const RE_MaterialPtr &mat = nullptr,
513  bool replace = false,
514  int vertices_per_patch = 0);
515 
516  /// Connect a subrange of vertices and place in index group 'connect_index'
517  int connectSomePrims(RE_Render *r,
518  int connect_group,
519  RE_PrimType prim,
520  int start,
521  int length,
522  unsigned int stride = 0,
523  const RE_MaterialPtr &mat = nullptr,
524  bool replace = false,
525  int vertices_per_patch = 0);
526 
527  /// @brief Connect vertices using an indexed vertex list, add to 'connect_group'.
528  /// 'num' is the size of the list, not the number of primitives. If
529  /// any index is greater than the number of points in the geometry,
530  /// the results will be undefined. This is added to connect_group.
531  int connectIndexedPrims(RE_Render *r,
532  int connect_group,
533  RE_PrimType prim,
534  int num,
535  const unsigned int *prims,
536  const RE_MaterialPtr &mat = nullptr,
537  bool replace = false,
538  int vertices_per_patch = 0);
539 
540  /// Connect vertices using the indices in the buffer object 'elements'
541  int connectIndexedPrims(RE_Render *r,
542  int connect_group,
543  RE_PrimType prim,
544  RE_VertexArray *elements,
545  const RE_MaterialPtr &mat = nullptr,
546  bool replace = false,
547  int vertices_per_patch = 0);
548 
549  /// Connect vertices using the indices in the element array 'elements'
550  int connectIndexedPrims(RE_Render *r,
551  int connect_group,
552  RE_ElementArray *elements,
553  const RE_MaterialPtr &mat = nullptr,
554  bool replace = false);
555 
556 
557  /// Returns the number of discrete connectivities in 'connect_group'
558  int getConnectNumElementArrays(int connect_group);
559  /// Returns the element array associated with connect_group, if any.
560  RE_ElementArray *getConnectElementArray(int connect_group,
561  int index = 0);
562 
563  /// Returns true if the connectivity index 'connect_group' exists.
564  bool hasConnectGroup(int connect_group) const;
565 
566  bool hasNonEmptyConnectGroup(int connect_group) const;
567 
568  /// Returns the largest index of all the indexed connect groups. Some may
569  /// be nullptr.
570  int getMaxConnectGroup() const;
571 
572  /// Remove and delete the connection group specified, return false only if
573  /// the group doesn't exist.
574  bool removeConnectedPrims(int connect_group);
575 
576  /// Removes and deletes all connectivity groups.
577  void resetConnectedPrims();
578 
579  //@}
580 
581  /// Assign a new material to connectivity group 'connect_index'. The
582  /// connectivity group must exist or it will do nothing but return false.
583  bool assignMaterialToConnectivty(RE_Render *r,
584  int connect_index,
585  const RE_MaterialPtr &mat);
586 
587  /// Returns the material attached to the given connectivity group, if any.
588  /// If multiple connectivities were assigned to a group with different
589  /// materials, the subindex is used to select which connectivity is queried.
590  RE_MaterialPtr getConnectivityMaterial(int connect_index,
591  int subindex = 0);
592 
593  /// Methods to control which attributes are used when drawing a
594  /// connect_group. By default, all are enabled. When disabling an array or
595  /// attribute, it will return zero to the vertex shader.
596  //@{
597 
598  /// @brief Toggles the use of a generic vertex attribute for a connect
599  /// group. Index group version of useAttribute(); toggles the attribute
600  /// named 'name' on or off.
601  void useAttribute(int connect_group,
602  const char *name, bool enable);
603  /// @brief Toggles the use of a generic vertex attribute for a connect
604  /// group. Index group version of useAttribute(); toggles the attribute
605  /// specified by 'attrib' on or off.
606  void useAttribute(int connect_group,
607  RE_VertexArray *attrib, bool enable);
608 
609  // ---------------------------------------------------------------------
610 
611  /// Enables or disables textures on materials when drawn
612  void useMaterialTextures(bool enable = true);
613 
614  /// Clamp the number of layers to draw with a multi-layer material
615  void setNumMaterialLayers(int num);
616 
617  //@}
618 
619  // ---------------------------------------------------------------------
620 
621  /// @name Drawing
622  /// These methods draw connectivity groups that were previously set up,
623  /// with some modifications available.
624  /// If 'primtype' is not INVALID, it overrides the connectivity group's
625  /// primitive type. 'attrib_overrides' is a list of string pairs which
626  /// defines a mapping from shader attribute names (indices 0,2,4,6...)
627  /// to geometry attribute names (indices 1,3,5,7...).
628  //@{
629 
630  /// Draw an indexed connectivity group.
631  /// Draws the primitives specified by the cached connectibity info.
632  void draw(RE_Render *r,
633  int connect_idx,
634  RE_PrimType prim_type = RE_PRIM_AS_IS,
635  RE_OverrideList *attrib_overrides = nullptr)
636  {
637  drawPrivate(r, getConnect(connect_idx, false),0,
638  prim_type, attrib_overrides, 0);
639  }
640 
641  /// @brief Draw all connectivity groups.
642  /// Draws all connect_groups. Same as looping through all groups and calling
643  /// draw(). The draw order is undefined; if you need a specific order, use
644  /// multiple draw calls.
645  void drawAll(RE_Render *r,
646  RE_PrimType prim_type = RE_PRIM_AS_IS,
647  RE_OverrideList *attrib_overrides = nullptr);
648 
649  /// Draws all indexed connect groups in the range
650  /// if 'material_offset' is non-null, it acts as a offset when setting the
651  /// MATERIAL_GROUP uniform, which is added to (index-connect_group_start)
652  /// when drawing indexed connect groups. If num_connected_groups is
653  /// negative, all valid groups >= 'connect_group_start' are drawn,
654  /// otherwise it only draws up to `start+num-1`.
655  void drawRange(RE_Render *r,
656  int connect_group_start, int num_connect_groups,
657  RE_PrimType ptype = RE_PRIM_AS_IS,
658  RE_OverrideList *attrib_overrides = nullptr,
659  const int *material_offset = nullptr);
660 
661  /// @brief Draw with Instancing
662  /// Draws the same connect group 'num_instances' times. It is up to the
663  /// shader to differentiate the instances, using an instanced attribute
664  /// (createInstancedAttribute()) or GLSL's gl_InstanceID.
665  void drawInstanced(RE_Render *r,
666  int connect_idx,
667  int num_instances,
668  RE_PrimType prim_type = RE_PRIM_AS_IS,
669  RE_OverrideList *attrib_overrides = nullptr);
670 
671  /// Draw all connectivity groups using instancing, num_instance times.
672  void drawAllInstanced(RE_Render *r,
673  int num_instances,
674  RE_PrimType prim_type = RE_PRIM_AS_IS,
675  RE_OverrideList *attrib_overrides = nullptr);
676 
677  /// Draw a range of connectivity index groups with instancing
678  void drawRangeInstanced(RE_Render *r,
679  int connect_start, int num_connect,
680  int num_instances,
681  RE_PrimType prim_type = RE_PRIM_AS_IS,
682  RE_OverrideList *attrib_overrides = nullptr,
683  const int *material_offset = nullptr);
684 
685  /// Draw an instance group using a given connectivity
686  void drawInstanceGroup(RE_Render *r,
687  int connect_idx,
688  int instance_group,
689  RE_PrimType prim_type = RE_PRIM_AS_IS,
690  RE_OverrideList *attrib_over = nullptr);
691 
692  /// Draw an instance group using a given connectivity
693  void drawInstanceGroupRange(RE_Render *r,
694  int connect_start,
695  int num_connect,
696  int instance_group,
697  RE_PrimType prim_type = RE_PRIM_AS_IS,
698  RE_OverrideList *attrib_over = nullptr,
699  const int *material_offset = nullptr);
700  // Draw using parms from an indirect buffer (4 units).
701  // See GL_ARB_draw_indirect for more info. RE_EXT_DRAW_INDIRECT must be
702  // supported. The #prims & draw count in the connect group are ignored.
703  void drawIndirect(RE_Render *r,
704  int connect_group,
705  RE_VertexArray &indirect_buffer);
706 
707  //@}
708 
709  /// Manually enable and disable arrays. This is useful for determining
710  /// which ones are actually enabled via r->dumpNewState().
711  //@{
712  void enableArrays(RE_Render *r, int connect_group,
713  unsigned int stride = 0);
714  void disableArrays(RE_Render *r, int connect_group);
715  //@}
716 
717  /// @private Used by RE_Shader::prepShader.
718  void bindToVertexState(RE_Render *r,
719  RE_Shader *sh,
720  unsigned int stride,
721  RE_VertexState *vstate,
722  int instance_group);
723 
724  /// resets all VAOs so that on the next draw all VBOs are rebound
725  void resetVertexState(RE_Render *r);
726 
727  /// Remove all arrays and attributes from their GL bindings.
728  void unbindAllArrays(RE_Render *r);
729 
730  // --------------------------------------------------------------------
731  // For debug:
732 
733  // dumps the current configuration of the geometry object
734  // (out == nullptr will use std::cerr).
735  void print(std::ostream *out = nullptr) const;
736 
737  // For the next draw only, dump uniforms, builtin uniforms, and/or GL state.
738  void setDebugDraw(bool dump_uniforms,
739  bool dump_builtins,
740  bool dump_gl_state);
741 
742 private:
743 
744  RE_VertexArray *getBaseArray(RE_OverrideList *attrib_ovrrides
745  = nullptr) const;
746 
747  re_Connectivity *getConnect(int group_idx,
748  bool create_if_none);
749 
750  // Clears all the attached buffers. If this object is cached, all cached
751  // vertex arrays/buffers will remain in the cache.
752  void clearBuffers(bool connectivity_too = true);
753 
754  void bindBuffer(RE_Render *r,
755  RE_VertexArray *array,
756  unsigned int stride,
757  RE_Shader *sh,
758  const char *attrib_name);
759 
760  void unbindBuffer(RE_Render *r,
761  RE_VertexArray *array,
762  RE_Shader *sh,
763  const char *attrib_name);
764 
765  RE_VertexArray *getCachedVertexBuffer(RE_Render *r,
767  int tex_level,
768  const char *attrib_name,
769  RE_ArrayType array_type,
770  RE_GPUType data_format,
771  int vectorsize,
772  int length,
773  RE_VertexArray *target_array,
774  const char *cache_prefix);
775 
776  void freeArray(RE_VertexArray *&a, bool mark_unused = true);
777  void purgeArray(RE_VertexArray *&a, bool mark_unused = true);
778 
779  void assignAttribute(RE_VertexArray *a, int index);
780  void updateKnownAttrib(RE_VertexArray *a, bool set_known);
781  bool privAttachAttribute(RE_VertexArray *attrib, bool show_errors);
782 
783  static bool arrayDeleted(RE_VertexArray *a, void *data);
784 
785  RE_VertexArray * createNewAttribute(RE_Render *r,
786  const char *attrib_name,
787  RE_GPUType data_format,
788  int vectorsize,
789  int instance_stride,
791  int array_size = 0,
794  const char *cache_prefix = nullptr,
795  bool create_const_attrib = false,
796  int array_capacity = -1);
797 
798  RE_VertexArray *fetchCachedAttrib(RE_Render *r,
799  const char *attrib_name,
800  RE_GPUType data_format,
801  int vectorsize,
802  RE_ArrayType array_type,
803  int inst_step,
804  bool create_if_missing,
805  int array_size,
806  const RE_CacheVersion *cv,
808  const char *cache_prefix = nullptr,
809  int capacity = -1);
810  void drawPrivate(RE_Render *r,
811  re_Connectivity *connect,
812  int num_instances,
813  RE_PrimType prim_type,
814  RE_OverrideList *override_attrib,
815  int instance_group,
816  bool indirect = false);
817 
818  RE_OGLTexture *prepTexBufferArray(RE_Render *r,
819  RE_VertexArray *array,
820  RE_GPUType buftype,
821  int &pmode);
822  void privEnableArrays(
823  RE_Render *r,
824  re_Connectivity *connect,
825  unsigned int stride = 0,
826  RE_OverrideList *attrib_overrides = nullptr,
827  int instance_group = 0);
828  void privDisableArrays(
829  RE_Render *r,
830  re_Connectivity *connect,
831  RE_OverrideList *attrib_overrides = nullptr);
832  void privUseAttrib(
833  re_Connectivity *connect,
834  const char *attrib_name,
835  bool enable);
836 
837  void addToInstanceGroup(RE_VertexArray *attrib,
838  int group = -1);
839  void removeFromInstanceGroup(RE_VertexArray *attrib);
840 
841 // DATA:
842  int myNumPoints;
843  int myNumVertices;
844  int myNumPrimitives;
845  RE_VertexMap *myVertexMap;
846  mutable int myAttribPIndex;
847  bool myUseVertexState;
848  bool myPurgeOnDelete;
849  int myVertexStateSerial;
850  UT_String myCacheName;
851  bool myUseTextures;
852  int myNumMaterialLayers;
853 
854  UT_ValArray<RE_VertexArray *> myAttributes;
855 
856  UT_ValArray<RE_VertexArray *> myTextureAttributes;
857  UT_ValArray<RE_Texture *> myBufferTextures;
858 
859  UT_ValArray<RE_VertexArray *> myKnownAttributes;
860  UT_ValArray<RE_VertexArray *> myStashedAttributes;
861 
862  UT_ValArray<re_Connectivity *> myConnectGroups;
863  UT_Array<re_InstanceGroup *> myInstanceGroups;
864 
865  RE_CacheTagHandle myCacheTagHandle;
866 
867  int myDebugDrawFlags;
868 
869  friend class re_InstanceGroup;
870 };
871 
872 inline void
874 {
875  myUseTextures = enable;
876 }
877 
878 inline void
880 {
881  myNumMaterialLayers = SYSclamp(num, 1, 32);
882 }
883 
884 inline RE_VertexArray *
886  const char *attrib_name,
887  RE_GPUType data_format,
888  int vectorsize,
889  RE_ArrayType array_type,
890  bool create_if_missing,
891  int array_size,
892  const RE_CacheVersion *cache_version,
894  const char *cache_prefix,
895  int capacity)
896 {
897  return fetchCachedAttrib(r, attrib_name, data_format, vectorsize,
898  array_type, 0, create_if_missing,
899  array_size, cache_version, usage,
900  cache_prefix, capacity);
901 }
902 
903 inline RE_VertexArray *
905  const char *attrib_name,
906  RE_GPUType data_format,
907  int vectorsize,
908  int inst_step,
909  int array_size,
910  bool create_if_missing,
911  const RE_CacheVersion *cache_version,
913  const char *cache_prefix,
914  int capacity)
915 {
916  return fetchCachedAttrib(r, attrib_name, data_format, vectorsize,
917  RE_ARRAY_INSTANCE, inst_step,
918  create_if_missing, array_size,
919  cache_version, usage, cache_prefix, capacity);
920 }
921 
922 inline RE_VertexArray *
924 {
925  return (id > RE_GENATTRIB_NONE) ? myKnownAttributes(id) : nullptr;
926 }
927 
928 #endif
929 
int getNumInstanceGroups() const
Create a new instance group. instance_group must be a positive int.
Definition: RE_Geometry.h:384
void useMaterialTextures(bool enable=true)
Enables or disables textures on materials when drawn.
Definition: RE_Geometry.h:873
GLsizei GLenum const void * indices
Definition: glcorearb.h:406
const void * indirect
Definition: glcorearb.h:1795
#define RE_API
Definition: RE_API.h:10
const GLdouble * v
Definition: glcorearb.h:837
void purgeOnDelete(bool purge=true)
Remove all buffers from the cache when this geometry object is deleted.
Definition: RE_Geometry.h:316
GLuint start
Definition: glcorearb.h:475
void setNumMaterialLayers(int num)
Clamp the number of layers to draw with a multi-layer material.
Definition: RE_Geometry.h:879
A collection of vertex arrays defining a geometry object. This class acts as a wrapper around multipl...
Definition: RE_Geometry.h:52
void draw(RE_Render *r, int connect_idx, RE_PrimType prim_type=RE_PRIM_AS_IS, RE_OverrideList *attrib_overrides=nullptr)
Definition: RE_Geometry.h:632
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
const RE_VertexMap * getVertexMap() const
Return a vertex map representing the layout locations of the attributes.
Definition: RE_Geometry.h:240
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
bool isCaching() const
Check if this geometry object is caching.
Definition: RE_Geometry.h:313
RE_GenericAttribID
Definition: RE_Types.h:355
RE_GPUType
Definition: RE_Types.h:52
RE_BufferType
Definition: RE_Types.h:291
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
RE_Texture * getAddressableAttributeTexture(int index) const
Return the texture buffer object representing addressable attribute 'i'.
Definition: RE_Geometry.h:286
std::string OIIO_UTIL_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
Definition: UT_Vector3.h:1057
RE_VertexArray * getAddressableAttributeByIndex(int index) const
Return the vertex arrayrepresenting addressable attribute 'i'.
Definition: RE_Geometry.h:289
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
RE_VertexArray * findCachedInstancedAttrib(RE_Render *r, const char *attrib_name, RE_GPUType data_format, int vectorsize, int instance_step, int array_size, bool create_if_missing=false, const RE_CacheVersion *v=nullptr, RE_BufferUsageHint h=RE_BUFFER_WRITE_FREQUENT, const char *cache_prefix=nullptr, int capacity=-1)
Find an instanced attribute in the GL cache, possibly creating it. The instance_step parameter define...
Definition: RE_Geometry.h:904
long long int64
Definition: SYS_Types.h:116
GLuint const GLchar * name
Definition: glcorearb.h:786
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLuint shader
Definition: glcorearb.h:785
GLsizeiptr const void GLenum usage
Definition: glcorearb.h:664
int getNumVertices() const
Sets the number of elements in arrays declared as RE_ARRAY_VERTEX.
Definition: RE_Geometry.h:91
int getNumPoints() const
Number of points in the geometry. Number of points for the arrays declared as RE_ARRAY_POINT. This will clear the data in all point arrays and reset the connectivty.
Definition: RE_Geometry.h:85
GLuint index
Definition: glcorearb.h:786
int getNumAddressableAttributes() const
Return the number of addressable attributes.
Definition: RE_Geometry.h:282
RE_ArrayType
Definition: RE_Types.h:344
RE_BufferUsageHint
Definition: RE_Types.h:303
const char * getCacheName() const
Return the base cache name.
Definition: RE_Geometry.h:310
Simple class for a mutli-integer cache tag.
GLboolean r
Definition: glcorearb.h:1222
RE_VertexArray * getAttribute(const char *name) const
Fetch an attribute by name.
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
int getNumPrimitives() const
Sets the number of elements in arrays declared as RE_ARRAY_PRIMITIVE.
Definition: RE_Geometry.h:97
RE_PrimType
Definition: RE_Types.h:199
RE_VertexArray * findCachedAttrib(RE_Render *r, const char *attrib_name, RE_GPUType data_format, int vectorsize, RE_ArrayType array_type, bool create_if_missing=false, int random_array_size=-1, const RE_CacheVersion *cv=nullptr, RE_BufferUsageHint h=RE_BUFFER_WRITE_FREQUENT, const char *cache_prefix=nullptr, int capacity=-1)
Find an attribute or array in the GL cache, possibly creating it Returns the cached array...
Definition: RE_Geometry.h:885
Definition: format.h:1821