From: ouv Date: Mon, 26 Sep 2005 14:16:03 +0000 (+0000) Subject: Optimization of the drawing vertices by using GL_ARB_vertex_buffer_object extension X-Git-Tag: BR-D5-38-2003_D2005-12-10~139 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=04c6362f8523e2443fcdafdbb97f20d0d277d579;p=modules%2Fvisu.git Optimization of the drawing vertices by using GL_ARB_vertex_buffer_object extension --- diff --git a/src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx b/src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx index 513c8a5e..75c74663 100755 --- a/src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx +++ b/src/PIPELINE/VISU_OpenGLPointSpriteMapper.cxx @@ -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(); } //-----------------------------------------------------------------------------