1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkPixelBufferObject.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /** 16 * @class vtkPixelBufferObject 17 * @brief abstracts an OpenGL pixel buffer object. 18 * 19 * Provides low-level access to PBO mapped memory. Used to transfer raw data 20 * to/from PBO mapped memory and the application. Once data is transferred to 21 * the PBO it can then be transferred to the GPU (eg texture memory). Data may 22 * be uploaded from the application into a pixel buffer or downloaded from the 23 * pixel buffer to the application. The vtkTextureObject is used to transfer 24 * data from/to the PBO to/from texture memory on the GPU. 25 * @sa 26 * OpenGL Pixel Buffer Object Extension Spec (ARB_pixel_buffer_object): 27 * http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt 28 * @warning 29 * Since most PBO mapped don't support double format all double data is converted to 30 * float and then uploaded. 31 */ 32 33 #ifndef vtkPixelBufferObject_h 34 #define vtkPixelBufferObject_h 35 36 #include "vtkObject.h" 37 #include "vtkRenderingOpenGL2Module.h" // For export macro 38 #include "vtkWeakPointer.h" // needed for vtkWeakPointer. 39 40 class vtkRenderWindow; 41 class vtkOpenGLExtensionManager; 42 43 class VTKRENDERINGOPENGL2_EXPORT vtkPixelBufferObject : public vtkObject 44 { 45 public: 46 47 // Usage values. 48 enum 49 { 50 StreamDraw=0, 51 StreamRead, 52 StreamCopy, 53 StaticDraw, 54 StaticRead, 55 StaticCopy, 56 DynamicDraw, 57 DynamicRead, 58 DynamicCopy, 59 NumberOfUsages 60 }; 61 62 static vtkPixelBufferObject* New(); 63 vtkTypeMacro(vtkPixelBufferObject, vtkObject); 64 void PrintSelf(ostream& os, vtkIndent indent) override; 65 66 //@{ 67 /** 68 * Get/Set the context. Context must be a vtkOpenGLRenderWindow. 69 * This does not increase the reference count of the 70 * context to avoid reference loops. 71 * SetContext() may raise an error is the OpenGL context does not support the 72 * required OpenGL extensions. 73 */ 74 void SetContext(vtkRenderWindow* context); 75 vtkRenderWindow* GetContext(); 76 //@} 77 78 //@{ 79 /** 80 * Usage is a performance hint. 81 * Valid values are: 82 * - StreamDraw specified once by A, used few times S 83 * - StreamRead specified once by R, queried a few times by A 84 * - StreamCopy specified once by R, used a few times S 85 * - StaticDraw specified once by A, used many times S 86 * - StaticRead specified once by R, queried many times by A 87 * - StaticCopy specified once by R, used many times S 88 * - DynamicDraw respecified repeatedly by A, used many times S 89 * - DynamicRead respecified repeatedly by R, queried many times by A 90 * - DynamicCopy respecified repeatedly by R, used many times S 91 * A: the application 92 * S: as the source for GL drawing and image specification commands. 93 * R: reading data from the GL 94 * Initial value is StaticDraw, as in OpenGL spec. 95 */ 96 vtkGetMacro(Usage,int); 97 vtkSetMacro(Usage,int); 98 //@} 99 100 //@{ 101 /** 102 * Upload data to PBO mapped. 103 * The input data can be freed after this call. 104 * The data ptr is treated as an 1D array with the given number of tuples and 105 * given number of components in each tuple to be copied to the PBO mapped. increment 106 * is the offset added after the last component in each tuple is transferred. 107 * Look at the documentation for ContinuousIncrements in vtkImageData for 108 * details about how increments are specified. 109 */ Upload1D(int type,void * data,unsigned int numtuples,int comps,vtkIdType increment)110 bool Upload1D(int type, void* data, 111 unsigned int numtuples, int comps, vtkIdType increment) 112 { 113 unsigned int newdims[3]; 114 newdims[0] = numtuples; 115 newdims[1] = 1; 116 newdims[2] = 1; 117 vtkIdType newinc[3]; 118 newinc[0] = increment; 119 newinc[1] = 0; 120 newinc[2] = 0; 121 return this->Upload3D(type, data, newdims, comps, newinc,0,nullptr); 122 } 123 //@} 124 125 //@{ 126 /** 127 * Update data to PBO mapped sourcing it from a 2D array. 128 * The input data can be freed after this call. 129 * The data ptr is treated as a 2D array with increments indicating how to 130 * iterate over the data. 131 * Look at the documentation for ContinuousIncrements in vtkImageData for 132 * details about how increments are specified. 133 */ Upload2D(int type,void * data,unsigned int dims[2],int comps,vtkIdType increments[2])134 bool Upload2D(int type, void* data, 135 unsigned int dims[2], 136 int comps, 137 vtkIdType increments[2]) 138 { 139 unsigned int newdims[3]; 140 newdims[0] = dims[0]; 141 newdims[1] = dims[1]; 142 newdims[2] = 1; 143 vtkIdType newinc[3]; 144 newinc[0] = increments[0]; 145 newinc[1] = increments[1]; 146 newinc[2] = 0; 147 return this->Upload3D(type, data, newdims, comps, newinc,0,nullptr); 148 } 149 //@} 150 151 /** 152 * Update data to PBO mapped sourcing it from a 3D array. 153 * The input data can be freed after this call. 154 * The data ptr is treated as a 3D array with increments indicating how to 155 * iterate over the data. 156 * Look at the documentation for ContinuousIncrements in vtkImageData for 157 * details about how increments are specified. 158 */ 159 bool Upload3D(int type, void* data, 160 unsigned int dims[3], int comps, 161 vtkIdType increments[3], 162 int components, 163 int *componentList); 164 165 //@{ 166 /** 167 * Get the type with which the data is loaded into the PBO mapped. 168 * eg. VTK_FLOAT for float32, VTK_CHAR for byte, VTK_UNSIGNED_CHAR for 169 * unsigned byte etc. 170 */ 171 vtkGetMacro(Type, int); 172 vtkSetMacro(Type, int); 173 //@} 174 175 //@{ 176 /** 177 * Get the number of components used to initialize the buffer. 178 */ 179 vtkGetMacro(Components, int); 180 vtkSetMacro(Components, int); 181 //@} 182 183 //@{ 184 /** 185 * Get the size of the data loaded into the PBO mapped memory. Size is 186 * in the number of elements of the uploaded Type. 187 */ 188 vtkGetMacro(Size, unsigned int); 189 vtkSetMacro(Size, unsigned int); 190 void SetSize(unsigned int nTups, int nComps); 191 //@} 192 193 //@{ 194 /** 195 * Get the openGL buffer handle. 196 */ 197 vtkGetMacro(Handle, unsigned int); 198 //@} 199 200 //@{ 201 /** 202 * Download data from pixel buffer to the 1D array. The length of the array 203 * must be equal to the size of the data in the memory. 204 */ Download1D(int type,void * data,unsigned int dim,int numcomps,vtkIdType increment)205 bool Download1D( 206 int type, void* data, 207 unsigned int dim, 208 int numcomps, vtkIdType increment) 209 { 210 unsigned int newdims[3]; 211 newdims[0] = dim; 212 newdims[1] = 1; 213 newdims[2] = 1; 214 vtkIdType newincrements[3]; 215 newincrements[0] = increment; 216 newincrements[1] = 0; 217 newincrements[2] = 0; 218 return this->Download3D(type, data, newdims, numcomps, newincrements); 219 } 220 //@} 221 222 //@{ 223 /** 224 * Download data from pixel buffer to the 2D array. (lengthx * lengthy) 225 * must be equal to the size of the data in the memory. 226 */ Download2D(int type,void * data,unsigned int dims[2],int numcomps,vtkIdType increments[2])227 bool Download2D( 228 int type, void* data, 229 unsigned int dims[2], 230 int numcomps, vtkIdType increments[2]) 231 { 232 unsigned int newdims[3]; 233 newdims[0] = dims[0]; 234 newdims[1] = dims[1]; 235 newdims[2] = 1; 236 vtkIdType newincrements[3]; 237 newincrements[0] = increments[0]; 238 newincrements[1] = increments[1]; 239 newincrements[2] = 0; 240 return this->Download3D(type, data, newdims, numcomps, newincrements); 241 } 242 //@} 243 244 /** 245 * Download data from pixel buffer to the 3D array. 246 * (lengthx * lengthy * lengthz) must be equal to the size of the data in 247 * the memory. 248 */ 249 bool Download3D(int type, void* data, 250 unsigned int dims[3], 251 int numcomps, vtkIdType increments[3]); 252 253 /** 254 * Convenience methods for binding. 255 */ BindToPackedBuffer()256 void BindToPackedBuffer() 257 { this->Bind(PACKED_BUFFER); } 258 BindToUnPackedBuffer()259 void BindToUnPackedBuffer() 260 { this->Bind(UNPACKED_BUFFER); } 261 262 /** 263 * Deactivate the buffer. 264 */ 265 void UnBind(); 266 267 /** 268 * Convenience api for mapping buffers to app address space. 269 * See also MapBuffer. 270 */ MapPackedBuffer()271 void *MapPackedBuffer() 272 { return this->MapBuffer(PACKED_BUFFER); } 273 MapPackedBuffer(int type,unsigned int numtuples,int comps)274 void *MapPackedBuffer(int type, unsigned int numtuples, int comps) 275 { return this->MapBuffer(type, numtuples, comps, PACKED_BUFFER); } 276 MapPackedBuffer(unsigned int numbytes)277 void *MapPackedBuffer(unsigned int numbytes) 278 { return this->MapBuffer(numbytes, PACKED_BUFFER); } 279 MapUnpackedBuffer()280 void *MapUnpackedBuffer() 281 { return this->MapBuffer(UNPACKED_BUFFER); } 282 MapUnpackedBuffer(int type,unsigned int numtuples,int comps)283 void *MapUnpackedBuffer(int type, unsigned int numtuples, int comps) 284 { return this->MapBuffer(type, numtuples, comps, UNPACKED_BUFFER); } 285 MapUnpackedBuffer(unsigned int numbytes)286 void *MapUnpackedBuffer(unsigned int numbytes) 287 { return this->MapBuffer(numbytes, UNPACKED_BUFFER); } 288 289 /** 290 * Convenience api for unmapping buffers from app address space. 291 * See also UnmapBuffer. 292 */ UnmapUnpackedBuffer()293 void UnmapUnpackedBuffer() 294 { this->UnmapBuffer(UNPACKED_BUFFER); } 295 UnmapPackedBuffer()296 void UnmapPackedBuffer() 297 { this->UnmapBuffer(PACKED_BUFFER); } 298 299 // PACKED_BUFFER for download APP<-PBO 300 // UNPACKED_BUFFER for upload APP->PBO 301 enum BufferType{ 302 UNPACKED_BUFFER=0, 303 PACKED_BUFFER 304 }; 305 306 /** 307 * Make the buffer active. 308 */ 309 void Bind(BufferType buffer); 310 311 //@{ 312 /** 313 * Map the buffer to our addresspace. Returns a pointer to the mapped memory 314 * for read/write access. If type, tuples and components are specified new buffer 315 * data will be allocated, else the current allocation is mapped. When finished 316 * call UnmapBuffer. 317 */ 318 void *MapBuffer(int type, unsigned int numtuples, int comps, BufferType mode); 319 void *MapBuffer(unsigned int numbytes, BufferType mode); 320 void *MapBuffer(BufferType mode); 321 //@} 322 323 /** 324 * Un-map the buffer from our address space, OpenGL can then use/reclaim the 325 * buffer contents. 326 */ 327 void UnmapBuffer(BufferType mode); 328 329 /** 330 * Allocate PACKED/UNPACKED memory to hold numTuples*numComponents of vtkType. 331 */ 332 void Allocate( 333 int vtkType, 334 unsigned int numtuples, 335 int comps, 336 BufferType mode); 337 338 /** 339 * Allocate PACKED/UNPACKED memory to hold nBytes of data. 340 */ 341 void Allocate( 342 unsigned int nbytes, 343 BufferType mode); 344 345 /** 346 * Release the memory allocated without destroying the PBO handle. 347 */ 348 void ReleaseMemory(); 349 350 /** 351 * Returns if the context supports the required extensions. 352 * Extension will be loaded when the context is set. 353 */ 354 static bool IsSupported(vtkRenderWindow* renWin); 355 356 protected: 357 vtkPixelBufferObject(); 358 ~vtkPixelBufferObject() override; 359 360 /** 361 * Loads all required OpenGL extensions. Must be called every time a new 362 * context is set. 363 */ 364 bool LoadRequiredExtensions(vtkRenderWindow* renWin); 365 366 /** 367 * Create the pixel buffer object. 368 */ 369 void CreateBuffer(); 370 371 /** 372 * Destroys the pixel buffer object. 373 */ 374 void DestroyBuffer(); 375 376 int Usage; 377 unsigned int BufferTarget; // GLenum 378 int Type; 379 int Components; 380 unsigned int Size; 381 vtkWeakPointer<vtkRenderWindow> Context; 382 unsigned int Handle; 383 private: 384 vtkPixelBufferObject(const vtkPixelBufferObject&) = delete; 385 void operator=(const vtkPixelBufferObject&) = delete; 386 }; 387 388 #endif 389