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