HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_OGLBuffer.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_OGLBuffer.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * Buffer objects are merely registered chunks of memory that is
10  * managed by the graphics driver. Although the come in different
11  * flavours, they are all created and accessed in the same way.
12  *
13  * One buffer object represents one type of data - texture coords,
14  * point positions, pixels or colors. There are two main types in terms
15  * of usage, vertex and pixel buffers.
16  *
17  * 1. Vertex-oriented buffers are used in lieu of glVertex, glNormal,
18  * glColor, etc.. They are much more efficient in that you can send
19  * a lot of data with one call, and you can update parts of the
20  * list instead of rewriting the entire list. They are used in
21  * conjunction with glDrawArrays() to create geometry. As an example:
22  *
23  * RE_OGLAttributeBuffer vBuf("P", nVertices);
24  * RE_OGLAttributeBuffer texBuf("uv", nVertices);
25  *
26  * vBuf.setData(vertex_list);
27  * texBuf.setData(tex_coord_list); // you can free the lists after this
28  *
29  * vBuf.enable();
30  * texBuf.enable();
31  *
32  * r->getExt()->glDrawArrays(GL_TRIANGLES, 0, nVertices);
33  *
34  * vBuf.disable();
35  * texBuf.disable();
36  *
37  * The data is always assumed to be interleaved (xyzxyz...)
38  *
39  * 2. Pixel buffers are used to write and rewrite pixel data to a GL structure
40  * (normally a texture). In this case, there use is slighly different.
41  * Instead of passing the image data directly to glTexImage...(), you
42  * pass NULL and instead enable the pixel buffer first. Ex:
43  *
44  * RE_OGLPixelWriteBuffer pBuf(xres, yres);
45  *
46  * pBuf.setFormat(RE_GPU_UINT8, 4);
47  * pBuf.setData( image_data );
48  * pBuf.enable();
49  * glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xres, yres, 0,
50  * GL_UNSIGNED_BYTE, GL_RGBA, NULL);
51  * pBuf.disable();
52  *
53  * After that, you can change the texture (or a portion of the texture)
54  * by calling setData() again.
55  *
56  * You can also use a pixel buffer as a target for reading data back from
57  * the GPU (via glReadPixels(), glGetTexImage(), etc).
58  *
59  * RE_OGLPixelReadBuffer pBuf(xres, yres);
60  *
61  * pBuf.enable();
62  * glReadPixels(0,0, xres, yres, GL_RGB, GL_UNSIGNED_BYTE, NULL);
63  * pBuf.disable();
64  *
65  * ptr = pBug.getData();
66  *
67  * This allows you to do asynchronous reads. The glReadPixels() starts the
68  * DMA transfer, but does not wait - the getData() does.
69  *
70  * Finally, the various types of buffer objects, and their default settings,
71  * are:
72  *
73  * Vertex:
74  * RE_OGLAttributeBuffer shader vertex attrib 3 fp32
75  *
76  * Pixel:
77  * RE_OGLPixelReadBuffer read pixels from GPU 4 uint8
78  * RE_OGLPixelWriteBuffer write pixels to GPU 4 uint8
79  *
80  * Other:
81  * RE_OGLUniformBuffer uniforms for shaders 1 uint8
82  * RE_OGLElementBuffer primitive connectivity 1 uint32
83  * RE_OGLTexBuffer texture buffer object 1 fp32
84  */
85 #ifndef RE_OGLBuffer_H
86 #define RE_OGLBuffer_H
87 
88 #include "RE_CachedObject.h"
89 #include "RE_Types.h"
90 #include "RE_OGL.h"
91 #include <SYS/SYS_Types.h>
92 #include <UT/UT_String.h>
93 #include <UT/UT_NonCopyable.h>
94 #include <UT/UT_SharedPtr.h>
95 
96 class RE_Render;
97 class RE_OGLBuffer;
98 class RE_OGLTexture;
99 
101 {
102 public:
103  // Alternatively, you can use the convenience classes listed below.
104 
105  RE_OGLBuffer(RE_BufferType type, int num_elements, int capacity = -1);
106 
107  // Create a new RE_OGLBuffer derived class of 'type'.
108  // 'name' is the requied name for an attribute array, ignored for other
109  // types. 'cap' is the optional, actual size of the buffer.
110  static RE_OGLBuffer *newBuffer(RE_BufferType type,
111  int num_elements,
112  const char *name = nullptr,
113  int capacity = -1);
114 
115  // Setup
116  // standard GL attributes use the buffer types
117  void setBufferType(RE_BufferType type);
118 
119  // custom attributes are referenced by name.
120  void setAttributeName(const char *attrib);
121 
122  // Sets the data type for the array. This type is one array 'element'.
123  bool setFormat(RE_GPUType type, int vectorsize);
124 
125  // If an integer format is chosen (byte, short, int; unsigned or signed)
126  // and hooked up to a floating point vertex shader attribute, this specifies
127  // how the conversion is done. If normalize is true, unsigned ints are
128  // converted to [0,1] FP and signed ints to [-1, 1] FP. If normalize is
129  // false, the integer is converted as-is to FP (not remapped).
130  // This has no effect on FP formats, or integer arrays connected to integer
131  // vertex attributes. This needs to be called before the array is bound.
132  // The default is unnormalized.
133  void setNormalizedFormat(bool normalize = true);
134 
135  // Sets the length of the array, in elements (a fp32 vec3 is 1 element)
136  // Returns true if the length changed, false if the array was already len.
137  bool setLength(int len);
138 
139  // Sets the capacity of the array, in elements (a fp32 vec3 is 1 element)
140  // Returns true if the size changed, false if the array was already that
141  // size. If capacity is smaller than the current length, it will also be set
142  // to that size.
143  bool setCapacity(int size);
144 
145  // Increment this attribute once every 'nprim' primitives, rather than once
146  // per vertex. RE_EXT_INSTANCE_ARRAYS is required.
147  void setInstanceStride(int nprim);
148 
149  // You can optionally give GL a hint how you'll be using the data.
150  // Hints are set reasonably for the convenience classes below. If called
151  // after setData(), this has no effect.
152  void setUsage(RE_BufferUsageHint hint);
153 
154  // Use persistent buffers, if RE_EXT_BUFFER_STORAGE is supported.
155  // Normal persistent buffers require the use of RE_Render::memoryBarrier()
156  // with RE_BARRIER_PERSISTENT_BUFFER. Coherent buffers are automatically
157  // updated before a draw call
158  void setPersistentBuffer(RE_PersistentBufferMode mode);
159 
160  // This index is for binding matrix arrays, which are composed of multiple
161  // vertex arrays (a 4x4 uses 4 vertex array bindings). This index indicates
162  // which part of the matrix this vertex array maps to.
163  void setSubComponentIndex(int index);
164 
165  // Requires RE_EXT_DEBUG_LABEL extension (GL_ARB_debug_label). Sets a
166  // debug label on this array for GL debugging. Only applicable to buffers.
167  void setLabel(RE_Render *, const char *);
168 
169  // Array data methods
170 
171  // Specifies all the data at once, or a subrange of the data if sublen!=0.
172  // offset and sublen are specified in elements, not bytes.
173  bool setData(RE_Render *r, const void *data,
174  int offset = 0, int sublen = 0);
175 
176  bool replaceData(RE_Render *r, const void *subdata,
177  int suboffset, int sublength)
178  { return setData(r, subdata, suboffset, sublength); }
179 
180  // fetch data from the buffer into 'data', which should be large enough to
181  // hold it.
182  bool getData(RE_Render *, void *data,
183  int offset = 0, int sublen = 0) const;
184 
185  // Cut the current buffer loose and hand it over to the driver, so that
186  // it's possible to start writing to a new buffer immediately. Has no effect
187  // if no buffer was previously allocated.
188  void orphan(RE_Render *r);
189 
190  // Enable or disable this buffer, binding it to a bind point that depends
191  // on its derived type.
192  virtual bool enable(RE_Render *r, unsigned int stride = 0,
193  bool geo_object = false);
194  virtual bool disable(RE_Render *r);
195 
196  bool rebindAttrib(RE_Render *r,
197  int location, // attrib location
198  int stride = -1, // use previous if -1
199  RE_GPUType *type = NULL);
200  bool unbindAttrib(RE_Render *r);
201 
202  // Allows binding of this buffer to any buffer binding point (enable() only
203  // binds the buffer to the specific binding point for its type)
204  bool bindBuffer(RE_Render *r,
205  RE_BufferBinding point,
206  int bind_index = 0);
207  bool unbindBuffer(RE_Render *r,
208  RE_BufferBinding point,
209  int bind_index = 0);
210 
211  // Drawing methods
212 
213  // Draws primitives using every n'th point (where n=stride) in this array
214  // as 'prim' primitive type.
215  virtual void draw(RE_Render *r,
216  RE_PrimType prim,
217  unsigned int stride,
218  int num_instanced,
219  int vertices_per_patch);
220  // Draws primitives using a subrange of points in this array
221  virtual void drawRange(RE_Render *r,
222  RE_PrimType prim,
223  int start,int num,
224  int num_instanced,
225  int vertices_per_patch);
226  // Draws primitives using some points in this array using a 2nd array as
227  // the indices. The array must be an element array.
228  virtual void drawElements(RE_Render *r,
229  RE_PrimType prim,
230  RE_OGLBuffer *index_array,
231  int offset, int num,
232  int num_instanced,
233  int vertices_per_patch);
234 
235  // If you want to write or read directly from the memory chunk,
236  // this returns a pointer to the data. You must upmap it when you're done.
237  // Do NOT delete this pointer - it is owned by the graphics driver.
238  // mapDataRange() maps a subrange. offset and length are in element units.
239  void *map(RE_Render *r,
241  void *mapRange(RE_Render *r, int offset, int length,
243  void unmap(RE_Render *r);
244 
245  // For persistent mapped buffers, this returns the currently mapped data.
246  // Will only return a value if mapped, persisent is set, and
247  // RE_EXT_BUFFER_STORAGE is supported.
248  void *getPersistentMap() const
249  { return myMappedPersistentData; }
250 
251  /// Graphics memory usage estimate
252  int64 getSizeBytes() const;
253 
254  /// Returns the amount of main memory owned by this RE_OGLBuffer.
255  virtual int64 getMemoryUsage(bool inclusive) const
256  {
257  int64 mem = inclusive ? sizeof(*this) : 0;
258  mem += myAttribName.getMemoryUsage(false);
259  return mem;
260  }
261 
262  // Query
263  RE_BufferType getBufferType() const { return myBufferType; }
264  RE_GPUType getDataType() const { return myType; }
265  int getVectorSize() const { return myVectorSize; }
266  int getSubComponentIndex() const { return mySubIndex; }
267  int getLength() const { return myLength; }
268  int getCapacity() const { return myCapacity; }
269  int getInstanceStride() const{ return myInstanceStride; }
270  const char *getAttributeName() const { return myAttribName; }
271  bool isBound() const { return myBoundFlag; }
272  bool isMapped() const { return myMappedFlag; }
273  bool isEnabled() const { return myEnableFlag; }
274  RE_BufferAccess getMapAccess() const { return myMappedAccess; }
275 
276  // Return the GL buffer ID for the underlying GL buffer.
277  int getID() const { return myBufferID; }
278 
279  // Return a unique ID for this buffer instance (not the GL identifier)
280  int getUniqueID() const { return myUniqueID; }
281 
282  // Returns the GL maximum size of a vertex array and an element array when
283  // using glDrawRangeElements().
284  static int getMaxVertexArraySize(RE_Render *r);
285  static int getMaxElementArraySize(RE_Render *r);
286 
287  // Treat as protected for RE_VertexArray.
288  bool setEnabled(bool enabled)
289  { bool e=myEnableFlag; myEnableFlag=enabled; return e; }
290 
291  // For caching.
292  void incref() { myRefCount++; }
293  void decref()
294  {
295  myRefCount--;
296  if (myRefCount== 0)
297  delete this;
298  }
299  int getRefCount() const { return myRefCount; }
300 
301  void setTBO(RE_OGLTexture *tbo);
302  RE_OGLTexture *getTBO() const { return myTBO; }
303 
304  // Cached only; not actively in use if 0.
305  void markAsUsed() { myUseCount ++; }
306  void markAsUnused() { myUseCount --; UT_ASSERT(myUseCount>=0); }
307  bool isUsed() const { return myUseCount>0; }
308  int getUseCount() const { return myUseCount; }
309 
310 protected:
311  bool initialize(RE_Render *r, const void *data, int length = 0);
312  void resetBuffer();
313  void drawArraysCommon(RE_Render *r,
314  RE_PrimType prim,
315  int start,
316  int num,
317  unsigned int stride,
318  int num_instances,
319  int vertices_per_patch);
320 
321  bool bindAttribute(RE_Render *r, int location,
322  RE_GPUType type, int stride,
323  const void *data);
324 
325  bool enableAttribArray(RE_Render *r,
326  const char *name,
327  RE_GPUType datatype, int vectorsize,
328  unsigned int stride,
329  const void *data);
330  void disableAttribArray(RE_Render *r, const char *name);
331 
332  virtual ~RE_OGLBuffer();
333 
340  int myLength;
348 
352 
357 
363 
365 };
366 
367 static inline void intrusive_ptr_add_ref(RE_OGLBuffer *b) { b->incref(); }
368 static inline void intrusive_ptr_release(RE_OGLBuffer *b) { b->decref(); }
369 
371 {
372 public:
373  RE_OGLVertexBuffer(RE_BufferType type, int num_elements, int capacity=-1);
374 
375  virtual bool enable(RE_Render *r, unsigned int stride = 0,
376  bool geo_object = false);
377  virtual bool disable(RE_Render *r);
378 
379  // This is a convenience method that will draw the object with all
380  // currently enabled buffer objects (you only need to call this on one of
381  // the buffers, if multiple buffers are enabled). 'gltype' is the GL
382  // primitive you want to draw (GL_LINES, GL_TRIANGLE_STRIP, GL_QUADS, etc).
383  // The stride will all you to draw using every n'th element in the buffer.
384  virtual void draw(RE_Render *r, RE_PrimType prim_type,
385  unsigned int stride,
386  int num_instanced,
387  int vertices_per_patch);
388 
389  // This is a convenience method that will draw objects using a portion of
390  // the vertices in the buffer.
391  virtual void drawRange(RE_Render *r, RE_PrimType prim_type,
392  int start, int num,
393  int num_instanced,
394  int vertices_per_patch);
395 
396  // same as above, but uses an element buffer to store the indices. If
397  // num is not zero, offset/num define a subrange of the buffer to render.
398  virtual void drawElements(RE_Render *r,
399  RE_PrimType prim_type,
400  RE_OGLBuffer *element_bufer,
401  int offset, int num,
402  int num_instanced,
403  int vertices_per_patch);
404 
405  /// Returns the amount of main memory (NOT graphics memory!)
406  /// owned by this RE_OGLVertexBuffer.
407  virtual int64 getMemoryUsage(bool inclusive) const
408  {
409  int64 mem = inclusive ? sizeof(*this) : 0;
410  mem += RE_OGLBuffer::getMemoryUsage(false);
411  return mem;
412  }
413 
414 protected:
415  virtual ~RE_OGLVertexBuffer();
416 
418 };
419 
421 {
422 public:
423  RE_OGLAttributeBuffer(const char *name, int num = 0, int cap = -1)
425  {
427  setAttributeName(name);
428  }
429 };
430 
431 
432 // Non-vertex buffer objects ----------------------------------------------
433 
435 {
436 public:
437  RE_OGLElementBuffer(int num = 0, int cap = -1)
439  {
441  }
442 };
443 
445 {
446 public:
449  {
451  }
452  virtual ~RE_OGLUniformBuffer();
453 };
454 
456 {
457 public:
458  RE_OGLTexBuffer(int size, int cap =-1)
459  : RE_OGLBuffer(RE_BUFFER_TEXTURE, size, cap)
460  {
462  }
463 };
464 
465 
466 // A pixel read buffer is used to read data back from the GPU.
467 // Data type defaults to 3 8bit ints.
469 {
470 public:
471  RE_OGLPixelReadBuffer(int xres = 0, int yres = 1)
472  : RE_OGLBuffer(RE_BUFFER_PIXEL_READ, xres * yres)
473  {
476  }
477 };
478 
479 // A pixel write buffer is used to write data to the GPU.
480 // Data type defaults to 3 8bit ints.
482 {
483 public:
484  RE_OGLPixelWriteBuffer(int xres = 0, int yres = 1)
485  : RE_OGLBuffer(RE_BUFFER_PIXEL_WRITE, xres * yres)
486  {
489  }
490 };
491 
492 // This pixel buffer is used for copying data between objects on the GPU,
493 // without returning the data across the bus to the CPU.
495 {
496 public:
497  RE_OGLCopyPixelBuffer(int xres = 0, int yres = 1)
498  : RE_OGLBuffer(RE_BUFFER_PIXEL_WRITE, xres*yres)
499  {
502  }
503 
504  // Enables the buffer for either reading or writing - note the slightly
505  // different sematic for the last parameter to indicate this.
506  virtual bool enable(RE_Render *r, unsigned int = 0,
507  bool bind_for_gpu_read = true);
508 };
509 #endif
510 
virtual bool enable(RE_Render *r, unsigned int stride=0, bool geo_object=false)
int getLength() const
Definition: RE_OGLBuffer.h:267
RE_OGLPixelWriteBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:484
bool isUsed() const
Definition: RE_OGLBuffer.h:307
bool isEnabled() const
Definition: RE_OGLBuffer.h:273
#define RE_API
Definition: RE_API.h:10
int getInstanceStride() const
Definition: RE_OGLBuffer.h:269
bool setEnabled(bool enabled)
Definition: RE_OGLBuffer.h:288
GLuint start
Definition: glcorearb.h:474
virtual bool enable(RE_Render *r, unsigned int stride=0, bool geo_object=false)
virtual int64 getMemoryUsage(bool inclusive) const
Definition: RE_OGLBuffer.h:407
RE_OGLVertexBuffer(RE_BufferType type, int num_elements, int capacity=-1)
void setUsage(RE_BufferUsageHint hint)
void intrusive_ptr_release(PXR_NS::Sdf_Identity *p)
Definition: identity.h:81
int getUseCount() const
Definition: RE_OGLBuffer.h:308
bool replaceData(RE_Render *r, const void *subdata, int suboffset, int sublength)
Definition: RE_OGLBuffer.h:176
UT_String myAttribName
Definition: RE_OGLBuffer.h:334
unsigned int GLuint
Definition: cl.hpp:167
GLenum myDataType
Definition: RE_OGLBuffer.h:353
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:2538
unsigned int GLenum
Definition: cl.hpp:166
RE_OGLTexBuffer(int size, int cap=-1)
Definition: RE_OGLBuffer.h:458
RE_OGLPixelReadBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:471
GLsizeiptr size
Definition: glcorearb.h:663
int myAttribLocation
Definition: RE_OGLBuffer.h:344
RE_BufferAccess getMapAccess() const
Definition: RE_OGLBuffer.h:274
RE_BufferUsageHint myUsage
Definition: RE_OGLBuffer.h:345
void * myMappedPersistentData
Definition: RE_OGLBuffer.h:359
long long int64
Definition: SYS_Types.h:107
RE_GPUType
Definition: RE_Types.h:44
RE_BufferType
Definition: RE_Types.h:264
virtual void draw(RE_Render *r, RE_PrimType prim_type, unsigned int stride, int num_instanced, int vertices_per_patch)
RE_GPUType myType
Definition: RE_OGLBuffer.h:336
int getVectorSize() const
Definition: RE_OGLBuffer.h:265
void * myMappedDataEnd
Definition: RE_OGLBuffer.h:358
RE_BufferBinding
Definition: RE_Types.h:300
RE_OGLCopyPixelBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:497
int getRefCount() const
Definition: RE_OGLBuffer.h:299
virtual void drawRange(RE_Render *r, RE_PrimType prim_type, int start, int num, int num_instanced, int vertices_per_patch)
bool isBound() const
Definition: RE_OGLBuffer.h:271
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2221
RE_OGLTexture * myTBO
Definition: RE_OGLBuffer.h:360
RE_OGLUniformBuffer(int size)
Definition: RE_OGLBuffer.h:447
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:871
GLintptr offset
Definition: glcorearb.h:664
int getSubComponentIndex() const
Definition: RE_OGLBuffer.h:266
void intrusive_ptr_add_ref(PXR_NS::Sdf_Identity *p)
Definition: identity.h:78
void setAttributeName(const char *attrib)
GLint location
Definition: glcorearb.h:804
GLuint myBufferID
Definition: RE_OGLBuffer.h:355
virtual ~RE_OGLVertexBuffer()
GLboolean * data
Definition: glcorearb.h:130
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:318
RE_PersistentBufferMode myPersistentBufferMode
Definition: RE_OGLBuffer.h:346
GLuint const GLchar * name
Definition: glcorearb.h:785
GridType::Ptr normalize(const GridType &grid, bool threaded, InterruptT *interrupt)
Normalize the vectors of the given vector-valued grid.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
int64 myRefCount
Definition: RE_OGLBuffer.h:361
RE_GPUType getDataType() const
Definition: RE_OGLBuffer.h:264
GLenum mode
Definition: glcorearb.h:98
RE_OGLTexture * getTBO() const
Definition: RE_OGLBuffer.h:302
RE_BufferAccess
Definition: RE_Types.h:293
int getID() const
Definition: RE_OGLBuffer.h:277
Basic cached object, with version and extra data only.
int getUniqueID() const
Definition: RE_OGLBuffer.h:280
virtual bool disable(RE_Render *r)
bool setFormat(RE_GPUType type, int vectorsize)
GLuint index
Definition: glcorearb.h:785
void markAsUsed()
Definition: RE_OGLBuffer.h:305
GLenum myGLBufferType
Definition: RE_OGLBuffer.h:356
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
RE_BufferUsageHint
Definition: RE_Types.h:275
png_infop png_uint_32 int num
Definition: png.h:2158
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
virtual void drawElements(RE_Render *r, RE_PrimType prim_type, RE_OGLBuffer *element_bufer, int offset, int num, int num_instanced, int vertices_per_patch)
RE_BufferAccess myMappedAccess
Definition: RE_OGLBuffer.h:347
GLboolean r
Definition: glcorearb.h:1221
RE_BufferType getBufferType() const
Definition: RE_OGLBuffer.h:263
void * getPersistentMap() const
Definition: RE_OGLBuffer.h:248
void markAsUnused()
Definition: RE_OGLBuffer.h:306
RE_PrimType
Definition: RE_Types.h:193
int myInstanceStride
Definition: RE_OGLBuffer.h:342
const char * getAttributeName() const
Definition: RE_OGLBuffer.h:270
RE_PersistentBufferMode
Definition: RE_Types.h:504
RE_BufferType myBufferType
Definition: RE_OGLBuffer.h:335
RE_OGLElementBuffer(int num=0, int cap=-1)
Definition: RE_OGLBuffer.h:437
virtual int64 getMemoryUsage(bool inclusive) const
Returns the amount of main memory owned by this RE_OGLBuffer.
Definition: RE_OGLBuffer.h:255
bool isMapped() const
Definition: RE_OGLBuffer.h:272
RE_OGLAttributeBuffer(const char *name, int num=0, int cap=-1)
Definition: RE_OGLBuffer.h:423
int getCapacity() const
Definition: RE_OGLBuffer.h:268
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794