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