HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_VertexArray.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_VertexArray.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * These classes provide a GL-indepedent way of specify vertex attributes
10  * in array or constant form. Array attributes use VBOs, whereas constant
11  * attributes use glVertexAttrib*() calls.
12  */
13 #ifndef RE_VERTEX_ARRAY_H
14 #define RE_VERTEX_ARRAY_H
15 
16 class RE_Render;
17 class RE_ElementArray;
18 class RE_OGLConstAttribute;
19 
20 #include "RE_CachedObject.h"
21 #include "RE_Types.h"
22 #include "RE_Texture.h"
23 #include "RE_OGLBuffer.h"
24 #include <UT/UT_NonCopyable.h>
25 #include <UT/UT_StringHolder.h>
26 #include <UT/UT_UniquePtr.h>
27 #include <UT/UT_WorkBuffer.h>
28 #include <iosfwd>
29 
30 // Base class for various array types.
32 {
33 public:
34  // Returns a new vertex array
35  static RE_VertexArray *newAttribArray(const UT_StringHolder &name,
36  int num_elements=0,
37  const char *cachename = nullptr,
39  int capacity = 0);
40 
41  static RE_VertexArray *newElementArray(int num_elements=0,
42  const char *cachename = nullptr,
43  int capacity = 0);
44 
45  // Creates a container RE_VertexArray around the passed array.
46  static RE_VertexArray *newArrayContainer(RE_OGLBufferHandle &array,
47  const char *cachename = nullptr,
49 
50  static RE_VertexArray *newArrayContainer(UT_Array<RE_OGLBufferHandle>&array,
51  const char *cachename = nullptr,
53 
54  // Returns the cache name
55  static void getAttribCacheName(UT_WorkBuffer &str,
56  const char *name,
57  RE_ArrayType attrib_type,
58  const char *cachename);
59 
60  ~RE_VertexArray();
61 
62  // Creates a new RE_VertexArray with exactly the same format and
63  // buffer references.
64  UT_UniquePtr<RE_VertexArray> clone() const;
65 
66  /// Returns the amount of main memory (NOT graphics memory!)
67  /// owned by this RE_VertexArray.
68  int64 getMemoryUsage(bool inclusive) const;
69 
70  // add this buffer to the GL cache using a tag of 'name'/attribname
71  void cacheBuffer(const UT_StringHolder &name)
72  { myCacheName = name; }
73  const char *getCacheName() const { return myCacheName; }
74 
75  // Set the version number on the cached buffer.
76  void setCacheVersion(RE_CacheVersion v);
77  RE_CacheVersion getCacheVersion() const;
78 
79  void allowShared(bool shared) { myAllowShared = shared; }
80 
81  // Indicate if this array is actively in use by the cache.
82  void markAsUsed();
83  void markAsUnused(bool move_to_unused_cache = true);
84  bool isUsed() const { return myInUse; }
85 
86  // sets the cache tag on underlying arrays. The cache tag is used to notify
87  // other entities when the array is evicted from the cache.
88  void setCacheTag(RE_CacheTagHandle h);
89 
90  /// Hint to the GL driver how this buffer will be used. May only be set
91  /// before the buffer is created (initialize(), setArray(), etc).
92  void setUsage(RE_BufferUsageHint h);
93 
94  /// Set the buffer to use persistent mapped buffers, optionally with
95  /// coherent behaviour (writes seen automatically). RE_EXT_BUFFER_STORAGE
96  /// must be supported, or false will be returned and the setting will have
97  /// no effect.
98  void setPersistent(RE_PersistentBufferMode mode);
99 
100  // assigns 'num' buffers to this vertex array, cachable with 'cachename'.
101  void adoptArrays(const UT_Array<RE_OGLBufferHandle> &buffers,
102  const UT_StringHolder &cachename);
103 
104  // Removes all contained arrays, possibly deleting them if not cached.
105  void resetBuffer(bool delete_cached = false,
106  bool mark_as_unused = true);
107 
108  // If the size, type or format of the buffer is changed, this method can
109  // ensure that the underlying array is initialized afterward. 'created'
110  // can be used to query if a new buffer was allocated by this method.
111  bool initialize(RE_Render *r, bool *created = nullptr);
112 
113  // Allows some extra data to be cached with the buffer. Caching must be
114  // enabled, and this can't be a constant attribute (no buffer).
115  // Owndership of the data is always given up, and it will be deleted when
116  // the buffer is.
117  bool setExtraBufferData(RE_CachedExtraData *data);
118  RE_CachedExtraDataHandle getExtraBufferData() const;
119 
120  // Setup
121  // standard GL attributes use the buffer types
122  void setBufferType(RE_BufferType type);
123 
124  // custom attributes are referenced by name.
125  void setAttributeName(const char *attrib);
126 
127  // Sets the data type for the array. This type is one array 'element'.
128  // If normalized is true, fixed formats will be normalized to [0,1]
129  void setFormat(RE_GPUType type, int vectorsize,
130  bool normalized = true);
131 
132  // Sets the length of the array, in elements (a fp32 vec3 is 1 element)
133  void setLength(int len);
134 
135  // Sets the total capacity of the array, in elements (a fp32 vec3 is 1
136  // element). Length may be less than this.
137  bool setCapacity(int cap);
138 
139  // If non-zero, this attribute advances once every 'nprims' number of
140  // primitives instead of once per vertex. RE_EXT_INSTANCED_ARRAYS required.
141  void setInstanceStride(int nprims);
142 
143  // if non-negative, specifies an instance draw group to which this belongs
144  void setInstanceGroup(int instance_group)
145  { myInstanceGroup = instance_group; }
146 
147  // Sets the sampling frequency of this array - either per point, vertex,
148  // primitive, instance or randomly accessed.
149  void setArrayType(RE_ArrayType t) { myArrayType = t; }
150 
151  // Array data methods
152 
153  // Specifies all the data at once, or a subrange of the data if sublen!=0.
154  // offset and sublen are specified in elements, not bytes.
155  bool setArray(RE_Render *r,
156  const void *data,
157  int offset = 0,
158  int sublen = 0,
159  int array_index = 0);
160 
162  const void *data,
163  int array_index = 0)
164  { return setArray(r,data, 0,myLength, array_index); }
165 
167  const void *data,
168  int offset,
169  int length,
170  int array_index)
171  { return setArray(r, data, offset, length, array_index); }
172 
173 
174  // fetch data from a buffer, starting at element 'offset' for 'sublen'
175  // elements (the size of an element depends on the format & type). If
176  // sublen is zero, it will fetch to the end of the buffer.
177  bool getArray(RE_Render *r,
178  void *data,
179  int offset = 0,
180  int sublen = 0,
181  int array_index = 0) const;
182 
183  // Cuts loose the current buffer and recreates a new one. Will still
184  // maintain the same buffer ID, but the underlying chunk of memory will be
185  // handed off to the driver.
186  void orphan(RE_Render *r);
187 
188  // The attribute is constant-valued. Data must be big enough to fill one
189  // element, and the data is always FP. Constant values cannot be mapped.
190  void setConstant(const fpreal32 *data);
191  void setConstant(const fpreal64 *data);
192 
193  // Ensure that a constant is created without assigning any data.
194  void createConstant();
195 
196  // Internally constant data is stored as double.
197  fpreal64 *getConstant();
198  const fpreal64 *getConstant() const;
199 
200  // Indicate that the vertex array is a default value placeholder.
201  void markAsDefaultValue(bool def) { myDefaultValue = def; }
202  bool isDefaultValue() const { return myDefaultValue; }
203 
204  // Returns a pointer to the array so it can be modified. must call unmap()
205  // when finished, before attempting to use the array again. This maps the
206  // entire buffer, so in some instances it may be better to use setArray()
207  // with a subrange.
208  // NOTE: map()/unmap() is generally slower than setArray(), so use only
209  // for reading or persistent buffers.
210  void *map(RE_Render *r,
212  int array_index = 0);
213  void *mapRange(RE_Render *r, int start, int length,
215  int array_index = 0);
216  void unmap(RE_Render *r, int array_index = 0);
217 
218  // For persistent mapped buffers, this returns the currently mapped data.
219  // Will only return a value if mapped, persisent is set, and
220  // RE_EXT_BUFFER_STORAGE is supported.
221  void *getPersistentMap(int array_index = 0) const;
222 
223  // Returns true if this is a persistently mapped buffer
224  bool isPersistentMap() const;
225 
226  // Zero the buffer.
227  void zero(RE_Render *r);
228 
229  // Attach a texture buffer object to a VERTEX, PRIM or RANDOM array type.
230  bool attachTexBuffer(RE_Render *r,
231  RE_Texture *tex);
232 
233  // Return the TBO attached to a VERTEX, PRIM or RANDOM array type.
234  RE_Texture *getTextureBufferObject() const; // inlined below
235 
236  // Binding methods
237 
238  // Binds the array to the given array attribute type for subsequent draw
239  // calls. When drawing with multiple attributes, the first N-1 should be
240  // bound, and the Nth should call draw...Prims().
241  // geo_obj is only true when called from RE_Geometry.
242  bool bind(RE_Render *r, unsigned int stride = 0,
243  bool geo_obj=false,
244  const char *shader_attrib = nullptr);
245  bool unbind(RE_Render *r);
246 
247  // Rebinds an array to a new attribute location due to a shader change.
248  bool rebindAttrib(RE_Render *r, int location);
249  bool unbindAttrib(RE_Render *r);
250 
251  // Bind to a VAO.
252  bool setupForAttribIndex(RE_Render *r, int attrib_location,
253  RE_GPUType t, int stride);
254 
255 
256  // These bind methods bind the buffer to the specificied buffer binding
257  // point, which may be different than the buffer type's default binding
258  // point. Some binding points are indexed (uniform and transform feedback)
259  // while most have a single binding point.
260  bool bindBuffer(RE_Render *r, RE_BufferBinding point, int index=0,
261  int array_index=0);
262  bool unbindBuffer(RE_Render *r, RE_BufferBinding point, int index=0,
263  int array_index=0);
264 
265  // Drawing methods
266 
267  // Draws primitives using every n'th point (where n=stride) in this array
268  // as 'prim' primitive type.
269  void drawPrims(RE_Render *r,
270  RE_PrimType prim,
271  unsigned int stride,
272  int num_instances,
273  bool enable_arrays,
274  int vertices_per_patch);
275 
276  // Draws primitives using a subrange of points in this array
277  void drawSomePrims(RE_Render *r,
278  RE_PrimType prim,
279  int start,
280  int num,
281  int num_instances,
282  bool enable_arrays,
283  int vertices_per_patch);
284 
285  // Draws primitives using some points in this array using a 2nd array as
286  // the indices. The array must be an element array.
287  void drawSomePrims(RE_Render *r,
288  RE_PrimType prim,
289  RE_VertexArray *index_array,
290  int index_offset,
291  int index_num_elements,
292  int num_instances,
293  bool enable_arrays,
294  int vertices_per_patch);
295 
296  // Query
297  RE_BufferType getBufferType() const { return myBufferType; }
298  RE_GPUType getDataType() const { return myType; }
299  int getVectorSize() const { return myVectorSize; }
300  int getLength() const { return myLength; }
301  int getLengthScale() const { return myLengthScale; }
302  int getCapacity() const { return myCapacity; }
303  int getNumBuffers() const { return myArray.entries(); }
304  const RE_OGLBufferHandle &getArrayBuffer(int i=0) const
305  { return (i < myArray.entries()) ? myArray(i) : theNullArray; }
306  const char *getAttributeName() const { return myAttribName; }
307  RE_ArrayType getArrayType() const { return myArrayType; }
308  bool isBufferBound(int array_index=0) const;
309  bool isConstantBuffer() const { return myConstantFlag; }
310  void getHoudiniName(UT_StringHolder &name) const;
311  void getGLName(UT_StringHolder &name) const;
312  int getInstanceStride() const { return myInstanceStride; }
313  int getInstanceGroup() const { return myInstanceGroup; }
314 
315  int64 getSizeBytes() const;
316 
317  // Debugging prints
318  void print(std::ostream *os = nullptr) const;
319  void printValues(RE_Render *r, std::ostream &os,
320  int start=0, int len=0) const;
321 
322  void addRef(void (*callback)(void *), void *data);
323  void removeRef(void (*callback)(void *), void *data);
324 
325  // Some attributes are 'known' types, as listed in RE_GenericAttribID.
326  // Setting the ID can help performance. Do not change the type of an attrib
327  // while bound to an RE_Geometry; this should only be called once.
329  { UT_ASSERT(myGenID == RE_GENATTRIB_UNDEF || myGenID == id);
330  myGenID = id; }
331  RE_GenericAttribID getGenericID() const { return myGenID; }
332 
333 protected:
334  RE_VertexArray(RE_BufferType type, int nelements = 0, int capacity = 0);
335  RE_VertexArray(const UT_StringHolder &name, int nelements = 0,
336  int capacity= 0 );
337 
338  RE_VertexArray(const RE_VertexArray &va); // used only by clone()
339  RE_VertexArray &operator=(const RE_VertexArray &va) = delete;
340 
341  void detachTexBuffer(int index);
342  void generateCacheName(UT_StringHolder &cachename,
343  int index) const;
344 
350  int myLength;
356  RE_OGLConstAttribute *myConstAttrib;
359  bool myInUse;
360 
361  bool myMappedFlag[4];
371 
373  {
374  public:
375  re_VertexArrayCB(void (*cb)(void *),void *d) : callback(cb), data(d) {}
376  void (*callback)(void *);
377  void *data;
378  };
379 
381 };
382 
383 inline RE_Texture *
385 {
386  return (myArray.entries() == 1) ? myArray(0)->getTBO() : nullptr;
387 }
388 
389 /// Shallow reference to an RE_VertexArray. Will be cleared if the
390 /// RE_VertexArray is deleted.
392 {
393 public:
394  RE_VertexArrayRef() : myArray(nullptr) {}
396 
398 
399  bool isValid() { return myArray!=nullptr; }
400  void operator=(RE_VertexArray &va);
401  void clear();
402  RE_VertexArray *get() { return myArray; }
403  const RE_VertexArray *get() const { return myArray; }
405  {
406  UT_ASSERT(myArray);
407  return myArray;
408  }
409  const RE_VertexArray *operator->() const
410  {
411  UT_ASSERT(myArray);
412  return myArray;
413  }
414 
415 private:
416  static void arrayDeleted(void *);
417 
418  RE_VertexArray *myArray;
419 };
420 
421 #endif
bool replaceArrayRange(RE_Render *r, const void *data, int offset, int length, int array_index)
RE_GenericAttribID getGenericID() const
UT_StringHolder myAttribName
int getNumBuffers() const
#define RE_API
Definition: RE_API.h:10
void
Definition: png.h:1083
void setArrayType(RE_ArrayType t)
const RE_VertexArray * operator->() const
const GLdouble * v
Definition: glcorearb.h:837
int getLength() const
GLuint start
Definition: glcorearb.h:475
UT_Array< re_VertexArrayCB > myRefs
void cacheBuffer(const UT_StringHolder &name)
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
bool isDefaultValue() const
UT_StringHolder myCacheName
RE_PersistentBufferMode myPersistentBufferMode
RE_ArrayType myArrayType
RE_GenericAttribID myGenID
float fpreal32
Definition: SYS_Types.h:200
OutGridT const XformOp bool bool
RE_OGLConstAttribute * myConstAttrib
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
double fpreal64
Definition: SYS_Types.h:201
const char * getAttributeName() const
RE_GenericAttribID
Definition: RE_Types.h:355
RE_GPUType
Definition: RE_Types.h:52
RE_BufferType
Definition: RE_Types.h:291
RE_BufferType myBufferType
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
bool isConstantBuffer() const
GLintptr offset
Definition: glcorearb.h:665
RE_BufferBinding
Definition: RE_Types.h:328
RE_CacheTagHandle myCacheTagHandle
RE_GPUType getDataType() const
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2222
void setGenericID(RE_GenericAttribID id)
void allowShared(bool shared)
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
const GLuint * buffers
Definition: glcorearb.h:661
Wrapper around hboost::intrusive_ptr.
long long int64
Definition: SYS_Types.h:116
GLint location
Definition: glcorearb.h:805
GLuint id
Definition: glcorearb.h:655
int getLengthScale() const
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
GLint GLenum GLboolean normalized
Definition: glcorearb.h:872
bool replaceArray(RE_Render *r, const void *data, int array_index=0)
int getInstanceStride() const
bool myPersistentMapCopied
GLdouble t
Definition: glad.h:2397
GLenum mode
Definition: glcorearb.h:99
int getCapacity() const
RE_BufferUsageHint myUsage
void markAsDefaultValue(bool def)
static RE_OGLBufferHandle theNullArray
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
re_VertexArrayCB(void(*cb)(void *), void *d)
RE_BufferAccess
Definition: RE_Types.h:321
LeafData & operator=(const LeafData &)=delete
bool isUsed() const
GLuint index
Definition: glcorearb.h:786
const RE_OGLBufferHandle & getArrayBuffer(int i=0) const
RE_VertexArray * operator->()
RE_ArrayType
Definition: RE_Types.h:344
const char * getCacheName() const
RE_ArrayType getArrayType() const
RE_Texture * getTextureBufferObject() const
RE_BufferUsageHint
Definition: RE_Types.h:303
Simple class for a mutli-integer cache tag.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
OutGridT XformOp bool bool shared
RE_GPUType myType
GLboolean r
Definition: glcorearb.h:1222
UT_Array< RE_OGLBufferHandle > myArray
int getInstanceGroup() const
int getVectorSize() const
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
RE_BufferType getBufferType() const
RE_PrimType
Definition: RE_Types.h:199
RE_PersistentBufferMode
Definition: RE_Types.h:548
Definition: format.h:1821
void setInstanceGroup(int instance_group)