1 // Copyright (C) 2007-2015 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 #include "VTKViewer_PolyDataMapper.h"
21 #include "VTKViewer_MarkerUtils.h"
23 #include <utilities.h>
27 #include <vtkCellArray.h>
28 #include <vtkXMLImageDataReader.h>
29 #include <vtkImageData.h>
30 #include <vtkObjectFactory.h>
31 #include <vtkPointData.h>
32 #include <vtkPolyData.h>
33 #include <vtkProperty.h>
34 #include <vtkRenderer.h>
35 #include <vtkSmartPointer.h>
36 #include <vtkTimerLog.h>
37 #include <vtkWindow.h>
38 #include <vtkRenderWindow.h>
39 #include <vtkCommand.h>
40 #include <vtkCellData.h>
43 # ifndef GLX_GLXEXT_LEGACY
44 # define GLX_GLXEXT_LEGACY
52 #ifndef VTK_IMPLEMENT_MESA_CXX
53 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
56 // some definitions for what the polydata has in it
57 #define VTK_PDPSM_COLORS 0x0001
58 #define VTK_PDPSM_CELL_COLORS 0x0002
59 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
60 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
61 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
62 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
63 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
69 #define APIENTRYP APIENTRY *
72 #ifndef GL_ARB_shader_objects
73 typedef char GLcharARB;
76 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
77 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
80 #ifndef GL_VERTEX_SHADER_ARB
81 #define GL_VERTEX_SHADER_ARB 0x8B31
84 #ifndef GL_ARB_point_sprite
85 #define GL_POINT_SPRITE_ARB 0x8861
86 #define GL_COORD_REPLACE_ARB 0x8862
89 #ifndef GL_ARB_vertex_buffer_object
90 typedef ptrdiff_t GLsizeiptrARB;
92 #define GL_ARRAY_BUFFER_ARB 0x8892
93 #define GL_STATIC_DRAW_ARB 0x88E4
95 typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
96 typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
97 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
98 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
99 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
100 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
101 typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
102 typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
103 typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
104 typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
105 typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
106 typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
107 typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
108 typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
109 typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
111 typedef GLfloat TBall;
114 static PFNGLSHADERSOURCEARBPROC vglShaderSourceARB = NULL;
115 static PFNGLCREATESHADEROBJECTARBPROC vglCreateShaderObjectARB = NULL;
116 static PFNGLCOMPILESHADERARBPROC vglCompileShaderARB = NULL;
117 static PFNGLCREATEPROGRAMOBJECTARBPROC vglCreateProgramObjectARB = NULL;
118 static PFNGLATTACHOBJECTARBPROC vglAttachObjectARB = NULL;
119 static PFNGLLINKPROGRAMARBPROC vglLinkProgramARB = NULL;
120 static PFNGLUSEPROGRAMOBJECTARBPROC vglUseProgramObjectARB = NULL;
122 static PFNGLGENBUFFERSARBPROC vglGenBuffersARB = NULL;
123 static PFNGLBINDBUFFERARBPROC vglBindBufferARB = NULL;
124 static PFNGLBUFFERDATAARBPROC vglBufferDataARB = NULL;
125 static PFNGLDELETEBUFFERSARBPROC vglDeleteBuffersARB = NULL;
126 static PFNGLGETATTRIBLOCATIONARBPROC vglGetAttribLocationARB = NULL;
127 static PFNGLVERTEXATTRIBPOINTERARBPROC vglVertexAttribPointerARB = NULL;
128 static PFNGLENABLEVERTEXATTRIBARRAYARBPROC vglEnableVertexAttribArrayARB = NULL;
129 static PFNGLDISABLEVERTEXATTRIBARRAYARBPROC vglDisableVertexAttribArrayARB = NULL;
133 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
135 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
144 // ----------------------------------------------- Special Textures -----------------------------------
145 // texture id for balls drawing
146 #define BallTextureId 0
148 bool InitializeBufferExtensions()
150 vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
151 if( !vglShaderSourceARB )
154 vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
155 if( !vglCreateShaderObjectARB )
158 vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
159 if( !vglCompileShaderARB )
162 vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
163 if( !vglCreateProgramObjectARB )
166 vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
167 if( !vglAttachObjectARB )
170 vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
171 if( !vglLinkProgramARB )
174 vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
175 if( !vglUseProgramObjectARB )
178 vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
179 if( !vglGenBuffersARB )
182 vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
183 if( !vglBindBufferARB )
186 vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
187 if( !vglBufferDataARB )
190 vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
191 if( !vglDeleteBuffersARB )
194 vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocation" );
195 if( !vglGetAttribLocationARB )
198 vglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GL_GetProcAddress( "glVertexAttribPointer" );
199 if( !vglVertexAttribPointerARB )
202 vglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glEnableVertexAttribArray" );
203 if(!vglEnableVertexAttribArrayARB)
206 vglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glDisableVertexAttribArray" );
208 if(!vglDisableVertexAttribArrayARB)
215 //-----------------------------------------------------------------------------
216 char* readFromFile( std::string fileName )
218 FILE* file = fopen( fileName.c_str(), "r" );
220 char* content = NULL;
225 fseek( file, 0, SEEK_END );
226 count = ftell( file );
231 content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
232 count = fread( content, sizeof( char ), count, file );
233 content[ count ] = '\0';
241 static bool IsBufferExtensionsInitialized = InitializeBufferExtensions();
243 //-----------------------------------------------------------------------------
244 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
246 Q_INIT_RESOURCE( VTKViewer );
248 this->ExtensionsInitialized = ES_None;
250 this->PointSpriteTexture = 0;
252 this->MarkerEnabled = false;
253 this->MarkerType = VTK::MT_NONE;
254 this->MarkerScale = VTK::MS_NONE;
256 this->BallEnabled = false;
257 this->BallScale = 1.0;
258 this->VertexProgram = 0;
261 //-----------------------------------------------------------------------------
262 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
264 if( PointSpriteTexture > 0 )
265 glDeleteTextures( 1, &PointSpriteTexture );
268 //-----------------------------------------------------------------------------
269 void VTKViewer_PolyDataMapper::InitShader()
271 std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
272 "/share/salome/resources/gui/Vertex_Program_ARB.txt";
274 char* shader = readFromFile( fileName );
276 GLhandleARB VertexShader = vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
277 vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
278 vglCompileShaderARB( VertexShader );
280 this->VertexProgram = vglCreateProgramObjectARB();
281 vglAttachObjectARB( this->VertexProgram, VertexShader );
283 vglLinkProgramARB( this->VertexProgram );
288 //-----------------------------------------------------------------------------
289 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
291 if( this->MarkerEnabled == theMarkerEnabled )
294 this->MarkerEnabled = theMarkerEnabled;
298 //-----------------------------------------------------------------------------
299 // Definition of structures and fuctions used in SetBallEnabled() method
302 //----------------------------------------------------------------------------
303 vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
304 if( !theMainTexture || !theAlphaTexture )
307 vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
308 vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
310 aMainReader->SetFileName( theMainTexture );
311 anAlphaReader->SetFileName( theAlphaTexture );
313 aMainReader->Update();
314 anAlphaReader->Update();
316 vtkImageData* aMainImageData = aMainReader->GetOutput();
317 vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
319 int* aMainImageSize = aMainImageData->GetDimensions();
320 int* anAlphaImageSize = anAlphaImageData->GetDimensions();
321 if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
324 vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
325 aCompositeImageData->Delete();
327 int aNbCompositeComponents = 4;
328 aCompositeImageData->SetDimensions(aMainImageSize);
329 aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
331 unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
332 unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
333 unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
335 int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
336 int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
337 int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
339 int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
340 for(; aCompositeId < aCompositeSize;) {
341 aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
342 aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
343 aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
344 aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
346 aMainId += aNbMainComponents;
347 anAlphaId += aNbAlphaComponents;
348 aCompositeId += aNbCompositeComponents;
350 aMainReader->Delete();
351 anAlphaReader->Delete();
352 return aCompositeImageData;
356 //-----------------------------------------------------------------------------
357 bool VTKViewer_PolyDataMapper::GetBallEnabled()
359 return this->BallEnabled;
361 //-----------------------------------------------------------------------------
362 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
364 if( this->BallEnabled == theBallEnabled )
367 this->BallEnabled = theBallEnabled;
369 if(!this->BallEnabled) {
370 this->ImageData = NULL;
373 if(this->BallEnabled) {
374 if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
375 QString aMainTexture = getenv( "GUI_ROOT_DIR" );
376 aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
378 QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
379 anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
380 vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toLatin1().constData(), anAlphaTexture.toLatin1().constData() );
381 this->SpecialTextures[BallTextureId] = aTextureValue;
383 this->ImageData = this->SpecialTextures[BallTextureId];
388 //-----------------------------------------------------------------------------
389 double VTKViewer_PolyDataMapper::GetBallScale()
391 return this->BallScale;
393 //-----------------------------------------------------------------------------
394 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
396 if( this->BallScale == theBallScale )
398 this->BallScale = theBallScale;
401 //-----------------------------------------------------------------------------
402 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
404 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
407 this->MarkerType = theMarkerType;
408 this->MarkerScale = theMarkerScale;
410 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
411 this->ImageData = NULL;
416 int aMarkerType = (int)this->MarkerType;
417 int aMarkerScale = (int)this->MarkerScale;
419 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
421 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
423 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
424 VTK::MarkerTexture aMarkerTexture;
425 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
426 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
429 this->ImageData = this->StandardTextures[ anId ];
433 //-----------------------------------------------------------------------------
434 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
436 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
439 this->MarkerType = VTK::MT_USER;
440 this->MarkerId = theMarkerId;
442 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
443 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
445 this->ImageData = this->CustomTextures[ theMarkerId ];
449 //-----------------------------------------------------------------------------
450 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
452 return this->MarkerType;
455 //-----------------------------------------------------------------------------
456 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
458 return this->MarkerScale;
461 //-----------------------------------------------------------------------------
462 int VTKViewer_PolyDataMapper::GetMarkerTexture()
464 return this->MarkerId;
467 //-----------------------------------------------------------------------------
468 int VTKViewer_PolyDataMapper::InitExtensions()
470 char* ext = (char*)glGetString( GL_EXTENSIONS );
471 if( !IsBufferExtensionsInitialized ||
472 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
473 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
474 strstr( ext, "GL_ARB_shader_objects") == NULL )
476 MESSAGE("Initializing ARB extensions failed");
480 if( this->BallEnabled )
486 //-----------------------------------------------------------------------------
487 void VTKViewer_PolyDataMapper::InitPointSprites()
489 glEnable( GL_POINT_SPRITE_ARB );
490 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
492 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
494 glDepthFunc( GL_LEQUAL );
495 glEnable( GL_DEPTH_TEST );
497 glEnable( GL_ALPHA_TEST );
498 if(!this->BallEnabled) {
499 glAlphaFunc( GL_GREATER, 0.0 );
502 glAlphaFunc( GL_GREATER, 0.5 );
505 glDisable( GL_LIGHTING );
507 glDisable( GL_COLOR_MATERIAL );
510 //-----------------------------------------------------------------------------
511 void VTKViewer_PolyDataMapper::CleanupPointSprites()
515 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
516 glDisable( GL_POINT_SPRITE_ARB );
519 //-----------------------------------------------------------------------------
520 void VTKViewer_PolyDataMapper::InitTextures()
522 if( !this->ImageData.GetPointer() )
525 glEnable( GL_TEXTURE_2D );
526 if( this->PointSpriteTexture == 0 ) {
527 glGenTextures( 1, &this->PointSpriteTexture );
529 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
530 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
531 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
532 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
534 if(this->BallEnabled) {
535 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
536 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
538 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
539 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
542 int* aSize = this->ImageData->GetDimensions();
543 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
544 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
545 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
548 //-----------------------------------------------------------------------------
549 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
551 bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) ||
553 if( isUsePointSprites )
555 if( this->ExtensionsInitialized == ES_None )
556 this->ExtensionsInitialized = this->InitExtensions();
557 this->InitPointSprites();
558 this->InitTextures();
561 if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
562 MAPPER_SUPERCLASS::RenderPiece( ren, act );
563 if( isUsePointSprites )
564 this->CleanupPointSprites();
565 glBindTexture( GL_TEXTURE_2D, 0 );
568 vtkPolyData *input= this->GetInput();
571 // make sure that we've been properly initialized
573 if (ren->GetRenderWindow()->CheckAbortStatus())
578 vtkErrorMacro(<< "No input!");
583 this->InvokeEvent(vtkCommand::StartEvent,NULL);
585 this->InvokeEvent(vtkCommand::EndEvent,NULL);
586 numPts = input->GetNumberOfPoints();
591 vtkDebugMacro(<< "No points!");
595 // make sure our window is current
596 ren->GetRenderWindow()->MakeCurrent();
599 vglUseProgramObjectARB( this->VertexProgram );
602 // if something has changed regenerate colors and display lists
606 if ( this->GetMTime() > this->BuildTime ||
607 input->GetMTime() > this->BuildTime ||
608 act->GetProperty()->GetMTime() > this->BuildTime ||
609 ren->GetRenderWindow() != this->LastWindow)
611 // sets this->Colors as side effect
612 this->MapScalars( act->GetProperty()->GetOpacity() );
614 if (!this->ImmediateModeRendering &&
615 !this->GetGlobalImmediateModeRendering())
617 this->ReleaseGraphicsResources(ren->GetRenderWindow());
618 this->LastWindow = ren->GetRenderWindow();
620 // get a unique display list id
621 this->ListId = glGenLists(1);
622 glNewList(this->ListId,GL_COMPILE);
624 noAbort = this->Draw(ren,act);
627 // Time the actual drawing
628 this->Timer->StartTimer();
629 glCallList(this->ListId);
630 this->Timer->StopTimer();
634 this->ReleaseGraphicsResources(ren->GetRenderWindow());
635 this->LastWindow = ren->GetRenderWindow();
638 this->BuildTime.Modified();
640 // if nothing changed but we are using display lists, draw it
643 if (!this->ImmediateModeRendering &&
644 !this->GetGlobalImmediateModeRendering())
646 // Time the actual drawing
647 this->Timer->StartTimer();
648 glCallList(this->ListId);
649 this->Timer->StopTimer();
653 // if we are in immediate mode rendering we always
654 // want to draw the primitives here
655 if (this->ImmediateModeRendering ||
656 this->GetGlobalImmediateModeRendering())
658 // sets this->Colors as side effect
659 this->MapScalars( act->GetProperty()->GetOpacity() );
661 // Time the actual drawing
662 this->Timer->StartTimer();
664 this->Timer->StopTimer();
667 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
669 // If the timer is not accurate enough, set it to a small
670 // time so that it is not zero
671 if ( this->TimeToDraw == 0.0 )
672 this->TimeToDraw = 0.0001;
674 vglUseProgramObjectARB( 0 );
675 this->CleanupPointSprites();
676 glBindTexture( GL_TEXTURE_2D, 0 );
680 //-----------------------------------------------------------------------------
681 // Definition of structures and fuctions used in Draw() method
684 //-----------------------------------------------------------------------------
691 //-----------------------------------------------------------------------------
692 struct TColorFunctorBase
696 TColorFunctorBase( vtkProperty* theProperty )
698 myAlpha = theProperty->GetOpacity();
703 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
706 //-----------------------------------------------------------------------------
707 struct TPropertyColor : TColorFunctorBase
711 TPropertyColor( vtkProperty* theProperty ):
712 TColorFunctorBase( theProperty )
714 theProperty->GetColor( myColor );
719 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
721 theVertex.r = myColor[0];
722 theVertex.g = myColor[1];
723 theVertex.b = myColor[2];
724 theVertex.a = myAlpha;
728 //-----------------------------------------------------------------------------
729 struct TColors2Color : TColorFunctorBase
731 vtkUnsignedCharArray* myColors;
733 TColors2Color( vtkProperty* theProperty,
734 vtkUnsignedCharArray* theColors ):
735 TColorFunctorBase( theProperty ),
736 myColors( theColors )
741 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
743 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
744 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
746 theVertex.r = int( aColor[0] ) / 255.0;
747 theVertex.g = int( aColor[1] ) / 255.0;
748 theVertex.b = int( aColor[2] ) / 255.0;
749 theVertex.a = myAlpha;
754 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
757 //-----------------------------------------------------------------------------
758 struct TPointColors2Color : TColors2Color
760 TPointColors2Color( vtkProperty* theProperty,
761 vtkUnsignedCharArray* theColors ):
762 TColors2Color( theProperty, theColors )
767 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
773 //-----------------------------------------------------------------------------
774 struct TCellColors2Color : TColors2Color
776 TCellColors2Color( vtkProperty* theProperty,
777 vtkUnsignedCharArray* theColors ):
778 TColors2Color( theProperty, theColors )
783 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
789 //-----------------------------------------------------------------------------
790 template < class TCoordinates >
791 void DrawPoints( TCoordinates* theStartPoints,
792 vtkCellArray* theCells,
793 TColorFunctorBase* theColorFunctor,
794 TVertex* theVertexArr,
795 vtkIdType &theCellId,
796 vtkIdType &theVertexId,
798 vtkDataArray* theDiamArray,
799 double theBallScale )
801 vtkIdType* ptIds = theCells->GetPointer();
802 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
804 bool mapBalls = false;
805 if(theBallArr && theDiamArray) {
809 while ( ptIds < endPtIds ) {
810 vtkIdType nPts = *ptIds;
814 TVertex& aVertex = theVertexArr[ theVertexId ];
815 vtkIdType aPointId = *ptIds;
817 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
818 aVertex.vx = anOffsetPoints[0];
819 aVertex.vy = anOffsetPoints[1];
820 aVertex.vz = anOffsetPoints[2];
822 theColorFunctor->get( aVertex, aPointId, theCellId );
830 theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
837 //-----------------------------------------------------------------------------
838 template < class TCoordinates >
839 void DrawCellsPoints( vtkPolyData* theInput,
840 vtkPoints* thePoints,
841 TColorFunctorBase* theColorFunctor,
842 TVertex* theVertexArr,
844 double theBallScale )
846 vtkIdType aCellId = 0, aVertexId = 0;
848 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
849 vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;
851 if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
852 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
855 if ( vtkCellArray* aCellArray = theInput->GetLines() )
856 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
858 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
859 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
861 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
862 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
866 //-----------------------------------------------------------------------------
867 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
869 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
870 return MAPPER_SUPERCLASS::Draw( ren, act );
872 vtkUnsignedCharArray* colors = NULL;
873 vtkPolyData* input = this->GetInput();
877 vtkProperty* prop = act->GetProperty();
879 points = input->GetPoints();
883 if(!this->BallEnabled) {
884 colors = this->Colors;
885 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
886 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
887 !input->GetPointData()->GetScalars() )
888 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
894 vtkIdType aTotalConnectivitySize = 0;
895 vtkIdType aNbCells = 0;
897 if ( vtkCellArray* aCellArray = input->GetVerts() ) {
898 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
899 aNbCells += aCellArray->GetNumberOfCells();
902 if ( vtkCellArray* aCellArray = input->GetLines() ) {
903 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
904 aNbCells += aCellArray->GetNumberOfCells();
907 if ( vtkCellArray* aCellArray = input->GetPolys() ) {
908 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
909 aNbCells += aCellArray->GetNumberOfCells();
912 if ( vtkCellArray* aCellArray = input->GetStrips() ) {
913 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
914 aNbCells += aCellArray->GetNumberOfCells();
917 if ( aTotalConnectivitySize > 0 ) {
918 VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
920 TBall* aBallArray = 0;
922 if(this->BallEnabled) {
923 aBallArray = new TBall[aNbCells];
926 int* aSize = this->ImageData->GetDimensions();
927 glPointSize( std::max( aSize[0], aSize[1] ) );
929 int aMode = 0; // to remove
931 VTK::TColorFunctorBase* aColorFunctor = NULL;
932 if( colors && aMode != 1 ) {
934 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
936 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
938 aColorFunctor = new VTK::TPropertyColor( prop );
940 if ( points->GetDataType() == VTK_FLOAT )
941 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
943 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
945 delete aColorFunctor;
948 if( this->ExtensionsInitialized == ES_Ok ) {
949 GLuint aBufferObjectID, aDiamsID = 0;
950 GLint attribute_diams = -1;
951 vglGenBuffersARB( 1, &aBufferObjectID );
952 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
954 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
955 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
957 delete [] aVertexArr;
959 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
960 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
962 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
963 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
965 glEnableClientState( GL_VERTEX_ARRAY );
966 glEnableClientState( GL_COLOR_ARRAY );
968 if(this->BallEnabled) {
969 vglGenBuffersARB( 2, &aDiamsID);
970 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
972 int aDiamsSize = sizeof(TBall)*aNbCells;
973 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
975 delete [] aBallArray;
976 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
977 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
979 attribute_diams = vglGetAttribLocationARB(this->VertexProgram, "diameter");
980 vglEnableVertexAttribArrayARB(attribute_diams);
981 vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
982 vglVertexAttribPointerARB(
983 attribute_diams, // attribute
984 1, // number of elements per vertex, here (diameter)
985 GL_FLOAT, // the type of each element
986 GL_FALSE, // take our values as-is
987 0, // no extra data between each position
988 0 // offset of first element
992 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
994 glDisableClientState( GL_COLOR_ARRAY );
995 glDisableClientState( GL_VERTEX_ARRAY );
996 vglDeleteBuffersARB( 1, &aBufferObjectID );
998 if(this->BallEnabled) {
999 vglDisableVertexAttribArrayARB(attribute_diams);
1000 vglDeleteBuffersARB( 2, &aDiamsID );
1003 } else { // there are no extensions
1004 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1005 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
1006 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1008 glEnableClientState( GL_VERTEX_ARRAY );
1009 glEnableClientState( GL_COLOR_ARRAY );
1011 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1013 glDisableClientState( GL_COLOR_ARRAY );
1014 glDisableClientState( GL_VERTEX_ARRAY );
1016 delete [] aVertexArr;
1021 this->UpdateProgress(1.0);