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