1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #define GL_GLEXT_PROTOTYPES
23 #include "VTKViewer_PolyDataMapper.h"
24 #include "VTKViewer_MarkerUtils.h"
26 #include <utilities.h>
30 #include <vtkCellArray.h>
31 #include <vtkXMLImageDataReader.h>
32 #include <vtkImageData.h>
33 #include <vtkObjectFactory.h>
34 #include <vtkPointData.h>
35 #include <vtkPolyData.h>
36 #include <vtkProperty.h>
37 #include <vtkRenderer.h>
38 #include <vtkSmartPointer.h>
39 #include <vtkTimerLog.h>
40 #include <vtkWindow.h>
41 #include <vtkRenderWindow.h>
42 #include <vtkCommand.h>
43 #include <vtkCellData.h>
45 #include <Basics_Utils.hxx>
48 # ifndef GLX_GLXEXT_LEGACY
49 # define GLX_GLXEXT_LEGACY
52 #import <mach-o/dyld.h>
55 void * glXGetProcAddressARB (const GLubyte *name)
60 symbolName = (char *)malloc (strlen ((const char *)name) + 2); // 1
61 strcpy(symbolName + 1, (const char *)name); // 2
62 symbolName[0] = '_'; // 3
64 if (NSIsSymbolNameDefined (symbolName)) // 4
65 symbol = NSLookupAndBindSymbol (symbolName);
66 free (symbolName); // 5
67 return symbol ? NSAddressOfSymbol (symbol) : NULL; // 6
77 #ifndef VTK_IMPLEMENT_MESA_CXX
78 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
81 // some definitions for what the polydata has in it
82 #define VTK_PDPSM_COLORS 0x0001
83 #define VTK_PDPSM_CELL_COLORS 0x0002
84 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
85 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
86 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
87 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
88 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
90 typedef GLfloat TBall;
98 // ----------------------------------------------- Special Textures -----------------------------------
99 // texture id for balls drawing
100 #define BallTextureId 0
104 void MessageCallback( GLenum source,
109 const GLcharARB* message,
110 const void* userParam )
112 fprintf( stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
113 ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
114 type, severity, message );
118 //-----------------------------------------------------------------------------
119 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
121 Q_INIT_RESOURCE( VTKViewer );
123 this->ExtensionsInitialized = ES_None;
125 this->PointSpriteTexture = 0;
127 this->MarkerEnabled = false;
128 this->MarkerType = VTK::MT_NONE;
129 this->MarkerScale = VTK::MS_NONE;
131 this->BallEnabled = false;
132 this->BallScale = 1.0;
133 this->PointProgram = 0;
135 this->VertexShader = 0;
136 this->FragmentShader = 0;
139 this->OpenGLHelper.Init();
141 // For debug purposes only
142 // glEnable ( GL_DEBUG_OUTPUT );
143 // glDebugMessageCallback( (GLDEBUGPROC) MessageCallback, 0 );
147 //-----------------------------------------------------------------------------
148 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
150 if( PointSpriteTexture > 0 )
151 glDeleteTextures( 1, &PointSpriteTexture );
154 this->OpenGLHelper.DestroyShaderProgram( this->PointProgram, this->VertexShader, this->FragmentShader);
158 //-----------------------------------------------------------------------------
159 int VTKViewer_PolyDataMapper::InitShader()
162 #if defined(WIN32) && defined(UNICODE)
163 std::wstring wFilePath = std::wstring(_wgetenv(L"GUI_ROOT_DIR")) + L"/share/salome/resources/gui/Point";
164 std::string filePath = Kernel_Utils::utf8_encode_s(wFilePath.c_str());
166 std::string filePath = std::string( getenv( "GUI_ROOT_DIR") ) + "/share/salome/resources/gui/Point";
168 if( !this->OpenGLHelper.CreateShaderProgram(filePath, this->PointProgram, this->VertexShader, this->FragmentShader) )
171 // Get uniform locations.
172 GLint current_program;
173 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
174 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
176 this->myLocations.ModelViewProjection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uModelViewProjectionMatrix" );
177 this->myLocations.Projection = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uProjectionMatrix" );
178 this->myLocations.GeneralPointSize = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uGeneralPointSize" );
179 this->myLocations.PointSprite = this->OpenGLHelper.vglGetUniformLocationARB( this->PointProgram, "uPointSprite" );
181 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
183 this->OpenGLHelper.vglGenVertexArraysARB(1, &this->VertexArrayObject);
185 #if defined(WIN32) && defined(UNICODE)
186 std::wstring wFilePath = std::wstring(_wgetenv( L"GUI_ROOT_DIR" ) ) + L"/share/salome/resources/gui/Vertex_Program_ARB.txt";
187 std::string fileName = Kernel_Utils::utf8_encode( wFilePath.c_str() );
189 std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
190 "/share/salome/resources/gui/Vertex_Program_ARB.txt";
193 char* shader = GUI_OPENGL::readFromFile( fileName );
195 GLhandleARB VertexShader = this->OpenGLHelper.vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
196 this->OpenGLHelper.vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
197 this->OpenGLHelper.vglCompileShaderARB( VertexShader );
199 this->PointProgram = this->OpenGLHelper.vglCreateProgramObjectARB();
200 this->OpenGLHelper.vglAttachObjectARB( this->PointProgram, VertexShader );
202 this->OpenGLHelper.vglLinkProgramARB( this->PointProgram );
210 //-----------------------------------------------------------------------------
211 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
213 if( this->MarkerEnabled == theMarkerEnabled )
216 this->MarkerEnabled = theMarkerEnabled;
220 //-----------------------------------------------------------------------------
221 // Definition of structures and fuctions used in SetBallEnabled() method
224 //----------------------------------------------------------------------------
225 vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
226 if( !theMainTexture || !theAlphaTexture )
229 vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
230 vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
232 aMainReader->SetFileName( theMainTexture );
233 anAlphaReader->SetFileName( theAlphaTexture );
235 aMainReader->Update();
236 anAlphaReader->Update();
238 vtkImageData* aMainImageData = aMainReader->GetOutput();
239 vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
241 int* aMainImageSize = aMainImageData->GetDimensions();
242 int* anAlphaImageSize = anAlphaImageData->GetDimensions();
243 if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
246 vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
247 aCompositeImageData->Delete();
249 int aNbCompositeComponents = 4;
250 aCompositeImageData->SetDimensions(aMainImageSize);
251 aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
253 unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
254 unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
255 unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
257 int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
258 int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
259 int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
261 int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
262 for(; aCompositeId < aCompositeSize;) {
263 aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
264 aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
265 aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
266 aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
268 aMainId += aNbMainComponents;
269 anAlphaId += aNbAlphaComponents;
270 aCompositeId += aNbCompositeComponents;
272 aMainReader->Delete();
273 anAlphaReader->Delete();
274 return aCompositeImageData;
278 //-----------------------------------------------------------------------------
279 bool VTKViewer_PolyDataMapper::GetBallEnabled()
281 return this->BallEnabled;
283 //-----------------------------------------------------------------------------
284 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
286 if( this->BallEnabled == theBallEnabled )
289 this->BallEnabled = theBallEnabled;
291 if(!this->BallEnabled) {
292 this->ImageData = NULL;
295 if(this->BallEnabled) {
296 if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
297 QString aMainTexture = getenv( "GUI_ROOT_DIR" );
298 aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
300 QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
301 anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
302 vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toUtf8().constData(), anAlphaTexture.toUtf8().constData() );
303 this->SpecialTextures[BallTextureId] = aTextureValue;
305 this->ImageData = this->SpecialTextures[BallTextureId];
310 //-----------------------------------------------------------------------------
311 double VTKViewer_PolyDataMapper::GetBallScale()
313 return this->BallScale;
315 //-----------------------------------------------------------------------------
316 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
318 if( this->BallScale == theBallScale )
320 this->BallScale = theBallScale;
323 //-----------------------------------------------------------------------------
324 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
326 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
329 this->MarkerType = theMarkerType;
330 this->MarkerScale = theMarkerScale;
332 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
333 this->ImageData = NULL;
338 int aMarkerType = (int)this->MarkerType;
339 int aMarkerScale = (int)this->MarkerScale;
341 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
343 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
345 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
346 VTK::MarkerTexture aMarkerTexture;
347 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
348 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
351 this->ImageData = this->StandardTextures[ anId ];
355 //-----------------------------------------------------------------------------
356 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
358 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
361 this->MarkerType = VTK::MT_USER;
362 this->MarkerId = theMarkerId;
364 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
365 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
367 this->ImageData = this->CustomTextures[ theMarkerId ];
371 //-----------------------------------------------------------------------------
372 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
374 return this->MarkerType;
377 //-----------------------------------------------------------------------------
378 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
380 return this->MarkerScale;
383 //-----------------------------------------------------------------------------
384 int VTKViewer_PolyDataMapper::GetMarkerTexture()
386 return this->MarkerId;
389 //-----------------------------------------------------------------------------
390 int VTKViewer_PolyDataMapper::InitExtensions()
394 std::ostringstream strm;
395 glGetIntegerv(GL_NUM_EXTENSIONS, &n);
396 for (int i = 0; i < n; i++)
398 const char *exti = (const char *)this->OpenGLHelper.vglGetStringiARB(GL_EXTENSIONS, i);
401 std::string s = strm.str();
402 const char* ext = s.c_str();
404 const char* ext = (const char*)glGetString( GL_EXTENSIONS );
406 if( !this->OpenGLHelper.IsInitialized() || !ext ||
407 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
408 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
409 strstr( ext, "GL_ARB_shader_objects") == NULL )
411 MESSAGE("Initializing ARB extensions failed");
415 return this->InitShader();
418 //-----------------------------------------------------------------------------
419 void VTKViewer_PolyDataMapper::InitPointSprites()
421 glEnable( GL_POINT_SPRITE_ARB );
422 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
424 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
426 glDepthFunc( GL_LEQUAL );
427 glEnable( GL_DEPTH_TEST );
429 glEnable( GL_ALPHA_TEST );
430 if(!this->BallEnabled) {
431 glAlphaFunc( GL_GREATER, 0.0 );
434 glAlphaFunc( GL_GREATER, 0.5 );
437 glDisable( GL_LIGHTING );
439 glDisable( GL_COLOR_MATERIAL );
442 //-----------------------------------------------------------------------------
443 void VTKViewer_PolyDataMapper::CleanupPointSprites()
447 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
448 glDisable( GL_POINT_SPRITE_ARB );
451 //-----------------------------------------------------------------------------
452 void VTKViewer_PolyDataMapper::InitTextures()
454 if( !this->ImageData.GetPointer() )
457 glEnable( GL_TEXTURE_2D );
458 if( this->PointSpriteTexture == 0 ) {
459 glGenTextures( 1, &this->PointSpriteTexture );
462 this->OpenGLHelper.vglActiveTextureARB( GL_TEXTURE0 );
464 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
465 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
466 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
467 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
469 if(this->BallEnabled) {
470 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
471 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
473 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
474 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
477 int* aSize = this->ImageData->GetDimensions();
478 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
479 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
480 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
484 this->OpenGLHelper.vglUniform1iARB( this->myLocations.PointSprite, GL_TEXTURE0 );
488 //-----------------------------------------------------------------------------
489 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
491 bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) ||
493 if( isUsePointSprites )
495 if( this->ExtensionsInitialized != ES_Ok )
496 this->ExtensionsInitialized = this->InitExtensions();
497 this->InitPointSprites();
498 this->InitTextures();
501 if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
502 MAPPER_SUPERCLASS::RenderPiece( ren, act );
503 if( isUsePointSprites )
504 this->CleanupPointSprites();
505 glBindTexture( GL_TEXTURE_2D, 0 );
508 vtkPolyData *input= this->GetInput();
511 // make sure that we've been properly initialized
513 if (ren->GetRenderWindow()->CheckAbortStatus())
518 vtkErrorMacro(<< "No input!");
523 this->InvokeEvent(vtkCommand::StartEvent,NULL);
525 this->InvokeEvent(vtkCommand::EndEvent,NULL);
526 numPts = input->GetNumberOfPoints();
531 vtkDebugMacro(<< "No points!");
535 // make sure our window is current
536 ren->GetRenderWindow()->MakeCurrent();
538 GLint current_program;
539 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
540 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
544 // if something has changed regenerate colors and display lists
548 if ( this->GetMTime() > this->BuildTime ||
549 input->GetMTime() > this->BuildTime ||
550 act->GetProperty()->GetMTime() > this->BuildTime ||
551 ren->GetRenderWindow() != this->LastWindow)
553 // sets this->Colors as side effect
554 this->MapScalars( act->GetProperty()->GetOpacity() );
556 if (!this->ImmediateModeRendering &&
557 !this->GetGlobalImmediateModeRendering())
559 this->ReleaseGraphicsResources(ren->GetRenderWindow());
560 this->LastWindow = ren->GetRenderWindow();
562 // get a unique display list id
563 this->ListId = glGenLists(1);
564 glNewList(this->ListId,GL_COMPILE);
566 noAbort = this->Draw(ren,act);
569 // Time the actual drawing
570 this->Timer->StartTimer();
571 glCallList(this->ListId);
572 this->Timer->StopTimer();
576 this->ReleaseGraphicsResources(ren->GetRenderWindow());
577 this->LastWindow = ren->GetRenderWindow();
580 this->BuildTime.Modified();
582 // if nothing changed but we are using display lists, draw it
585 if (!this->ImmediateModeRendering &&
586 !this->GetGlobalImmediateModeRendering())
588 // Time the actual drawing
589 this->Timer->StartTimer();
590 glCallList(this->ListId);
591 this->Timer->StopTimer();
595 // if we are in immediate mode rendering we always
596 // want to draw the primitives here
597 if (this->ImmediateModeRendering ||
598 this->GetGlobalImmediateModeRendering())
600 // sets this->Colors as side effect
601 this->MapScalars( act->GetProperty()->GetOpacity() );
603 // Time the actual drawing
604 this->Timer->StartTimer();
606 this->Timer->StopTimer();
609 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
611 // If the timer is not accurate enough, set it to a small
612 // time so that it is not zero
613 if ( this->TimeToDraw == 0.0 )
614 this->TimeToDraw = 0.0001;
616 //this->RenderPieceStart(ren, act);
617 this->RenderPieceDraw(ren, act);
618 // this->RenderEdges(ren,act);
619 //this->RenderPieceFinish(ren, act);
621 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
622 this->CleanupPointSprites();
623 glBindTexture( GL_TEXTURE_2D, 0 );
627 //-----------------------------------------------------------------------------
628 // Definition of structures and fuctions used in Draw() method
631 //-----------------------------------------------------------------------------
638 //-----------------------------------------------------------------------------
639 struct TColorFunctorBase
643 TColorFunctorBase( vtkProperty* theProperty )
645 myAlpha = theProperty->GetOpacity();
650 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
652 virtual ~TColorFunctorBase() {}
655 //-----------------------------------------------------------------------------
656 struct TPropertyColor : TColorFunctorBase
660 TPropertyColor( vtkProperty* theProperty ):
661 TColorFunctorBase( theProperty )
663 theProperty->GetColor( myColor );
668 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
670 theVertex.r = myColor[0];
671 theVertex.g = myColor[1];
672 theVertex.b = myColor[2];
673 theVertex.a = myAlpha;
677 //-----------------------------------------------------------------------------
678 struct TColors2Color : TColorFunctorBase
680 vtkUnsignedCharArray* myColors;
682 TColors2Color( vtkProperty* theProperty,
683 vtkUnsignedCharArray* theColors ):
684 TColorFunctorBase( theProperty ),
685 myColors( theColors )
690 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
692 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
693 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
695 theVertex.r = int( aColor[0] ) / 255.0;
696 theVertex.g = int( aColor[1] ) / 255.0;
697 theVertex.b = int( aColor[2] ) / 255.0;
698 theVertex.a = myAlpha;
703 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
706 //-----------------------------------------------------------------------------
707 struct TPointColors2Color : TColors2Color
709 TPointColors2Color( vtkProperty* theProperty,
710 vtkUnsignedCharArray* theColors ):
711 TColors2Color( theProperty, theColors )
716 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
722 //-----------------------------------------------------------------------------
723 struct TCellColors2Color : TColors2Color
725 TCellColors2Color( vtkProperty* theProperty,
726 vtkUnsignedCharArray* theColors ):
727 TColors2Color( theProperty, theColors )
732 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
738 //-----------------------------------------------------------------------------
739 template < class TCoordinates >
740 void DrawPoints( TCoordinates* theStartPoints,
741 vtkCellArray* theCells,
742 TColorFunctorBase* theColorFunctor,
743 TVertex* theVertexArr,
744 vtkIdType &theCellId,
745 vtkIdType &theVertexId,
747 vtkDataArray* theDiamArray,
748 double theBallScale )
750 vtkIdType* ptIds = theCells->GetPointer();
751 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
753 bool mapBalls = false;
754 if(theBallArr && theDiamArray) {
758 while ( ptIds < endPtIds ) {
759 vtkIdType nPts = *ptIds;
763 TVertex& aVertex = theVertexArr[ theVertexId ];
764 vtkIdType aPointId = *ptIds;
766 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
767 aVertex.vx = anOffsetPoints[0];
768 aVertex.vy = anOffsetPoints[1];
769 aVertex.vz = anOffsetPoints[2];
771 theColorFunctor->get( aVertex, aPointId, theCellId );
779 theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
786 //-----------------------------------------------------------------------------
787 template < class TCoordinates >
788 void DrawCellsPoints( vtkPolyData* theInput,
789 vtkPoints* thePoints,
790 TColorFunctorBase* theColorFunctor,
791 TVertex* theVertexArr,
793 double theBallScale )
795 vtkIdType aCellId = 0, aVertexId = 0;
797 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
798 vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;
800 if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
801 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
804 if ( vtkCellArray* aCellArray = theInput->GetLines() )
805 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
807 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
808 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
810 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
811 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
816 //-----------------------------------------------------------------------------
817 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
820 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
821 return MAPPER_SUPERCLASS::Draw( ren, act );
823 InternalDraw( ren, act );
828 //-----------------------------------------------------------------------------
829 void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
831 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
832 MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
835 InternalDraw( ren, act );
840 #include <vtkCamera.h>
841 #include <vtkOpenGLCamera.h>
842 #include <vtkOpenGLActor.h>
845 void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
846 vtkUnsignedCharArray* colors = NULL;
847 vtkPolyData* input = this->GetInput();
850 vtkProperty* prop = act->GetProperty();
852 points = input->GetPoints();
856 if(!this->BallEnabled) {
857 colors = this->Colors;
858 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
859 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
860 !input->GetPointData()->GetScalars() )
861 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
867 vtkIdType aTotalConnectivitySize = 0;
868 vtkIdType aNbCells = 0;
870 if ( vtkCellArray* aCellArray = input->GetVerts() ) {
871 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
872 aNbCells += aCellArray->GetNumberOfCells();
875 if ( vtkCellArray* aCellArray = input->GetLines() ) {
876 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
877 aNbCells += aCellArray->GetNumberOfCells();
880 if ( vtkCellArray* aCellArray = input->GetPolys() ) {
881 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
882 aNbCells += aCellArray->GetNumberOfCells();
885 if ( vtkCellArray* aCellArray = input->GetStrips() ) {
886 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
887 aNbCells += aCellArray->GetNumberOfCells();
890 if ( aTotalConnectivitySize > 0 ) {
891 VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
893 TBall* aBallArray = 0;
895 if(this->BallEnabled) {
896 aBallArray = new TBall[aNbCells];
899 int* aSize = this->ImageData->GetDimensions();
901 int aMode = 0; // to remove
903 VTK::TColorFunctorBase* aColorFunctor = NULL;
904 if( colors && aMode != 1 ) {
906 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
908 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
910 aColorFunctor = new VTK::TPropertyColor( prop );
912 if ( points->GetDataType() == VTK_FLOAT )
913 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
915 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
917 delete aColorFunctor;
920 if( this->ExtensionsInitialized == ES_Ok ) {
922 GLint current_program;
923 glGetIntegerv( GL_CURRENT_PROGRAM, ¤t_program );
924 this->OpenGLHelper.vglUseProgramObjectARB( this->PointProgram );
926 vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
931 cam->GetKeyMatrices(ren,wcvc,norms,vcdc,wcdc);
932 if (!act->GetIsIdentity())
935 vtkMatrix3x3 *anorms;
936 ((vtkOpenGLActor *)act)->GetKeyMatrices( mcwc, anorms );
937 vtkMatrix4x4::Multiply4x4( mcwc, wcdc, this->TempMatrix4 );
939 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, this->TempMatrix4 );
943 this->OpenGLHelper.SetUniformMatrix( this->myLocations.ModelViewProjection, wcdc );
945 this->OpenGLHelper.SetUniformMatrix( this->myLocations.Projection, vcdc );
947 this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, std::max( aSize[0], aSize[1] ) );
949 GLuint aBufferObjectID, aDiamsID = 0;
951 this->OpenGLHelper.vglBindVertexArrayARB( this->VertexArrayObject );
952 this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
953 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
955 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
956 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
958 delete [] aVertexArr;
961 GLint colorAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Color" );
962 GLint vertexAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Vertex" );
963 GLint diamAttrib = this->OpenGLHelper.vglGetAttribLocationARB( this->PointProgram, "Diameter" );
965 GLsizei vertexSize = sizeof(VTK::TVertex);
967 this->OpenGLHelper.vglVertexAttribPointerARB( colorAttrib, 4, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)0 );
968 this->OpenGLHelper.vglEnableVertexAttribArrayARB( colorAttrib );
970 this->OpenGLHelper.vglVertexAttribPointerARB( vertexAttrib, 3, GL_FLOAT, GL_FALSE, vertexSize, (const GLvoid*)(sizeof(GLfloat) * 4) );
971 this->OpenGLHelper.vglEnableVertexAttribArrayARB( vertexAttrib );
973 if(this->BallEnabled) {
974 // Don't use uniform variable.
975 this->OpenGLHelper.vglUniform1iARB( this->myLocations.GeneralPointSize, -1 );
976 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
977 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
979 int aDiamsSize = sizeof(TBall)*aNbCells;
980 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
982 delete [] aBallArray;
984 this->OpenGLHelper.vglVertexAttribPointerARB( diamAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0 );
985 this->OpenGLHelper.vglEnableVertexAttribArrayARB( diamAttrib );
988 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
990 if( this->BallEnabled ) {
991 this->OpenGLHelper.vglDisableVertexAttribArrayARB( diamAttrib );
992 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
993 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
996 this->OpenGLHelper.vglDisableVertexAttribArrayARB( colorAttrib );
997 this->OpenGLHelper.vglDisableVertexAttribArrayARB( vertexAttrib );
998 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
999 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
1000 this->OpenGLHelper.vglBindVertexArrayARB( 0 );
1002 this->OpenGLHelper.vglUseProgramObjectARB( current_program );
1004 GLuint aBufferObjectID, aDiamsID = 0;
1005 GLint attribute_diams = -1;
1006 glPointSize( std::max( aSize[0], aSize[1] ) );
1007 this->OpenGLHelper.vglGenBuffersARB( 1, &aBufferObjectID );
1008 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1010 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
1011 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
1013 delete [] aVertexArr;
1015 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1016 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1018 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
1019 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
1021 glEnableClientState( GL_VERTEX_ARRAY );
1022 glEnableClientState( GL_COLOR_ARRAY );
1024 if(this->BallEnabled) {
1025 this->OpenGLHelper.vglGenBuffersARB( 1, &aDiamsID);
1026 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
1028 int aDiamsSize = sizeof(TBall)*aNbCells;
1029 this->OpenGLHelper.vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
1031 delete [] aBallArray;
1032 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1033 this->OpenGLHelper.vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
1035 attribute_diams = this->OpenGLHelper.vglGetAttribLocationARB(this->PointProgram, "diameter");
1036 this->OpenGLHelper.vglEnableVertexAttribArrayARB(attribute_diams);
1037 this->OpenGLHelper.vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
1038 this->OpenGLHelper.vglVertexAttribPointerARB(
1039 attribute_diams, // attribute
1040 1, // number of elements per vertex, here (diameter)
1041 GL_FLOAT, // the type of each element
1042 GL_FALSE, // take our values as-is
1043 0, // no extra data between each position
1044 0 // offset of first element
1048 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1050 glDisableClientState( GL_COLOR_ARRAY );
1051 glDisableClientState( GL_VERTEX_ARRAY );
1052 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aBufferObjectID );
1054 if(this->BallEnabled) {
1055 this->OpenGLHelper.vglDisableVertexAttribArrayARB(attribute_diams);
1056 this->OpenGLHelper.vglDeleteBuffersARB( 1, &aDiamsID );
1060 } else { // there are no extensions
1061 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1062 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
1063 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1065 glEnableClientState( GL_VERTEX_ARRAY );
1066 glEnableClientState( GL_COLOR_ARRAY );
1068 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1070 glDisableClientState( GL_COLOR_ARRAY );
1071 glDisableClientState( GL_VERTEX_ARRAY );
1073 delete [] aVertexArr;
1078 this->UpdateProgress(1.0);