From 7bf12546af4604e053f3bfb420142a0108340b1c Mon Sep 17 00:00:00 2001 From: ouv Date: Fri, 13 Apr 2012 10:35:39 +0000 Subject: [PATCH] IPAL22901: Extending functionality of setting gradient and textured background of the VTK viewer Part 1: textured background. --- src/SVTK/SVTK_Renderer.cxx | 4 +- src/SVTK/SVTK_ViewModel.cxx | 4 +- src/SVTK/SVTK_ViewWindow.cxx | 18 +- src/VTKViewer/Makefile.am | 4 + src/VTKViewer/VTKViewer_OpenGLRenderer.cxx | 180 ++++++++ src/VTKViewer/VTKViewer_OpenGLRenderer.h | 53 +++ src/VTKViewer/VTKViewer_Texture.cxx | 491 +++++++++++++++++++++ src/VTKViewer/VTKViewer_Texture.h | 71 +++ src/VTKViewer/VTKViewer_ViewModel.cxx | 4 +- src/VTKViewer/VTKViewer_ViewWindow.cxx | 7 +- 10 files changed, 815 insertions(+), 21 deletions(-) create mode 100644 src/VTKViewer/VTKViewer_OpenGLRenderer.cxx create mode 100644 src/VTKViewer/VTKViewer_OpenGLRenderer.h create mode 100644 src/VTKViewer/VTKViewer_Texture.cxx create mode 100644 src/VTKViewer/VTKViewer_Texture.h diff --git a/src/SVTK/SVTK_Renderer.cxx b/src/SVTK/SVTK_Renderer.cxx index 9a7e07d5a..6584727de 100644 --- a/src/SVTK/SVTK_Renderer.cxx +++ b/src/SVTK/SVTK_Renderer.cxx @@ -35,9 +35,9 @@ #include "VTKViewer_Algorithm.h" #include "VTKViewer_Transform.h" #include "VTKViewer_Utilities.h" +#include "VTKViewer_OpenGLRenderer.h" #include -#include #include #include #include @@ -61,7 +61,7 @@ vtkStandardNewMacro(SVTK_Renderer); */ SVTK_Renderer ::SVTK_Renderer(): - myDevice(vtkRenderer::New()), + myDevice(VTKViewer_OpenGLRenderer::New()), myInteractor(NULL), myPriority(0.0), myEventCallbackCommand(vtkCallbackCommand::New()), diff --git a/src/SVTK/SVTK_ViewModel.cxx b/src/SVTK/SVTK_ViewModel.cxx index cf294479a..aaaea4eff 100644 --- a/src/SVTK/SVTK_ViewModel.cxx +++ b/src/SVTK/SVTK_ViewModel.cxx @@ -48,7 +48,7 @@ #include "QtxBackgroundTool.h" // VSR: Uncomment below line to allow texture background support in VTK viewer -// #define VTK_ENABLE_TEXTURED_BACKGROUND +#define VTK_ENABLE_TEXTURED_BACKGROUND // in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study. @@ -106,7 +106,7 @@ QString SVTK_Viewer::backgroundData( QStringList& gradList, QIntList& idList, QI gradList << tr( "GT_VERTICALGRADIENT" ); // only vertical type of gradient is supported idList << VerticalGradient; // only vertical type of gradient is supported #ifdef VTK_ENABLE_TEXTURED_BACKGROUND - txtList << Qtx::StretchTexture; // only stretch texture mode is supported + txtList << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture; #endif return tr("BG_IMAGE_FILES"); } diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 4f6d07f60..44227e2e3 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -26,6 +26,7 @@ #include "SVTK_SetRotationPointDlg.h" #include "SVTK_ViewParameterDlg.h" #include "SVTK_ViewModel.h" +#include "VTKViewer_Texture.h" #include "SALOME_Actor.h" @@ -645,9 +646,8 @@ void SVTK_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) if ( aReader ) { // create texture aReader->SetFileName( fi.absoluteFilePath().toLatin1().constData() ); - aReader->Update(); - - vtkTexture* aTexture = vtkTexture::New(); + aReader->Update(); + VTKViewer_Texture* aTexture = VTKViewer_Texture::New(); vtkImageMapToColors* aMap = 0; vtkAlgorithmOutput* anOutput; /* @@ -674,20 +674,14 @@ void SVTK_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) // the same results for all modes switch ( textureMode ) { case Qtx::TileTexture: - aTexture->RepeatOn(); - aTexture->EdgeClampOff(); - aTexture->InterpolateOff(); + aTexture->SetPosition((int)VTKViewer_Texture::Tiled); break; case Qtx::StretchTexture: - aTexture->RepeatOff(); - aTexture->EdgeClampOff(); - aTexture->InterpolateOn(); + aTexture->SetPosition((int)VTKViewer_Texture::Stretched); break; case Qtx::CenterTexture: + aTexture->SetPosition((int)VTKViewer_Texture::Centered); default: - aTexture->RepeatOff(); - aTexture->EdgeClampOn(); - aTexture->InterpolateOff(); break; } // show textured background diff --git a/src/VTKViewer/Makefile.am b/src/VTKViewer/Makefile.am index a29675745..58fecd67e 100755 --- a/src/VTKViewer/Makefile.am +++ b/src/VTKViewer/Makefile.am @@ -60,6 +60,8 @@ salomeinclude_HEADERS = \ VTKViewer_MarkerDlg.h \ VTKViewer_PolyDataMapper.h \ VTKViewer_DataSetMapper.h \ + VTKViewer_Texture.h \ + VTKViewer_OpenGLRenderer.h \ VTKViewer_CellCenters.h dist_libVTKViewer_la_SOURCES = \ @@ -89,6 +91,8 @@ dist_libVTKViewer_la_SOURCES = \ VTKViewer_MarkerDlg.cxx \ VTKViewer_PolyDataMapper.cxx \ VTKViewer_DataSetMapper.cxx \ + VTKViewer_Texture.cxx \ + VTKViewer_OpenGLRenderer.cxx \ VTKViewer_CellCenters.cxx MOC_FILES = \ diff --git a/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx b/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx new file mode 100644 index 000000000..a9625143b --- /dev/null +++ b/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx @@ -0,0 +1,180 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "VTKViewer_OpenGLRenderer.h" +#include "VTKViewer_Texture.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // vtkgl namespace +#include +#include +#include +#include +#include +#include + +vtkStandardNewMacro(VTKViewer_OpenGLRenderer); + +VTKViewer_OpenGLRenderer::VTKViewer_OpenGLRenderer() +{ +} + +VTKViewer_OpenGLRenderer::~VTKViewer_OpenGLRenderer() +{ +} + +void VTKViewer_OpenGLRenderer::Clear(void) +{ + GLbitfield clear_mask = 0; + + if( !this->Transparent() ) + { + glClearColor( static_cast(this->Background[0]), + static_cast(this->Background[1]), + static_cast(this->Background[2]), + static_cast(0.0)); + clear_mask |= GL_COLOR_BUFFER_BIT; + } + + if( !this->GetPreserveDepthBuffer() ) + { + glClearDepth(static_cast(1.0)); + clear_mask |= GL_DEPTH_BUFFER_BIT; + } + + vtkDebugMacro(<< "glClear\n"); + glClear(clear_mask); + + // If gradient background is turned on, draw it now. + if( !this->Transparent() && + ( this->GradientBackground || this->TexturedBackground ) ) + { + double aTileViewport[4]; + this->GetRenderWindow()->GetTileViewport( aTileViewport ); + glPushAttrib( GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_TEXTURE_BIT ); + glDisable( GL_ALPHA_TEST ); + glDisable( GL_DEPTH_TEST ); + glDisable( GL_LIGHTING ); + glDisable( GL_TEXTURE_1D ); + glDisable( GL_TEXTURE_2D ); + glDisable( GL_BLEND ); + glShadeModel( GL_SMOOTH ); // color interpolation + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glOrtho( aTileViewport[0], aTileViewport[2], aTileViewport[1], aTileViewport[3], -1.0, 1.0 ); + + if( this->GradientBackground ) + { + glBegin( GL_QUADS ); + + glColor4d( this->Background[0], this->Background[1], this->Background[2], 0.0 ); + glVertex2f( 0.F, 0.F ); + glVertex2f( 1.F, 0.F ); + + glColor4d( this->Background2[0], this->Background2[1], this->Background2[2], 0.0 ); + glVertex2f( 1.F, 1.F ); + glVertex2f( 0.F, 1.F ); + + glEnd(); + } + + if( this->TexturedBackground && this->BackgroundTexture ) + { + if( VTKViewer_Texture* aTexture = VTKViewer_Texture::SafeDownCast( this->BackgroundTexture ) ) + { + glEnable( GL_TEXTURE_2D ); + + aTexture->Render( this ); + + // NOTE: By default the mode is GL_MODULATE. Since the user + // cannot set the mode, the default is set to replace. + glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + // NOTE: vtkTexture Render enables the alpha test + // so that no buffer is affected if alpha of incoming fragment is + // below the threshold. Here we have to enable it so that it won't + // rejects the fragments of the quad as the alpha is set to 0 on it. + glDisable( GL_ALPHA_TEST ); + + GLfloat texX = 1.F; // texture coordinate + GLfloat texY = 1.F; // texture coordinate + GLfloat x_offset = 0.5, y_offset = 0.5; + GLfloat coeff = 0.5; + + // OCCT issue 0023102: Change the algorithm of rendering the + // 3d viewer background using tiled texture + // Setting this coefficient to -1.F allows to tile textures relatively + // to the top-left corner of the view (value 1.F corresponds to the + // initial behaviour - tiling from the bottom-left corner) + GLfloat aCoef = -1.F; + + int aPosition = aTexture->GetPosition(); + int aWidth = aTexture->GetWidth(); + int aHeight = aTexture->GetHeight(); + int aViewWidth = this->RenderWindow->GetSize()[0]; + int aViewHeight = this->RenderWindow->GetSize()[1]; + if( aPosition == VTKViewer_Texture::Centered ) + { + x_offset = ( (GLfloat)aWidth / (GLfloat)aViewWidth ) / 2.; + y_offset = ( (GLfloat)aHeight / (GLfloat)aViewHeight ) / 2.; + } + else if( aPosition == VTKViewer_Texture::Tiled ) + { + texX = (GLfloat)aViewWidth / (GLfloat)aWidth; + texY = (GLfloat)aViewHeight / (GLfloat)aHeight; + } + + // Note that texture is mapped using GL_REPEAT wrapping mode so integer part + // is simply ignored, and negative multiplier is here for convenience only + // and does not result e.g. in texture mirroring + glBegin( GL_QUADS ); + glTexCoord2f( 0.F, 0.F ); glVertex2f( -x_offset + coeff, -aCoef * y_offset + coeff ); + glTexCoord2f( texX, 0.F ); glVertex2f( x_offset + coeff, -aCoef * y_offset + coeff ); + glTexCoord2f( texX, aCoef * texY ); glVertex2f( x_offset + coeff, aCoef * y_offset + coeff ); + glTexCoord2f( 0.F, aCoef * texY ); glVertex2f( -x_offset + coeff, aCoef * y_offset + coeff ); + glEnd(); + } + } + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + + glPopAttrib(); + } +} diff --git a/src/VTKViewer/VTKViewer_OpenGLRenderer.h b/src/VTKViewer/VTKViewer_OpenGLRenderer.h new file mode 100644 index 000000000..797d21221 --- /dev/null +++ b/src/VTKViewer/VTKViewer_OpenGLRenderer.h @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SALOME VTKViewer : build VTK viewer into Salome desktop +// File : +// Author : +// Module : +// $Header$ +// + +#ifndef VTKVIEWER_OPENGLRENDERER_H +#define VTKVIEWER_OPENGLRENDERER_H + +#include "VTKViewer.h" +#include "vtkOpenGLRenderer.h" + +class VTKVIEWER_EXPORT VTKViewer_OpenGLRenderer : public vtkOpenGLRenderer +{ +public: + static VTKViewer_OpenGLRenderer *New(); + vtkTypeMacro(VTKViewer_OpenGLRenderer,vtkOpenGLRenderer); + + virtual void Clear(void); + +protected: + VTKViewer_OpenGLRenderer(); + ~VTKViewer_OpenGLRenderer(); + +private: + VTKViewer_OpenGLRenderer(const VTKViewer_OpenGLRenderer&); // Not implemented. + void operator=(const VTKViewer_OpenGLRenderer&); // Not implemented. +}; + +#endif diff --git a/src/VTKViewer/VTKViewer_Texture.cxx b/src/VTKViewer/VTKViewer_Texture.cxx new file mode 100644 index 000000000..68b98277c --- /dev/null +++ b/src/VTKViewer/VTKViewer_Texture.cxx @@ -0,0 +1,491 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "VTKViewer_Texture.h" + +#include "vtkHomogeneousTransform.h" +#include "vtkImageData.h" +#include "vtkLookupTable.h" +#include "vtkObjectFactory.h" +#include "vtkOpenGLRenderer.h" +#include "vtkPointData.h" +#include "vtkRenderWindow.h" +#include "vtkOpenGLExtensionManager.h" +#include "vtkOpenGLRenderWindow.h" +#include "vtkTransform.h" +#include "vtkPixelBufferObject.h" +#include "vtkOpenGL.h" +#include "vtkgl.h" // vtkgl namespace +#include + +vtkStandardNewMacro(VTKViewer_Texture); + + +// ---------------------------------------------------------------------------- +VTKViewer_Texture::VTKViewer_Texture() +{ + myWidth = 0; + myHeight = 0; + myPosition = VTKViewer_Texture::Centered; +} + +// ---------------------------------------------------------------------------- +VTKViewer_Texture::~VTKViewer_Texture() +{ +} + +// ---------------------------------------------------------------------------- +// Implement base class method. +void VTKViewer_Texture::Load(vtkRenderer *ren) +{ + GLenum format = GL_LUMINANCE; + vtkImageData *input = this->GetInput(); + + this->Initialize(ren); + + // Need to reload the texture. + // There used to be a check on the render window's mtime, but + // this is too broad of a check (e.g. it would cause all textures + // to load when only the desired update rate changed). + // If a better check is required, check something more specific, + // like the graphics context. + vtkOpenGLRenderWindow* renWin = + static_cast(ren->GetRenderWindow()); + + if(this->BlendingMode != VTK_TEXTURE_BLENDING_MODE_NONE + && vtkgl::ActiveTexture) + { + glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, vtkgl::COMBINE); + + switch(this->BlendingMode) + { + case VTK_TEXTURE_BLENDING_MODE_REPLACE: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_REPLACE); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_REPLACE); + break; + } + case VTK_TEXTURE_BLENDING_MODE_MODULATE: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_MODULATE); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_MODULATE); + break; + } + case VTK_TEXTURE_BLENDING_MODE_ADD: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_ADD); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_ADD); + break; + } + case VTK_TEXTURE_BLENDING_MODE_ADD_SIGNED: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::ADD_SIGNED); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::ADD_SIGNED); + break; + } + case VTK_TEXTURE_BLENDING_MODE_INTERPOLATE: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::INTERPOLATE); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::INTERPOLATE); + break; + } + case VTK_TEXTURE_BLENDING_MODE_SUBTRACT: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, vtkgl::SUBTRACT); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, vtkgl::SUBTRACT); + break; + } + default: + { + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_RGB, GL_ADD); + glTexEnvf (GL_TEXTURE_ENV, vtkgl::COMBINE_ALPHA, GL_ADD); + } + } + } + + if (this->GetMTime() > this->LoadTime.GetMTime() || + input->GetMTime() > this->LoadTime.GetMTime() || + (this->GetLookupTable() && this->GetLookupTable()->GetMTime () > + this->LoadTime.GetMTime()) || + renWin != this->RenderWindow.GetPointer() || + renWin->GetContextCreationTime() > this->LoadTime) + { + int bytesPerPixel; + int size[3]; + vtkDataArray *scalars; + unsigned char *dataPtr; + unsigned char *resultData=NULL; + int xsize, ysize; + unsigned int xs,ys; + GLuint tempIndex=0; + + // Get the scalars the user choose to color with. + scalars = this->GetInputArrayToProcess(0, input); + + // make sure scalars are non null + if (!scalars) + { + vtkErrorMacro(<< "No scalar values found for texture input!"); + return; + } + + // get some info + input->GetDimensions(size); + + if (input->GetNumberOfCells() == scalars->GetNumberOfTuples()) + { + // we are using cell scalars. Adjust image size for cells. + for (int kk=0; kk < 3; kk++) + { + if (size[kk]>1) + { + size[kk]--; + } + } + } + + bytesPerPixel = scalars->GetNumberOfComponents(); + + // make sure using unsigned char data of color scalars type + if (this->MapColorScalarsThroughLookupTable || + scalars->GetDataType() != VTK_UNSIGNED_CHAR ) + { + dataPtr = this->MapScalarsToColors (scalars); + bytesPerPixel = 4; + } + else + { + dataPtr = static_cast(scalars)->GetPointer(0); + } + + // we only support 2d texture maps right now + // so one of the three sizes must be 1, but it + // could be any of them, so lets find it + if (size[0] == 1) + { + xsize = size[1]; ysize = size[2]; + } + else + { + xsize = size[0]; + if (size[1] == 1) + { + ysize = size[2]; + } + else + { + ysize = size[1]; + if (size[2] != 1) + { + vtkErrorMacro(<< "3D texture maps currently are not supported!"); + return; + } + } + } + + + if(!this->CheckedHardwareSupport) + { + vtkOpenGLExtensionManager *m=renWin->GetExtensionManager(); + this->CheckedHardwareSupport=true; + this->SupportsNonPowerOfTwoTextures= + m->ExtensionSupported("GL_VERSION_2_0") + || m->ExtensionSupported("GL_ARB_texture_non_power_of_two"); + this->SupportsPBO=vtkPixelBufferObject::IsSupported(renWin); + } + + // -- decide whether the texture needs to be resampled -- + + GLint maxDimGL; + glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxDimGL); + // if larger than permitted by the graphics library then must resample + bool resampleNeeded=xsize > maxDimGL || ysize > maxDimGL; + if(resampleNeeded) + { + vtkDebugMacro( "Texture too big for gl, maximum is " << maxDimGL); + } + + if(!resampleNeeded && !this->SupportsNonPowerOfTwoTextures) + { + // xsize and ysize must be a power of 2 in OpenGL + xs = static_cast(xsize); + ys = static_cast(ysize); + while (!(xs & 0x01)) + { + xs = xs >> 1; + } + while (!(ys & 0x01)) + { + ys = ys >> 1; + } + // if not a power of two then resampling is required + resampleNeeded= (xs>1) || (ys>1); + } + + if(resampleNeeded) + { + vtkDebugMacro(<< "Resampling texture to power of two for OpenGL"); + resultData = this->ResampleToPowerOfTwo(xsize, ysize, dataPtr, + bytesPerPixel); + } + + if ( resultData == NULL ) + { + resultData = dataPtr; + } + + // free any old display lists (from the old context) + if (this->RenderWindow) + { + this->ReleaseGraphicsResources(this->RenderWindow); + } + + this->RenderWindow = ren->GetRenderWindow(); + + // make the new context current before we mess with opengl + this->RenderWindow->MakeCurrent(); + + // define a display list for this texture + // get a unique display list id + +#ifdef GL_VERSION_1_1 + glGenTextures(1, &tempIndex); + this->Index = static_cast(tempIndex); + glBindTexture(GL_TEXTURE_2D, this->Index); +#else + this->Index = glGenLists(1); + glDeleteLists (static_cast(this->Index), static_cast(0)); + glNewList (static_cast(this->Index), GL_COMPILE); +#endif + //seg fault protection for those wackos that don't use an + //opengl render window + if(this->RenderWindow->IsA("vtkOpenGLRenderWindow")) + { + static_cast(ren->GetRenderWindow())-> + RegisterTextureResource( this->Index ); + } + + if (this->Interpolate) + { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR ); + } + else + { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + } + if (this->Repeat) + { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + } + else + { + vtkOpenGLExtensionManager* manager = renWin->GetExtensionManager(); + if (this->EdgeClamp && + (manager->ExtensionSupported("GL_VERSION_1_2") || + manager->ExtensionSupported("GL_EXT_texture_edge_clamp"))) + { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + vtkgl::CLAMP_TO_EDGE ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + vtkgl::CLAMP_TO_EDGE ); + } + else + { + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + } + } + int internalFormat = bytesPerPixel; + switch (bytesPerPixel) + { + case 1: format = GL_LUMINANCE; break; + case 2: format = GL_LUMINANCE_ALPHA; break; + case 3: format = GL_RGB; break; + case 4: format = GL_RGBA; break; + } + // if we are using OpenGL 1.1, you can force 32 or16 bit textures +#ifdef GL_VERSION_1_1 + if (this->Quality == VTK_TEXTURE_QUALITY_32BIT) + { + switch (bytesPerPixel) + { + case 1: internalFormat = GL_LUMINANCE8; break; + case 2: internalFormat = GL_LUMINANCE8_ALPHA8; break; + case 3: internalFormat = GL_RGB8; break; + case 4: internalFormat = GL_RGBA8; break; + } + } + else if (this->Quality == VTK_TEXTURE_QUALITY_16BIT) + { + switch (bytesPerPixel) + { + case 1: internalFormat = GL_LUMINANCE4; break; + case 2: internalFormat = GL_LUMINANCE4_ALPHA4; break; + case 3: internalFormat = GL_RGB4; break; + case 4: internalFormat = GL_RGBA4; break; + } + } +#endif + if(this->SupportsPBO) + { + if(this->PBO==0) + { + this->PBO=vtkPixelBufferObject::New(); + this->PBO->SetContext(renWin); + } + unsigned int dims[2]; + vtkIdType increments[2]; + dims[0]=static_cast(xsize); + dims[1]=static_cast(ysize); + increments[0]=0; + increments[1]=0; + this->PBO->Upload2D(VTK_UNSIGNED_CHAR,resultData,dims,bytesPerPixel, + increments); + // non-blocking call + this->PBO->Bind(vtkPixelBufferObject::UNPACKED_BUFFER); + glTexImage2D( GL_TEXTURE_2D, 0 , internalFormat, + xsize, ysize, 0, format, + GL_UNSIGNED_BYTE,0); + myWidth = xsize; + myHeight = ysize; + this->PBO->UnBind(); + } + else + { + // blocking call + glTexImage2D( GL_TEXTURE_2D, 0 , internalFormat, + xsize, ysize, 0, format, + GL_UNSIGNED_BYTE, + static_cast(resultData) ); + myWidth = xsize; + myHeight = ysize; + } +#ifndef GL_VERSION_1_1 + glEndList (); +#endif + // modify the load time to the current time + this->LoadTime.Modified(); + + // free memory + if (resultData != dataPtr) + { + delete [] resultData; + } + } + + // execute the display list that uses creates the texture +#ifdef GL_VERSION_1_1 + glBindTexture(GL_TEXTURE_2D, this->Index); +#else + glCallList(this->Index); +#endif + + // don't accept fragments if they have zero opacity. this will stop the + // zbuffer from be blocked by totally transparent texture fragments. + glAlphaFunc (GL_GREATER, static_cast(0)); + glEnable (GL_ALPHA_TEST); + + if (this->PremultipliedAlpha) + { + // save the blend function. + glPushAttrib(GL_COLOR_BUFFER_BIT); + + // make the blend function correct for textures premultiplied by alpha. + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + + // now bind it + glEnable(GL_TEXTURE_2D); + + // clear any texture transform + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + // build transformation + if (this->Transform) + { + double *mat = this->Transform->GetMatrix()->Element[0]; + double mat2[16]; + mat2[0] = mat[0]; + mat2[1] = mat[4]; + mat2[2] = mat[8]; + mat2[3] = mat[12]; + mat2[4] = mat[1]; + mat2[5] = mat[5]; + mat2[6] = mat[9]; + mat2[7] = mat[13]; + mat2[8] = mat[2]; + mat2[9] = mat[6]; + mat2[10] = mat[10]; + mat2[11] = mat[14]; + mat2[12] = mat[3]; + mat2[13] = mat[7]; + mat2[14] = mat[11]; + mat2[15] = mat[15]; + + // insert texture transformation + glMultMatrixd(mat2); + } + glMatrixMode(GL_MODELVIEW); + + GLint uUseTexture=-1; + GLint uTexture=-1; + + vtkOpenGLRenderer *oRenderer=static_cast(ren); + +/* if(oRenderer->GetDepthPeelingHigherLayer()) + { + uUseTexture=oRenderer->GetUseTextureUniformVariable(); + uTexture=oRenderer->GetTextureUniformVariable(); + vtkgl::Uniform1i(uUseTexture,1); + vtkgl::Uniform1i(uTexture,0); // active texture 0 + } + */ +} + +void VTKViewer_Texture::Initialize(vtkRenderer * vtkNotUsed(ren)) +{ +} + +int VTKViewer_Texture::GetWidth() const +{ + return myWidth; +} + +int VTKViewer_Texture::GetHeight() const +{ + return myHeight; +} + +void VTKViewer_Texture::SetPosition(int pos) +{ + myPosition = pos; +} + +int VTKViewer_Texture::GetPosition() const +{ + return myPosition; +} diff --git a/src/VTKViewer/VTKViewer_Texture.h b/src/VTKViewer/VTKViewer_Texture.h new file mode 100644 index 000000000..b17028a34 --- /dev/null +++ b/src/VTKViewer/VTKViewer_Texture.h @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SALOME VTKViewer : build VTK viewer into Salome desktop +// File : +// Author : +// Module : +// $Header$ +// + +#ifndef VTKVIEWER_TEXTURE_H +#define VTKVIEWER_TEXTURE_H + +#include "VTKViewer.h" +#include + +#ifdef WIN32 +#pragma warning ( disable:4251 ) +#endif + +class vtkRenderer; + +class VTKVIEWER_EXPORT VTKViewer_Texture : public vtkOpenGLTexture +{ +public: + enum { Stretched = 0, Centered, Tiled }; + +public: + static VTKViewer_Texture *New(); + vtkTypeMacro(VTKViewer_Texture,vtkOpenGLTexture); + + virtual void Load(vtkRenderer *ren); + + int GetWidth() const; + int GetHeight() const; + + void SetPosition(int type); + int GetPosition() const; + +protected: + VTKViewer_Texture(); + ~VTKViewer_Texture(); + + int myWidth; + int myHeight; + int myPosition; + +private: + virtual void Initialize(vtkRenderer * ren); +}; + +#endif diff --git a/src/VTKViewer/VTKViewer_ViewModel.cxx b/src/VTKViewer/VTKViewer_ViewModel.cxx index cc6bd480c..44cb5fd90 100755 --- a/src/VTKViewer/VTKViewer_ViewModel.cxx +++ b/src/VTKViewer/VTKViewer_ViewModel.cxx @@ -36,7 +36,7 @@ #include // VSR: Uncomment below line to allow texture background support in VTK viewer -// #define VTK_ENABLE_TEXTURED_BACKGROUND +#define VTK_ENABLE_TEXTURED_BACKGROUND bool _InitializeVtkWarningsCall() { @@ -67,7 +67,7 @@ QString VTKViewer_Viewer::backgroundData( QStringList& gradList, QIntList& idLis gradList << tr( "GT_VERTICALGRADIENT" ); // only vertical type of gradient is supported idList << VerticalGradient; // only vertical type of gradient is supported #ifdef VTK_ENABLE_TEXTURED_BACKGROUND - txtList << Qtx::StretchTexture; // only stretch texture mode is supported + txtList << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture; #endif return tr("BG_IMAGE_FILES"); } diff --git a/src/VTKViewer/VTKViewer_ViewWindow.cxx b/src/VTKViewer/VTKViewer_ViewWindow.cxx index 15458695e..3dfd85752 100755 --- a/src/VTKViewer/VTKViewer_ViewWindow.cxx +++ b/src/VTKViewer/VTKViewer_ViewWindow.cxx @@ -28,6 +28,8 @@ #include "VTKViewer_Trihedron.h" #include "VTKViewer_Transform.h" #include "VTKViewer_Utilities.h" +#include "VTKViewer_Texture.h" +#include "VTKViewer_OpenGLRenderer.h" #include #include @@ -37,7 +39,6 @@ #include #include -#include #include #include #include @@ -61,7 +62,7 @@ VTKViewer_ViewWindow::VTKViewer_ViewWindow( SUIT_Desktop* theDesktop, myTrihedron = VTKViewer_Trihedron::New(); myTransform = VTKViewer_Transform::New(); - myRenderer = vtkRenderer::New() ; + myRenderer = VTKViewer_OpenGLRenderer::New() ; myTrihedron->AddToRender( myRenderer ); @@ -539,7 +540,7 @@ void VTKViewer_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) aReader->SetFileName( fi.absoluteFilePath().toLatin1().constData() ); aReader->Update(); - vtkTexture* aTexture = vtkTexture::New(); + VTKViewer_Texture* aTexture = VTKViewer_Texture::New(); vtkImageMapToColors* aMap = 0; vtkAlgorithmOutput* anOutput; /* -- 2.39.2