1 // Copyright (C) 2007-2016 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>
46 # ifndef GLX_GLXEXT_LEGACY
47 # define GLX_GLXEXT_LEGACY
55 #ifndef VTK_IMPLEMENT_MESA_CXX
56 vtkStandardNewMacro(VTKViewer_PolyDataMapper);
59 // some definitions for what the polydata has in it
60 #define VTK_PDPSM_COLORS 0x0001
61 #define VTK_PDPSM_CELL_COLORS 0x0002
62 #define VTK_PDPSM_POINT_TYPE_FLOAT 0x0004
63 #define VTK_PDPSM_POINT_TYPE_DOUBLE 0x0008
64 #define VTK_PDPSM_NORMAL_TYPE_FLOAT 0x0010
65 #define VTK_PDPSM_NORMAL_TYPE_DOUBLE 0x0020
66 #define VTK_PDPSM_OPAQUE_COLORS 0x0040
72 #define APIENTRYP APIENTRY *
75 #ifndef GL_ARB_shader_objects
76 typedef char GLcharARB;
79 #ifndef GL_VERTEX_PROGRAM_POINT_SIZE_ARB
80 #define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
83 #ifndef GL_VERTEX_SHADER_ARB
84 #define GL_VERTEX_SHADER_ARB 0x8B31
87 #ifndef GL_ARB_point_sprite
88 #define GL_POINT_SPRITE_ARB 0x8861
89 #define GL_COORD_REPLACE_ARB 0x8862
92 #ifndef GL_ARB_vertex_buffer_object
93 typedef ptrdiff_t GLsizeiptrARB;
95 #define GL_ARRAY_BUFFER_ARB 0x8892
96 #define GL_STATIC_DRAW_ARB 0x88E4
98 typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
99 typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
100 typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
101 typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
102 typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
103 typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
104 typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
105 typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
106 typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
107 typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
108 typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
109 typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
110 typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
111 typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
112 typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
114 typedef GLfloat TBall;
117 static PFNGLSHADERSOURCEARBPROC vglShaderSourceARB = NULL;
118 static PFNGLCREATESHADEROBJECTARBPROC vglCreateShaderObjectARB = NULL;
119 static PFNGLCOMPILESHADERARBPROC vglCompileShaderARB = NULL;
120 static PFNGLCREATEPROGRAMOBJECTARBPROC vglCreateProgramObjectARB = NULL;
121 static PFNGLATTACHOBJECTARBPROC vglAttachObjectARB = NULL;
122 static PFNGLLINKPROGRAMARBPROC vglLinkProgramARB = NULL;
123 static PFNGLUSEPROGRAMOBJECTARBPROC vglUseProgramObjectARB = NULL;
125 static PFNGLGENBUFFERSARBPROC vglGenBuffersARB = NULL;
126 static PFNGLBINDBUFFERARBPROC vglBindBufferARB = NULL;
127 static PFNGLBUFFERDATAARBPROC vglBufferDataARB = NULL;
128 static PFNGLDELETEBUFFERSARBPROC vglDeleteBuffersARB = NULL;
129 static PFNGLGETATTRIBLOCATIONARBPROC vglGetAttribLocationARB = NULL;
130 static PFNGLVERTEXATTRIBPOINTERARBPROC vglVertexAttribPointerARB = NULL;
131 static PFNGLENABLEVERTEXATTRIBARRAYARBPROC vglEnableVertexAttribArrayARB = NULL;
132 static PFNGLDISABLEVERTEXATTRIBARRAYARBPROC vglDisableVertexAttribArrayARB = NULL;
136 #define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
138 #define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
147 // ----------------------------------------------- Special Textures -----------------------------------
148 // texture id for balls drawing
149 #define BallTextureId 0
151 bool InitializeBufferExtensions()
153 vglShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)GL_GetProcAddress( "glShaderSourceARB" );
154 if( !vglShaderSourceARB )
157 vglCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)GL_GetProcAddress( "glCreateShaderObjectARB" );
158 if( !vglCreateShaderObjectARB )
161 vglCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)GL_GetProcAddress( "glCompileShaderARB" );
162 if( !vglCompileShaderARB )
165 vglCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glCreateProgramObjectARB" );
166 if( !vglCreateProgramObjectARB )
169 vglAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)GL_GetProcAddress( "glAttachObjectARB" );
170 if( !vglAttachObjectARB )
173 vglLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)GL_GetProcAddress( "glLinkProgramARB" );
174 if( !vglLinkProgramARB )
177 vglUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)GL_GetProcAddress( "glUseProgramObjectARB" );
178 if( !vglUseProgramObjectARB )
181 vglGenBuffersARB = (PFNGLGENBUFFERSARBPROC)GL_GetProcAddress( "glGenBuffersARB" );
182 if( !vglGenBuffersARB )
185 vglBindBufferARB = (PFNGLBINDBUFFERARBPROC)GL_GetProcAddress( "glBindBufferARB" );
186 if( !vglBindBufferARB )
189 vglBufferDataARB = (PFNGLBUFFERDATAARBPROC)GL_GetProcAddress( "glBufferDataARB" );
190 if( !vglBufferDataARB )
193 vglDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)GL_GetProcAddress( "glDeleteBuffersARB" );
194 if( !vglDeleteBuffersARB )
197 vglGetAttribLocationARB = (PFNGLGETATTRIBLOCATIONARBPROC)GL_GetProcAddress( "glGetAttribLocation" );
198 if( !vglGetAttribLocationARB )
201 vglVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC)GL_GetProcAddress( "glVertexAttribPointer" );
202 if( !vglVertexAttribPointerARB )
205 vglEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glEnableVertexAttribArray" );
206 if(!vglEnableVertexAttribArrayARB)
209 vglDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)GL_GetProcAddress( "glDisableVertexAttribArray" );
211 if(!vglDisableVertexAttribArrayARB)
218 //-----------------------------------------------------------------------------
219 char* readFromFile( std::string fileName )
221 FILE* file = fopen( fileName.c_str(), "r" );
223 char* content = NULL;
228 fseek( file, 0, SEEK_END );
229 count = ftell( file );
234 content = ( char* )malloc( sizeof( char ) * ( count + 1 ) );
235 count = fread( content, sizeof( char ), count, file );
236 content[ count ] = '\0';
244 static bool IsBufferExtensionsInitialized = InitializeBufferExtensions();
246 //-----------------------------------------------------------------------------
247 VTKViewer_PolyDataMapper::VTKViewer_PolyDataMapper()
249 Q_INIT_RESOURCE( VTKViewer );
251 this->ExtensionsInitialized = ES_None;
253 this->PointSpriteTexture = 0;
255 this->MarkerEnabled = false;
256 this->MarkerType = VTK::MT_NONE;
257 this->MarkerScale = VTK::MS_NONE;
259 this->BallEnabled = false;
260 this->BallScale = 1.0;
261 this->VertexProgram = 0;
264 //-----------------------------------------------------------------------------
265 VTKViewer_PolyDataMapper::~VTKViewer_PolyDataMapper()
267 if( PointSpriteTexture > 0 )
268 glDeleteTextures( 1, &PointSpriteTexture );
271 //-----------------------------------------------------------------------------
272 void VTKViewer_PolyDataMapper::InitShader()
274 std::string fileName = std::string( getenv( "GUI_ROOT_DIR") ) +
275 "/share/salome/resources/gui/Vertex_Program_ARB.txt";
277 char* shader = readFromFile( fileName );
279 GLhandleARB VertexShader = vglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
280 vglShaderSourceARB( VertexShader, 1, (const GLcharARB**)&shader, NULL );
281 vglCompileShaderARB( VertexShader );
283 this->VertexProgram = vglCreateProgramObjectARB();
284 vglAttachObjectARB( this->VertexProgram, VertexShader );
286 vglLinkProgramARB( this->VertexProgram );
291 //-----------------------------------------------------------------------------
292 void VTKViewer_PolyDataMapper::SetMarkerEnabled( bool theMarkerEnabled )
294 if( this->MarkerEnabled == theMarkerEnabled )
297 this->MarkerEnabled = theMarkerEnabled;
301 //-----------------------------------------------------------------------------
302 // Definition of structures and fuctions used in SetBallEnabled() method
305 //----------------------------------------------------------------------------
306 vtkSmartPointer<vtkImageData> MakeTexture( const char* theMainTexture, const char* theAlphaTexture ) {
307 if( !theMainTexture || !theAlphaTexture )
310 vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
311 vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
313 aMainReader->SetFileName( theMainTexture );
314 anAlphaReader->SetFileName( theAlphaTexture );
316 aMainReader->Update();
317 anAlphaReader->Update();
319 vtkImageData* aMainImageData = aMainReader->GetOutput();
320 vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
322 int* aMainImageSize = aMainImageData->GetDimensions();
323 int* anAlphaImageSize = anAlphaImageData->GetDimensions();
324 if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
327 vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
328 aCompositeImageData->Delete();
330 int aNbCompositeComponents = 4;
331 aCompositeImageData->SetDimensions(aMainImageSize);
332 aCompositeImageData->AllocateScalars( VTK_UNSIGNED_CHAR, aNbCompositeComponents );
334 unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
335 unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
336 unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
338 int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
339 int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
340 int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
342 int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
343 for(; aCompositeId < aCompositeSize;) {
344 aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
345 aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
346 aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
347 aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
349 aMainId += aNbMainComponents;
350 anAlphaId += aNbAlphaComponents;
351 aCompositeId += aNbCompositeComponents;
353 aMainReader->Delete();
354 anAlphaReader->Delete();
355 return aCompositeImageData;
359 //-----------------------------------------------------------------------------
360 bool VTKViewer_PolyDataMapper::GetBallEnabled()
362 return this->BallEnabled;
364 //-----------------------------------------------------------------------------
365 void VTKViewer_PolyDataMapper::SetBallEnabled( bool theBallEnabled )
367 if( this->BallEnabled == theBallEnabled )
370 this->BallEnabled = theBallEnabled;
372 if(!this->BallEnabled) {
373 this->ImageData = NULL;
376 if(this->BallEnabled) {
377 if(this->SpecialTextures.find(BallTextureId) == SpecialTextures.end()){
378 QString aMainTexture = getenv( "GUI_ROOT_DIR" );
379 aMainTexture.append("/share/salome/resources/gui/sprite_texture.vti");
381 QString anAlphaTexture = getenv( "GUI_ROOT_DIR" );
382 anAlphaTexture.append( "/share/salome/resources/gui/sprite_alpha.vti" );
383 vtkSmartPointer<vtkImageData> aTextureValue = VTK::MakeTexture( aMainTexture.toLatin1().constData(), anAlphaTexture.toLatin1().constData() );
384 this->SpecialTextures[BallTextureId] = aTextureValue;
386 this->ImageData = this->SpecialTextures[BallTextureId];
391 //-----------------------------------------------------------------------------
392 double VTKViewer_PolyDataMapper::GetBallScale()
394 return this->BallScale;
396 //-----------------------------------------------------------------------------
397 void VTKViewer_PolyDataMapper::SetBallScale( double theBallScale )
399 if( this->BallScale == theBallScale )
401 this->BallScale = theBallScale;
404 //-----------------------------------------------------------------------------
405 void VTKViewer_PolyDataMapper::SetMarkerStd( VTK::MarkerType theMarkerType, VTK::MarkerScale theMarkerScale )
407 if( this->MarkerType == theMarkerType && this->MarkerScale == theMarkerScale )
410 this->MarkerType = theMarkerType;
411 this->MarkerScale = theMarkerScale;
413 if( this->MarkerType == VTK::MT_NONE || this->MarkerType == VTK::MT_USER ) {
414 this->ImageData = NULL;
419 int aMarkerType = (int)this->MarkerType;
420 int aMarkerScale = (int)this->MarkerScale;
422 int anId = (int)VTK::MS_70 * aMarkerType + aMarkerScale;
424 if( this->StandardTextures.find( anId ) == this->StandardTextures.end() )
426 QString aFileName = QString( ":/textures/texture%1.dat" ).arg( aMarkerType );
427 VTK::MarkerTexture aMarkerTexture;
428 if( VTK::LoadTextureData( aFileName, theMarkerScale, aMarkerTexture ) )
429 this->StandardTextures[ anId ] = VTK::MakeVTKImage( aMarkerTexture );
432 this->ImageData = this->StandardTextures[ anId ];
436 //-----------------------------------------------------------------------------
437 void VTKViewer_PolyDataMapper::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMarkerTexture )
439 if( this->MarkerType == VTK::MT_USER && this->MarkerId == theMarkerId )
442 this->MarkerType = VTK::MT_USER;
443 this->MarkerId = theMarkerId;
445 if( this->CustomTextures.find( theMarkerId ) == this->CustomTextures.end() )
446 this->CustomTextures[ theMarkerId ] = VTK::MakeVTKImage( theMarkerTexture );
448 this->ImageData = this->CustomTextures[ theMarkerId ];
452 //-----------------------------------------------------------------------------
453 VTK::MarkerType VTKViewer_PolyDataMapper::GetMarkerType()
455 return this->MarkerType;
458 //-----------------------------------------------------------------------------
459 VTK::MarkerScale VTKViewer_PolyDataMapper::GetMarkerScale()
461 return this->MarkerScale;
464 //-----------------------------------------------------------------------------
465 int VTKViewer_PolyDataMapper::GetMarkerTexture()
467 return this->MarkerId;
470 //-----------------------------------------------------------------------------
471 int VTKViewer_PolyDataMapper::InitExtensions()
475 std::ostringstream strm;
476 glGetIntegerv(GL_NUM_EXTENSIONS, &n);
477 for (int i = 0; i < n; i++)
479 const char *exti = (const char *)glGetStringi(GL_EXTENSIONS, i);
482 std::string s = strm.str();
483 const char* ext = s.c_str();
485 const char* ext = (const char*)glGetString( GL_EXTENSIONS );
487 if( !IsBufferExtensionsInitialized || !ext ||
488 strstr( ext, "GL_ARB_point_sprite" ) == NULL ||
489 strstr( ext, "GL_ARB_vertex_buffer_object" ) == NULL ||
490 strstr( ext, "GL_ARB_shader_objects") == NULL )
492 MESSAGE("Initializing ARB extensions failed");
496 if( this->BallEnabled )
502 //-----------------------------------------------------------------------------
503 void VTKViewer_PolyDataMapper::InitPointSprites()
505 glEnable( GL_POINT_SPRITE_ARB );
506 glEnable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
508 glPushAttrib( GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT );
510 glDepthFunc( GL_LEQUAL );
511 glEnable( GL_DEPTH_TEST );
513 glEnable( GL_ALPHA_TEST );
514 if(!this->BallEnabled) {
515 glAlphaFunc( GL_GREATER, 0.0 );
518 glAlphaFunc( GL_GREATER, 0.5 );
521 glDisable( GL_LIGHTING );
523 glDisable( GL_COLOR_MATERIAL );
526 //-----------------------------------------------------------------------------
527 void VTKViewer_PolyDataMapper::CleanupPointSprites()
531 glDisable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB );
532 glDisable( GL_POINT_SPRITE_ARB );
535 //-----------------------------------------------------------------------------
536 void VTKViewer_PolyDataMapper::InitTextures()
538 if( !this->ImageData.GetPointer() )
541 glEnable( GL_TEXTURE_2D );
542 if( this->PointSpriteTexture == 0 ) {
543 glGenTextures( 1, &this->PointSpriteTexture );
545 glBindTexture( GL_TEXTURE_2D, this->PointSpriteTexture );
546 glTexEnvf( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
547 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
548 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
550 if(this->BallEnabled) {
551 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
552 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
554 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
555 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
558 int* aSize = this->ImageData->GetDimensions();
559 unsigned char* dataPtr = (unsigned char*)this->ImageData->GetScalarPointer();
560 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, aSize[0], aSize[1], 0,
561 GL_RGBA, GL_UNSIGNED_BYTE, dataPtr );
564 //-----------------------------------------------------------------------------
565 void VTKViewer_PolyDataMapper::RenderPiece( vtkRenderer* ren, vtkActor* act )
567 bool isUsePointSprites = (this->MarkerEnabled && this->MarkerType != VTK::MT_NONE) ||
569 if( isUsePointSprites )
571 if( this->ExtensionsInitialized == ES_None )
572 this->ExtensionsInitialized = this->InitExtensions();
573 this->InitPointSprites();
574 this->InitTextures();
577 if(!this->BallEnabled || this->ExtensionsInitialized != ES_Ok) {
578 MAPPER_SUPERCLASS::RenderPiece( ren, act );
579 if( isUsePointSprites )
580 this->CleanupPointSprites();
581 glBindTexture( GL_TEXTURE_2D, 0 );
584 vtkPolyData *input= this->GetInput();
587 // make sure that we've been properly initialized
589 if (ren->GetRenderWindow()->CheckAbortStatus())
594 vtkErrorMacro(<< "No input!");
599 this->InvokeEvent(vtkCommand::StartEvent,NULL);
601 this->InvokeEvent(vtkCommand::EndEvent,NULL);
602 numPts = input->GetNumberOfPoints();
607 vtkDebugMacro(<< "No points!");
611 // make sure our window is current
612 ren->GetRenderWindow()->MakeCurrent();
615 vglUseProgramObjectARB( this->VertexProgram );
619 // if something has changed regenerate colors and display lists
623 if ( this->GetMTime() > this->BuildTime ||
624 input->GetMTime() > this->BuildTime ||
625 act->GetProperty()->GetMTime() > this->BuildTime ||
626 ren->GetRenderWindow() != this->LastWindow)
628 // sets this->Colors as side effect
629 this->MapScalars( act->GetProperty()->GetOpacity() );
631 if (!this->ImmediateModeRendering &&
632 !this->GetGlobalImmediateModeRendering())
634 this->ReleaseGraphicsResources(ren->GetRenderWindow());
635 this->LastWindow = ren->GetRenderWindow();
637 // get a unique display list id
638 this->ListId = glGenLists(1);
639 glNewList(this->ListId,GL_COMPILE);
641 noAbort = this->Draw(ren,act);
644 // Time the actual drawing
645 this->Timer->StartTimer();
646 glCallList(this->ListId);
647 this->Timer->StopTimer();
651 this->ReleaseGraphicsResources(ren->GetRenderWindow());
652 this->LastWindow = ren->GetRenderWindow();
655 this->BuildTime.Modified();
657 // if nothing changed but we are using display lists, draw it
660 if (!this->ImmediateModeRendering &&
661 !this->GetGlobalImmediateModeRendering())
663 // Time the actual drawing
664 this->Timer->StartTimer();
665 glCallList(this->ListId);
666 this->Timer->StopTimer();
670 // if we are in immediate mode rendering we always
671 // want to draw the primitives here
672 if (this->ImmediateModeRendering ||
673 this->GetGlobalImmediateModeRendering())
675 // sets this->Colors as side effect
676 this->MapScalars( act->GetProperty()->GetOpacity() );
678 // Time the actual drawing
679 this->Timer->StartTimer();
681 this->Timer->StopTimer();
684 this->TimeToDraw = (float)this->Timer->GetElapsedTime();
686 // If the timer is not accurate enough, set it to a small
687 // time so that it is not zero
688 if ( this->TimeToDraw == 0.0 )
689 this->TimeToDraw = 0.0001;
691 //this->RenderPieceStart(ren, act);
692 this->RenderPieceDraw(ren, act);
693 // this->RenderEdges(ren,act);
694 //this->RenderPieceFinish(ren, act);
696 vglUseProgramObjectARB( 0 );
697 this->CleanupPointSprites();
698 glBindTexture( GL_TEXTURE_2D, 0 );
702 //-----------------------------------------------------------------------------
703 // Definition of structures and fuctions used in Draw() method
706 //-----------------------------------------------------------------------------
713 //-----------------------------------------------------------------------------
714 struct TColorFunctorBase
718 TColorFunctorBase( vtkProperty* theProperty )
720 myAlpha = theProperty->GetOpacity();
725 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId ) = 0;
728 //-----------------------------------------------------------------------------
729 struct TPropertyColor : TColorFunctorBase
733 TPropertyColor( vtkProperty* theProperty ):
734 TColorFunctorBase( theProperty )
736 theProperty->GetColor( myColor );
741 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
743 theVertex.r = myColor[0];
744 theVertex.g = myColor[1];
745 theVertex.b = myColor[2];
746 theVertex.a = myAlpha;
750 //-----------------------------------------------------------------------------
751 struct TColors2Color : TColorFunctorBase
753 vtkUnsignedCharArray* myColors;
755 TColors2Color( vtkProperty* theProperty,
756 vtkUnsignedCharArray* theColors ):
757 TColorFunctorBase( theProperty ),
758 myColors( theColors )
763 get( TVertex& theVertex, vtkIdType thePointId, vtkIdType theCellId )
765 vtkIdType aTupleId = GetTupleId( thePointId, theCellId );
766 unsigned char* aColor = myColors->GetPointer( aTupleId << 2 );
768 theVertex.r = int( aColor[0] ) / 255.0;
769 theVertex.g = int( aColor[1] ) / 255.0;
770 theVertex.b = int( aColor[2] ) / 255.0;
771 theVertex.a = myAlpha;
776 GetTupleId( vtkIdType thePointId, vtkIdType theCellId ) = 0;
779 //-----------------------------------------------------------------------------
780 struct TPointColors2Color : TColors2Color
782 TPointColors2Color( vtkProperty* theProperty,
783 vtkUnsignedCharArray* theColors ):
784 TColors2Color( theProperty, theColors )
789 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
795 //-----------------------------------------------------------------------------
796 struct TCellColors2Color : TColors2Color
798 TCellColors2Color( vtkProperty* theProperty,
799 vtkUnsignedCharArray* theColors ):
800 TColors2Color( theProperty, theColors )
805 GetTupleId( vtkIdType thePointId, vtkIdType theCellId )
811 //-----------------------------------------------------------------------------
812 template < class TCoordinates >
813 void DrawPoints( TCoordinates* theStartPoints,
814 vtkCellArray* theCells,
815 TColorFunctorBase* theColorFunctor,
816 TVertex* theVertexArr,
817 vtkIdType &theCellId,
818 vtkIdType &theVertexId,
820 vtkDataArray* theDiamArray,
821 double theBallScale )
823 vtkIdType* ptIds = theCells->GetPointer();
824 vtkIdType* endPtIds = ptIds + theCells->GetNumberOfConnectivityEntries();
826 bool mapBalls = false;
827 if(theBallArr && theDiamArray) {
831 while ( ptIds < endPtIds ) {
832 vtkIdType nPts = *ptIds;
836 TVertex& aVertex = theVertexArr[ theVertexId ];
837 vtkIdType aPointId = *ptIds;
839 TCoordinates* anOffsetPoints = theStartPoints + 3 * aPointId;
840 aVertex.vx = anOffsetPoints[0];
841 aVertex.vy = anOffsetPoints[1];
842 aVertex.vz = anOffsetPoints[2];
844 theColorFunctor->get( aVertex, aPointId, theCellId );
852 theBallArr[theCellId] = (TBall)theDiamArray->GetTuple(theCellId)[0]*theBallScale;
859 //-----------------------------------------------------------------------------
860 template < class TCoordinates >
861 void DrawCellsPoints( vtkPolyData* theInput,
862 vtkPoints* thePoints,
863 TColorFunctorBase* theColorFunctor,
864 TVertex* theVertexArr,
866 double theBallScale )
868 vtkIdType aCellId = 0, aVertexId = 0;
870 TCoordinates* aStartPoints = (TCoordinates*)thePoints->GetVoidPointer(0);
871 vtkDataArray* aDiams = theInput->GetCellData() ? theInput->GetCellData()->GetScalars() : 0;
873 if ( vtkCellArray* aCellArray = theInput->GetVerts() ) {
874 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
877 if ( vtkCellArray* aCellArray = theInput->GetLines() )
878 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
880 if ( vtkCellArray* aCellArray = theInput->GetPolys() )
881 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
883 if ( vtkCellArray* aCellArray = theInput->GetStrips() )
884 DrawPoints( aStartPoints, aCellArray, theColorFunctor, theVertexArr, aCellId, aVertexId, theBallArr, aDiams, theBallScale );
889 //-----------------------------------------------------------------------------
890 int VTKViewer_PolyDataMapper::Draw( vtkRenderer* ren, vtkActor* act )
893 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled)
894 return MAPPER_SUPERCLASS::Draw( ren, act );
896 void InternalDraw( ren, act );
901 //-----------------------------------------------------------------------------
902 void VTKViewer_PolyDataMapper::RenderPieceDraw( vtkRenderer* ren, vtkActor* act ) {
904 if( (!this->MarkerEnabled || this->MarkerType == VTK::MT_NONE || !this->ImageData.GetPointer()) && !this->BallEnabled) {
905 MAPPER_SUPERCLASS::RenderPieceDraw( ren, act );
908 InternalDraw( ren, act );
912 void VTKViewer_PolyDataMapper::InternalDraw(vtkRenderer* ren, vtkActor* act ) {
913 vtkUnsignedCharArray* colors = NULL;
914 vtkPolyData* input = this->GetInput();
917 vtkProperty* prop = act->GetProperty();
919 points = input->GetPoints();
923 if(!this->BallEnabled) {
924 colors = this->Colors;
925 if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
926 this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
927 !input->GetPointData()->GetScalars() )
928 && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA )
934 vtkIdType aTotalConnectivitySize = 0;
935 vtkIdType aNbCells = 0;
937 if ( vtkCellArray* aCellArray = input->GetVerts() ) {
938 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
939 aNbCells += aCellArray->GetNumberOfCells();
942 if ( vtkCellArray* aCellArray = input->GetLines() ) {
943 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
944 aNbCells += aCellArray->GetNumberOfCells();
947 if ( vtkCellArray* aCellArray = input->GetPolys() ) {
948 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
949 aNbCells += aCellArray->GetNumberOfCells();
952 if ( vtkCellArray* aCellArray = input->GetStrips() ) {
953 aTotalConnectivitySize += aCellArray->GetNumberOfConnectivityEntries() - aCellArray->GetNumberOfCells();
954 aNbCells += aCellArray->GetNumberOfCells();
957 if ( aTotalConnectivitySize > 0 ) {
958 VTK::TVertex* aVertexArr = new VTK::TVertex[ aTotalConnectivitySize ];
960 TBall* aBallArray = 0;
962 if(this->BallEnabled) {
963 aBallArray = new TBall[aNbCells];
966 int* aSize = this->ImageData->GetDimensions();
967 glPointSize( std::max( aSize[0], aSize[1] ) );
969 int aMode = 0; // to remove
971 VTK::TColorFunctorBase* aColorFunctor = NULL;
972 if( colors && aMode != 1 ) {
974 aColorFunctor = new VTK::TCellColors2Color( prop, colors );
976 aColorFunctor = new VTK::TPointColors2Color( prop, colors );
978 aColorFunctor = new VTK::TPropertyColor( prop );
980 if ( points->GetDataType() == VTK_FLOAT )
981 VTK::DrawCellsPoints< float >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
983 VTK::DrawCellsPoints< double >( input, points, aColorFunctor, aVertexArr, aBallArray, GetBallScale() );
985 delete aColorFunctor;
988 if( this->ExtensionsInitialized == ES_Ok ) {
989 GLuint aBufferObjectID, aDiamsID = 0;
990 GLint attribute_diams = -1;
991 vglGenBuffersARB( 1, &aBufferObjectID );
992 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
994 int anArrayObjectSize = sizeof( VTK::TVertex ) * aTotalConnectivitySize;
995 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, anArrayObjectSize, aVertexArr, GL_STATIC_DRAW_ARB );
997 delete [] aVertexArr;
999 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1000 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aBufferObjectID );
1002 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), (void*)0 );
1003 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex), (void*)(4*sizeof(GLfloat)) );
1005 glEnableClientState( GL_VERTEX_ARRAY );
1006 glEnableClientState( GL_COLOR_ARRAY );
1008 if(this->BallEnabled) {
1009 vglGenBuffersARB( 2, &aDiamsID);
1010 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID);
1012 int aDiamsSize = sizeof(TBall)*aNbCells;
1013 vglBufferDataARB( GL_ARRAY_BUFFER_ARB, aDiamsSize, aBallArray, GL_STATIC_DRAW_ARB);
1015 delete [] aBallArray;
1016 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1017 vglBindBufferARB( GL_ARRAY_BUFFER_ARB, aDiamsID );
1019 attribute_diams = vglGetAttribLocationARB(this->VertexProgram, "diameter");
1020 vglEnableVertexAttribArrayARB(attribute_diams);
1021 vglBindBufferARB(GL_ARRAY_BUFFER_ARB, aDiamsID);
1022 vglVertexAttribPointerARB(
1023 attribute_diams, // attribute
1024 1, // number of elements per vertex, here (diameter)
1025 GL_FLOAT, // the type of each element
1026 GL_FALSE, // take our values as-is
1027 0, // no extra data between each position
1028 0 // offset of first element
1032 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1034 glDisableClientState( GL_COLOR_ARRAY );
1035 glDisableClientState( GL_VERTEX_ARRAY );
1036 vglDeleteBuffersARB( 1, &aBufferObjectID );
1038 if(this->BallEnabled) {
1039 vglDisableVertexAttribArrayARB(attribute_diams);
1040 vglDeleteBuffersARB( 2, &aDiamsID );
1043 } else { // there are no extensions
1044 glColorPointer( 4, GL_FLOAT, sizeof(VTK::TVertex), aVertexArr );
1045 glVertexPointer( 3, GL_FLOAT, sizeof(VTK::TVertex),
1046 (void*)((GLfloat*)((void*)(aVertexArr)) + 4));
1048 glEnableClientState( GL_VERTEX_ARRAY );
1049 glEnableClientState( GL_COLOR_ARRAY );
1051 glDrawArrays( GL_POINTS, 0, aTotalConnectivitySize );
1053 glDisableClientState( GL_COLOR_ARRAY );
1054 glDisableClientState( GL_VERTEX_ARRAY );
1056 delete [] aVertexArr;
1061 this->UpdateProgress(1.0);