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