HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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);
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.
110  static RE_OGLBuffer *newBuffer(RE_BufferType type, int num_elements,
111  const char *name = NULL);
112 
113  // Setup
114  // standard GL attributes use the buffer types
115  void setBufferType(RE_BufferType type);
116 
117  // custom attributes are referenced by name.
118  void setAttributeName(const char *attrib);
119 
120  // Sets the data type for the array. This type is one array 'element'.
121  bool setFormat(RE_GPUType type, int vectorsize);
122 
123  // If an integer format is chosen (byte, short, int; unsigned or signed)
124  // and hooked up to a floating point vertex shader attribute, this specifies
125  // how the conversion is done. If normalize is true, unsigned ints are
126  // converted to [0,1] FP and signed ints to [-1, 1] FP. If normalize is
127  // false, the integer is converted as-is to FP (not remapped).
128  // This has no effect on FP formats, or integer arrays connected to integer
129  // vertex attributes. This needs to be called before the array is bound.
130  // The default is unnormalized.
131  void setNormalizedFormat(bool normalize = true);
132 
133  // Sets the length of the array, in elements (a fp32 vec3 is 1 element)
134  // Returns true if the length changed, false if the array was already len.
135  bool setLength(int len);
136 
137  // Increment this attribute once every 'nprim' primitives, rather than once
138  // per vertex. RE_EXT_INSTANCE_ARRAYS is required.
139  void setInstanceStride(int nprim);
140 
141  // You can optionally give GL a hint how you'll be using the data.
142  // Hints are set reasonably for the convenience classes below. If called
143  // after setData(), this has no effect.
144  void setUsage(RE_BufferUsageHint hint);
145 
146  // Use persistent buffers, if RE_EXT_BUFFER_STORAGE is supported.
147  // Normal persistent buffers require the use of RE_Render::memoryBarrier()
148  // with RE_BARRIER_PERSISTENT_BUFFER. Coherent buffers are automatically
149  // updated before a draw call
150  void setPersistentBuffer(RE_PersistentBufferMode mode);
151 
152  // This index is for binding matrix arrays, which are composed of multiple
153  // vertex arrays (a 4x4 uses 4 vertex array bindings). This index indicates
154  // which part of the matrix this vertex array maps to.
155  void setSubComponentIndex(int index);
156 
157  // Requires RE_EXT_DEBUG_LABEL extension (GL_ARB_debug_label). Sets a
158  // debug label on this array for GL debugging. Only applicable to buffers.
159  void setLabel(RE_Render *, const char *);
160 
161  // Array data methods
162 
163  // Specifies all the data at once, or a subrange of the data if sublen!=0.
164  // offset and sublen are specified in elements, not bytes.
165  bool setData(RE_Render *r, const void *data,
166  int offset = 0, int sublen = 0);
167 
168  bool replaceData(RE_Render *r, const void *subdata,
169  int suboffset, int sublength)
170  { return setData(r, subdata, suboffset, sublength); }
171 
172  // fetch data from the buffer into 'data', which should be large enough to
173  // hold it.
174  bool getData(RE_Render *, void *data,
175  int offset = 0, int sublen = 0) const;
176 
177  // Cut the current buffer loose and hand it over to the driver, so that
178  // it's possible to start writing to a new buffer immediately. Has no effect
179  // if no buffer was previously allocated.
180  void orphan(RE_Render *r);
181 
182  // Enable or disable this buffer, binding it to a bind point that depends
183  // on its derived type.
184  virtual bool enable(RE_Render *r, unsigned int stride = 0,
185  bool geo_object = false);
186  virtual bool disable(RE_Render *r);
187 
188  bool rebindAttrib(RE_Render *r,
189  int location, // attrib location
190  int stride = -1, // use previous if -1
191  RE_GPUType *type = NULL);
192  bool unbindAttrib(RE_Render *r);
193 
194  // Allows binding of this buffer to any buffer binding point (enable() only
195  // binds the buffer to the specific binding point for its type)
196  bool bindBuffer(RE_Render *r,
197  RE_BufferBinding point,
198  int bind_index = 0);
199  bool unbindBuffer(RE_Render *r,
200  RE_BufferBinding point,
201  int bind_index = 0);
202 
203  // Drawing methods
204 
205  // Draws primitives using every n'th point (where n=stride) in this array
206  // as 'prim' primitive type.
207  virtual void draw(RE_Render *r,
208  RE_PrimType prim,
209  unsigned int stride,
210  int num_instanced,
211  int vertices_per_patch);
212  // Draws primitives using a subrange of points in this array
213  virtual void drawRange(RE_Render *r,
214  RE_PrimType prim,
215  int start,int num,
216  int num_instanced,
217  int vertices_per_patch);
218  // Draws primitives using some points in this array using a 2nd array as
219  // the indices. The array must be an element array.
220  virtual void drawElements(RE_Render *r,
221  RE_PrimType prim,
222  RE_OGLBuffer *index_array,
223  int offset, int num,
224  int num_instanced,
225  int vertices_per_patch);
226 
227  // If you want to write or read directly from the memory chunk,
228  // this returns a pointer to the data. You must upmap it when you're done.
229  // Do NOT delete this pointer - it is owned by the graphics driver.
230  // mapDataRange() maps a subrange. offset and length are in element units.
231  void *map(RE_Render *r,
233  void *mapRange(RE_Render *r, int offset, int length,
235  void unmap(RE_Render *r);
236 
237  // For persistent mapped buffers, this returns the currently mapped data.
238  // Will only return a value if mapped, persisent is set, and
239  // RE_EXT_BUFFER_STORAGE is supported.
240  void *getPersistentMap() const
241  { return myMappedPersistentData; }
242 
243  /// Graphics memory usage estimate
244  int64 getSizeBytes() const;
245 
246  /// Returns the amount of main memory owned by this RE_OGLBuffer.
247  virtual int64 getMemoryUsage(bool inclusive) const
248  {
249  int64 mem = inclusive ? sizeof(*this) : 0;
250  mem += myAttribName.getMemoryUsage(false);
251  return mem;
252  }
253 
254  // Query
255  RE_BufferType getBufferType() const { return myBufferType; }
256  RE_GPUType getDataType() const { return myType; }
257  int getVectorSize() const { return myVectorSize; }
258  int getSubComponentIndex() const { return mySubIndex; }
259  int getLength() const { return myLength; }
260  int getInstanceStride() const{ return myInstanceStride; }
261  const char *getAttributeName() const { return myAttribName; }
262  bool isBound() const { return myBoundFlag; }
263  bool isMapped() const { return myMappedFlag; }
264  bool isEnabled() const { return myEnableFlag; }
265  RE_BufferAccess getMapAccess() const { return myMappedAccess; }
266 
267  // Return the GL buffer ID for the underlying GL buffer.
268  int getID() const { return myBufferID; }
269 
270  // Return a unique ID for this buffer instance (not the GL identifier)
271  int getUniqueID() const { return myUniqueID; }
272 
273  // Returns the GL maximum size of a vertex array and an element array when
274  // using glDrawRangeElements().
275  static int getMaxVertexArraySize(RE_Render *r);
276  static int getMaxElementArraySize(RE_Render *r);
277 
278  // Treat as protected for RE_VertexArray.
279  bool setEnabled(bool enabled)
280  { bool e=myEnableFlag; myEnableFlag=enabled; return e; }
281 
282  // For caching.
283  void incref() { myRefCount++; }
284  void decref()
285  {
286  myRefCount--;
287  if (myRefCount== 0)
288  delete this;
289  }
290  int getRefCount() const { return myRefCount; }
291 
292  void setTBO(RE_OGLTexture *tbo);
293  RE_OGLTexture *getTBO() const { return myTBO; }
294 
295  // Cached only; not actively in use if 0.
296  void markAsUsed() { myUseCount ++; }
297  void markAsUnused() { myUseCount --; UT_ASSERT(myUseCount>=0); }
298  bool isUsed() const { return myUseCount>0; }
299  int getUseCount() const { return myUseCount; }
300 
301 protected:
302  bool initialize(RE_Render *r, const void *data);
303  void resetBuffer();
304  void drawArraysCommon(RE_Render *r,
305  RE_PrimType prim,
306  int start,
307  int num,
308  unsigned int stride,
309  int num_instances,
310  int vertices_per_patch);
311 
312  bool bindAttribute(RE_Render *r, int location,
313  RE_GPUType type, int stride,
314  const void *data);
315 
316  bool enableAttribArray(RE_Render *r,
317  const char *name,
318  RE_GPUType datatype, int vectorsize,
319  unsigned int stride,
320  const void *data);
321  void disableAttribArray(RE_Render *r, const char *name);
322 
323  virtual ~RE_OGLBuffer();
324 
331  int myLength;
338 
342 
347 
353 
355 };
356 
357 static inline void intrusive_ptr_add_ref(RE_OGLBuffer *b) { b->incref(); }
358 static inline void intrusive_ptr_release(RE_OGLBuffer *b) { b->decref(); }
359 
361 {
362 public:
363  RE_OGLVertexBuffer(RE_BufferType type, int num_elements);
364 
365  virtual bool enable(RE_Render *r, unsigned int stride = 0,
366  bool geo_object = false);
367  virtual bool disable(RE_Render *r);
368 
369  // This is a convenience method that will draw the object with all
370  // currently enabled buffer objects (you only need to call this on one of
371  // the buffers, if multiple buffers are enabled). 'gltype' is the GL
372  // primitive you want to draw (GL_LINES, GL_TRIANGLE_STRIP, GL_QUADS, etc).
373  // The stride will all you to draw using every n'th element in the buffer.
374  virtual void draw(RE_Render *r, RE_PrimType prim_type,
375  unsigned int stride,
376  int num_instanced,
377  int vertices_per_patch);
378 
379  // This is a convenience method that will draw objects using a portion of
380  // the vertices in the buffer.
381  virtual void drawRange(RE_Render *r, RE_PrimType prim_type,
382  int start, int num,
383  int num_instanced,
384  int vertices_per_patch);
385 
386  // same as above, but uses an element buffer to store the indices. If
387  // num is not zero, offset/num define a subrange of the buffer to render.
388  virtual void drawElements(RE_Render *r,
389  RE_PrimType prim_type,
390  RE_OGLBuffer *element_bufer,
391  int offset, int num,
392  int num_instanced,
393  int vertices_per_patch);
394 
395  /// Returns the amount of main memory (NOT graphics memory!)
396  /// owned by this RE_OGLVertexBuffer.
397  virtual int64 getMemoryUsage(bool inclusive) const
398  {
399  int64 mem = inclusive ? sizeof(*this) : 0;
400  mem += RE_OGLBuffer::getMemoryUsage(false);
401  return mem;
402  }
403 
404 protected:
405  virtual ~RE_OGLVertexBuffer();
406 
408 };
409 
411 {
412 public:
413  RE_OGLAttributeBuffer(const char *name, int num = 0)
415  {
417  setAttributeName(name);
418  }
419 };
420 
421 
422 // Non-vertex buffer objects ----------------------------------------------
423 
425 {
426 public:
429  {
431  }
432 };
433 
435 {
436 public:
439  {
441  }
442  virtual ~RE_OGLUniformBuffer();
443 };
444 
446 {
447 public:
450  {
452  }
453 };
454 
455 
456 // A pixel read buffer is used to read data back from the GPU.
457 // Data type defaults to 3 8bit ints.
459 {
460 public:
461  RE_OGLPixelReadBuffer(int xres = 0, int yres = 1)
462  : RE_OGLBuffer(RE_BUFFER_PIXEL_READ, xres * yres)
463  {
466  }
467 };
468 
469 // A pixel write buffer is used to write data to the GPU.
470 // Data type defaults to 3 8bit ints.
472 {
473 public:
474  RE_OGLPixelWriteBuffer(int xres = 0, int yres = 1)
475  : RE_OGLBuffer(RE_BUFFER_PIXEL_WRITE, xres * yres)
476  {
479  }
480 };
481 
482 // This pixel buffer is used for copying data between objects on the GPU,
483 // without returning the data across the bus to the CPU.
485 {
486 public:
487  RE_OGLCopyPixelBuffer(int xres = 0, int yres = 1)
488  : RE_OGLBuffer(RE_BUFFER_PIXEL_WRITE, xres*yres)
489  {
492  }
493 
494  // Enables the buffer for either reading or writing - note the slightly
495  // different sematic for the last parameter to indicate this.
496  virtual bool enable(RE_Render *r, unsigned int = 0,
497  bool bind_for_gpu_read = true);
498 };
499 #endif
500 
virtual bool enable(RE_Render *r, unsigned int stride=0, bool geo_object=false)
int getLength() const
Definition: RE_OGLBuffer.h:259
RE_OGLPixelWriteBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:474
bool isUsed() const
Definition: RE_OGLBuffer.h:298
bool isEnabled() const
Definition: RE_OGLBuffer.h:264
#define RE_API
Definition: RE_API.h:10
int getInstanceStride() const
Definition: RE_OGLBuffer.h:260
bool setEnabled(bool enabled)
Definition: RE_OGLBuffer.h:279
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:397
void setUsage(RE_BufferUsageHint hint)
int getUseCount() const
Definition: RE_OGLBuffer.h:299
bool replaceData(RE_Render *r, const void *subdata, int suboffset, int sublength)
Definition: RE_OGLBuffer.h:168
UT_String myAttribName
Definition: RE_OGLBuffer.h:325
unsigned int GLuint
Definition: cl.hpp:167
GLenum myDataType
Definition: RE_OGLBuffer.h:343
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:2538
unsigned int GLenum
Definition: cl.hpp:166
RE_OGLPixelReadBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:461
GLsizeiptr size
Definition: glcorearb.h:663
int myAttribLocation
Definition: RE_OGLBuffer.h:334
RE_BufferAccess getMapAccess() const
Definition: RE_OGLBuffer.h:265
RE_BufferUsageHint myUsage
Definition: RE_OGLBuffer.h:335
void * myMappedPersistentData
Definition: RE_OGLBuffer.h:349
long long int64
Definition: SYS_Types.h:106
RE_GPUType
Definition: RE_Types.h:42
RE_BufferType
Definition: RE_Types.h:262
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:327
int getVectorSize() const
Definition: RE_OGLBuffer.h:257
void * myMappedDataEnd
Definition: RE_OGLBuffer.h:348
RE_BufferBinding
Definition: RE_Types.h:298
RE_OGLCopyPixelBuffer(int xres=0, int yres=1)
Definition: RE_OGLBuffer.h:487
int getRefCount() const
Definition: RE_OGLBuffer.h:290
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
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:262
GLuint GLint GLboolean GLint GLenum access
Definition: glcorearb.h:2221
RE_OGLTexture * myTBO
Definition: RE_OGLBuffer.h:350
RE_OGLUniformBuffer(int size)
Definition: RE_OGLBuffer.h:437
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:871
GLintptr offset
Definition: glcorearb.h:664
int getSubComponentIndex() const
Definition: RE_OGLBuffer.h:258
void setAttributeName(const char *attrib)
GLint location
Definition: glcorearb.h:804
GLuint myBufferID
Definition: RE_OGLBuffer.h:345
virtual ~RE_OGLVertexBuffer()
GLboolean * data
Definition: glcorearb.h:130
OPENVDB_API void initialize()
Global registration of basic types.
Definition: logging.h:316
RE_PersistentBufferMode myPersistentBufferMode
Definition: RE_OGLBuffer.h:336
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:351
RE_GPUType getDataType() const
Definition: RE_OGLBuffer.h:256
GLenum mode
Definition: glcorearb.h:98
RE_OGLTexture * getTBO() const
Definition: RE_OGLBuffer.h:293
RE_OGLTexBuffer(int size)
Definition: RE_OGLBuffer.h:448
RE_BufferAccess
Definition: RE_Types.h:291
int getID() const
Definition: RE_OGLBuffer.h:268
Basic cached object, with version and extra data only.
int getUniqueID() const
Definition: RE_OGLBuffer.h:271
virtual bool disable(RE_Render *r)
bool setFormat(RE_GPUType type, int vectorsize)
GLuint index
Definition: glcorearb.h:785
RE_OGLAttributeBuffer(const char *name, int num=0)
Definition: RE_OGLBuffer.h:413
void markAsUsed()
Definition: RE_OGLBuffer.h:296
RE_OGLVertexBuffer(RE_BufferType type, int num_elements)
RE_OGLElementBuffer(int num=0)
Definition: RE_OGLBuffer.h:427
GLenum myGLBufferType
Definition: RE_OGLBuffer.h:346
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
RE_BufferUsageHint
Definition: RE_Types.h:273
png_infop png_uint_32 int num
Definition: png.h:2158
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:337
GLboolean r
Definition: glcorearb.h:1221
RE_BufferType getBufferType() const
Definition: RE_OGLBuffer.h:255
void * getPersistentMap() const
Definition: RE_OGLBuffer.h:240
void markAsUnused()
Definition: RE_OGLBuffer.h:297
RE_PrimType
Definition: RE_Types.h:191
int myInstanceStride
Definition: RE_OGLBuffer.h:332
const char * getAttributeName() const
Definition: RE_OGLBuffer.h:261
RE_PersistentBufferMode
Definition: RE_Types.h:501
RE_BufferType myBufferType
Definition: RE_OGLBuffer.h:326
virtual int64 getMemoryUsage(bool inclusive) const
Returns the amount of main memory owned by this RE_OGLBuffer.
Definition: RE_OGLBuffer.h:247
bool isMapped() const
Definition: RE_OGLBuffer.h:263
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794