]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/visu.git] / src / PIPELINE / VISU_OpenGLPointSpriteMapper.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 // File:    VISU_OpenGLPointSpriteMapper.cxx
25 // Author:  
26 // Module : VISU
27
28 #include "VISU_OpenGLPointSpriteMapper.hxx"
29
30 #include "SVTK_Extension.h"
31
32 #include <vtkCamera.h>
33 #include <vtkCellArray.h>
34 #include <vtkCellData.h>
35 #include <vtkCommand.h>
36 #include <vtkImageData.h>
37 #include <vtkMatrix4x4.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkRenderer.h>
40 #include <vtkRenderWindow.h>
41 #include <vtkPointData.h>
42 #include <vtkPolyData.h>
43 #include <vtkPolygon.h>
44 #include <vtkProperty.h>
45 #include <vtkTimerLog.h>
46 #include <vtkTriangle.h>
47
48 #include <stdio.h>
49 #include <cmath>
50 #include <string>
51
52 #ifndef WNT
53 # ifndef GLX_GLXEXT_LEGACY
54 #  define GLX_GLXEXT_LEGACY
55 # endif
56 # include <GL/glx.h>
57 # include <dlfcn.h>
58 #else
59 # include <wingdi.h>
60 #endif
61
62 #ifndef VTK_IMPLEMENT_MESA_CXX
63 vtkCxxRevisionMacro(VISU_OpenGLPointSpriteMapper, "Revision$");
64 vtkStandardNewMacro(VISU_OpenGLPointSpriteMapper);
65 #endif
66
67 // some definitions for what the polydata has in it
68 #define VTK_PDPSM_COLORS             0x0001
69 #define VTK_PDPSM_CELL_COLORS        0x0002
70 #define VTK_PDPSM_POINT_TYPE_FLOAT   0x0004
71 #define VTK_PDPSM_POINT_TYPE_DOUBLE  0x0008
72 #define VTK_PDPSM_NORMAL_TYPE_FLOAT  0x0010
73 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
74 #define VTK_PDPSM_OPAQUE_COLORS      0x0040
75
76 #ifndef APIENTRY
77 #define APIENTRY
78 #endif
79 #ifndef APIENTRYP
80 #define APIENTRYP APIENTRY *
81 #endif
82
83 #ifndef GL_OBJECT_INFO_LOG_LENGTH_ARB
84 #define GL_OBJECT_INFO_LOG_LENGTH_ARB     0x8B84
85 #endif
86
87 #ifndef GL_VERTEX_SHADER_ARB
88 #define GL_VERTEX_SHADER_ARB              0x8B31
89 #endif
90
91 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
92 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB  0x8642
93 #endif
94
95 #ifndef GL_ARB_point_sprite
96 #define GL_POINT_SPRITE_ARB               0x8861
97 #define GL_COORD_REPLACE_ARB              0x8862
98 #endif
99
100 #ifndef GL_ARB_shader_objects
101 typedef char GLcharARB;
102 #endif
103
104 #ifndef GL_ARB_vertex_buffer_object
105 typedef ptrdiff_t GLsizeiptrARB;
106
107 #define GL_ARRAY_BUFFER_ARB               0x8892
108 #define GL_STATIC_DRAW_ARB                0x88E4
109 #endif
110
111 typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
112 typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
113 typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
114 typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
115 typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
116 typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
117 typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
118 typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
119 typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
120 typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
121 typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
122
123 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
124 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
125 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
126 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
127
128 static PFNGLSHADERSOURCEARBPROC             vglShaderSourceARB            = NULL;
129 static PFNGLCREATESHADEROBJECTARBPROC       vglCreateShaderObjectARB      = NULL;
130 static PFNGLCOMPILESHADERARBPROC            vglCompileShaderARB           = NULL;
131 static PFNGLCREATEPROGRAMOBJECTARBPROC      vglCreateProgramObjectARB     = NULL;
132 static PFNGLATTACHOBJECTARBPROC             vglAttachObjectARB            = NULL;
133 static PFNGLLINKPROGRAMARBPROC              vglLinkProgramARB             = NULL;
134 static PFNGLUSEPROGRAMOBJECTARBPROC         vglUseProgramObjectARB        = NULL;
135 static PFNGLGETOBJECTPARAMETERIVARBPROC     vglGetObjectParameterivARB    = NULL;
136 static PFNGLGETINFOLOGARBPROC               vglGetInfoLogARB              = NULL;
137 static PFNGLGETATTRIBLOCATIONARBPROC        vglGetAttribLocationARB       = NULL;
138 static PFNGLVERTEXATTRIB1FARBPROC           vglVertexAttrib1fARB          = NULL;
139
140 static PFNGLGENBUFFERSARBPROC               vglGenBuffersARB              = NULL;
141 static PFNGLBINDBUFFERARBPROC               vglBindBufferARB              = NULL;
142 static PFNGLBUFFERDATAARBPROC               vglBufferDataARB              = NULL;
143 static PFNGLDELETEBUFFERSARBPROC            vglDeleteBuffersARB           = NULL;
144
145 #ifndef WNT
146 #define GL_GetProcAddress( x )   glXGetProcAddressARB( (const GLubyte*)x )
147 #else
148 #define GL_GetProcAddress( x )   wglGetProcAddress( (const LPCSTR)x )
149 #endif
150
151 bool InitializeARB()
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   vglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)GL_GetProcAddress( "glGetObjectParameterivARB" );
182   if( !vglGetObjectParameterivARB )
183     return false;
184
185   vglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)GL_GetProcAddress( "glGetInfoLogARB" );
186   if( !vglGetInfoLogARB )
187     return false;
188
189   vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocationARB" );
190   if( !vglGetAttribLocationARB )
191     return false;
192
193   vglVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)GL_GetProcAddress( "glVertexAttrib1fARB" );
194   if( !vglVertexAttrib1fARB )
195     return false;
196
197   vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
198   if( !vglGenBuffersARB )
199     return false;
200
201   vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
202   if( !vglBindBufferARB )
203     return false;
204
205   vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
206   if( !vglBufferDataARB )
207     return false;
208
209   vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
210   if( !vglDeleteBuffersARB )
211     return false;
212
213   return true;
214 };
215
216 static bool IsARBInitialized = InitializeARB();
217 static vtkFloatingPointType Tolerance = 1.0 / VTK_LARGE_FLOAT;
218
219 //-----------------------------------------------------------------------------
220 // Construct empty object.
221 VISU_OpenGLPointSpriteMapper::VISU_OpenGLPointSpriteMapper()
222 {
223   this->RenderMode               = VISU_OpenGLPointSpriteMapper::Occlude;
224
225   this->ListId                   = 0;
226   this->TotalCells               = 0;
227   this->ExtensionsInitialized    = 0;
228   this->DefaultPointSize         = 20.0;
229   this->AverageCellSize          = 0.0;
230
231   this->UsePointSprites          = true;
232   this->UseTextures              = true;
233   this->UseShader                = true;
234
235   this->PrimitiveType            = VISU_OpenGLPointSpriteMapper::PointSprite;
236
237   this->PointSpriteMode          = 0;
238
239   this->PointSpriteClamp         = 256.0;
240   this->PointSpriteSize          = 0.2;
241   this->PointSpriteMinSize       = 0.1;
242   this->PointSpriteMaxSize       = 0.3;
243   this->PointSpriteMagnification = 1.0;
244
245   this->PointSpriteAlphaThreshold = 0.5;
246   this->PointSpriteTexture       = 0;
247
248   this->UseOpenGLMapper          = false;
249 }
250 //-----------------------------------------------------------------------------
251 VISU_OpenGLPointSpriteMapper::~VISU_OpenGLPointSpriteMapper()
252 {
253   if( PointSpriteTexture>0 )
254     glDeleteTextures( 1, &PointSpriteTexture );
255
256   if( this->LastWindow )
257     this->ReleaseGraphicsResources(this->LastWindow);
258 }
259
260 //-----------------------------------------------------------------------------
261 char* readFromFile( std::string fileName )
262 {
263   FILE* file = fopen( fileName.c_str(), "r" );
264
265   char* content = NULL;
266   int count = 0;
267
268   if( file != NULL )
269   {
270     fseek( file, 0, SEEK_END );
271     count = ftell( file );
272     rewind( file );
273
274     if( count > 0 )
275     {
276       content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
277       count = fread( content, sizeof( char ), count, file );
278       content[ count ] = '\0';
279     }
280     fclose( file );
281   }
282
283   return content;
284 }
285 //-----------------------------------------------------------------------------
286 void VISU_OpenGLPointSpriteMapper::PrintInfoLog( GLhandleARB obj )
287 {
288   int infologLength = 0;
289   int charsWritten  = 0;
290   char* infoLog;
291
292   vglGetObjectParameterivARB( obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength );
293
294   if( infologLength > 0 )
295   {
296     infoLog = ( char* )malloc( infologLength );
297     vglGetInfoLogARB( obj, infologLength, &charsWritten, infoLog );
298     printf( "%s\n", infoLog );
299     free( infoLog );
300   }
301 }
302 //-----------------------------------------------------------------------------
303 void VISU_OpenGLPointSpriteMapper::InitShader()
304 {
305   //cout << "Initializing vertex program" << endl;
306
307   std::string fileName = std::string( getenv( "VISU_ROOT_DIR") ) +
308                          "/share/salome/resources/visu/Vertex_Program_ARB.txt";
309
310   char* shader = readFromFile( fileName );
311
312   GLhandleARB VertexShader = vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
313   vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
314   vglCompileShaderARB( VertexShader );
315   //this->PrintInfoLog( VertexShader );
316
317   this->VertexProgram = vglCreateProgramObjectARB();
318   vglAttachObjectARB( this->VertexProgram, VertexShader );
319
320   vglLinkProgramARB( this->VertexProgram );
321   //this->PrintInfoLog( VertexProgram );
322   /*
323   cout << "Shader from " << fileName << endl;
324   for( int i = 0; i < strlen( shader ); i++ )
325     cout << shader[i];
326   cout << endl;
327
328   if( glGetError() == GL_NO_ERROR )
329     cout << "Loading vertex program... ok" << endl << endl;
330   else
331     cout << "Loading vertex program... failed" << endl << endl;
332   */
333   free( shader );
334 }
335
336 //-----------------------------------------------------------------------------
337 void VISU_OpenGLPointSpriteMapper::SetShaderVariable( const char* variable, float value )
338 {
339   //cout << this->VertexProgram << " ";
340   //cout << vglGetAttribLocationARB( this->VertexProgram, variable ) << " ";
341   //cout << variable << " " << value << endl;
342
343   vglVertexAttrib1fARB( vglGetAttribLocationARB( this->VertexProgram, variable ), value );
344 }
345
346 //-----------------------------------------------------------------------------
347 void VISU_OpenGLPointSpriteMapper::SetPrimitiveType( int thePrimitiveType )
348 {
349   if( this->PrimitiveType == thePrimitiveType )
350     return;
351
352   this->PrimitiveType = thePrimitiveType;
353 }
354
355 //-----------------------------------------------------------------------------
356 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMode( int theMode )
357 {
358   if( this->PointSpriteMode == theMode )
359     return;
360
361   this->PointSpriteMode = theMode;
362   this->Modified();
363 }
364
365 //-----------------------------------------------------------------------------
366 void VISU_OpenGLPointSpriteMapper::SetPointSpriteClamp( float theClamp )
367 {
368   if( fabs( this->PointSpriteClamp - theClamp ) < Tolerance )
369     return;
370
371   this->PointSpriteClamp = theClamp;
372 }
373
374 //-----------------------------------------------------------------------------
375 void VISU_OpenGLPointSpriteMapper::SetAverageCellSize(float theSize)
376 {
377   if( fabs( this->AverageCellSize - theSize ) < Tolerance )
378     return;
379
380   this->AverageCellSize = theSize;
381 }
382
383 //-----------------------------------------------------------------------------
384 void VISU_OpenGLPointSpriteMapper::SetPointSpriteSize( float theSize )
385 {
386   if( fabs( this->PointSpriteSize - theSize ) < Tolerance )
387     return;
388
389   this->PointSpriteSize = theSize;
390 }
391
392 //-----------------------------------------------------------------------------
393 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize( float theMinSize )
394 {
395   if( fabs( this->PointSpriteMinSize - theMinSize ) < Tolerance )
396     return;
397
398   this->PointSpriteMinSize = theMinSize;
399 }
400
401 //-----------------------------------------------------------------------------
402 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMaxSize( float theMaxSize )
403 {
404   if( fabs( this->PointSpriteMaxSize - theMaxSize ) < Tolerance )
405     return;
406
407   this->PointSpriteMaxSize = theMaxSize;
408 }
409
410 //-----------------------------------------------------------------------------
411 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMagnification( float theMagnification )
412 {
413   if( fabs( this->PointSpriteMagnification - theMagnification ) < Tolerance )
414     return;
415
416   this->PointSpriteMagnification = theMagnification;
417 }
418
419 //-----------------------------------------------------------------------------
420 void VISU_OpenGLPointSpriteMapper::SetPointSpriteAlphaThreshold( float theAlphaThreshold )
421 {
422   if( fabs( this->PointSpriteAlphaThreshold - theAlphaThreshold ) < Tolerance )
423     return;
424
425   this->PointSpriteAlphaThreshold = theAlphaThreshold;
426 }
427
428 //-----------------------------------------------------------------------------
429 bool VISU_OpenGLPointSpriteMapper::InitExtensions()
430 {
431   if( this->ExtensionsInitialized )
432     return true;
433
434   InitializeARB();
435
436   char* ext = (char*)glGetString( GL_EXTENSIONS );
437   //cout << "OpenGL extensions : " << ext << endl;
438
439   if( !IsARBInitialized ||
440       strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
441       strstr( ext, "GL_ARB_shader_objects" ) == NULL ||
442       strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
443   {
444     vtkWarningMacro(<<"Initializing ARB extensions failed");
445     this->UseOpenGLMapper = true;
446
447     return false;
448   }
449
450   if( this->UseShader )
451     this->InitShader();
452
453   this->ExtensionsInitialized = 1;
454   return true;
455 }
456
457 //-----------------------------------------------------------------------------
458 float ViewToDisplay( vtkRenderer* theRenderer )
459 {
460   vtkFloatingPointType p1[3], p2[3];
461
462   theRenderer->SetViewPoint( 0.0, 0.0, 0.0 );
463   theRenderer->ViewToDisplay();
464   theRenderer->GetDisplayPoint( p1 );
465
466   theRenderer->SetViewPoint( 1.0, 1.0, 1.0 );
467   theRenderer->ViewToDisplay();
468   theRenderer->GetDisplayPoint( p2 );
469
470   vtkFloatingPointType coefficient = sqrt( pow( p2[0] - p1[0], 2 ) + pow( p2[1] - p1[1], 2 ) ) / sqrt( 2. );
471   //cout << p1[0] << " " << p1[1] << " " << p1[2] << endl;
472   //cout << p2[0] << " " << p2[1] << " " << p2[2] << endl;
473   //cout << "ZOOM  : " << coefficient << endl;
474
475   return coefficient;
476 }
477
478 //-----------------------------------------------------------------------------
479 //
480 // Receives from Actor -> maps data to primitives
481 //
482 void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
483 {
484   bool isUseThisMapper = !( this->UseOpenGLMapper ||
485                             this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere );
486
487   if( isUseThisMapper )
488     if( !this->InitExtensions() )
489       return;
490
491   if( !isUseThisMapper )
492   {
493     MAPPER_SUPERCLASS::RenderPiece( ren, act );
494     return;
495   }
496
497   vtkIdType numPts;
498   vtkPolyData *input= this->GetInput();
499
500   //
501   // make sure that we've been properly initialized
502   //
503   if (ren->GetRenderWindow()->CheckAbortStatus())
504     return;
505
506   if ( input == NULL )
507   {
508     vtkErrorMacro(<< "No input!");
509     return;
510   }
511   else
512   {
513     this->InvokeEvent(vtkCommand::StartEvent,NULL);
514     input->Update();
515     this->InvokeEvent(vtkCommand::EndEvent,NULL);
516
517     numPts = input->GetNumberOfPoints();
518   }
519
520   if (numPts == 0)
521   {
522     vtkDebugMacro(<< "No points!");
523     return;
524   }
525
526   if ( this->LookupTable == NULL )
527     this->CreateDefaultLookupTable();
528
529   // make sure our window is current
530   ren->GetRenderWindow()->MakeCurrent();
531
532   if( this->UsePointSprites ) //&& this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
533     this->InitPointSprites();
534
535   // Initializing the texture for Point Sprites
536   if( this->UseTextures && this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
537     this->InitTextures();
538
539   vglUseProgramObjectARB( this->VertexProgram );
540   float aViewToDisplay = ViewToDisplay( ren );
541   this->SetShaderVariable( "mode",          this->PointSpriteMode );
542   this->SetShaderVariable( "clampSize",     this->PointSpriteClamp );
543   this->SetShaderVariable( "geomSize",      aViewToDisplay * this->AverageCellSize * this->PointSpriteSize );
544   this->SetShaderVariable( "minSize",       aViewToDisplay * this->AverageCellSize * this->PointSpriteMinSize );
545   this->SetShaderVariable( "maxSize",       aViewToDisplay * this->AverageCellSize * this->PointSpriteMaxSize );
546   this->SetShaderVariable( "magnification", this->PointSpriteMagnification );
547
548   //
549   // if something has changed regenerate colors and display lists
550   // if required
551   //
552   int noAbort=1;
553   if ( this->GetMTime() > this->BuildTime ||
554        input->GetMTime() > this->BuildTime ||
555        act->GetProperty()->GetMTime() > this->BuildTime ||
556        ren->GetRenderWindow() != this->LastWindow)
557   {
558 #ifdef _DEBUG_RENDERING_PERFORMANCE_
559     // To control when the mapper is recalculated
560     cout<<"VISU_OpenGLPointSpriteMapper::RenderPiece - "
561         <<(this->GetMTime() > this->BuildTime)<<"; "
562         <<(input->GetMTime() > this->BuildTime)<<"; "
563         <<(act->GetProperty()->GetMTime() > this->BuildTime)<<"; "
564         <<endl;
565 #endif
566     // sets this->Colors as side effect
567     this->MapScalars( act->GetProperty()->GetOpacity() );
568
569     if (!this->ImmediateModeRendering &&
570         !this->GetGlobalImmediateModeRendering())
571     {
572       this->ReleaseGraphicsResources(ren->GetRenderWindow());
573       this->LastWindow = ren->GetRenderWindow();
574
575       // get a unique display list id
576       this->ListId = glGenLists(1);
577       glNewList(this->ListId,GL_COMPILE);
578
579       noAbort = this->Draw(ren,act);
580       glEndList();
581
582       // Time the actual drawing
583       this->Timer->StartTimer();
584       glCallList(this->ListId);
585       this->Timer->StopTimer();
586     }
587     else
588     {
589       this->ReleaseGraphicsResources(ren->GetRenderWindow());
590       this->LastWindow = ren->GetRenderWindow();
591     }
592     if (noAbort)
593       this->BuildTime.Modified();
594   }
595   // if nothing changed but we are using display lists, draw it
596   else
597   {
598     if (!this->ImmediateModeRendering &&
599         !this->GetGlobalImmediateModeRendering())
600     {
601       // Time the actual drawing
602       this->Timer->StartTimer();
603       glCallList(this->ListId);
604       this->Timer->StopTimer();
605     }
606   }
607
608   // if we are in immediate mode rendering we always
609   // want to draw the primitives here
610   if (this->ImmediateModeRendering ||
611       this->GetGlobalImmediateModeRendering())
612   {
613     // sets this->Colors as side effect
614     this->MapScalars( act->GetProperty()->GetOpacity() );
615
616     // Time the actual drawing
617     this->Timer->StartTimer();
618     this->Draw(ren,act);
619     this->Timer->StopTimer();
620   }
621
622   this->TimeToDraw = (float)this->Timer->GetElapsedTime();
623
624   // If the timer is not accurate enough, set it to a small
625   // time so that it is not zero
626   if ( this->TimeToDraw == 0.0 )
627     this->TimeToDraw = 0.0001;
628
629   vglUseProgramObjectARB( 0 );
630
631   if( this->UsePointSprites ) //&& this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
632     this->CleanupPointSprites();
633 }
634
635 //-----------------------------------------------------------------------------
636 float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
637 {
638   float maximumSupportedSize = 512.0;
639   //glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maximumSupportedSize );
640
641   return maximumSupportedSize;
642 }
643
644 //-----------------------------------------------------------------------------
645 void VISU_OpenGLPointSpriteMapper::InitPointSprites()
646 {
647   glEnable( GL_POINT_SPRITE_ARB );
648   glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
649
650   switch (this->RenderMode)
651   {
652     case VISU_OpenGLPointSpriteMapper::Accumulate:
653     {
654       glDisable(GL_DEPTH_TEST);
655
656       glEnable( GL_BLEND );
657       glBlendFunc( GL_SRC_ALPHA, GL_ONE );
658
659       glEnable( GL_ALPHA_TEST );
660       glAlphaFunc( GL_GREATER, this->PointSpriteAlphaThreshold );
661       break;
662     }
663
664     case VISU_OpenGLPointSpriteMapper::Occlude:
665     {
666       glDepthFunc( GL_LEQUAL );
667       glEnable( GL_DEPTH_TEST );
668
669       glEnable( GL_ALPHA_TEST );
670       glAlphaFunc( GL_GREATER, this->PointSpriteAlphaThreshold );
671
672       glDisable( GL_BLEND );
673       break;
674     }
675
676     default:
677     {
678       break;
679     }
680   }
681   // Disable Lighting/Shading.
682   glDisable( GL_LIGHTING );
683
684   // Disable material properties
685   glDisable( GL_COLOR_MATERIAL );
686 }
687
688 //-----------------------------------------------------------------------------
689 void VISU_OpenGLPointSpriteMapper::CleanupPointSprites()
690 {
691   // Set GL params back to normal to stop other vtkMappers displaying wrongly
692   glDisable( GL_ALPHA_TEST );
693
694   glEnable( GL_BLEND );
695
696   glEnable( GL_DEPTH_TEST );
697   glEnable( GL_LIGHTING );
698   glEnable( GL_COLOR_MATERIAL );
699
700   glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
701   glDisable( GL_POINT_SPRITE_ARB );
702 }
703
704
705 //-----------------------------------------------------------------------------
706 void
707 VISU_OpenGLPointSpriteMapper
708 ::SetImageData( vtkImageData* theImageData )
709 {
710   if(GetImageData() == theImageData)
711     return;
712   this->ImageData = theImageData;
713   this->Modified();
714 }
715
716 vtkImageData*
717 VISU_OpenGLPointSpriteMapper
718 ::GetImageData()
719 {
720   return this->ImageData.GetPointer();
721 }
722
723
724 //-----------------------------------------------------------------------------
725 void VISU_OpenGLPointSpriteMapper::InitTextures()
726 {
727   //cout << "VISU_OpenGLPointSpriteMapper::InitTextures " << this->GetImageData() << endl;
728   if( !this->GetImageData() )
729     return;
730
731   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
732   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
733   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
734   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
735
736   int* aSize = GetImageData()->GetDimensions();
737   unsigned char* dataPtr = (unsigned char*)GetImageData()->GetScalarPointer();
738   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
739                 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
740
741   //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
742   glEnable( GL_TEXTURE_2D );
743   glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
744   glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
745 }
746
747
748 //-----------------------------------------------------------------------------
749 int ComputeHue( int r, int g, int b )
750 {
751   int h = 0;
752
753   int max = r;
754   int whatmax = 0;
755   if( g > max ) {
756     max = g;
757     whatmax = 1;
758   }
759   if( b > max ) {
760     max = b;
761     whatmax = 2;
762   }
763
764   int min = r;
765   if ( g < min ) min = g;
766   if ( b < min ) min = b;
767   int delta = max-min;
768
769   if( delta == 0 )
770     h = 0;
771   else if( whatmax == 0 ) {
772     if ( g >= b )
773       h = (120*(g-b)+delta)/(2*delta);
774     else
775       h = (120*(g-b+delta)+delta)/(2*delta) + 300;
776   }
777   else if( whatmax == 1 ) {
778     if ( b > r )
779       h = 120 + (120*(b-r)+delta)/(2*delta);
780     else
781       h = 60 + (120*(b-r+delta)+delta)/(2*delta);
782   }
783   else {
784     if ( r > g )
785       h = 240 + (120*(r-g)+delta)/(2*delta);
786     else
787       h = 180 + (120*(r-g+delta)+delta)/(2*delta);
788   }
789
790   return h + 1;
791 }
792
793 //-----------------------------------------------------------------------------
794 struct TVertex
795 {
796   GLfloat r, g, b, hue;
797   GLfloat vx, vy, vz;
798 };
799
800
801 //-----------------------------------------------------------------------------
802 struct TColorFunctorBase
803 {
804   virtual
805   void
806   get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
807 };
808
809
810 //-----------------------------------------------------------------------------
811 struct TPropertyColor : TColorFunctorBase
812 {
813   vtkFloatingPointType myColor[3];
814   vtkFloatingPointType myHue;
815
816   TPropertyColor( vtkProperty *theProperty )
817   {
818     theProperty->GetColor( myColor );
819     int aRed = int( myColor[0] * 255 );
820     int aGreen = int( myColor[1] * 255 );
821     int aBlue = int( myColor[2] * 255 );
822
823     myHue = ComputeHue( aRed, aGreen, aBlue );
824   }
825
826   virtual
827   void
828   get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
829   {
830     theVertex.r = myColor[0];
831     theVertex.g = myColor[1];
832     theVertex.b = myColor[2];
833
834     theVertex.hue = myHue;
835   }
836 };
837
838
839 //-----------------------------------------------------------------------------
840 struct TColors2Color : TColorFunctorBase
841 {
842   vtkUnsignedCharArray *myColors;
843
844   TColors2Color( vtkUnsignedCharArray *theColors ):
845     myColors( theColors )
846   {}
847
848   virtual
849   void
850   get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
851   {
852     vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
853     unsigned char *aColor = myColors->GetPointer( aTupleId << 2 );
854
855     theVertex.r = int( aColor[0] ) / 255.0;
856     theVertex.g = int( aColor[1] ) / 255.0;
857     theVertex.b = int( aColor[2] ) / 255.0;
858
859     theVertex.hue = ComputeHue( aColor[0], aColor[1], aColor[2] );
860   }  
861
862   virtual
863   vtkIdType
864   GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
865 };
866
867
868 //-----------------------------------------------------------------------------
869 struct TPointColors2Color : TColors2Color
870 {
871   TPointColors2Color( vtkUnsignedCharArray *theColors ):
872     TColors2Color( theColors )
873   {}
874
875   virtual
876   vtkIdType
877   GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
878   {
879     return thePointId;
880   }
881 };
882
883
884 //-----------------------------------------------------------------------------
885 struct TCellColors2Color : TColors2Color
886 {
887   TCellColors2Color( vtkUnsignedCharArray *theColors ):
888     TColors2Color( theColors )
889   {}
890
891   virtual
892   vtkIdType
893   GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
894   {
895     return theCellId;
896   }
897 };
898
899
900 //-----------------------------------------------------------------------------
901 template < class TCoordinates >
902 void DrawPoints( TCoordinates *theStartPoints,
903                  vtkCellArray *theCells,
904                  TColorFunctorBase* theColorFunctor,
905                  TVertex* theVertexArr,
906                  vtkIdType &theCellId,
907                  vtkIdType &theVertexId )
908 {
909   vtkIdType *ptIds = theCells->GetPointer();
910   vtkIdType *endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
911
912   while ( ptIds < endPtIds ) {
913     vtkIdType nPts = *ptIds;
914     ++ptIds;
915
916     while ( nPts > 0 ) {
917       TVertex& aVertex = theVertexArr[ theVertexId ];
918       vtkIdType aPointId = *ptIds;
919
920       TCoordinates *anOffsetPoints = theStartPoints + 3 * aPointId;
921       aVertex.vx = anOffsetPoints[0];
922       aVertex.vy = anOffsetPoints[1];
923       aVertex.vz = anOffsetPoints[2];
924
925       theColorFunctor->get( aVertex, aPointId, theCellId );
926
927       ++theVertexId;
928       ++ptIds; 
929       --nPts; 
930     }
931
932     ++theCellId;
933   }
934 }
935
936
937 //-----------------------------------------------------------------------------
938 template < class TCoordinates >
939 void DrawCellsPoints( vtkPolyData *theInput,
940                       vtkPoints* thePoints,
941                       TColorFunctorBase* theColorFunctor,
942                       TVertex* theVertexArr )
943 {
944   vtkIdType aCellId = 0, aVertexId = 0;
945
946   TCoordinates *aStartPoints = (TCoordinates *) thePoints->GetVoidPointer(0);
947
948   if ( vtkCellArray* aCellArray = theInput->GetVerts() )
949     DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
950   
951   if ( vtkCellArray* aCellArray = theInput->GetLines() )
952     DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
953   
954   if ( vtkCellArray* aCellArray = theInput->GetPolys() )
955     DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
956   
957   if ( vtkCellArray* aCellArray = theInput->GetStrips() )
958     DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId ); 
959 }
960
961
962 //-----------------------------------------------------------------------------
963 int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *theRenderer, vtkActor *theActor)
964 {
965
966   if( this->UseOpenGLMapper ||
967       this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere )
968     return MAPPER_SUPERCLASS::Draw( theRenderer, theActor );
969
970   vtkUnsignedCharArray *colors = NULL;
971   vtkPolyData          *input  = this->GetInput();
972   vtkPoints            *points;
973   int noAbort = 1;
974   int cellScalars = 0;
975   float  tran;
976
977   // get the transparency
978   tran = theActor->GetProperty()->GetOpacity();
979
980   // if the primitives are invisable then get out of here
981   if (tran <= 0.0)
982   {
983     return noAbort;
984   }
985
986   // and draw the display list
987   points = input->GetPoints();
988
989   // are they cell or point scalars
990   if ( this->Colors )
991   {
992     colors = this->Colors;
993     if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
994           this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
995           !input->GetPointData()->GetScalars() )
996          && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA)
997     {
998       cellScalars = 1;
999     }
1000   }
1001
1002   {
1003     vtkIdType aTotalConnectivitySize = 0;
1004
1005     if ( vtkCellArray* aCellArray = input->GetVerts() )
1006       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1007
1008     if ( vtkCellArray* aCellArray = input->GetLines() )
1009       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1010
1011     if ( vtkCellArray* aCellArray = input->GetPolys() )
1012       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1013
1014     if ( vtkCellArray* aCellArray = input->GetStrips() )
1015       aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1016
1017     if ( aTotalConnectivitySize > 0 ) {
1018       TVertex* aVertexArr = new TVertex[ aTotalConnectivitySize ];
1019
1020       vtkFloatingPointType aPropertyColor[3];
1021       theActor->GetProperty()->GetColor( aPropertyColor );
1022
1023       glPointSize( this->DefaultPointSize );
1024
1025       {
1026         TColorFunctorBase* aColorFunctor = NULL;
1027         if( colors && this->PointSpriteMode != 1 ) {
1028           if ( cellScalars )
1029             aColorFunctor = new TCellColors2Color( colors );
1030           else
1031             aColorFunctor = new TPointColors2Color( colors );
1032         } else {
1033           aColorFunctor = new TPropertyColor( theActor->GetProperty() );
1034         }
1035         if ( points->GetDataType() == VTK_FLOAT )
1036           ::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr );
1037         else
1038           ::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr );
1039
1040         delete aColorFunctor;
1041       }
1042
1043       GLuint aBufferObjectID = 0;
1044       vglGenBuffersARB( 1, &aBufferObjectID );
1045       vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1046       
1047       int anArrayObjectSize = sizeof( TVertex ) * aTotalConnectivitySize;
1048       vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
1049       
1050       delete [] aVertexArr;
1051       
1052       vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1053       vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1054       
1055       glColorPointer( 4, GL_FLOAT, sizeof(TVertex), (void*)0 );
1056       glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)(4*sizeof(GLfloat)) );
1057       
1058       glEnableClientState( GL_VERTEX_ARRAY );
1059       glEnableClientState( GL_COLOR_ARRAY );
1060       
1061       glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1062       
1063       glDisableClientState( GL_COLOR_ARRAY );
1064       glDisableClientState( GL_VERTEX_ARRAY );
1065       
1066       vglDeleteBuffersARB( 1, &aBufferObjectID );
1067     }
1068
1069     input->GetVerts()->GetNumberOfCells() + 
1070     input->GetLines()->GetNumberOfCells() + 
1071     input->GetPolys()->GetNumberOfCells() + 
1072     input->GetStrips()->GetNumberOfCells();
1073     
1074
1075
1076   }
1077
1078
1079   this->UpdateProgress(1.0);
1080   return noAbort;
1081 }
1082 //-----------------------------------------------------------------------------
1083 // Release the graphics resources used by this mapper.  In this case, release
1084 // the display list if any.
1085 void VISU_OpenGLPointSpriteMapper::ReleaseGraphicsResources(vtkWindow *win)
1086 {
1087   this->Superclass::ReleaseGraphicsResources(win);
1088
1089   if (this->ListId && win)
1090     {
1091     win->MakeCurrent();
1092     glDeleteLists(this->ListId,1);
1093     this->ListId = 0;
1094     }
1095   this->LastWindow = NULL;
1096 }