1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File: VISU_OpenGLPointSpriteMapper.cxx
28 #include "VISU_OpenGLPointSpriteMapper.hxx"
30 //#include "SVTK_Extension.h"
32 #include <vtkCamera.h>
33 #include <vtkCellArray.h>
34 #include <vtkCellData.h>
35 #include <vtkCommand.h>
36 #include <vtkImageData.h>
37 #include <vtkMatrix4x4.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkRenderer.h>
40 #include <vtkRenderWindow.h>
41 #include <vtkPointData.h>
42 #include <vtkPolyData.h>
43 #include <vtkPolygon.h>
44 #include <vtkProperty.h>
45 #include <vtkTimerLog.h>
46 #include <vtkTriangle.h>
52 #include "utilities.h"
55 # ifndef GLX_GLXEXT_LEGACY
56 # define GLX_GLXEXT_LEGACY
64 #ifndef VTK_IMPLEMENT_MESA_CXX
65 vtkCxxRevisionMacro(VISU_OpenGLPointSpriteMapper, "Revision$");
66 vtkStandardNewMacro(VISU_OpenGLPointSpriteMapper);
69 // some definitions for what the polydata has in it
70 #define VTK_PDPSM_COLORS 0x0001
71 #define VTK_PDPSM_CELL_COLORS 0x0002
72 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
73 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
74 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
75 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
76 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
82 #define APIENTRYP APIENTRY *
85 #ifndef GL_OBJECT_INFO_LOG_LENGTH_ARB
86 #define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
89 #ifndef GL_VERTEX_SHADER_ARB
90 #define GL_VERTEX_SHADER_ARB 0x8B31
93 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
94 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
97 #ifndef GL_ARB_point_sprite
98 #define GL_POINT_SPRITE_ARB 0x8861
99 #define GL_COORD_REPLACE_ARB 0x8862
102 #ifndef GL_ARB_shader_objects
103 typedef char GLcharARB;
106 #ifndef GL_ARB_vertex_buffer_object
107 typedef ptrdiff_t GLsizeiptrARB;
109 #define GL_ARRAY_BUFFER_ARB 0x8892
110 #define GL_STATIC_DRAW_ARB 0x88E4
113 typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
114 typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
115 typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
116 typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
117 typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
118 typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
119 typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
120 typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
121 typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
122 typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
123 typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
125 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
126 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
127 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
128 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
130 static PFNGLSHADERSOURCEARBPROC vglShaderSourceARB = NULL;
131 static PFNGLCREATESHADEROBJECTARBPROC vglCreateShaderObjectARB = NULL;
132 static PFNGLCOMPILESHADERARBPROC vglCompileShaderARB = NULL;
133 static PFNGLCREATEPROGRAMOBJECTARBPROC vglCreateProgramObjectARB = NULL;
134 static PFNGLATTACHOBJECTARBPROC vglAttachObjectARB = NULL;
135 static PFNGLLINKPROGRAMARBPROC vglLinkProgramARB = NULL;
136 static PFNGLUSEPROGRAMOBJECTARBPROC vglUseProgramObjectARB = NULL;
137 static PFNGLGETOBJECTPARAMETERIVARBPROC vglGetObjectParameterivARB = NULL;
138 static PFNGLGETINFOLOGARBPROC vglGetInfoLogARB = NULL;
139 static PFNGLGETATTRIBLOCATIONARBPROC vglGetAttribLocationARB = NULL;
140 static PFNGLVERTEXATTRIB1FARBPROC vglVertexAttrib1fARB = NULL;
142 static PFNGLGENBUFFERSARBPROC vglGenBuffersARB = NULL;
143 static PFNGLBINDBUFFERARBPROC vglBindBufferARB = NULL;
144 static PFNGLBUFFERDATAARBPROC vglBufferDataARB = NULL;
145 static PFNGLDELETEBUFFERSARBPROC vglDeleteBuffersARB = NULL;
148 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
150 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
155 vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
156 if( !vglShaderSourceARB )
159 vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
160 if( !vglCreateShaderObjectARB )
163 vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
164 if( !vglCompileShaderARB )
167 vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
168 if( !vglCreateProgramObjectARB )
171 vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
172 if( !vglAttachObjectARB )
175 vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
176 if( !vglLinkProgramARB )
179 vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
180 if( !vglUseProgramObjectARB )
183 vglGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)GL_GetProcAddress( "glGetObjectParameterivARB" );
184 if( !vglGetObjectParameterivARB )
187 vglGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)GL_GetProcAddress( "glGetInfoLogARB" );
188 if( !vglGetInfoLogARB )
191 vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocationARB" );
192 if( !vglGetAttribLocationARB )
195 vglVertexAttrib1fARB = (PFNGLVERTEXATTRIB1FARBPROC)GL_GetProcAddress( "glVertexAttrib1fARB" );
196 if( !vglVertexAttrib1fARB )
199 vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
200 if( !vglGenBuffersARB )
203 vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
204 if( !vglBindBufferARB )
207 vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
208 if( !vglBufferDataARB )
211 vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
212 if( !vglDeleteBuffersARB )
218 static bool IsARBInitialized = InitializeARB();
219 static vtkFloatingPointType Tolerance = 1.0 / VTK_LARGE_FLOAT;
221 //-----------------------------------------------------------------------------
222 // Construct empty object.
223 VISU_OpenGLPointSpriteMapper::VISU_OpenGLPointSpriteMapper()
225 this->RenderMode = VISU_OpenGLPointSpriteMapper::Occlude;
228 this->TotalCells = 0;
229 this->ExtensionsInitialized = 0;
230 this->DefaultPointSize = 20.0;
231 this->AverageCellSize = 0.0;
233 this->UsePointSprites = true;
234 this->UseTextures = true;
235 this->UseShader = true;
237 this->PrimitiveType = VISU_OpenGLPointSpriteMapper::PointSprite;
239 this->PointSpriteMode = 0;
241 this->PointSpriteClamp = 256.0;
242 this->PointSpriteSize = 0.2;
243 this->PointSpriteMinSize = 0.1;
244 this->PointSpriteMaxSize = 0.3;
245 this->PointSpriteMagnification = 1.0;
247 this->PointSpriteAlphaThreshold = 0.5;
248 this->PointSpriteOpacity = 1.0;
249 this->PointSpriteTexture = 0;
251 this->UseOpenGLMapper = false;
253 //-----------------------------------------------------------------------------
254 VISU_OpenGLPointSpriteMapper::~VISU_OpenGLPointSpriteMapper()
256 if( PointSpriteTexture>0 )
257 glDeleteTextures( 1, &PointSpriteTexture );
259 if( this->LastWindow )
260 this->ReleaseGraphicsResources(this->LastWindow);
263 //-----------------------------------------------------------------------------
264 char* readFromFile( std::string fileName )
266 FILE* file = fopen( fileName.c_str(), "r" );
268 char* content = NULL;
273 fseek( file, 0, SEEK_END );
274 count = ftell( file );
279 content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
280 count = fread( content, sizeof( char ), count, file );
281 content[ count ] = '\0';
288 //-----------------------------------------------------------------------------
289 void VISU_OpenGLPointSpriteMapper::PrintInfoLog( GLhandleARB obj )
291 int infologLength = 0;
292 int charsWritten = 0;
295 vglGetObjectParameterivARB( obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength );
297 if( infologLength > 0 )
299 infoLog = ( char* )malloc( infologLength );
300 vglGetInfoLogARB( obj, infologLength, &charsWritten, infoLog );
301 printf( "%s\n", infoLog );
305 //-----------------------------------------------------------------------------
306 void VISU_OpenGLPointSpriteMapper::InitShader()
308 //cout << "Initializing vertex program" << endl;
310 std::string fileName = std::string( getenv( "VISU_ROOT_DIR") ) +
311 "/share/salome/resources/visu/Vertex_Program_ARB.txt";
313 char* shader = readFromFile( fileName );
315 GLhandleARB VertexShader = vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
316 vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
317 vglCompileShaderARB( VertexShader );
318 //this->PrintInfoLog( VertexShader );
320 this->VertexProgram = vglCreateProgramObjectARB();
321 vglAttachObjectARB( this->VertexProgram, VertexShader );
323 vglLinkProgramARB( this->VertexProgram );
324 //this->PrintInfoLog( VertexProgram );
326 cout << "Shader from " << fileName << endl;
327 for( int i = 0; i < strlen( shader ); i++ )
331 if( glGetError() == GL_NO_ERROR )
332 cout << "Loading vertex program... ok" << endl << endl;
334 cout << "Loading vertex program... failed" << endl << endl;
339 //-----------------------------------------------------------------------------
340 void VISU_OpenGLPointSpriteMapper::SetShaderVariable( const char* variable, float value )
342 //cout << this->VertexProgram << " ";
343 //cout << vglGetAttribLocationARB( this->VertexProgram, variable ) << " ";
344 //cout << variable << " " << value << endl;
346 vglVertexAttrib1fARB( vglGetAttribLocationARB( this->VertexProgram, variable ), value );
349 //-----------------------------------------------------------------------------
350 void VISU_OpenGLPointSpriteMapper::SetPrimitiveType( int thePrimitiveType )
352 if( this->PrimitiveType == thePrimitiveType )
355 this->PrimitiveType = thePrimitiveType;
359 //-----------------------------------------------------------------------------
360 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMode( int theMode )
362 if( this->PointSpriteMode == theMode )
365 this->PointSpriteMode = theMode;
369 //-----------------------------------------------------------------------------
370 void VISU_OpenGLPointSpriteMapper::SetPointSpriteClamp( float theClamp )
372 if( fabs( this->PointSpriteClamp - theClamp ) < Tolerance )
375 this->PointSpriteClamp = theClamp;
379 //-----------------------------------------------------------------------------
380 void VISU_OpenGLPointSpriteMapper::SetAverageCellSize(float theSize)
382 if( fabs( this->AverageCellSize - theSize ) < Tolerance )
385 this->AverageCellSize = theSize;
389 //-----------------------------------------------------------------------------
390 void VISU_OpenGLPointSpriteMapper::SetPointSpriteSize( float theSize )
392 if( fabs( this->PointSpriteSize - theSize ) < Tolerance )
395 this->PointSpriteSize = theSize;
399 //-----------------------------------------------------------------------------
400 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMinSize( float theMinSize )
402 if( fabs( this->PointSpriteMinSize - theMinSize ) < Tolerance )
405 this->PointSpriteMinSize = theMinSize;
409 //-----------------------------------------------------------------------------
410 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMaxSize( float theMaxSize )
412 if( fabs( this->PointSpriteMaxSize - theMaxSize ) < Tolerance )
415 this->PointSpriteMaxSize = theMaxSize;
419 //-----------------------------------------------------------------------------
420 void VISU_OpenGLPointSpriteMapper::SetPointSpriteMagnification( float theMagnification )
422 if( fabs( this->PointSpriteMagnification - theMagnification ) < Tolerance )
425 this->PointSpriteMagnification = theMagnification;
429 //-----------------------------------------------------------------------------
430 void VISU_OpenGLPointSpriteMapper::SetPointSpriteAlphaThreshold( float theAlphaThreshold )
432 if( fabs( this->PointSpriteAlphaThreshold - theAlphaThreshold ) < Tolerance )
435 this->PointSpriteAlphaThreshold = theAlphaThreshold;
439 //-----------------------------------------------------------------------------
440 bool VISU_OpenGLPointSpriteMapper::InitExtensions()
442 if( this->ExtensionsInitialized )
447 char* ext = (char*)glGetString( GL_EXTENSIONS );
448 //cout << "OpenGL extensions : " << ext << endl;
450 if( !IsARBInitialized ||
451 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
452 strstr( ext, "GL_ARB_shader_objects" ) == NULL ||
453 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL )
455 vtkWarningMacro(<<"Initializing ARB extensions failed");
456 this->UseOpenGLMapper = true;
461 if( this->UseShader )
464 this->ExtensionsInitialized = 1;
468 //-----------------------------------------------------------------------------
469 float ViewToDisplay( vtkRenderer* theRenderer )
471 vtkFloatingPointType p1[3], p2[3];
473 theRenderer->SetViewPoint( 0.0, 0.0, 0.0 );
474 theRenderer->ViewToDisplay();
475 theRenderer->GetDisplayPoint( p1 );
477 theRenderer->SetViewPoint( 1.0, 1.0, 1.0 );
478 theRenderer->ViewToDisplay();
479 theRenderer->GetDisplayPoint( p2 );
481 vtkFloatingPointType coefficient = sqrt( pow( p2[0] - p1[0], 2 ) + pow( p2[1] - p1[1], 2 ) ) / sqrt( 2. );
482 //cout << p1[0] << " " << p1[1] << " " << p1[2] << endl;
483 //cout << p2[0] << " " << p2[1] << " " << p2[2] << endl;
484 //cout << "ZOOM : " << coefficient << endl;
489 //-----------------------------------------------------------------------------
491 // Receives from Actor -> maps data to primitives
493 void VISU_OpenGLPointSpriteMapper::RenderPiece(vtkRenderer *ren, vtkActor *act)
495 bool isUseThisMapper = this->PrimitiveType != VISU_OpenGLPointSpriteMapper::GeomSphere;
497 if( isUseThisMapper )
498 this->InitExtensions();
500 if( !isUseThisMapper )
502 MAPPER_SUPERCLASS::RenderPiece( ren, act );
507 vtkPolyData *input= this->GetInput();
510 // make sure that we've been properly initialized
512 if (ren->GetRenderWindow()->CheckAbortStatus())
517 vtkErrorMacro(<< "No input!");
522 this->InvokeEvent(vtkCommand::StartEvent,NULL);
524 this->InvokeEvent(vtkCommand::EndEvent,NULL);
526 numPts = input->GetNumberOfPoints();
531 vtkDebugMacro(<< "No points!");
535 if ( this->LookupTable == NULL )
536 this->CreateDefaultLookupTable();
538 // make sure our window is current
539 ren->GetRenderWindow()->MakeCurrent();
541 if( this->UsePointSprites ) //&& this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
542 this->InitPointSprites();
544 // Initializing the texture for Point Sprites
545 if( this->UseTextures && this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
546 this->InitTextures();
548 vglUseProgramObjectARB( this->VertexProgram );
549 float aViewToDisplay = ViewToDisplay( ren );
550 this->SetShaderVariable( "mode", this->PointSpriteMode );
551 this->SetShaderVariable( "clampSize", this->PointSpriteClamp );
552 this->SetShaderVariable( "geomSize", aViewToDisplay * this->AverageCellSize * this->PointSpriteSize );
553 this->SetShaderVariable( "minSize", aViewToDisplay * this->AverageCellSize * this->PointSpriteMinSize );
554 this->SetShaderVariable( "maxSize", aViewToDisplay * this->AverageCellSize * this->PointSpriteMaxSize );
555 this->SetShaderVariable( "magnification", this->PointSpriteMagnification );
558 // if something has changed regenerate colors and display lists
562 if ( this->GetMTime() > this->BuildTime ||
563 input->GetMTime() > this->BuildTime ||
564 act->GetProperty()->GetMTime() > this->BuildTime ||
565 ren->GetRenderWindow() != this->LastWindow)
567 #ifdef _DEBUG_RENDERING_PERFORMANCE_
568 // To control when the mapper is recalculated
569 MESSAGE( "VISU_OpenGLPointSpriteMapper::RenderPiece - "
570 <<(this->GetMTime() > this->BuildTime)<<"; "
571 <<(input->GetMTime() > this->BuildTime)<<"; "
572 <<(act->GetProperty()->GetMTime() > this->BuildTime)<<"; ");
574 // sets this->Colors as side effect
575 this->MapScalars( act->GetProperty()->GetOpacity() );
577 if (!this->ImmediateModeRendering &&
578 !this->GetGlobalImmediateModeRendering())
580 this->ReleaseGraphicsResources(ren->GetRenderWindow());
581 this->LastWindow = ren->GetRenderWindow();
583 // get a unique display list id
584 this->ListId = glGenLists(1);
585 glNewList(this->ListId,GL_COMPILE);
587 noAbort = this->Draw(ren,act);
590 // Time the actual drawing
591 this->Timer->StartTimer();
592 glCallList(this->ListId);
593 this->Timer->StopTimer();
597 this->ReleaseGraphicsResources(ren->GetRenderWindow());
598 this->LastWindow = ren->GetRenderWindow();
601 this->BuildTime.Modified();
603 // if nothing changed but we are using display lists, draw it
606 if (!this->ImmediateModeRendering &&
607 !this->GetGlobalImmediateModeRendering())
609 // Time the actual drawing
610 this->Timer->StartTimer();
611 glCallList(this->ListId);
612 this->Timer->StopTimer();
616 // if we are in immediate mode rendering we always
617 // want to draw the primitives here
618 if (this->ImmediateModeRendering ||
619 this->GetGlobalImmediateModeRendering())
621 // sets this->Colors as side effect
622 this->MapScalars( act->GetProperty()->GetOpacity() );
624 // Time the actual drawing
625 this->Timer->StartTimer();
627 this->Timer->StopTimer();
630 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
632 // If the timer is not accurate enough, set it to a small
633 // time so that it is not zero
634 if ( this->TimeToDraw == 0.0 )
635 this->TimeToDraw = 0.0001;
637 vglUseProgramObjectARB( 0 );
639 if( this->UsePointSprites ) //&& this->PrimitiveType == VISU_OpenGLPointSpriteMapper::PointSprite )
640 this->CleanupPointSprites();
643 //-----------------------------------------------------------------------------
644 float VISU_OpenGLPointSpriteMapper::GetMaximumSupportedSize()
646 float maximumSupportedSize = 512.0;
647 //glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maximumSupportedSize );
649 return maximumSupportedSize;
652 //-----------------------------------------------------------------------------
653 void VISU_OpenGLPointSpriteMapper::InitPointSprites()
655 glEnable( GL_POINT_SPRITE_ARB );
656 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
658 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
660 this->RenderMode = this->PointSpriteOpacity < 1.0 ? VISU_OpenGLPointSpriteMapper::Accumulate : VISU_OpenGLPointSpriteMapper::Occlude;
662 switch (this->RenderMode)
664 case VISU_OpenGLPointSpriteMapper::Accumulate:
666 glDepthFunc( GL_LESS );
667 glEnable( GL_DEPTH_TEST );
669 glEnable( GL_BLEND );
670 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
672 glEnable( GL_ALPHA_TEST );
673 glAlphaFunc( GL_GREATER, this->PointSpriteAlphaThreshold );
677 case VISU_OpenGLPointSpriteMapper::Occlude:
679 glDepthFunc( GL_LEQUAL );
680 glEnable( GL_DEPTH_TEST );
682 glEnable( GL_ALPHA_TEST );
683 glAlphaFunc( GL_GREATER, this->PointSpriteAlphaThreshold );
685 glDisable( GL_BLEND );
694 // Disable Lighting/Shading.
695 glDisable( GL_LIGHTING );
697 // Disable material properties
698 glDisable( GL_COLOR_MATERIAL );
701 //-----------------------------------------------------------------------------
702 void VISU_OpenGLPointSpriteMapper::CleanupPointSprites()
704 // Set GL params back to normal to stop other vtkMappers displaying wrongly
707 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
708 glDisable( GL_POINT_SPRITE_ARB );
712 //-----------------------------------------------------------------------------
714 VISU_OpenGLPointSpriteMapper
715 ::SetImageData( vtkImageData* theImageData )
717 if(GetImageData() == theImageData)
719 this->ImageData = theImageData;
724 VISU_OpenGLPointSpriteMapper
727 return this->ImageData.GetPointer();
731 //-----------------------------------------------------------------------------
732 void VISU_OpenGLPointSpriteMapper::InitTextures()
734 //cout << "VISU_OpenGLPointSpriteMapper::InitTextures " << this->GetImageData() << endl;
735 if( !this->GetImageData() )
738 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
739 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
740 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
741 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
743 int* aSize = GetImageData()->GetDimensions();
744 unsigned char* dataPtr = (unsigned char*)GetImageData()->GetScalarPointer();
745 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
746 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
748 //glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
749 glEnable( GL_TEXTURE_2D );
750 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
751 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
755 //-----------------------------------------------------------------------------
756 int ComputeHue( int r, int g, int b )
772 if ( g < min ) min = g;
773 if ( b < min ) min = b;
778 else if( whatmax == 0 ) {
780 h = (120*(g-b)+delta)/(2*delta);
782 h = (120*(g-b+delta)+delta)/(2*delta) + 300;
784 else if( whatmax == 1 ) {
786 h = 120 + (120*(b-r)+delta)/(2*delta);
788 h = 60 + (120*(b-r+delta)+delta)/(2*delta);
792 h = 240 + (120*(r-g)+delta)/(2*delta);
794 h = 180 + (120*(r-g+delta)+delta)/(2*delta);
800 //-----------------------------------------------------------------------------
803 GLfloat r, g, b, hue;
808 //-----------------------------------------------------------------------------
809 struct TColorFunctorBase
813 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
817 //-----------------------------------------------------------------------------
818 struct TPropertyColor : TColorFunctorBase
820 vtkFloatingPointType myColor[3];
821 vtkFloatingPointType myHue;
823 TPropertyColor( vtkProperty *theProperty )
825 theProperty->GetColor( myColor );
826 int aRed = int( myColor[0] * 255 );
827 int aGreen = int( myColor[1] * 255 );
828 int aBlue = int( myColor[2] * 255 );
830 myHue = ComputeHue( aRed, aGreen, aBlue );
835 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
837 theVertex.r = myColor[0];
838 theVertex.g = myColor[1];
839 theVertex.b = myColor[2];
841 theVertex.hue = myHue;
846 //-----------------------------------------------------------------------------
847 struct TColors2Color : TColorFunctorBase
849 vtkUnsignedCharArray *myColors;
851 TColors2Color( vtkUnsignedCharArray *theColors ):
852 myColors( theColors )
857 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
859 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
860 unsigned char *aColor = myColors->GetPointer( aTupleId << 2 );
862 theVertex.r = int( aColor[0] ) / 255.0;
863 theVertex.g = int( aColor[1] ) / 255.0;
864 theVertex.b = int( aColor[2] ) / 255.0;
866 theVertex.hue = ComputeHue( aColor[0], aColor[1], aColor[2] );
871 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
875 //-----------------------------------------------------------------------------
876 struct TPointColors2Color : TColors2Color
878 TPointColors2Color( vtkUnsignedCharArray *theColors ):
879 TColors2Color( theColors )
884 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
891 //-----------------------------------------------------------------------------
892 struct TCellColors2Color : TColors2Color
894 TCellColors2Color( vtkUnsignedCharArray *theColors ):
895 TColors2Color( theColors )
900 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
907 //-----------------------------------------------------------------------------
908 template < class TCoordinates >
909 void DrawPoints( TCoordinates *theStartPoints,
910 vtkCellArray *theCells,
911 TColorFunctorBase* theColorFunctor,
912 TVertex* theVertexArr,
913 vtkIdType &theCellId,
914 vtkIdType &theVertexId )
916 vtkIdType *ptIds = theCells->GetPointer();
917 vtkIdType *endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
919 while ( ptIds < endPtIds ) {
920 vtkIdType nPts = *ptIds;
924 TVertex& aVertex = theVertexArr[ theVertexId ];
925 vtkIdType aPointId = *ptIds;
927 TCoordinates *anOffsetPoints = theStartPoints + 3 * aPointId;
928 aVertex.vx = anOffsetPoints[0];
929 aVertex.vy = anOffsetPoints[1];
930 aVertex.vz = anOffsetPoints[2];
932 theColorFunctor->get( aVertex, aPointId, theCellId );
944 //-----------------------------------------------------------------------------
945 template < class TCoordinates >
946 void DrawCellsPoints( vtkPolyData *theInput,
947 vtkPoints* thePoints,
948 TColorFunctorBase* theColorFunctor,
949 TVertex* theVertexArr )
951 vtkIdType aCellId = 0, aVertexId = 0;
953 TCoordinates *aStartPoints = (TCoordinates *) thePoints->GetVoidPointer(0);
955 if ( vtkCellArray* aCellArray = theInput->GetVerts() )
956 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
958 if ( vtkCellArray* aCellArray = theInput->GetLines() )
959 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
961 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
962 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
964 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
965 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId );
969 //-----------------------------------------------------------------------------
970 int VISU_OpenGLPointSpriteMapper::Draw(vtkRenderer *theRenderer, vtkActor *theActor)
973 if( this->PrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere )
974 return MAPPER_SUPERCLASS::Draw( theRenderer, theActor );
976 vtkUnsignedCharArray *colors = NULL;
977 vtkPolyData *input = this->GetInput();
982 // if the primitives are invisable then get out of here
983 if (this->PointSpriteOpacity <= 0.0)
988 // and draw the display list
989 points = input->GetPoints();
991 // are they cell or point scalars
994 colors = this->Colors;
995 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
996 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
997 !input->GetPointData()->GetScalars() )
998 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA)
1005 vtkIdType aTotalConnectivitySize = 0;
1007 if ( vtkCellArray* aCellArray = input->GetVerts() )
1008 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1010 if ( vtkCellArray* aCellArray = input->GetLines() )
1011 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1013 if ( vtkCellArray* aCellArray = input->GetPolys() )
1014 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1016 if ( vtkCellArray* aCellArray = input->GetStrips() )
1017 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
1019 if ( aTotalConnectivitySize > 0 ) {
1020 TVertex* aVertexArr = new TVertex[ aTotalConnectivitySize ];
1022 vtkFloatingPointType aPropertyColor[3];
1023 theActor->GetProperty()->GetColor( aPropertyColor );
1025 glPointSize( this->DefaultPointSize );
1028 TColorFunctorBase* aColorFunctor = NULL;
1029 if( colors && this->PointSpriteMode != 1 ) {
1031 aColorFunctor = new TCellColors2Color( colors );
1033 aColorFunctor = new TPointColors2Color( colors );
1035 aColorFunctor = new TPropertyColor( theActor->GetProperty() );
1037 if ( points->GetDataType() == VTK_FLOAT )
1038 ::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr );
1040 ::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr );
1042 delete aColorFunctor;
1045 if( this->ExtensionsInitialized ) {
1046 GLuint aBufferObjectID = 0;
1047 vglGenBuffersARB( 1, &aBufferObjectID );
1048 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1050 int anArrayObjectSize = sizeof( TVertex ) * aTotalConnectivitySize;
1051 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
1053 delete [] aVertexArr;
1055 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1056 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1058 glColorPointer( 4, GL_FLOAT, sizeof(TVertex), (void*)0 );
1059 glVertexPointer( 3, GL_FLOAT, sizeof(TVertex), (void*)(4*sizeof(GLfloat)) );
1061 glEnableClientState( GL_VERTEX_ARRAY );
1062 glEnableClientState( GL_COLOR_ARRAY );
1064 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1066 glDisableClientState( GL_COLOR_ARRAY );
1067 glDisableClientState( GL_VERTEX_ARRAY );
1069 vglDeleteBuffersARB( 1, &aBufferObjectID );
1070 } else { // there are not extensions
1071 glColorPointer( 4, GL_FLOAT, sizeof(TVertex), aVertexArr );
1072 glVertexPointer( 3, GL_FLOAT, sizeof(TVertex),
1073 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1075 glEnableClientState( GL_VERTEX_ARRAY );
1076 glEnableClientState( GL_COLOR_ARRAY );
1078 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1080 glDisableClientState( GL_COLOR_ARRAY );
1081 glDisableClientState( GL_VERTEX_ARRAY );
1083 delete [] aVertexArr;
1087 input->GetVerts()->GetNumberOfCells() +
1088 input->GetLines()->GetNumberOfCells() +
1089 input->GetPolys()->GetNumberOfCells() +
1090 input->GetStrips()->GetNumberOfCells();
1094 this->UpdateProgress(1.0);
1097 //-----------------------------------------------------------------------------
1098 // Release the graphics resources used by this mapper. In this case, release
1099 // the display list if any.
1100 void VISU_OpenGLPointSpriteMapper::ReleaseGraphicsResources(vtkWindow *win)
1102 this->Superclass::ReleaseGraphicsResources(win);
1104 if (this->ListId && win)
1107 glDeleteLists(this->ListId,1);
1110 this->LastWindow = NULL;