Salome HOME
Merge remote-tracking branch 'origin/rnv/vtk_opengl2_backend' into V8_1_BR
[modules/gui.git] / src / VTKViewer / VTKViewer_PolyDataMapper.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifdef VTK_OPENGL2
20 #define GL_GLEXT_PROTOTYPES
21 #endif
22
23 #include "VTKViewer_PolyDataMapper.h"
24 #include "VTKViewer_MarkerUtils.h"
25
26 #include <utilities.h>
27
28 #include <QString>
29
30 #include <vtkCellArray.h>
31 #include <vtkXMLImageDataReader.h>
32 #include <vtkImageData.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkPointData.h>
35 #include <vtkPolyData.h>
36 #include <vtkProperty.h>
37 #include <vtkRenderer.h>
38 #include <vtkSmartPointer.h>
39 #include <vtkTimerLog.h>
40 #include <vtkWindow.h>
41 #include <vtkRenderWindow.h>
42 #include <vtkCommand.h>
43 #include <vtkCellData.h>
44
45 #ifndef WIN32
46 # ifndef GLX_GLXEXT_LEGACY
47 #  define GLX_GLXEXT_LEGACY
48 # endif
49 # include <GL/glx.h>
50 # include <dlfcn.h>
51 #else
52 # include <wingdi.h>
53 #endif
54
55 #ifndef VTK_IMPLEMENT_MESA_CXX
56 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
57 #endif
58
59 // some definitions for what the polydata has in it
60 #define VTK_PDPSM_COLORS             0x0001
61 #define VTK_PDPSM_CELL_COLORS        0x0002
62 #define VTK_PDPSM_POINT_TYPE_FLOAT   0x0004
63 #define VTK_PDPSM_POINT_TYPE_DOUBLE  0x0008
64 #define VTK_PDPSM_NORMAL_TYPE_FLOAT  0x0010
65 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
66 #define VTK_PDPSM_OPAQUE_COLORS      0x0040
67
68 typedef GLfloat TBall;
69
70 #ifdef WIN32
71   #ifdef max
72     #undef max
73   #endif
74 #endif
75
76 // ----------------------------------------------- Special Textures -----------------------------------
77 // texture id for balls drawing
78 #define BallTextureId 0 
79
80
81 //-----------------------------------------------------------------------------
82 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
83 {
84   Q_INIT_RESOURCE( VTKViewer );
85
86   this->ExtensionsInitialized     = ES_None;
87
88   this->PointSpriteTexture        = 0;
89
90   this->MarkerEnabled             = false;
91   this->MarkerType                = VTK::MT_NONE;
92   this->MarkerScale               = VTK::MS_NONE;
93   this->MarkerId                  = 0;
94   this->BallEnabled               = false;
95   this->BallScale                 = 1.0;
96   this->PointProgram              = 0;
97 #ifdef VTK_OPENGL2
98   this->VertexShader              = 0;
99   this->FragmentShader            = 0;
100 #endif
101
102   this->OpenGLHelper.Init();
103 }
104
105 //-----------------------------------------------------------------------------
106 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
107 {
108   if( PointSpriteTexture > 0 )
109     glDeleteTextures( 1, &PointSpriteTexture );
110
111 #ifdef VTK_OPENGL2
112   this->OpenGLHelper.DestroyShaderProgram( this->PointProgram, this->VertexShader, this->FragmentShader);
113 #endif
114 }
115
116 //-----------------------------------------------------------------------------
117 int VTKViewer_PolyDataMapper::InitShader()
118 {
119 #ifdef VTK_OPENGL2
120   std::string filePath = std::string( getenv( "GUI_ROOT_DIR") ) + "/share/salome/resources/gui/Point";
121   if( !this->OpenGLHelper.CreateShaderProgram(filePath, this->PointProgram, this->VertexShader, this->FragmentShader) )
122     return false;
123
124   // Get uniform locations.
125   this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
126
127   this->myLocations.ModelViewProjection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uModelViewProjectionMatrix" );
128   this->myLocations.Projection          = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uProjectionMatrix" );
129   this->myLocations.GeneralPointSize    = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uGeneralPointSize" );
130   this->myLocations.PointSprite         = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uPointSprite" );
131
132   this->OpenGLHelper.vglUseProgramObjectARB( 0 );
133
134   this->OpenGLHelper.vglGenVertexArraysARB(1, &this->VertexArrayObject);
135 #else
136   std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
137                          "/share/salome/resources/gui/Vertex_Program_ARB.txt";
138
139   char* shader = readFromFile( fileName );
140
141   GLhandleARB VertexShader = this->OpenGLHelper.vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
142   this->OpenGLHelper.vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
143   this->OpenGLHelper.vglCompileShaderARB( VertexShader );
144
145   this->PointProgram = this->OpenGLHelper.vglCreateProgramObjectARB();
146   this->OpenGLHelper.vglAttachObjectARB( this->PointProgram, VertexShader );
147
148   this->OpenGLHelper.vglLinkProgramARB( this->PointProgram );
149   free( shader );
150 #endif
151
152   return ES_Ok;
153 }
154
155
156 //-----------------------------------------------------------------------------
157 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
158 {
159   if( this->MarkerEnabled == theMarkerEnabled )
160     return;
161
162   this->MarkerEnabled = theMarkerEnabled;
163   this->Modified();
164 }
165
166 //-----------------------------------------------------------------------------
167 // Definition of structures and fuctions used in SetBallEnabled() method
168 namespace VTK
169 {
170   //----------------------------------------------------------------------------
171   vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
172     if( !theMainTexture || !theAlphaTexture )
173       return 0;
174     
175     vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
176     vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
177     
178     aMainReader->SetFileName( theMainTexture );
179     anAlphaReader->SetFileName( theAlphaTexture );
180
181     aMainReader->Update();
182     anAlphaReader->Update();
183     
184     vtkImageData* aMainImageData = aMainReader->GetOutput();
185     vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
186     
187     int* aMainImageSize = aMainImageData->GetDimensions();
188     int* anAlphaImageSize = anAlphaImageData->GetDimensions();
189     if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
190       return NULL;
191
192     vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
193     aCompositeImageData->Delete();
194     
195     int aNbCompositeComponents = 4;
196     aCompositeImageData->SetDimensions(aMainImageSize);
197     aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
198     
199     unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
200     unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
201     unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
202
203     int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
204     int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
205     int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
206
207     int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
208     for(; aCompositeId < aCompositeSize;) {
209       aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
210       aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
211       aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
212       aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
213
214       aMainId += aNbMainComponents;
215       anAlphaId += aNbAlphaComponents;
216       aCompositeId += aNbCompositeComponents;
217     }
218     aMainReader->Delete();
219     anAlphaReader->Delete();
220     return aCompositeImageData;
221   }  
222 }
223
224 //-----------------------------------------------------------------------------
225 bool VTKViewer_PolyDataMapper::GetBallEnabled()
226 {
227   return this->BallEnabled;
228 }
229 //-----------------------------------------------------------------------------
230 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
231
232   if( this->BallEnabled == theBallEnabled )
233     return;
234   else 
235     this->BallEnabled = theBallEnabled;
236
237   if(!this->BallEnabled) {
238     this->ImageData = NULL;
239   }
240
241   if(this->BallEnabled) {
242     if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
243       QString aMainTexture  = getenv( "GUI_ROOT_DIR" );
244       aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
245       
246       QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
247       anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
248       vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toLatin1().constData(), anAlphaTexture.toLatin1().constData() );
249       this->SpecialTextures[BallTextureId] = aTextureValue;
250     }
251     this->ImageData = this->SpecialTextures[BallTextureId];
252   }
253   this->Modified();
254 }
255
256 //-----------------------------------------------------------------------------
257 double VTKViewer_PolyDataMapper::GetBallScale()
258 {
259   return this->BallScale;
260 }
261 //-----------------------------------------------------------------------------
262 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
263 {
264   if( this->BallScale == theBallScale )
265     return;
266   this->BallScale = theBallScale;
267 }
268
269 //-----------------------------------------------------------------------------
270 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
271 {
272   if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
273     return;
274
275   this->MarkerType = theMarkerType;
276   this->MarkerScale = theMarkerScale;
277
278   if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
279     this->ImageData = NULL;
280     this->Modified();
281     return;
282   }
283
284   int aMarkerType = (int)this->MarkerType;
285   int aMarkerScale = (int)this->MarkerScale;
286
287   int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
288
289   if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
290   {
291     QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
292     VTK::MarkerTexture aMarkerTexture;
293     if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
294       this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
295   }
296
297   this->ImageData = this->StandardTextures[ anId ];
298   this->Modified();
299 }
300
301 //-----------------------------------------------------------------------------
302 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
303 {
304   if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
305     return;
306
307   this->MarkerType = VTK::MT_USER;
308   this->MarkerId = theMarkerId;
309
310   if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
311     this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
312
313   this->ImageData = this->CustomTextures[ theMarkerId ];
314   this->Modified();
315 }
316
317 //-----------------------------------------------------------------------------
318 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
319 {
320   return this->MarkerType;
321 }
322
323 //-----------------------------------------------------------------------------
324 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
325 {
326   return this->MarkerScale;
327 }
328
329 //-----------------------------------------------------------------------------
330 int VTKViewer_PolyDataMapper::GetMarkerTexture()
331 {
332   return this->MarkerId;
333 }
334
335 //-----------------------------------------------------------------------------
336 int VTKViewer_PolyDataMapper::InitExtensions()
337 {
338 #ifdef VTK_OPENGL2
339   int n = 0;
340   std::ostringstream strm;
341   glGetIntegerv(GL_NUM_EXTENSIONS, &n);
342   for (int i = 0; i < n; i++)
343     {
344       const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
345       strm<< exti <<" ";
346     }
347   std::string s = strm.str();
348   const char* ext = s.c_str();
349 #else  
350   const char* ext = (const char*)glGetString( GL_EXTENSIONS );
351 #endif
352   if( !this->OpenGLHelper.IsInitialized() || !ext ||
353       strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
354       strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
355       strstr( ext, "GL_ARB_shader_objects") == NULL )
356   {
357     MESSAGE("Initializing ARB extensions failed");
358     return ES_Error;
359   }
360
361   return this->InitShader();
362 }
363
364 //-----------------------------------------------------------------------------
365 void VTKViewer_PolyDataMapper::InitPointSprites()
366 {
367   glEnable( GL_POINT_SPRITE_ARB );
368   glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
369
370   glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
371
372   glDepthFunc( GL_LEQUAL );
373   glEnable( GL_DEPTH_TEST );
374
375   glEnable( GL_ALPHA_TEST );
376   if(!this->BallEnabled) {
377     glAlphaFunc( GL_GREATER, 0.0 );
378   }
379   else { 
380     glAlphaFunc( GL_GREATER, 0.5 );
381   }
382
383   glDisable( GL_LIGHTING );
384
385   glDisable( GL_COLOR_MATERIAL );
386 }
387
388 //-----------------------------------------------------------------------------
389 void VTKViewer_PolyDataMapper::CleanupPointSprites()
390 {
391   glPopAttrib();
392
393   glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
394   glDisable( GL_POINT_SPRITE_ARB );
395 }
396
397 //-----------------------------------------------------------------------------
398 void VTKViewer_PolyDataMapper::InitTextures()
399 {
400   if( !this->ImageData.GetPointer() )
401     return;
402
403   glEnable( GL_TEXTURE_2D );
404   if( this->PointSpriteTexture == 0 ) {
405     glGenTextures( 1, &this->PointSpriteTexture );
406   }
407 #ifdef VTK_OPENGL2
408   glActiveTexture( GL_TEXTURE0 );
409 #endif
410   glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
411   glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
412   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
413   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
414   
415   if(this->BallEnabled) {
416     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
417     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
418   } else {
419     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
420     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
421   }
422
423   int* aSize = this->ImageData->GetDimensions();
424   unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
425   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
426                 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
427
428 #ifdef VTK_OPENGL2
429   // Set sampler.
430   this->OpenGLHelper.vglUniform1iARB( this->myLocations.PointSprite, GL_TEXTURE0 );
431 #endif
432 }
433
434 //-----------------------------------------------------------------------------
435 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
436 {
437   bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) || 
438     this->BallEnabled;
439   if( isUsePointSprites )
440   {
441     if( this->ExtensionsInitialized != ES_Ok )
442       this->ExtensionsInitialized = this->InitExtensions();
443     this->InitPointSprites();
444     this->InitTextures();
445   }
446
447   if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
448     MAPPER_SUPERCLASS::RenderPiece( ren, act );
449     if( isUsePointSprites )
450       this->CleanupPointSprites();
451     glBindTexture( GL_TEXTURE_2D, 0 );
452   } else {
453     vtkIdType numPts;
454     vtkPolyData *input= this->GetInput();
455
456     //
457     // make sure that we've been properly initialized
458     //
459     if (ren->GetRenderWindow()->CheckAbortStatus())
460       return;
461
462     if ( input == NULL )
463     {
464       vtkErrorMacro(<< "No input!");
465       return;
466     }
467     else
468     {
469       this->InvokeEvent(vtkCommand::StartEvent,NULL);
470       this->Update();
471       this->InvokeEvent(vtkCommand::EndEvent,NULL);
472       numPts = input->GetNumberOfPoints();
473     }
474
475     if (numPts == 0)
476     {
477       vtkDebugMacro(<< "No points!");
478       return;
479     }
480
481     // make sure our window is current
482     ren->GetRenderWindow()->MakeCurrent();
483
484
485     this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
486
487 #ifndef VTK_OPENGL2
488     //
489     // if something has changed regenerate colors and display lists
490     // if required
491     //
492     int noAbort=1;
493     if ( this->GetMTime() > this->BuildTime ||
494          input->GetMTime() > this->BuildTime ||
495          act->GetProperty()->GetMTime() > this->BuildTime ||
496          ren->GetRenderWindow() != this->LastWindow)
497     {
498       // sets this->Colors as side effect
499       this->MapScalars( act->GetProperty()->GetOpacity() );
500
501       if (!this->ImmediateModeRendering &&
502           !this->GetGlobalImmediateModeRendering())
503       {
504         this->ReleaseGraphicsResources(ren->GetRenderWindow());
505         this->LastWindow = ren->GetRenderWindow();
506
507         // get a unique display list id
508         this->ListId = glGenLists(1);
509         glNewList(this->ListId,GL_COMPILE);
510
511         noAbort = this->Draw(ren,act);
512         glEndList();
513
514         // Time the actual drawing
515         this->Timer->StartTimer();
516         glCallList(this->ListId);
517         this->Timer->StopTimer();
518       }
519       else
520       {
521         this->ReleaseGraphicsResources(ren->GetRenderWindow());
522         this->LastWindow = ren->GetRenderWindow();
523       }
524       if (noAbort)
525         this->BuildTime.Modified();
526     }
527     // if nothing changed but we are using display lists, draw it
528     else
529     {
530       if (!this->ImmediateModeRendering &&
531           !this->GetGlobalImmediateModeRendering())
532       {
533         // Time the actual drawing
534         this->Timer->StartTimer();
535         glCallList(this->ListId);
536         this->Timer->StopTimer();
537       }
538     }
539
540     // if we are in immediate mode rendering we always
541     // want to draw the primitives here
542     if (this->ImmediateModeRendering ||
543         this->GetGlobalImmediateModeRendering())
544     {
545       // sets this->Colors as side effect
546       this->MapScalars( act->GetProperty()->GetOpacity() );
547
548       // Time the actual drawing
549       this->Timer->StartTimer();
550       this->Draw(ren,act);
551       this->Timer->StopTimer();
552     }
553
554     this->TimeToDraw = (float)this->Timer->GetElapsedTime();
555
556     // If the timer is not accurate enough, set it to a small
557     // time so that it is not zero
558     if ( this->TimeToDraw == 0.0 )
559       this->TimeToDraw = 0.0001;
560 #else
561     //this->RenderPieceStart(ren, act);
562     this->RenderPieceDraw(ren, act);
563     //    this->RenderEdges(ren,act);
564     //this->RenderPieceFinish(ren, act);
565 #endif    
566     this->OpenGLHelper.vglUseProgramObjectARB( 0 );
567     this->CleanupPointSprites();
568     glBindTexture( GL_TEXTURE_2D, 0 );
569   }  
570 }
571
572 //-----------------------------------------------------------------------------
573 // Definition of structures and fuctions used in Draw() method
574 namespace VTK
575 {
576   //-----------------------------------------------------------------------------
577   struct TVertex
578   {
579     GLfloat r, g, b, a;
580     GLfloat vx, vy, vz;
581   };
582
583   //-----------------------------------------------------------------------------
584   struct TColorFunctorBase
585   {
586     double myAlpha;
587
588     TColorFunctorBase( vtkProperty* theProperty )
589     {
590       myAlpha = theProperty->GetOpacity();
591     }
592
593     virtual
594     void
595     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
596   };
597
598   //-----------------------------------------------------------------------------
599   struct TPropertyColor : TColorFunctorBase
600   {
601     double myColor[3];
602
603     TPropertyColor( vtkProperty* theProperty ):
604       TColorFunctorBase( theProperty )
605     {
606       theProperty->GetColor( myColor );
607     }
608
609     virtual
610     void
611     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
612     {
613       theVertex.r = myColor[0];
614       theVertex.g = myColor[1];
615       theVertex.b = myColor[2];
616       theVertex.a = myAlpha;
617     }
618   };
619
620   //-----------------------------------------------------------------------------
621   struct TColors2Color : TColorFunctorBase
622   {
623     vtkUnsignedCharArray* myColors;
624
625     TColors2Color( vtkProperty* theProperty,
626                    vtkUnsignedCharArray* theColors ):
627       TColorFunctorBase( theProperty ),
628       myColors( theColors )
629     {}
630
631     virtual
632     void
633     get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
634     {
635       vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
636       unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
637
638       theVertex.r = int( aColor[0] ) / 255.0;
639       theVertex.g = int( aColor[1] ) / 255.0;
640       theVertex.b = int( aColor[2] ) / 255.0;
641       theVertex.a = myAlpha;
642     }
643
644     virtual
645     vtkIdType
646     GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
647   };
648
649   //-----------------------------------------------------------------------------
650   struct TPointColors2Color : TColors2Color
651   {
652     TPointColors2Color( vtkProperty* theProperty,
653                         vtkUnsignedCharArray* theColors ):
654       TColors2Color( theProperty, theColors )
655     {}
656
657     virtual
658     vtkIdType
659     GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
660     {
661       return thePointId;
662     }
663   };
664
665   //-----------------------------------------------------------------------------
666   struct TCellColors2Color : TColors2Color
667   {
668     TCellColors2Color( vtkProperty* theProperty,
669                        vtkUnsignedCharArray* theColors ):
670       TColors2Color( theProperty, theColors )
671     {}
672
673     virtual
674     vtkIdType
675     GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
676     {
677       return theCellId;
678     }
679   };
680
681   //-----------------------------------------------------------------------------
682   template < class TCoordinates >
683   void DrawPoints( TCoordinates* theStartPoints,
684                    vtkCellArray* theCells,
685                    TColorFunctorBase* theColorFunctor,
686                    TVertex* theVertexArr,
687                    vtkIdType &theCellId,
688                    vtkIdType &theVertexId,
689                    TBall* theBallArr,
690                    vtkDataArray* theDiamArray,
691                    double theBallScale )
692   {
693     vtkIdType* ptIds = theCells->GetPointer();
694     vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
695
696     bool mapBalls = false; 
697     if(theBallArr && theDiamArray) {
698       mapBalls = true;
699     }
700
701     while ( ptIds < endPtIds ) {
702       vtkIdType nPts = *ptIds;
703       ++ptIds;
704
705       while ( nPts > 0 ) {
706         TVertex& aVertex = theVertexArr[ theVertexId ];
707         vtkIdType aPointId = *ptIds;
708
709         TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
710         aVertex.vx = anOffsetPoints[0];
711         aVertex.vy = anOffsetPoints[1];
712         aVertex.vz = anOffsetPoints[2];
713
714         theColorFunctor->get( aVertex, aPointId, theCellId );
715
716         ++theVertexId;
717         ++ptIds; 
718         --nPts; 
719       }
720       
721       if(mapBalls){
722         theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
723       }
724
725       ++theCellId;
726     }
727   }
728
729   //-----------------------------------------------------------------------------
730   template < class TCoordinates >
731   void DrawCellsPoints( vtkPolyData* theInput,
732                         vtkPoints* thePoints,
733                         TColorFunctorBase* theColorFunctor,
734                         TVertex* theVertexArr,
735                         TBall* theBallArr,
736                         double theBallScale )
737   {
738     vtkIdType aCellId = 0, aVertexId = 0;
739
740     TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
741     vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;    
742
743     if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
744       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
745     }
746   
747     if ( vtkCellArray* aCellArray = theInput->GetLines() )
748       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
749   
750     if ( vtkCellArray* aCellArray = theInput->GetPolys() )
751       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
752   
753     if ( vtkCellArray* aCellArray = theInput->GetStrips() )
754       DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale ); 
755   }
756 } // namespace VTK
757
758 #ifndef VTK_OPENGL2
759 //-----------------------------------------------------------------------------
760 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
761 {
762   int noAbort = 1;
763   if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
764     return MAPPER_SUPERCLASS::Draw( ren, act );
765
766   InternalDraw( ren, act );
767
768   return noAbort;
769 }
770 #else
771 //-----------------------------------------------------------------------------
772 void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
773   int noAbort = 1;
774   if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
775     MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
776     return;
777   }
778   InternalDraw( ren, act );
779 }
780 #endif
781
782 #ifdef VTK_OPENGL2
783 #include <vtkCamera.h>
784 #include <vtkOpenGLCamera.h>
785 #include <vtkOpenGLActor.h>
786 #endif
787
788 void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
789   vtkUnsignedCharArray* colors = NULL;
790   vtkPolyData* input  = this->GetInput();
791   vtkPoints* points;
792   int cellScalars = 0;
793   vtkProperty* prop = act->GetProperty();
794
795   points = input->GetPoints();
796
797   if ( this->Colors )
798   {
799     if(!this->BallEnabled) {
800       colors = this->Colors;
801       if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
802             this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
803             !input->GetPointData()->GetScalars() )
804            && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
805         cellScalars = 1;
806     }
807   }
808
809   {
810     vtkIdType aTotalConnectivitySize = 0;
811     vtkIdType aNbCells = 0;
812
813     if ( vtkCellArray* aCellArray = input->GetVerts() ) {
814       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
815       aNbCells += aCellArray->GetNumberOfCells();
816     }
817
818     if ( vtkCellArray* aCellArray = input->GetLines() ) {
819       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
820       aNbCells += aCellArray->GetNumberOfCells();
821     }
822
823     if ( vtkCellArray* aCellArray = input->GetPolys() ) {
824       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
825       aNbCells += aCellArray->GetNumberOfCells();
826     }
827
828     if ( vtkCellArray* aCellArray = input->GetStrips() ) {
829       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
830       aNbCells += aCellArray->GetNumberOfCells();
831     }
832
833     if ( aTotalConnectivitySize > 0 ) {
834       VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
835       
836       TBall* aBallArray = 0;
837
838       if(this->BallEnabled) {
839         aBallArray = new TBall[aNbCells];
840       }
841
842       int* aSize = this->ImageData->GetDimensions();
843       //glPointSize( std::max( aSize[0], aSize[1] ) );
844
845       int aMode = 0; // to remove
846       {
847         VTK::TColorFunctorBase* aColorFunctor = NULL;
848         if( colors && aMode != 1 ) {
849           if ( cellScalars )
850             aColorFunctor = new VTK::TCellColors2Color( prop, colors );
851           else
852             aColorFunctor = new VTK::TPointColors2Color( prop, colors );
853         } else {
854           aColorFunctor = new VTK::TPropertyColor( prop );
855         }
856         if ( points->GetDataType() == VTK_FLOAT )
857           VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
858         else
859           VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
860
861         delete aColorFunctor;
862       }
863
864       if( this->ExtensionsInitialized == ES_Ok ) {
865 #ifdef VTK_OPENGL2
866         this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
867
868         vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
869         vtkMatrix4x4 *wcdc;
870         vtkMatrix4x4 *wcvc;
871         vtkMatrix3x3 *norms;
872         vtkMatrix4x4 *vcdc;
873         cam->GetKeyMatrices(ren,wcvc,norms,vcdc,wcdc);
874         if (!act->GetIsIdentity())
875         {
876           vtkMatrix4x4 *mcwc;
877           vtkMatrix3x3 *anorms;
878           ((vtkOpenGLActor *)act)->GetKeyMatrices( mcwc, anorms );
879           vtkMatrix4x4::Multiply4x4( mcwc, wcdc, this->TempMatrix4 );
880
881           this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, this->TempMatrix4 );
882         }
883         else
884         {
885                 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, wcdc );
886         }
887         this->OpenGLHelper.SetUniformMatrix( this->myLocations.Projection, vcdc );
888
889         this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, std::max( aSize[0], aSize[1] ) );
890
891         GLuint aBufferObjectID, aDiamsID = 0;
892
893         this->OpenGLHelper.vglBindVertexArrayARB( this->VertexArrayObject );
894         this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
895         this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
896         
897         int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
898         this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
899         
900         delete [] aVertexArr;
901         
902
903         GLint colorAttrib  = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Color" );
904         GLint vertexAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Vertex" );
905         GLint diamAttrib   = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Diameter" );
906
907         GLsizei vertexSize = sizeof(VTK::TVertex);
908
909         this->OpenGLHelper.vglVertexAttribPointerARB( colorAttrib, 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0 );
910         this->OpenGLHelper.vglEnableVertexAttribArrayARB( colorAttrib );
911
912         this->OpenGLHelper.vglVertexAttribPointerARB( vertexAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 4) );
913         this->OpenGLHelper.vglEnableVertexAttribArrayARB( vertexAttrib );
914
915        if(this->BallEnabled) {
916          // Don't use uniform variable.
917          this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, -1 );
918          this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
919          this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
920
921          int aDiamsSize = sizeof(TBall)*aNbCells;
922          this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
923
924          delete [] aBallArray;
925
926          this->OpenGLHelper.vglVertexAttribPointerARB( diamAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0 );
927          this->OpenGLHelper.vglEnableVertexAttribArrayARB( diamAttrib );
928        }
929
930        glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
931
932        if( this->BallEnabled ) {
933          this->OpenGLHelper.vglDisableVertexAttribArrayARB( diamAttrib );
934          this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
935          this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
936        }
937
938        this->OpenGLHelper.vglDisableVertexAttribArrayARB( colorAttrib );
939        this->OpenGLHelper.vglDisableVertexAttribArrayARB( vertexAttrib );
940        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
941        this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
942        this->OpenGLHelper.vglBindVertexArrayARB( 0 );
943
944        this->OpenGLHelper.vglUseProgramObjectARB( 0 );
945 #else
946        GLuint aBufferObjectID, aDiamsID = 0;
947        GLint attribute_diams = -1;
948
949        this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
950        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
951
952        int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
953        this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
954
955        delete [] aVertexArr;
956
957        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
958        this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
959         
960         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
961         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
962         
963         glEnableClientState( GL_VERTEX_ARRAY );
964         glEnableClientState( GL_COLOR_ARRAY );
965
966         if(this->BallEnabled) {
967                 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
968                 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
969
970           int aDiamsSize = sizeof(TBall)*aNbCells;
971           this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
972
973           delete [] aBallArray;
974           this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
975           this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
976
977           attribute_diams = vglGetAttribLocationARB(this->PointProgram, "diameter");
978           this->OpenGLHelper.vglEnableVertexAttribArrayARB(attribute_diams);
979           this->OpenGLHelper.vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
980           this->OpenGLHelper.vglVertexAttribPointerARB(
981                                     attribute_diams,   // attribute
982                                     1,                 // number of elements per vertex, here (diameter)
983                                     GL_FLOAT,          // the type of each element
984                                     GL_FALSE,          // take our values as-is
985                                     0,                 // no extra data between each position
986                                     0                  // offset of first element
987                                     );
988         }
989
990         glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
991         
992         glDisableClientState( GL_COLOR_ARRAY );
993         glDisableClientState( GL_VERTEX_ARRAY );       
994         this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
995
996         if(this->BallEnabled) {
997                 this->OpenGLHelper.vglDisableVertexAttribArrayARB(attribute_diams);
998                 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
999         }
1000
1001 #endif
1002           } else { // there are no extensions
1003         glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1004         glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), 
1005                          (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1006
1007         glEnableClientState( GL_VERTEX_ARRAY );
1008         glEnableClientState( GL_COLOR_ARRAY );
1009         
1010         glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1011         
1012         glDisableClientState( GL_COLOR_ARRAY );
1013         glDisableClientState( GL_VERTEX_ARRAY );
1014
1015         delete [] aVertexArr;
1016       }
1017     }
1018   }
1019
1020   this->UpdateProgress(1.0);
1021 }