]> SALOME platform Git repositories - modules/visu.git/commitdiff
Salome HOME
Optimization of the drawing vertices by using GL_ARB_vertex_buffer_object extension
authorouv <ouv@opencascade.com>
Mon, 26 Sep 2005 14:16:03 +0000 (14:16 +0000)
committerouv <ouv@opencascade.com>
Mon, 26 Sep 2005 14:16:03 +0000 (14:16 +0000)
src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx

index 513c8a5ed8043e992424626e287ff6ff6c3bd6bb..75c74663a7ca69be1b23c235a37bbcb0b1d7cee0 100755 (executable)
@@ -103,6 +103,13 @@ PFNGLVERTEXATTRIB1FARBPROC           glVertexAttrib1fARB          = NULL;
 GLhandleARB VISU_OpenGLPointSpriteMapper::VertexProgram = 0;
 #endif
 
+
+struct TVertex
+{
+  GLfloat r, g, b;
+  GLfloat vx, vy, vz;
+};
+
 //-----------------------------------------------------------------------------
 // Construct empty object.
 VISU_OpenGLPointSpriteMapper::VISU_OpenGLPointSpriteMapper()
@@ -113,7 +120,7 @@ VISU_OpenGLPointSpriteMapper::VISU_OpenGLPointSpriteMapper()
   this->ExtensionsOK             = 0;
   this->AlphaChannelArray        = NULL;
   this->SizeChannelArray         = NULL;
-  this->DefaultPointSize         = 30.0;
+  this->DefaultPointSize         = 50.0;
   this->QuadraticPointDistanceAttenuation[0] = 1.0;
   this->QuadraticPointDistanceAttenuation[1] = 0.0;
   this->QuadraticPointDistanceAttenuation[2] = 0.0;
@@ -201,8 +208,10 @@ char* readFromFile( std::string fileName )
 #ifdef GL_ARB_shader_objects
 void VISU_OpenGLPointSpriteMapper::PrintInfoLog( GLhandleARB obj )
 {
-  PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)dlsym( this->OpenGLLibrary, "glGetObjectParameterivARB" );
-  PFNGLGETINFOLOGARBPROC glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)dlsym( this->OpenGLLibrary, "glGetInfoLogARB" );
+  PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB =
+    (PFNGLGETOBJECTPARAMETERIVARBPROC)dlsym( this->OpenGLLibrary, "glGetObjectParameterivARB" );
+  PFNGLGETINFOLOGARBPROC glGetInfoLogARB =
+    (PFNGLGETINFOLOGARBPROC)dlsym( this->OpenGLLibrary, "glGetInfoLogARB" );
 
   int infologLength = 0;
   int charsWritten  = 0;
@@ -231,13 +240,20 @@ GLhandleARB VISU_OpenGLPointSpriteMapper::InitShader()
   //std::string fileName = std::string( "/dn06/salome/ouv/SALOME/VISU_SRC/resources/Vertex_Program_ARB.txt");
   char* shader = readFromFile( fileName );
 
-  PFNGLSHADERSOURCEARBPROC glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)dlsym( this->OpenGLLibrary, "glShaderSourceARB" );
-  PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)dlsym( this->OpenGLLibrary, "glCreateShaderObjectARB" );
-  PFNGLCOMPILESHADERARBPROC glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)dlsym( this->OpenGLLibrary, "glCompileShaderARB" );
-  PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glCreateProgramObjectARB" );
-  PFNGLATTACHOBJECTARBPROC glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glAttachObjectARB" );
-  PFNGLLINKPROGRAMPROC glLinkProgramARB = (PFNGLLINKPROGRAMPROC)dlsym( this->OpenGLLibrary, "glLinkProgramARB" );
-  //PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glUseProgramObjectARB" );
+  PFNGLSHADERSOURCEARBPROC glShaderSourceARB =
+    (PFNGLSHADERSOURCEARBPROC)dlsym( this->OpenGLLibrary, "glShaderSourceARB" );
+  PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB =
+    (PFNGLCREATESHADEROBJECTARBPROC)dlsym( this->OpenGLLibrary, "glCreateShaderObjectARB" );
+  PFNGLCOMPILESHADERARBPROC glCompileShaderARB =
+    (PFNGLCOMPILESHADERARBPROC)dlsym( this->OpenGLLibrary, "glCompileShaderARB" );
+  PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB =
+    (PFNGLCREATEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glCreateProgramObjectARB" );
+  PFNGLATTACHOBJECTARBPROC glAttachObjectARB =
+    (PFNGLATTACHOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glAttachObjectARB" );
+  PFNGLLINKPROGRAMPROC glLinkProgramARB =
+    (PFNGLLINKPROGRAMPROC)dlsym( this->OpenGLLibrary, "glLinkProgramARB" );
+  //PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB =
+  //  (PFNGLUSEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glUseProgramObjectARB" );
 
   GLhandleARB VertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
   glShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
@@ -282,8 +298,10 @@ GLhandleARB VISU_OpenGLPointSpriteMapper::InitShader()
 #ifdef GL_ARB_shader_objects
 void VISU_OpenGLPointSpriteMapper::SetShaderVariable( const char* variable, float value )
 {
-  PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)dlsym( this->OpenGLLibrary, "glGetAttribLocationARB" );
-  PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)dlsym( this->OpenGLLibrary, "glVertexAttrib1fARB" );
+  PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB =
+    (PFNGLGETATTRIBLOCATIONARBPROC)dlsym( this->OpenGLLibrary, "glGetAttribLocationARB" );
+  PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB =
+    (PFNGLVERTEXATTRIB1FARBPROC)dlsym( this->OpenGLLibrary, "glVertexAttrib1fARB" );
 
   //cout << VISU_OpenGLPointSpriteMapper::VertexProgram << " ";
   //cout << glGetAttribLocationARB( VISU_OpenGLPointSpriteMapper::VertexProgram, variable ) << " ";
@@ -339,7 +357,9 @@ void VISU_OpenGLPointSpriteMapper::InitExtensions()
   //cout << "OpenGL extensions : " << ext << endl;
 
   if( strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
-      strstr( ext, "GL_ARB_vertex_program" ) == NULL )
+      //strstr( ext, "GL_ARB_vertex_program" ) == NULL ||
+      strstr( ext, "GL_ARB_shader_objects" ) == NULL ||
+      strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
   {
     vtkErrorMacro(<<"Initializing ARB extensions failed");
 
@@ -380,7 +400,8 @@ void VISU_OpenGLPointSpriteMapper::InitExtensions()
     VISU_OpenGLPointSpriteMapper::VertexProgram = this->InitShader();
   }
 
-  PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glUseProgramObjectARB" );
+  PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB =
+    (PFNGLUSEPROGRAMOBJECTARBPROC)dlsym( this->OpenGLLibrary, "glUseProgramObjectARB" );
   glUseProgramObjectARB( VISU_OpenGLPointSpriteMapper::VertexProgram );
 
   this->SetShaderVariable( "attrib1",       1.0 );
@@ -541,6 +562,9 @@ void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
   this->ActorOpacity = act->GetProperty()->GetOpacity();
   this->MapScalars(this->ActorOpacity);
 
+  // Initializing the texture for Point Sprites
+  this->InitTexture();
+
   //
   // if something has changed regenerate colors and display lists
   // if required
@@ -620,38 +644,6 @@ void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
     }
 }
 //-----------------------------------------------------------------------------
-#define vtkDrawPointsMacro(ptype,glVertFuncs,glInitFuncs) \
-{ \
-  vtkIdType nPts; unsigned short count = 0; \
-  ptype *points = (ptype *)voidPoints; \
-  glInitFuncs \
-  glBegin(GL_POINTS); \
-  while (ptIds < endPtIds) \
-    { \
-    nPts = *ptIds; \
-    ++ptIds; \
-    while (nPts > 0) \
-      { \
-      glVertFuncs \
-      ++ptIds; \
-      --nPts; \
-      } \
-    if (++count == 10000) \
-      { \
-      cellNum += 10000; \
-      count = 0; \
-      this->UpdateProgress((double)cellNum/this->TotalCells); \
-      if (ren->GetRenderWindow()->CheckAbortStatus()) \
-        { \
-        noAbort = 0; \
-        break; \
-        } \
-      } \
-    } \
-  cellNum += count; \
-  glEnd(); \
-}
-//-----------------------------------------------------------------------------
 float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
 {
   float maximumSupportedSize = 0.0;
@@ -662,6 +654,9 @@ float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::InitSprites()
 {
+  glEnable( GL_POINT_SPRITE_ARB );
+  glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
+
   switch (this->RenderMode)
   {
     case VISU_OpenGLPointSpriteMapper::Accumulate:
@@ -691,19 +686,11 @@ void VISU_OpenGLPointSpriteMapper::InitSprites()
     }
   }
   // Disable Lighting/Shading.
-  // This will fall back on the color set in the glColor4fv()
-  // call in vtkOpenGLProperty::Render() - the color returned
-  // by vtkProperty::GetColor() with alpha set to 1.0.
-  glDisable( GL_LIGHTING);
+  glDisable( GL_LIGHTING );
 
   // Disable material properties
   glDisable( GL_COLOR_MATERIAL );
 
-  //
-  // Enable point smoothing. Not really needed
-  //
-  //glEnable(GL_POINT_SMOOTH);
-
   /*
   // Set Quadratic Attenuation parameters
   glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, this->QuadraticPointDistanceAttenuation );
@@ -725,11 +712,14 @@ void VISU_OpenGLPointSpriteMapper::InitSprites()
 void VISU_OpenGLPointSpriteMapper::CleanupSprites()
 {
   // Set GL params back to normal to stop other vtkMappers diusplaying wrongly
+  glEnable( GL_BLEND );
+
   glEnable( GL_DEPTH_TEST );
   glEnable( GL_LIGHTING );
-  glEnable( GL_BLEND );
+  glEnable( GL_COLOR_MATERIAL );
 
-  //glDisable( GL_VERTEX_PROGRAM_ARB );
+  glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
+  glDisable( GL_POINT_SPRITE_ARB );
 }
 
 
@@ -738,6 +728,7 @@ void
 VISU_OpenGLPointSpriteMapper
 ::SetImageData( vtkImageData* theImageData )
 {
+  //cout << "VISU_OpenGLPointSpriteMapper::SetImageData " << theImageData << endl;
   this->ImageData = theImageData;
 }
 
@@ -752,27 +743,26 @@ VISU_OpenGLPointSpriteMapper
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::InitTexture()
 {
-  int* aSize = GetImageData()->GetDimensions();
-  unsigned char* dataPtr = (unsigned char*)GetImageData()->GetScalarPointer();
+  //cout << "VISU_OpenGLPointSpriteMapper::InitTexture " << this->GetImageData() << endl;
+  if( !this->GetImageData() )
+    return;
 
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-  //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
-  //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
   glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 
+  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 );
 
   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
   glEnable( GL_TEXTURE_2D );
-  glEnable( GL_POINT_SPRITE_ARB );
-  //glEnable( GL_VERTEX_PROGRAM_ARB );
-  glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
   glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
   glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
 }
+
 //-----------------------------------------------------------------------------
 void VISU_OpenGLPointSpriteMapper::DrawPoints(int idx,
                                              vtkPoints *p,
@@ -783,112 +773,81 @@ void VISU_OpenGLPointSpriteMapper::DrawPoints(int idx,
                                              vtkCellArray *cells,
                                              vtkRenderer *ren)
 {
-  if( this->GetImageData() )
-    this->InitTexture();
+  //cout << "VISU_OpenGLPointSpriteMapper::DrawPoints" << endl;
 
   this->InitSprites();
+  //this->InitTexture();
 
   glPointSize( this->DefaultPointSize );
 
-  void *voidPoints = p->GetVoidPointer(0);
-  unsigned char *rgba;
-  float *alphadata;
-
-  if (cells->GetNumberOfCells() == 0)
-    {
-    return;
-    }
-  if (colors)
-    {
-    rgba = colors->GetPointer(0);
-    }
+#ifdef GL_ARB_vertex_buffer_object
+  PFNGLGENBUFFERSARBPROC glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)dlsym( this->OpenGLLibrary, "glGenBuffersARB" );
+  PFNGLBINDBUFFERARBPROC glBindBufferARB = (PFNGLBINDBUFFERARBPROC)dlsym( this->OpenGLLibrary, "glBindBufferARB" );
+  PFNGLBUFFERDATAARBPROC glBufferDataARB = (PFNGLBUFFERDATAARBPROC)dlsym( this->OpenGLLibrary, "glBufferDataARB" );
 
-  vtkIdType *ptIds = cells->GetPointer();
-  vtkIdType *endPtIds = ptIds + cells->GetNumberOfConnectivityEntries();
+  TVertex* aVertex = new TVertex[ this->TotalCells ];
 
-  // draw all the elements, use fast path if available
-  switch (idx)
+  vtkIdType *pts = 0;
+  vtkIdType npts = 0;
+  unsigned short i = 0;
+  for( cells->InitTraversal(); cells->GetNextCell( npts, pts ); i++ )
   {
-    case VTK_PDPSM_POINT_TYPE_FLOAT:
-      //std::cout << "VTK_PDPSM_POINT_TYPE_FLOAT " << std::endl;
-      vtkDrawPointsMacro(float, glVertex3fv(points + 3**ptIds);, InitSprites(););
-      break;
-    case VTK_PDPSM_POINT_TYPE_DOUBLE:
-      //std::cout << "VTK_PDPSM_POINT_TYPE_DOUBLE " << std::endl;
-      vtkDrawPointsMacro(double, glVertex3dv(points + 3**ptIds);, InitSprites(););
-      break;
-    case VTK_PDPSM_POINT_TYPE_FLOAT | VTK_PDPSM_COLORS:
-      //std::cout << "VTK_PDPSM_POINT_TYPE_FLOAT | VTK_PDPSM_COLORS " << std::endl;
-      vtkDrawPointsMacro(float,
-                         glColor4ubv(rgba + 4**ptIds);
-                         glVertex3fv(points + 3**ptIds);, InitSprites(););
-      break;
-    case VTK_PDPSM_POINT_TYPE_DOUBLE | VTK_PDPSM_COLORS:
-      //std::cout << "VTK_PDPSM_POINT_TYPE_DOUBLE | VTK_PDPSM_COLORS " << std::endl;
-      vtkDrawPointsMacro(double,
-                         glColor4ubv(rgba + 4**ptIds);
-                         glVertex3dv(points + 3**ptIds);, InitSprites(););
-      break;
-    case VTK_PDPSM_POINT_TYPE_FLOAT | VTK_PDPSM_COLORS | VTK_PDPSM_OPAQUE_COLORS:
-      //std::cout << "VTK_PDPSM_POINT_TYPE_FLOAT | VTK_PDPSM_COLORS | VTK_PDPSM_OPAQUE_COLORS " << std::endl;
-      vtkDrawPointsMacro(float,
-                         glColor3ubv(rgba + 4**ptIds);
-                         glVertex3fv(points + 3**ptIds);, InitSprites(););
-      break;
-    default:
-    {
-      //std::cout << "Default " << std::endl;
-      if (idx & VTK_PDPSM_ALPHA_ARRAY)
-        alphadata = alpha->GetPointer(0);
-
-      vtkIdType *pts = 0;
-      vtkIdType npts = 0;
-      unsigned short count = 0;
-      glBegin(GL_POINTS);
-      for (cells->InitTraversal(); noAbort && cells->GetNextCell(npts,pts); count++)
-      {
-        if (colors)
-        {
-          if (idx & VTK_PDPSM_CELL_COLORS)
-          {
-            unsigned char *col = colors->GetPointer(cellNum << 2);
-            if (idx & VTK_PDPSM_ALPHA_ARRAY)
-            {
-              vtkErrorMacro(<<"Not yet fully implemented cell arrays for Point sprite mapper");
-            }
-            glColor4ubv(col);
-          }
-          else
-          {
-            unsigned char *col = colors->GetPointer(pts[0]<< 2);
-            if (idx & VTK_PDPSM_ALPHA_ARRAY)
-            {
-              col[3] = (unsigned char)(this->ActorOpacity*255.0*alphadata[pts[0]]+0.499999);
-            }
-            glColor4ubv(col);
-          }
-        }
+    aVertex[i].vx = p->GetPoint( pts[0] )[0];
+    aVertex[i].vy = p->GetPoint( pts[0] )[1];
+    aVertex[i].vz = p->GetPoint( pts[0] )[2];
+
+    unsigned char *col = colors->GetPointer(pts[0]<< 2);
+    aVertex[i].r = ( ( int )col[0] ) / 255.0;
+    aVertex[i].g = ( ( int )col[1] ) / 255.0;
+    aVertex[i].b = ( ( int )col[2] ) / 255.0;
+  }
 
-       glVertex3fv(p->GetPoint(pts[0]));
+  GLuint aBufferObjectID = 0;
+  glGenBuffersARB( 1, &aBufferObjectID );
+  glBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
 
-        // check for abort condition
-        if (count == 10000)
-        {
-          count = 0;
-          // report progress
-          this->UpdateProgress((double)cellNum/this->TotalCells);
-          if (ren->GetRenderWindow()->CheckAbortStatus())
-            noAbort = 0;
-
-       }
-        ++cellNum;
-      }
+  int nArrayObjectSize = sizeof( TVertex ) * this->TotalCells;
+  glBufferDataARB( GL_ARRAY_BUFFER_ARB, nArrayObjectSize, aVertex, GL_STATIC_DRAW_ARB );
+
+  delete [] aVertex;
 
-      glEnd();
+  glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
+  glBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
+
+  static int aDisplacement = 3*sizeof(GLfloat);
+  
+  glColorPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)0 );
+  glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)aDisplacement );
+
+  glEnableClientState(GL_VERTEX_ARRAY);
+  glEnableClientState(GL_COLOR_ARRAY);
+
+  glDrawArrays(GL_POINTS,0,this->TotalCells);
+
+  glDisableClientState(GL_COLOR_ARRAY);
+  glDisableClientState(GL_VERTEX_ARRAY);
+#endif
+
+  /*
+  glBegin( GL_POINTS );
+
+  vtkIdType *pts = 0;
+  vtkIdType npts = 0;
+  unsigned short count = 0;
+  for( cells->InitTraversal(); cells->GetNextCell( npts, pts ); count++ )
+  {
+    if (colors)
+    {
+      unsigned char *col = colors->GetPointer(pts[0]<< 2);
+      glColor4ubv(col);
     }
-  }
 
-  CleanupSprites();
+    glVertex3fv(p->GetPoint(pts[0]));
+
+  }
+  glEnd();
+  */
+  this->CleanupSprites();
 }
 
 //-----------------------------------------------------------------------------