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 
195  // Indicate that the vertex array is a default value placeholder.
196  void markAsDefaultValue(bool def) { myDefaultValue = def; }
197  bool isDefaultValue() const { return myDefaultValue; }
198 
199  // Returns a pointer to the array so it can be modified. must call unmap()
200  // when finished, before attempting to use the array again. This maps the
201  // entire buffer, so in some instances it may be better to use setArray()
202  // with a subrange.
203  // NOTE: map()/unmap() is generally slower than setArray(), so use only
204  // for reading or persistent buffers.
205  void *map(RE_Render *r,
207  int array_index = 0);
208  void *mapRange(RE_Render *r, int start, int length,
210  int array_index = 0);
211  void unmap(RE_Render *r, int array_index = 0);
212 
213  // For persistent mapped buffers, this returns the currently mapped data.
214  // Will only return a value if mapped, persisent is set, and
215  // RE_EXT_BUFFER_STORAGE is supported.
216  void *getPersistentMap(int array_index = 0) const;
217 
218  // Returns true if this is a persistently mapped buffer
219  bool isPersistentMap() const;
220 
221  // Zero the buffer.
222  void zero(RE_Render *r);
223 
224  // Attach a texture buffer object to a VERTEX, PRIM or RANDOM array type.
225  bool attachTexBuffer(RE_Render *r,
226  RE_Texture *tex);
227 
228  // Return the TBO attached to a VERTEX, PRIM or RANDOM array type.
229  RE_Texture *getTextureBufferObject() const; // inlined below
230 
231  // Binding methods
232 
233  // Binds the array to the given array attribute type for subsequent draw
234  // calls. When drawing with multiple attributes, the first N-1 should be
235  // bound, and the Nth should call draw...Prims().
236  // geo_obj is only true when called from RE_Geometry.
237  bool bind(RE_Render *r, unsigned int stride = 0,
238  bool geo_obj=false,
239  const char *shader_attrib = NULL);
240  bool unbind(RE_Render *r);
241 
242  // Rebinds an array to a new attribute location due to a shader change.
243  bool rebindAttrib(RE_Render *r, int location);
244  bool unbindAttrib(RE_Render *r);
245 
246  // Bind to a VAO.
247  bool setupForAttribIndex(RE_Render *r, int attrib_location,
248  RE_GPUType t, int stride);
249 
250 
251  // These bind methods bind the buffer to the specificied buffer binding
252  // point, which may be different than the buffer type's default binding
253  // point. Some binding points are indexed (uniform and transform feedback)
254  // while most have a single binding point.
255  bool bindBuffer(RE_Render *r, RE_BufferBinding point, int index=0,
256  int array_index=0);
257  bool unbindBuffer(RE_Render *r, RE_BufferBinding point, int index=0,
258  int array_index=0);
259 
260  // Drawing methods
261 
262  // Draws primitives using every n'th point (where n=stride) in this array
263  // as 'prim' primitive type.
264  void drawPrims(RE_Render *r,
265  RE_PrimType prim,
266  unsigned int stride,
267  int num_instances,
268  bool enable_arrays,
269  int vertices_per_patch);
270 
271  // Draws primitives using a subrange of points in this array
272  void drawSomePrims(RE_Render *r,
273  RE_PrimType prim,
274  int start,
275  int num,
276  int num_instances,
277  bool enable_arrays,
278  int vertices_per_patch);
279 
280  // Draws primitives using some points in this array using a 2nd array as
281  // the indices. The array must be an element array.
282  void drawSomePrims(RE_Render *r,
283  RE_PrimType prim,
284  RE_VertexArray *index_array,
285  int index_offset,
286  int index_num_elements,
287  int num_instances,
288  bool enable_arrays,
289  int vertices_per_patch);
290 
291  // Query
292  RE_BufferType getBufferType() const { return myBufferType; }
293  RE_GPUType getDataType() const { return myType; }
294  int getVectorSize() const { return myVectorSize; }
295  int getLength() const { return myLength; }
296  int getLengthScale() const { return myLengthScale; }
297  int getCapacity() const { return myCapacity; }
298  int getNumBuffers() const { return myArray.entries(); }
299  const RE_OGLBufferHandle &getArrayBuffer(int i=0) const
300  { return (i < myArray.entries()) ? myArray(i) : theNullArray; }
301  const char *getAttributeName() const { return myAttribName; }
302  RE_ArrayType getArrayType() const { return myArrayType; }
303  bool isBufferBound(int array_index=0) const;
304  bool isConstantBuffer() const { return myConstantFlag; }
305  void getHoudiniName(UT_StringHolder &name) const;
306  void getGLName(UT_StringHolder &name) const;
307  int getInstanceStride() const { return myInstanceStride; }
308  int getInstanceGroup() const { return myInstanceGroup; }
309 
310  int64 getSizeBytes() const;
311 
312  // Debugging prints
313  void print(std::ostream *os = nullptr) const;
314  void printValues(RE_Render *r, std::ostream &os,
315  int start=0, int len=0) const;
316 
317  void addRef(void (*callback)(void *), void *data);
318  void removeRef(void (*callback)(void *), void *data);
319 
320  // Some attributes are 'known' types, as listed in RE_GenericAttribID.
321  // Setting the ID can help performance. Do not change the type of an attrib
322  // while bound to an RE_Geometry; this should only be called once.
324  { UT_ASSERT(myGenID == RE_GENATTRIB_UNDEF || myGenID == id);
325  myGenID = id; }
326  RE_GenericAttribID getGenericID() const { return myGenID; }
327 
328 protected:
329  RE_VertexArray(RE_BufferType type, int nelements = 0, int capacity = 0);
330  RE_VertexArray(const UT_StringHolder &name, int nelements = 0,
331  int capacity= 0 );
332  RE_VertexArray(const RE_VertexArray &va);
333 
334  void detachTexBuffer(int index);
335  void generateCacheName(UT_StringHolder &cachename,
336  int index) const;
337 
343  int myLength;
349  RE_OGLConstAttribute *myConstAttrib;
352  bool myInUse;
353 
354  bool myMappedFlag[4];
363 
365  {
366  public:
367  re_VertexArrayCB(void (*cb)(void *),void *d) : callback(cb), data(d) {}
368  void (*callback)(void *);
369  void *data;
370  };
371 
373 };
374 
375 inline RE_Texture *
377 {
378  return (myArray.entries() == 1) ? myArray(0)->getTBO() : NULL;
379 }
380 
381 /// Shallow reference to an RE_VertexArray. Will be cleared if the
382 /// RE_VertexArray is deleted.
384 {
385 public:
386  RE_VertexArrayRef() : myArray(NULL) {}
388 
389  bool isValid() { return myArray!=NULL; }
390  void operator=(RE_VertexArray &va);
391  void clear();
392  RE_VertexArray *get() { return myArray; }
394  {
395  UT_ASSERT(myArray);
396  return myArray;
397  }
398 
399 private:
400  static void arrayDeleted(void *);
401 
402  RE_VertexArray *myArray;
403 };
404 
405 #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 setArrayType(RE_ArrayType t)
int getLength() const
const GLdouble * v
Definition: glcorearb.h:836
GLuint start
Definition: glcorearb.h:474
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
UT_Array< re_VertexArrayCB > myRefs
void cacheBuffer(const UT_StringHolder &name)
bool isDefaultValue() const
UT_StringHolder myCacheName
RE_PersistentBufferMode myPersistentBufferMode
RE_ArrayType myArrayType
RE_GenericAttribID myGenID
png_uint_32 i
Definition: png.h:2877
RE_OGLConstAttribute * myConstAttrib
GLuint id
Definition: glcorearb.h:654
const char * getAttributeName() const
RE_GenericAttribID
Definition: RE_Types.h:323
long long int64
Definition: SYS_Types.h:107
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
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2221
void setGenericID(RE_GenericAttribID id)
double fpreal64
Definition: SYS_Types.h:192
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:871
GLintptr offset
Definition: glcorearb.h:664
Wrapper around hboost::intrusive_ptr.
GLint location
Definition: glcorearb.h:804
int getLengthScale() const
GLboolean * data
Definition: glcorearb.h:130
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:318
GLuint const GLchar * name
Definition: glcorearb.h:785
GLint GLenum GLboolean normalized
Definition: glcorearb.h:871
bool replaceArray(RE_Render *r, const void *data, int array_index=0)
int getInstanceStride() const
bool myPersistentMapCopied
GLenum mode
Definition: glcorearb.h:98
int getCapacity() const
const GLuint * buffers
Definition: glcorearb.h:660
RE_BufferUsageHint myUsage
void markAsDefaultValue(bool def)
static RE_OGLBufferHandle theNullArray
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
re_VertexArrayCB(void(*cb)(void *), void *d)
RE_BufferAccess
Definition: RE_Types.h:293
bool isUsed() const
GLuint index
Definition: glcorearb.h:785
const RE_OGLBufferHandle & getArrayBuffer(int i=0) const
RE_VertexArray * operator->()
RE_ArrayType
Definition: RE_Types.h:312
const char * getCacheName() const
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
RE_ArrayType getArrayType() const
RE_Texture * getTextureBufferObject() const
RE_BufferUsageHint
Definition: RE_Types.h:275
png_infop png_uint_32 int num
Definition: png.h:2158
Simple class for a mutli-integer cache tag.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
RE_GPUType myType
GLboolean r
Definition: glcorearb.h:1221
UT_Array< RE_OGLBufferHandle > myArray
int getInstanceGroup() const
int getVectorSize() const
RE_BufferType getBufferType() const
RE_PrimType
Definition: RE_Types.h:193
float fpreal32
Definition: SYS_Types.h:191
RE_PersistentBufferMode
Definition: RE_Types.h:504
void setInstanceGroup(int instance_group)
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794