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