1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPixelBufferObject.cxx
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 #include "vtkPixelBufferObject.h"
16
17 #include "vtk_glew.h"
18
19 #include "vtkObjectFactory.h"
20 #include "vtkOpenGLRenderWindow.h"
21
22 #include "vtkOpenGLError.h"
23
24 //#define VTK_PBO_DEBUG
25 //#define VTK_PBO_TIMING
26
27 #ifdef VTK_PBO_TIMING
28 #include "vtkTimerLog.h"
29 #endif
30
31 #include <cassert>
32
33 // Mapping from Usage values to OpenGL values.
34
35 static const GLenum OpenGLBufferObjectUsage[9]=
36 {
37 GL_STREAM_DRAW,
38 GL_STREAM_READ,
39 GL_STREAM_COPY,
40 GL_STATIC_DRAW,
41 GL_STATIC_READ,
42 GL_STATIC_COPY,
43 GL_DYNAMIC_DRAW,
44 GL_DYNAMIC_READ,
45 GL_DYNAMIC_COPY
46 };
47
48 static const char *BufferObjectUsageAsString[9]=
49 {
50 "StreamDraw",
51 "StreamRead",
52 "StreamCopy",
53 "StaticDraw",
54 "StaticRead",
55 "StaticCopy",
56 "DynamicDraw",
57 "DynamicRead",
58 "DynamicCopy"
59 };
60
61 // access modes
62 const GLenum OpenGLBufferObjectAccess[2]=
63 {
64 #if GL_ES_VERSION_3_0 == 1
65 GL_MAP_WRITE_BIT,
66 GL_MAP_READ_BIT
67 #else
68 GL_WRITE_ONLY,
69 GL_READ_ONLY
70 #endif
71 };
72
73 // targets
74 const GLenum OpenGLBufferObjectTarget[2]=
75 {
76 GL_PIXEL_UNPACK_BUFFER,
77 GL_PIXEL_PACK_BUFFER
78 };
79
80
81 #ifdef VTK_PBO_DEBUG
82 #include <pthread.h> // for debugging with MPI, pthread_self()
83 #endif
84
85 // converting double to float behind the
86 // scene so we need sizeof(double)==4
87 template< class T >
88 class vtksizeof
89 {
90 public:
GetSize()91 static int GetSize() { return sizeof(T); }
92 };
93
94 template<>
95 class vtksizeof< double >
96 {
97 public:
GetSize()98 static int GetSize() { return sizeof(float); }
99 };
100
vtkGetSize(int type)101 static int vtkGetSize(int type)
102 {
103 switch (type)
104 {
105 vtkTemplateMacro(
106 return ::vtksizeof<VTK_TT>::GetSize();
107 );
108 }
109 return 0;
110 }
111
112 //----------------------------------------------------------------------------
113 vtkStandardNewMacro(vtkPixelBufferObject);
114
115 //----------------------------------------------------------------------------
vtkPixelBufferObject()116 vtkPixelBufferObject::vtkPixelBufferObject()
117 {
118 this->Handle = 0;
119 this->Context = nullptr;
120 this->BufferTarget = 0;
121 this->Components = 0;
122 this->Size = 0;
123 this->Type = VTK_UNSIGNED_CHAR;
124 this->Usage = StaticDraw;
125 }
126
127 //----------------------------------------------------------------------------
~vtkPixelBufferObject()128 vtkPixelBufferObject::~vtkPixelBufferObject()
129 {
130 this->DestroyBuffer();
131 }
132
133 //----------------------------------------------------------------------------
IsSupported(vtkRenderWindow *)134 bool vtkPixelBufferObject::IsSupported(vtkRenderWindow*)
135 {
136 return true;
137 }
138
139 //----------------------------------------------------------------------------
LoadRequiredExtensions(vtkRenderWindow * vtkNotUsed (renWin))140 bool vtkPixelBufferObject::LoadRequiredExtensions(vtkRenderWindow *vtkNotUsed(renWin))
141 {
142 return true;
143 }
144
145 //----------------------------------------------------------------------------
SetContext(vtkRenderWindow * renWin)146 void vtkPixelBufferObject::SetContext(vtkRenderWindow* renWin)
147 {
148 // avoid pointless re-assignment
149 if (this->Context==renWin)
150 {
151 return;
152 }
153 // free resource allocations
154 this->DestroyBuffer();
155 this->Context = nullptr;
156 this->Modified();
157 // all done if assigned null
158 if (!renWin)
159 {
160 return;
161 }
162
163 // update context
164 this->Context = renWin;
165 this->Context->MakeCurrent();
166 }
167
168 //----------------------------------------------------------------------------
GetContext()169 vtkRenderWindow* vtkPixelBufferObject::GetContext()
170 {
171 return this->Context;
172 }
173
174 //----------------------------------------------------------------------------
SetSize(unsigned int nTups,int nComps)175 void vtkPixelBufferObject::SetSize(unsigned int nTups, int nComps)
176 {
177 this->Size = nTups*nComps;
178 }
179
180 //----------------------------------------------------------------------------
Bind(BufferType type)181 void vtkPixelBufferObject::Bind(BufferType type)
182 {
183 assert(this->Context);
184
185 this->CreateBuffer();
186
187 GLenum target;
188 switch (type)
189 {
190 case vtkPixelBufferObject::PACKED_BUFFER:
191 target = GL_PIXEL_PACK_BUFFER;
192 break;
193
194 case vtkPixelBufferObject::UNPACKED_BUFFER:
195 target = GL_PIXEL_UNPACK_BUFFER;
196 break;
197
198 default:
199 vtkErrorMacro("Impossible BufferType.");
200 target = static_cast<GLenum>(this->BufferTarget);
201 break;
202 }
203
204 if (this->BufferTarget && this->BufferTarget != target)
205 {
206 this->UnBind();
207 }
208 this->BufferTarget = target;
209 glBindBuffer(static_cast<GLenum>(this->BufferTarget), this->Handle);
210 vtkOpenGLCheckErrorMacro("failed at glBindBuffer");
211 }
212
213 //----------------------------------------------------------------------------
UnBind()214 void vtkPixelBufferObject::UnBind()
215 {
216 assert(this->Context);
217 if (this->Handle && this->BufferTarget)
218 {
219 glBindBuffer(this->BufferTarget, 0);
220 vtkOpenGLCheckErrorMacro("failed at glBindBuffer(0)");
221 this->BufferTarget = 0;
222 }
223 }
224
225 //----------------------------------------------------------------------------
CreateBuffer()226 void vtkPixelBufferObject::CreateBuffer()
227 {
228 if (!this->Handle)
229 {
230 GLuint ioBuf;
231 glGenBuffers(1, &ioBuf);
232 vtkOpenGLCheckErrorMacro("failed at glGenBuffers");
233 this->Handle = ioBuf;
234 }
235 }
236
237 //----------------------------------------------------------------------------
DestroyBuffer()238 void vtkPixelBufferObject::DestroyBuffer()
239 {
240 // because we don't hold a reference to the render
241 // context we don't have any control on when it is
242 // destroyed. In fact it may be destroyed before
243 // we are(eg smart pointers), in which case we should
244 // do nothing.
245 if (this->Context && this->Handle)
246 {
247 GLuint ioBuf = static_cast<GLuint>(this->Handle);
248 glDeleteBuffers(1, &ioBuf);
249 vtkOpenGLCheckErrorMacro("failed at glDeleteBuffers");
250 }
251 this->Handle = 0;
252 }
253
254 //----------------------------------------------------------------------------
255 template <class T>
256 class vtkUpload3D
257 {
258 public:
Upload(void * pboPtr,T * inData,unsigned int dims[3],int numComponents,vtkIdType continuousIncrements[3],int components,int * componentList)259 static void Upload(void *pboPtr,
260 T *inData,
261 unsigned int dims[3],
262 int numComponents,
263 vtkIdType continuousIncrements[3],
264 int components,
265 int *componentList)
266 {
267 // cout<<"incs[3]="<<continuousIncrements[0]<<" "<<continuousIncrements[1]
268 // <<" "<<continuousIncrements[2]<<endl;
269
270 T* fIoMem = static_cast<T*>(pboPtr);
271
272 int numComp;
273 int *permutation=nullptr;
274 if(components==0)
275 {
276 numComp=numComponents;
277 permutation=new int[numComponents];
278 int i=0;
279 while(i<numComp)
280 {
281 permutation[i]=i;
282 ++i;
283 }
284 }
285 else
286 {
287 numComp=components;
288 permutation=componentList;
289 }
290
291 vtkIdType tupleSize =
292 static_cast<vtkIdType>(numComponents + continuousIncrements[0]);
293 for (unsigned int zz=0; zz < dims[2]; zz++)
294 {
295 for (unsigned int yy = 0; yy < dims[1]; yy++)
296 {
297 for (unsigned int xx=0; xx < dims[0]; xx++)
298 {
299 for (int compNo=0; compNo < numComp; compNo++)
300 {
301 *fIoMem = inData[permutation[compNo]];
302 // cout<<"upload[zz="<<zz<<"][yy="<<yy<<"][xx="<<xx<<"][compNo="<<
303 // compNo<<"] from inData to pbo="<<(double)(*fIoMem)<<endl;
304
305 fIoMem++;
306 }
307 inData += tupleSize+continuousIncrements[0];
308 }
309 // Reached end of row, go to start of next row.
310 inData += continuousIncrements[1] * tupleSize;
311 }
312 // Reached end of 2D plane.
313 inData += continuousIncrements[2] * tupleSize;
314 }
315
316 if(components==0)
317 {
318 delete[] permutation;
319 }
320 }
321 };
322
323 template<>
324 class vtkUpload3D< double >
325 {
326 public:
Upload(void * pboPtr,double * inData,unsigned int dims[3],int numComponents,vtkIdType continuousIncrements[3],int components,int * componentList)327 static void Upload(void *pboPtr,
328 double *inData,
329 unsigned int dims[3],
330 int numComponents,
331 vtkIdType continuousIncrements[3],
332 int components,
333 int *componentList)
334 {
335 float* fIoMem = static_cast<float*>(pboPtr);
336
337 int numComp;
338 int *permutation=nullptr;
339 if(components==0)
340 {
341 numComp=numComponents;
342 permutation=new int[numComponents];
343 int i=0;
344 while(i<numComp)
345 {
346 permutation[i]=i;
347 ++i;
348 }
349 }
350 else
351 {
352 numComp=components;
353 permutation=componentList;
354 }
355
356 vtkIdType tupleSize =
357 static_cast<vtkIdType>(numComponents + continuousIncrements[0]);
358 for (unsigned int zz=0; zz < dims[2]; zz++)
359 {
360 for (unsigned int yy = 0; yy < dims[1]; yy++)
361 {
362 for (unsigned int xx=0; xx < dims[0]; xx++)
363 {
364 for (int compNo=0; compNo < numComponents; compNo++)
365 {
366 *fIoMem = static_cast<float>(inData[permutation[compNo]]);
367
368 // cout<<"upload specialized double[zz="<<zz<<"][yy="<<yy<<"][xx="<<xx<<"][compNo="<<compNo<<"] from inData="<<(*inData)<<" to pbo="<<(*fIoMem)<<endl;
369
370 fIoMem++;
371 }
372
373 inData += tupleSize+continuousIncrements[0];
374 }
375 // Reached end of row, go to start of next row.
376 inData += continuousIncrements[1] * tupleSize;
377 }
378 // Reached end of 2D plane.
379 inData += continuousIncrements[2] * tupleSize;
380 }
381 if(components==0)
382 {
383 delete[] permutation;
384 }
385 }
386 };
387
388 //----------------------------------------------------------------------------
MapBuffer(unsigned int nbytes,BufferType mode)389 void *vtkPixelBufferObject::MapBuffer(
390 unsigned int nbytes,
391 BufferType mode)
392 {
393 // from vtk to opengl enums
394 GLenum target = OpenGLBufferObjectTarget[mode];
395 GLenum access = OpenGLBufferObjectAccess[mode];
396 GLenum usage = OpenGLBufferObjectUsage[mode];
397 GLuint size = static_cast<GLuint>(nbytes);
398 GLuint ioBuf = static_cast<GLuint>(this->Handle);
399
400 if (!ioBuf)
401 {
402 glGenBuffers(1, &ioBuf);
403 vtkOpenGLCheckErrorMacro("failed at glGenBuffers");
404 this->Handle = static_cast<unsigned int>(ioBuf);
405 }
406 this->BufferTarget = 0;
407
408 // pointer to the mapped memory
409 glBindBuffer(target, ioBuf);
410 vtkOpenGLCheckErrorMacro("failed at glBindBuffer");
411
412 glBufferData(target, size, nullptr, usage);
413 vtkOpenGLCheckErrorMacro("failed at glBufferData");
414
415 #if GL_ES_VERSION_3_0 == 1
416 void *pPBO = glMapBufferRange(target, 0, size, access);
417 #else
418 void *pPBO = glMapBuffer(target, access);
419 #endif
420 vtkOpenGLCheckErrorMacro("failed at glMapBuffer");
421
422 glBindBuffer(target, 0);
423
424 return pPBO;
425 }
426
427 //----------------------------------------------------------------------------
MapBuffer(int type,unsigned int numtuples,int comps,BufferType mode)428 void *vtkPixelBufferObject::MapBuffer(
429 int type,
430 unsigned int numtuples,
431 int comps,
432 BufferType mode)
433 {
434 // from vtk to opengl enums
435 this->Size = numtuples*comps;
436 this->Type = type;
437 this->Components = comps;
438 unsigned int size = ::vtkGetSize(type)*this->Size;
439
440 return this->MapBuffer(size, mode);
441 }
442
443 //----------------------------------------------------------------------------
MapBuffer(BufferType mode)444 void *vtkPixelBufferObject::MapBuffer(BufferType mode)
445 {
446 // from vtk to opengl enum
447 GLuint ioBuf = static_cast<GLuint>(this->Handle);
448 if (!ioBuf)
449 {
450 vtkErrorMacro("Uninitialized object");
451 return nullptr;
452 }
453 GLenum target = OpenGLBufferObjectTarget[mode];
454 GLenum access = OpenGLBufferObjectAccess[mode];
455
456 // pointer to the mnapped memory
457 glBindBuffer(target, ioBuf);
458 vtkOpenGLCheckErrorMacro("failed at glBindBuffer");
459
460 #if GL_ES_VERSION_3_0 == 1
461 void *pPBO = glMapBufferRange(this->BufferTarget, 0, this->Size, access);
462 #else
463 void *pPBO = glMapBuffer(target, access);
464 #endif
465 vtkOpenGLCheckErrorMacro("failed at glMapBuffer");
466
467 glBindBuffer(target, 0);
468 vtkOpenGLCheckErrorMacro("failed at glBindBuffer(0)");
469
470 this->BufferTarget = 0;
471
472 return pPBO;
473 }
474
475 //----------------------------------------------------------------------------
UnmapBuffer(BufferType mode)476 void vtkPixelBufferObject::UnmapBuffer(BufferType mode)
477 {
478 GLuint ioBuf = static_cast<GLuint>(this->Handle);
479 if (!ioBuf)
480 {
481 vtkErrorMacro("Uninitialized object");
482 return;
483 }
484 GLenum target = OpenGLBufferObjectTarget[mode];
485
486 glBindBuffer(target, ioBuf);
487 vtkOpenGLCheckErrorMacro("failed at glBindBuffer");
488
489 glUnmapBuffer(target);
490 vtkOpenGLCheckErrorMacro("failed at glUnmapBuffer");
491
492 glBindBuffer(target, 0);
493 vtkOpenGLCheckErrorMacro("failed at glBindBuffer(0)");
494 }
495
496 //----------------------------------------------------------------------------
Upload3D(int type,void * data,unsigned int dims[3],int numComponents,vtkIdType continuousIncrements[3],int components,int * componentList)497 bool vtkPixelBufferObject::Upload3D(
498 int type, void* data,
499 unsigned int dims[3],
500 int numComponents,
501 vtkIdType continuousIncrements[3],
502 int components,
503 int *componentList)
504 {
505 #ifdef VTK_PBO_TIMING
506 vtkTimerLog *timer=vtkTimerLog::New();
507 timer->StartTimer();
508 #endif
509 assert(this->Context);
510
511 this->CreateBuffer();
512 this->Bind(vtkPixelBufferObject::UNPACKED_BUFFER);
513
514 unsigned int size;
515
516 if(components==0)
517 {
518 size = dims[0]*dims[1]*dims[2]*static_cast<unsigned int>(numComponents);
519 }
520 else
521 {
522 size = dims[0]*dims[1]*dims[2]*static_cast<unsigned int>(components);
523 }
524
525 this->Components = numComponents;
526
527 if(data!=nullptr)
528 {
529 this->Usage=StreamDraw;
530 }
531 else
532 {
533 this->Usage=StreamRead;
534 }
535
536 glBufferData(this->BufferTarget,
537 size*static_cast<unsigned int>(::vtkGetSize(type)),
538 nullptr,OpenGLBufferObjectUsage[this->Usage]);
539 vtkOpenGLCheckErrorMacro("failed at glBufferData");
540 this->Type = type;
541 if (this->Type == VTK_DOUBLE)
542 {
543 this->Type = VTK_FLOAT;
544 }
545 this->Size = size;
546
547 if (data)
548 {
549 #if GL_ES_VERSION_3_0 == 1
550 void* ioMem = glMapBufferRange(this->BufferTarget, 0, size, GL_MAP_WRITE_BIT);
551 #else
552 void* ioMem = glMapBuffer(this->BufferTarget, GL_WRITE_ONLY);
553 #endif
554 vtkOpenGLCheckErrorMacro("");
555 switch (type)
556 {
557 vtkTemplateMacro(
558 ::vtkUpload3D< VTK_TT >::Upload(ioMem, static_cast<VTK_TT*>(data),
559 dims, numComponents,
560 continuousIncrements,
561 components,componentList);
562 );
563 default:
564 vtkErrorMacro("unsupported vtk type");
565 return false;
566 }
567 glUnmapBuffer(this->BufferTarget);
568 vtkOpenGLCheckErrorMacro("failed at glUnmapBuffer");
569 }
570
571 this->UnBind();
572 #ifdef VTK_PBO_TIMING
573 timer->StopTimer();
574 double time=timer->GetElapsedTime();
575 timer->Delete();
576 cout<<"Upload data to PBO"<<time<<" seconds."<<endl;
577 #endif
578 return true;
579 }
580
581 //----------------------------------------------------------------------------
Allocate(int type,unsigned int numtuples,int comps,BufferType mode)582 void vtkPixelBufferObject::Allocate(
583 int type,
584 unsigned int numtuples,
585 int comps,
586 BufferType mode)
587 {
588 assert(this->Context);
589
590 // from vtk to opengl enums
591 this->Size = numtuples*comps;
592 this->Type = type;
593 this->Components = comps;
594 unsigned int size = ::vtkGetSize(type)*this->Size;
595
596 this->Allocate(size, mode);
597 }
598
599 //----------------------------------------------------------------------------
Allocate(unsigned int nbytes,BufferType mode)600 void vtkPixelBufferObject::Allocate(
601 unsigned int nbytes,
602 BufferType mode)
603 {
604 assert(this->Context);
605
606 // from vtk to opengl enums
607 GLenum target = OpenGLBufferObjectTarget[mode];
608 GLenum usage = OpenGLBufferObjectUsage[mode];
609 GLuint size = static_cast<GLuint>(nbytes);
610 GLuint ioBuf = static_cast<GLuint>(this->Handle);
611
612 if (!ioBuf)
613 {
614 glGenBuffers(1, &ioBuf);
615 vtkOpenGLCheckErrorMacro("failed at glGenBuffers");
616 this->Handle = static_cast<unsigned int>(ioBuf);
617 }
618 this->BufferTarget = 0;
619
620 glBindBuffer(target, ioBuf);
621 vtkOpenGLCheckErrorMacro("failed at glBindBuffer");
622
623 glBufferData(target, size, nullptr, usage);
624 vtkOpenGLCheckErrorMacro("failed at glBufferData");
625
626 glBindBuffer(target, 0);
627 }
628
629
630 //----------------------------------------------------------------------------
ReleaseMemory()631 void vtkPixelBufferObject::ReleaseMemory()
632 {
633 assert(this->Context);
634 assert(this->Handle);
635
636 this->Bind(vtkPixelBufferObject::PACKED_BUFFER);
637 glBufferData(this->BufferTarget, 0, nullptr, GL_STREAM_DRAW);
638 vtkOpenGLCheckErrorMacro("failed at glBufferData");
639 this->Size = 0;
640 }
641
642 // ----------------------------------------------------------------------------
643 template <class TPBO, class TCPU>
vtkDownload3D(TPBO * pboPtr,TCPU * cpuPtr,unsigned int dims[3],int numcomps,vtkIdType increments[3])644 void vtkDownload3D(TPBO *pboPtr,
645 TCPU *cpuPtr,
646 unsigned int dims[3],
647 int numcomps,
648 vtkIdType increments[3])
649 {
650 #ifdef VTK_PBO_DEBUG
651 cout << "template vtkDownload3D" << endl;
652 #endif
653 vtkIdType tupleSize = static_cast<vtkIdType>(numcomps + increments[0]);
654 for (unsigned int zz=0; zz < dims[2]; zz++)
655 {
656 for (unsigned int yy = 0; yy < dims[1]; yy++)
657 {
658 for (unsigned int xx=0; xx < dims[0]; xx++)
659 {
660 for (int comp=0; comp < numcomps; comp++)
661 {
662 *cpuPtr = static_cast<TCPU>(*pboPtr);
663 // cout<<"download[zz="<<zz<<"][yy="<<yy<<"][xx="<<xx<<"][comp="<<comp<<"] from pbo="<<(*pboPtr)<<" to cpu="<<(*cpuPtr)<<endl;
664 pboPtr++;
665 cpuPtr++;
666 }
667 cpuPtr += increments[0];
668 }
669 // Reached end of row, go to start of next row.
670 cpuPtr += increments[1]*tupleSize;
671 }
672 cpuPtr += increments[2]*tupleSize;
673 }
674 }
675
676 // ----------------------------------------------------------------------------
677 template <class OType>
vtkDownload3DSpe(int iType,void * iData,OType odata,unsigned int dims[3],int numcomps,vtkIdType increments[3])678 void vtkDownload3DSpe(int iType,
679 void *iData,
680 OType odata,
681 unsigned int dims[3],
682 int numcomps,
683 vtkIdType increments[3])
684 {
685 #ifdef VTK_PBO_DEBUG
686 cout << "vtkDownload3DSpe" << endl;
687 #endif
688 switch(iType)
689 {
690 vtkTemplateMacro(
691 ::vtkDownload3D(static_cast<VTK_TT*>(iData), odata,
692 dims, numcomps, increments);
693 );
694 default:
695 #ifdef VTK_PBO_DEBUG
696 cout << "d nested default." << endl;
697 #endif
698 break;
699 }
700 }
701
702 //----------------------------------------------------------------------------
Download3D(int type,void * data,unsigned int dims[3],int numcomps,vtkIdType increments[3])703 bool vtkPixelBufferObject::Download3D(
704 int type, void* data,
705 unsigned int dims[3],
706 int numcomps,
707 vtkIdType increments[3])
708 {
709 #ifdef VTK_PBO_TIMING
710 vtkTimerLog *timer=vtkTimerLog::New();
711 timer->StartTimer();
712 #endif
713 assert(this->Context);
714
715 if (!this->Handle)
716 {
717 vtkErrorMacro("No GPU data available.");
718 return false;
719 }
720
721 if (this->Size < dims[0]*dims[1]*dims[2]*static_cast<unsigned int>(numcomps))
722 {
723 vtkErrorMacro("Size too small.");
724 return false;
725 }
726
727 this->Bind(vtkPixelBufferObject::PACKED_BUFFER);
728
729
730 #if GL_ES_VERSION_3_0 == 1
731 void* ioMem = glMapBufferRange(this->BufferTarget, 0, this->Size, GL_MAP_READ_BIT);
732 #else
733 void* ioMem = glMapBuffer(this->BufferTarget, GL_READ_ONLY);
734 #endif
735 vtkOpenGLCheckErrorMacro("failed at glMapBuffer");
736
737 switch (type)
738 {
739 vtkTemplateMacro(
740 VTK_TT* odata = static_cast<VTK_TT*>(data);
741 ::vtkDownload3DSpe(this->Type,ioMem,odata,dims,numcomps,increments);
742 );
743 default:
744 vtkErrorMacro("unsupported vtk type");
745 return false;
746 }
747 glUnmapBuffer(this->BufferTarget);
748 vtkOpenGLCheckErrorMacro("failed at glUnmapBuffer");
749 this->UnBind();
750
751 #ifdef VTK_PBO_TIMING
752 timer->StopTimer();
753 double time=timer->GetElapsedTime();
754 timer->Delete();
755 cout<<"dowmload data from PBO"<<time<<" seconds."<<endl;
756 #endif
757
758 return true;
759 }
760
761 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)762 void vtkPixelBufferObject::PrintSelf(ostream& os, vtkIndent indent)
763 {
764 this->Superclass::PrintSelf(os, indent);
765 os << indent << "Context: " << this->Context << endl;
766 os << indent << "Handle: " << this->Handle << endl;
767 os << indent << "Size: " << this->Size << endl;
768 os << indent << "VTK Type: " << vtkImageScalarTypeNameMacro(this->Type)
769 << endl;
770 os << indent << "Usage:" << BufferObjectUsageAsString[this->Usage] << endl;
771 }
772