Salome HOME
Merge from V5_1_main 10/06/2010
[modules/visu.git] / src / PIPELINE / VISU_OpenGLPointSpriteMapper.cxx
index d8eb9e8ae9824755d88e8f2a0c8960d4be8a8b56..56c18d9330e6fd8edc590051614fdf6716038156 100755 (executable)
@@ -1,6 +1,6 @@
-//  VISU OBJECT : interactive object for VISU entities implementation
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
 //  This library is free software; you can redistribute it and/or
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
-//
-//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+//  VISU OBJECT : interactive object for VISU entities implementation
 // File:    VISU_OpenGLPointSpriteMapper.cxx
 // Author:  
 // Module : VISU
-
+//
 #include "VISU_OpenGLPointSpriteMapper.hxx"
 
+//#include "SVTK_Extension.h"
+
 #include <vtkCamera.h>
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
 #include <vtkCommand.h>
-#include <vtkDataArray.h>
-#include <vtkFloatArray.h>
 #include <vtkImageData.h>
 #include <vtkMatrix4x4.h>
 #include <vtkObjectFactory.h>
-#include <vtkOpenGLRenderer.h>
-#include <vtkOpenGLRenderWindow.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
 #include <vtkPointData.h>
 #include <vtkPolyData.h>
 #include <vtkPolygon.h>
 #include <vtkTimerLog.h>
 #include <vtkTriangle.h>
 
-#include <dlfcn.h>
-
 #include <stdio.h>
 #include <cmath>
 #include <string>
 
+#include "utilities.h"
+
+#ifndef WNT
+# ifndef GLX_GLXEXT_LEGACY
+#  define GLX_GLXEXT_LEGACY
+# endif
+# include <GL/glx.h>
+# include <dlfcn.h>
+#else
+# include <wingdi.h>
+#endif
+
 #ifndef VTK_IMPLEMENT_MESA_CXX
 vtkCxxRevisionMacro(VISU_OpenGLPointSpriteMapper, "Revision$");
 vtkStandardNewMacro(VISU_OpenGLPointSpriteMapper);
@@ -134,32 +144,79 @@ static PFNGLBINDBUFFERARBPROC               vglBindBufferARB              = NULL
 static PFNGLBUFFERDATAARBPROC               vglBufferDataARB              = NULL;
 static PFNGLDELETEBUFFERSARBPROC            vglDeleteBuffersARB           = NULL;
 
-int InitializeARB()
+#ifndef WNT
+#define GL_GetProcAddress( x )   glXGetProcAddressARB( (const GLubyte*)x )
+#else
+#define GL_GetProcAddress( x )   wglGetProcAddress( (const LPCSTR)x )
+#endif
+
+bool InitializeARB()
 {
-  void* OpenGLLibrary = dlopen( "libGL.so", RTLD_LAZY );
+  vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
+  if( !vglShaderSourceARB )
+    return false;
+
+  vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
+  if( !vglCreateShaderObjectARB )
+    return false;
+
+  vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
+  if( !vglCompileShaderARB )
+    return false;
+
+  vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
+  if( !vglCreateProgramObjectARB )
+    return false;
+
+  vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
+  if( !vglAttachObjectARB )
+    return false;
+
+  vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
+  if( !vglLinkProgramARB )
+    return false;
+
+  vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
+  if( !vglUseProgramObjectARB )
+    return false;
+
+  vglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)GL_GetProcAddress( "glGetObjectParameterivARB" );
+  if( !vglGetObjectParameterivARB )
+    return false;
+
+  vglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)GL_GetProcAddress( "glGetInfoLogARB" );
+  if( !vglGetInfoLogARB )
+    return false;
+
+  vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocationARB" );
+  if( !vglGetAttribLocationARB )
+    return false;
+
+  vglVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)GL_GetProcAddress( "glVertexAttrib1fARB" );
+  if( !vglVertexAttrib1fARB )
+    return false;
+
+  vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
+  if( !vglGenBuffersARB )
+    return false;
 
-  vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)dlsym( OpenGLLibrary, "glShaderSourceARB" );
-  vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)dlsym( OpenGLLibrary, "glCreateShaderObjectARB" );
-  vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)dlsym( OpenGLLibrary, "glCompileShaderARB" );
-  vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)dlsym( OpenGLLibrary, "glCreateProgramObjectARB" );
-  vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)dlsym( OpenGLLibrary, "glAttachObjectARB" );
-  vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)dlsym( OpenGLLibrary, "glLinkProgramARB" );
-  vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)dlsym( OpenGLLibrary, "glUseProgramObjectARB" );
-  vglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)dlsym( OpenGLLibrary, "glGetObjectParameterivARB" );
-  vglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)dlsym( OpenGLLibrary, "glGetInfoLogARB" );
-  vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)dlsym( OpenGLLibrary, "glGetAttribLocationARB" );
-  vglVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)dlsym( OpenGLLibrary, "glVertexAttrib1fARB" );
+  vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
+  if( !vglBindBufferARB )
+    return false;
 
-  vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)dlsym( OpenGLLibrary, "glGenBuffersARB" );
-  vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)dlsym( OpenGLLibrary, "glBindBufferARB" );
-  vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)dlsym( OpenGLLibrary, "glBufferDataARB" );
-  vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)dlsym( OpenGLLibrary, "glDeleteBuffersARB" );
+  vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
+  if( !vglBufferDataARB )
+    return false;
+
+  vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
+  if( !vglDeleteBuffersARB )
+    return false;
 
-  return 1;
+  return true;
 };
 
-static int IsARBInitialized = InitializeARB();
-static float Tolerance = 1.0 / VTK_LARGE_FLOAT;
+static bool IsARBInitialized = InitializeARB();
+static vtkFloatingPointType Tolerance = 1.0 / VTK_LARGE_FLOAT;
 
 //-----------------------------------------------------------------------------
 // Construct empty object.
@@ -188,48 +245,21 @@ VISU_OpenGLPointSpriteMapper::VISU_OpenGLPointSpriteMapper()
   this->PointSpriteMagnification = 1.0;
 
   this->PointSpriteAlphaThreshold = 0.5;
+  this->PointSpriteOpacity       = 1.0;
   this->PointSpriteTexture       = 0;
 
   this->UseOpenGLMapper          = false;
-
-  this->TempMapper               = vtkPolyDataMapper::New();
 }
 //-----------------------------------------------------------------------------
 VISU_OpenGLPointSpriteMapper::~VISU_OpenGLPointSpriteMapper()
 {
-  glDeleteTextures( 1, &PointSpriteTexture );
+  if( PointSpriteTexture>0 )
+    glDeleteTextures( 1, &PointSpriteTexture );
 
   if( this->LastWindow )
     this->ReleaseGraphicsResources(this->LastWindow);
-
-  if( this->TempMapper )
-    this->TempMapper->Delete();
 }
-//-----------------------------------------------------------------------------
-void VISU_OpenGLPointSpriteMapper::ShallowCopy( vtkAbstractMapper* mapper )
-{
-  VISU_OpenGLPointSpriteMapper* m = VISU_OpenGLPointSpriteMapper::SafeDownCast(mapper);
-  if( m != NULL )
-  {
-    this->SetPrimitiveType( m->GetPrimitiveType() );
-
-    this->SetPointSpriteMode( m->GetPointSpriteMode() );
 
-    this->SetPointSpriteClamp( m->GetPointSpriteClamp() );
-    this->SetPointSpriteSize( m->GetPointSpriteSize() );
-    this->SetPointSpriteMinSize( m->GetPointSpriteMinSize() );
-    this->SetPointSpriteMaxSize( m->GetPointSpriteMaxSize() );
-    this->SetPointSpriteMagnification( m->GetPointSpriteMagnification() );
-
-    this->SetImageData( m->GetImageData() );
-    this->SetPointSpriteAlphaThreshold( m->GetPointSpriteAlphaThreshold() );
-  }
-
-  this->TempMapper->ShallowCopy( m );
-  this->TempMapper->SetInput( this->GetInput() );
-  Superclass::ShallowCopy( this->TempMapper );
-
-}
 //-----------------------------------------------------------------------------
 char* readFromFile( std::string fileName )
 {
@@ -278,7 +308,7 @@ void VISU_OpenGLPointSpriteMapper::InitShader()
   //cout << "Initializing vertex program" << endl;
 
   std::string fileName = std::string( getenv( "VISU_ROOT_DIR") ) +
-                         "/share/salome/resources/Vertex_Program_ARB.txt";
+                         "/share/salome/resources/visu/Vertex_Program_ARB.txt";
 
   char* shader = readFromFile( fileName );
 
@@ -305,6 +335,7 @@ void VISU_OpenGLPointSpriteMapper::InitShader()
   */
   free( shader );
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetShaderVariable( const char* variable, float value )
 {
@@ -314,6 +345,7 @@ void VISU_OpenGLPointSpriteMapper::SetShaderVariable( const char* variable, floa
 
   vglVertexAttrib1fARB( vglGetAttribLocationARB( this->VertexProgram, variable ), value );
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPrimitiveType( int thePrimitiveType )
 {
@@ -321,7 +353,9 @@ void VISU_OpenGLPointSpriteMapper::SetPrimitiveType( int thePrimitiveType )
     return;
 
   this->PrimitiveType = thePrimitiveType;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMode( int theMode )
 {
@@ -331,6 +365,7 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteMode( int theMode )
   this->PointSpriteMode = theMode;
   this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteClamp( float theClamp )
 {
@@ -338,7 +373,19 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteClamp( float theClamp )
     return;
 
   this->PointSpriteClamp = theClamp;
+  this->Modified();
+}
+
+//-----------------------------------------------------------------------------
+void VISU_OpenGLPointSpriteMapper::SetAverageCellSize(float theSize)
+{
+  if( fabs( this->AverageCellSize - theSize ) < Tolerance )
+    return;
+
+  this->AverageCellSize = theSize;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteSize( float theSize )
 {
@@ -346,7 +393,9 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteSize( float theSize )
     return;
 
   this->PointSpriteSize = theSize;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize( float theMinSize )
 {
@@ -354,7 +403,9 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize( float theMinSize )
     return;
 
   this->PointSpriteMinSize = theMinSize;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMaxSize( float theMaxSize )
 {
@@ -362,7 +413,9 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteMaxSize( float theMaxSize )
     return;
 
   this->PointSpriteMaxSize = theMaxSize;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMagnification( float theMagnification )
 {
@@ -370,7 +423,9 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteMagnification( float theMagnifi
     return;
 
   this->PointSpriteMagnification = theMagnification;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::SetPointSpriteAlphaThreshold( float theAlphaThreshold )
 {
@@ -378,19 +433,26 @@ void VISU_OpenGLPointSpriteMapper::SetPointSpriteAlphaThreshold( float theAlphaT
     return;
 
   this->PointSpriteAlphaThreshold = theAlphaThreshold;
+  this->Modified();
 }
+
 //-----------------------------------------------------------------------------
 bool VISU_OpenGLPointSpriteMapper::InitExtensions()
 {
+  if( this->ExtensionsInitialized )
+    return true;
+
+  InitializeARB();
+
   char* ext = (char*)glGetString( GL_EXTENSIONS );
   //cout << "OpenGL extensions : " << ext << endl;
 
-  if( strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
+  if( !IsARBInitialized ||
+      strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
       strstr( ext, "GL_ARB_shader_objects" ) == NULL ||
       strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
   {
     vtkWarningMacro(<<"Initializing ARB extensions failed");
-
     this->UseOpenGLMapper = true;
 
     return false;
@@ -406,7 +468,7 @@ bool VISU_OpenGLPointSpriteMapper::InitExtensions()
 //-----------------------------------------------------------------------------
 float ViewToDisplay( vtkRenderer* theRenderer )
 {
-  float p1[3], p2[3];
+  vtkFloatingPointType p1[3], p2[3];
 
   theRenderer->SetViewPoint( 0.0, 0.0, 0.0 );
   theRenderer->ViewToDisplay();
@@ -416,7 +478,7 @@ float ViewToDisplay( vtkRenderer* theRenderer )
   theRenderer->ViewToDisplay();
   theRenderer->GetDisplayPoint( p2 );
 
-  float coefficient = sqrt( pow( p2[0] - p1[0], 2 ) + pow( p2[1] - p1[1], 2 ) ) / sqrt( 2 );
+  vtkFloatingPointType coefficient = sqrt( pow( p2[0] - p1[0], 2 ) + pow( p2[1] - p1[1], 2 ) ) / sqrt( 2. );
   //cout << p1[0] << " " << p1[1] << " " << p1[2] << endl;
   //cout << p2[0] << " " << p2[1] << " " << p2[2] << endl;
   //cout << "ZOOM  : " << coefficient << endl;
@@ -430,14 +492,10 @@ float ViewToDisplay( vtkRenderer* theRenderer )
 //
 void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
 {
-  bool isUseThisMapper = !( this->UseOpenGLMapper ||
-                           this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere );
+  bool isUseThisMapper = this->PrimitiveType != VISU_OpenGLPointSpriteMapper::GeomSphere;
 
-  if( !this->ExtensionsInitialized && isUseThisMapper )
-  {
-    if( !this->InitExtensions() )
-      return;
-  }
+  if( isUseThisMapper )
+    this->InitExtensions();
 
   if( !isUseThisMapper )
   {
@@ -506,6 +564,13 @@ void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
        act->GetProperty()->GetMTime() > this->BuildTime ||
        ren->GetRenderWindow() != this->LastWindow)
   {
+#ifdef _DEBUG_RENDERING_PERFORMANCE_
+    // To control when the mapper is recalculated
+    MESSAGE( "VISU_OpenGLPointSpriteMapper::RenderPiece - "
+             <<(this->GetMTime() > this->BuildTime)<<"; "
+             <<(input->GetMTime() > this->BuildTime)<<"; "
+             <<(act->GetProperty()->GetMTime() > this->BuildTime)<<"; ");
+#endif
     // sets this->Colors as side effect
     this->MapScalars( act->GetProperty()->GetOpacity() );
 
@@ -574,6 +639,7 @@ void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
   if( this->UsePointSprites ) //&& this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
     this->CleanupPointSprites();
 }
+
 //-----------------------------------------------------------------------------
 float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
 {
@@ -582,17 +648,23 @@ float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
 
   return maximumSupportedSize;
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::InitPointSprites()
 {
   glEnable( GL_POINT_SPRITE_ARB );
   glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
 
+  glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
+
+  this->RenderMode = this->PointSpriteOpacity < 1.0 ? VISU_OpenGLPointSpriteMapper::Accumulate : VISU_OpenGLPointSpriteMapper::Occlude;
+
   switch (this->RenderMode)
   {
     case VISU_OpenGLPointSpriteMapper::Accumulate:
     {
-      glDisable(GL_DEPTH_TEST);
+      glDepthFunc( GL_LESS );
+      glEnable( GL_DEPTH_TEST );
 
       glEnable( GL_BLEND );
       glBlendFunc( GL_SRC_ALPHA, GL_ONE );
@@ -625,17 +697,12 @@ void VISU_OpenGLPointSpriteMapper::InitPointSprites()
   // Disable material properties
   glDisable( GL_COLOR_MATERIAL );
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::CleanupPointSprites()
 {
   // Set GL params back to normal to stop other vtkMappers displaying wrongly
-  glDisable( GL_ALPHA_TEST );
-
-  glEnable( GL_BLEND );
-
-  glEnable( GL_DEPTH_TEST );
-  glEnable( GL_LIGHTING );
-  glEnable( GL_COLOR_MATERIAL );
+  glPopAttrib();
 
   glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
   glDisable( GL_POINT_SPRITE_ARB );
@@ -647,8 +714,10 @@ void
 VISU_OpenGLPointSpriteMapper
 ::SetImageData( vtkImageData* theImageData )
 {
-  //cout << "VISU_OpenGLPointSpriteMapper::SetImageData " << theImageData << endl;
+  if(GetImageData() == theImageData)
+    return;
   this->ImageData = theImageData;
+  this->Modified();
 }
 
 vtkImageData*
@@ -674,7 +743,7 @@ void VISU_OpenGLPointSpriteMapper::InitTextures()
   int* aSize = GetImageData()->GetDimensions();
   unsigned char* dataPtr = (unsigned char*)GetImageData()->GetScalarPointer();
   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
-               GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
+                GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
 
   //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
   glEnable( GL_TEXTURE_2D );
@@ -682,6 +751,7 @@ void VISU_OpenGLPointSpriteMapper::InitTextures()
   glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
 }
 
+
 //-----------------------------------------------------------------------------
 int ComputeHue( int r, int g, int b )
 {
@@ -734,111 +804,183 @@ struct TVertex
   GLfloat vx, vy, vz;
 };
 
+
 //-----------------------------------------------------------------------------
-void VISU_OpenGLPointSpriteMapper::DrawPoints(vtkPoints *thePoints,
-                                             vtkUnsignedCharArray *theColors,
-                                             vtkFloatArray *theAlpha,
-                                             vtkIdType &theCellNum,
-                                             int &theNoAbort,
-                                             vtkCellArray *theCells,
-                                             vtkRenderer *theRenderer,
-                                             vtkActor* theActor)
+struct TColorFunctorBase
 {
-  //cout << "VISU_OpenGLPointSpriteMapper::DrawPoints" << endl;
+  virtual
+  void
+  get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
+};
 
-  //if( this->PrimitiveType == VISU_OpenGLPointSpriteMapper::OpenGLPoint )
-  //  glEnable( GL_POINT_SMOOTH );
 
-  glPointSize( this->DefaultPointSize );
+//-----------------------------------------------------------------------------
+struct TPropertyColor : TColorFunctorBase
+{
+  vtkFloatingPointType myColor[3];
+  vtkFloatingPointType myHue;
 
-  TVertex* aVertexArr = new TVertex[ this->TotalCells ];
+  TPropertyColor( vtkProperty *theProperty )
+  {
+    theProperty->GetColor( myColor );
+    int aRed = int( myColor[0] * 255 );
+    int aGreen = int( myColor[1] * 255 );
+    int aBlue = int( myColor[2] * 255 );
 
-  float* aPropertyColor = theActor->GetProperty()->GetColor();
-  float aColor[3] = {aPropertyColor[0], aPropertyColor[1], aPropertyColor[2]};
+    myHue = ComputeHue( aRed, aGreen, aBlue );
+  }
 
-  unsigned long i = 0;
-  vtkIdType *pts = 0;
-  vtkIdType npts = 0;
-  for( theCells->InitTraversal(); theCells->GetNextCell( npts, pts ); i++ )
+  virtual
+  void
+  get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
   {
-    TVertex& aVertex = aVertexArr[i];
-    vtkIdType aPointId = pts[0];
-    float* aCoords = thePoints->GetPoint( aPointId );
-    aVertex.vx = aCoords[0];
-    aVertex.vy = aCoords[1];
-    aVertex.vz = aCoords[2];
-
-    int aRed, aGreen, aBlue;
-    if( theColors && this->PointSpriteMode != 1 )
-    {
-      unsigned char *col = theColors->GetPointer(pts[0] << 2);
-      aRed = int(col[0]);
-      aGreen = int(col[1]);
-      aBlue = int(col[2]);
-
-      aColor[0] = aRed / 255.0;
-      aColor[1] = aGreen / 255.0;
-      aColor[2] = aBlue / 255.0;
-    }
+    theVertex.r = myColor[0];
+    theVertex.g = myColor[1];
+    theVertex.b = myColor[2];
 
-    aVertex.r = aColor[0];
-    aVertex.g = aColor[1];
-    aVertex.b = aColor[2];
-    aVertex.hue = ComputeHue( aRed, aGreen, aBlue );
+    theVertex.hue = myHue;
   }
+};
 
-  GLuint aBufferObjectID = 0;
-  vglGenBuffersARB( 1, &aBufferObjectID );
-  vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
 
-  int nArrayObjectSize = sizeof( TVertex ) * this->TotalCells;
-  vglBufferDataARB( GL_ARRAY_BUFFER_ARB, nArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
+//-----------------------------------------------------------------------------
+struct TColors2Color : TColorFunctorBase
+{
+  vtkUnsignedCharArray *myColors;
 
-  delete [] aVertexArr;
+  TColors2Color( vtkUnsignedCharArray *theColors ):
+    myColors( theColors )
+  {}
 
-  vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
-  vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+  virtual
+  void
+  get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
+  {
+    vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
+    unsigned char *aColor = myColors->GetPointer( aTupleId << 2 );
 
-  glColorPointer( 4, GL_FLOAT, sizeof(TVertex), (void*)0 );
-  glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)(4*sizeof(GLfloat)) );
+    theVertex.r = int( aColor[0] ) / 255.0;
+    theVertex.g = int( aColor[1] ) / 255.0;
+    theVertex.b = int( aColor[2] ) / 255.0;
 
-  glEnableClientState( GL_VERTEX_ARRAY );
-  glEnableClientState( GL_COLOR_ARRAY );
+    theVertex.hue = ComputeHue( aColor[0], aColor[1], aColor[2] );
+  }  
 
-  glDrawArrays( GL_POINTS, 0, this->TotalCells );
+  virtual
+  vtkIdType
+  GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
+};
 
-  glDisableClientState( GL_COLOR_ARRAY );
-  glDisableClientState( GL_VERTEX_ARRAY );
 
-  vglDeleteBuffersARB( 1, &aBufferObjectID );
+//-----------------------------------------------------------------------------
+struct TPointColors2Color : TColors2Color
+{
+  TPointColors2Color( vtkUnsignedCharArray *theColors ):
+    TColors2Color( theColors )
+  {}
+
+  virtual
+  vtkIdType
+  GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
+  {
+    return thePointId;
+  }
+};
+
+
+//-----------------------------------------------------------------------------
+struct TCellColors2Color : TColors2Color
+{
+  TCellColors2Color( vtkUnsignedCharArray *theColors ):
+    TColors2Color( theColors )
+  {}
+
+  virtual
+  vtkIdType
+  GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
+  {
+    return theCellId;
+  }
+};
+
+
+//-----------------------------------------------------------------------------
+template < class TCoordinates >
+void DrawPoints( TCoordinates *theStartPoints,
+                 vtkCellArray *theCells,
+                 TColorFunctorBase* theColorFunctor,
+                 TVertex* theVertexArr,
+                 vtkIdType &theCellId,
+                 vtkIdType &theVertexId )
+{
+  vtkIdType *ptIds = theCells->GetPointer();
+  vtkIdType *endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
+
+  while ( ptIds < endPtIds ) {
+    vtkIdType nPts = *ptIds;
+    ++ptIds;
 
-  //if( this->PrimitiveType == VISU_OpenGLPointSpriteMapper::OpenGLPoint )
-  //  glDisable( GL_POINT_SMOOTH );
+    while ( nPts > 0 ) {
+      TVertex& aVertex = theVertexArr[ theVertexId ];
+      vtkIdType aPointId = *ptIds;
+
+      TCoordinates *anOffsetPoints = theStartPoints + 3 * aPointId;
+      aVertex.vx = anOffsetPoints[0];
+      aVertex.vy = anOffsetPoints[1];
+      aVertex.vz = anOffsetPoints[2];
+
+      theColorFunctor->get( aVertex, aPointId, theCellId );
+
+      ++theVertexId;
+      ++ptIds; 
+      --nPts; 
+    }
+
+    ++theCellId;
+  }
 }
 
+
 //-----------------------------------------------------------------------------
-int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *aren, vtkActor *act)
+template < class TCoordinates >
+void DrawCellsPoints( vtkPolyData *theInput,
+                      vtkPoints* thePoints,
+                      TColorFunctorBase* theColorFunctor,
+                      TVertex* theVertexArr )
 {
+  vtkIdType aCellId = 0, aVertexId = 0;
+
+  TCoordinates *aStartPoints = (TCoordinates *) thePoints->GetVoidPointer(0);
+
+  if ( vtkCellArray* aCellArray = theInput->GetVerts() )
+    DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+  
+  if ( vtkCellArray* aCellArray = theInput->GetLines() )
+    DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+  
+  if ( vtkCellArray* aCellArray = theInput->GetPolys() )
+    DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
+  
+  if ( vtkCellArray* aCellArray = theInput->GetStrips() )
+    DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId ); 
+}
 
-  if( this->UseOpenGLMapper ||
-      this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere )
-    return MAPPER_SUPERCLASS::Draw( aren, act );
 
-  vtkOpenGLRenderer    *ren    = (vtkOpenGLRenderer *)aren;
+//-----------------------------------------------------------------------------
+int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *theRenderer, vtkActor *theActor)
+{
+
+  if( this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere )
+    return MAPPER_SUPERCLASS::Draw( theRenderer, theActor );
+
   vtkUnsignedCharArray *colors = NULL;
-  vtkFloatArray        *alpha  = NULL;
   vtkPolyData          *input  = this->GetInput();
   vtkPoints            *points;
   int noAbort = 1;
   int cellScalars = 0;
-  vtkIdType cellNum = 0;
-  float  tran;
-
-  // get the transparency
-  tran = act->GetProperty()->GetOpacity();
 
   // if the primitives are invisable then get out of here
-  if (tran <= 0.0)
+  if (this->PointSpriteOpacity <= 0.0)
   {
     return noAbort;
   }
@@ -859,10 +1001,95 @@ int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *aren, vtkActor *act)
     }
   }
 
-  // we need to know the total number of cells so that we can report progress
-  this->TotalCells = input->GetVerts()->GetNumberOfCells();
+  {
+    vtkIdType aTotalConnectivitySize = 0;
+
+    if ( vtkCellArray* aCellArray = input->GetVerts() )
+      aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+
+    if ( vtkCellArray* aCellArray = input->GetLines() )
+      aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+
+    if ( vtkCellArray* aCellArray = input->GetPolys() )
+      aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+
+    if ( vtkCellArray* aCellArray = input->GetStrips() )
+      aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
+
+    if ( aTotalConnectivitySize > 0 ) {
+      TVertex* aVertexArr = new TVertex[ aTotalConnectivitySize ];
+
+      vtkFloatingPointType aPropertyColor[3];
+      theActor->GetProperty()->GetColor( aPropertyColor );
+
+      glPointSize( this->DefaultPointSize );
+
+      {
+        TColorFunctorBase* aColorFunctor = NULL;
+        if( colors && this->PointSpriteMode != 1 ) {
+          if ( cellScalars )
+            aColorFunctor = new TCellColors2Color( colors );
+          else
+            aColorFunctor = new TPointColors2Color( colors );
+        } else {
+          aColorFunctor = new TPropertyColor( theActor->GetProperty() );
+        }
+        if ( points->GetDataType() == VTK_FLOAT )
+          ::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr );
+        else
+          ::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr );
+
+        delete aColorFunctor;
+      }
+
+      if( this->ExtensionsInitialized ) {
+        GLuint aBufferObjectID = 0;
+        vglGenBuffersARB( 1, &aBufferObjectID );
+        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+        
+        int anArrayObjectSize = sizeof( TVertex ) * aTotalConnectivitySize;
+        vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
+        
+        delete [] aVertexArr;
+        
+        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+        vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+        
+        glColorPointer( 4, GL_FLOAT, sizeof(TVertex), (void*)0 );
+        glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)(4*sizeof(GLfloat)) );
+        
+        glEnableClientState( GL_VERTEX_ARRAY );
+        glEnableClientState( GL_COLOR_ARRAY );
+        
+        glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
+        
+        glDisableClientState( GL_COLOR_ARRAY );
+        glDisableClientState( GL_VERTEX_ARRAY );
+        
+        vglDeleteBuffersARB( 1, &aBufferObjectID );
+      } else { // there are not extensions
+        glColorPointer( 4, GL_FLOAT, sizeof(TVertex), aVertexArr );
+        glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), 
+                         (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
+
+        glEnableClientState( GL_VERTEX_ARRAY );
+        glEnableClientState( GL_COLOR_ARRAY );
+        
+        glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
+        
+        glDisableClientState( GL_COLOR_ARRAY );
+        glDisableClientState( GL_VERTEX_ARRAY );
+
+        delete [] aVertexArr;
+      }
+    }
+
+    input->GetVerts()->GetNumberOfCells() + 
+    input->GetLines()->GetNumberOfCells() + 
+    input->GetPolys()->GetNumberOfCells() + 
+    input->GetStrips()->GetNumberOfCells();
+  }
 
-  this->DrawPoints(points, colors, alpha, cellNum, noAbort, input->GetVerts(), ren, act);
 
   this->UpdateProgress(1.0);
   return noAbort;