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