]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
GUITHARE 2011. Issue 0000837: External 0020550: Dump VTK WIndows 7
authorouv <ouv@opencascade.com>
Thu, 15 Dec 2011 07:09:29 +0000 (07:09 +0000)
committerouv <ouv@opencascade.com>
Thu, 15 Dec 2011 07:09:29 +0000 (07:09 +0000)
src/SVTK/SVTK_FrameBuffer.cxx [new file with mode: 0644]
src/SVTK/SVTK_FrameBuffer.h [new file with mode: 0644]
src/SVTK/SVTK_ViewWindow.cxx
src/SVTK/SVTK_ViewWindow.h

diff --git a/src/SVTK/SVTK_FrameBuffer.cxx b/src/SVTK/SVTK_FrameBuffer.cxx
new file mode 100644 (file)
index 0000000..63f2d80
--- /dev/null
@@ -0,0 +1,202 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+//  File   : SVTK_FrameBuffer.cxx
+//  Module : SALOME
+//
+#include "SVTK_FrameBuffer.h"
+
+#include <utilities.h>
+
+#include <cstring>
+
+#ifndef WNT
+# ifndef GLX_GLXEXT_LEGACY
+#  define GLX_GLXEXT_LEGACY
+# endif
+# include <GL/glx.h>
+# include <dlfcn.h>
+#else
+# include <wingdi.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+
+#ifndef GL_FRAMEBUFFER_EXT
+#define GL_FRAMEBUFFER_EXT                0x8D40
+#endif
+
+#ifndef GL_RENDERBUFFER_EXT
+#define GL_RENDERBUFFER_EXT               0x8D41
+#endif
+
+#ifndef GL_COLOR_ATTACHMENT0_EXT
+#define GL_COLOR_ATTACHMENT0_EXT          0x8CE0
+#endif
+
+#ifndef GL_DEPTH_ATTACHMENT_EXT
+#define GL_DEPTH_ATTACHMENT_EXT           0x8D00
+#endif
+
+#ifndef GL_FRAMEBUFFER_COMPLETE_EXT
+#define GL_FRAMEBUFFER_COMPLETE_EXT       0x8CD5
+#endif
+
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+
+static PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL;
+static PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL;
+static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL;
+static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL;
+static PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL;
+static PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL;
+static PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL;
+static PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL;
+static PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL;
+static PFNGLDELETERENDERBUFFERSEXTPROC vglDeleteRenderbuffersEXT = NULL;
+
+#ifndef WNT
+#define GL_GetProcAddress( x ) glXGetProcAddressARB( (const GLubyte*)x )
+#else
+#define GL_GetProcAddress( x ) wglGetProcAddress( (const LPCSTR)x )
+#endif
+
+bool InitializeEXT()
+{
+  vglGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glGenFramebuffersEXT" );
+  vglBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)GL_GetProcAddress( "glBindFramebufferEXT" );
+  vglFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)GL_GetProcAddress( "glFramebufferTexture2DEXT" );
+  vglCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)GL_GetProcAddress( "glCheckFramebufferStatusEXT" );
+  vglDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteFramebuffersEXT" );
+  vglGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)GL_GetProcAddress( "glGenRenderbuffersEXT" );
+  vglBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)GL_GetProcAddress( "glBindRenderbufferEXT" );
+  vglRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)GL_GetProcAddress( "glRenderbufferStorageEXT" );
+  vglFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)GL_GetProcAddress( "glFramebufferRenderbufferEXT" );
+  vglDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)GL_GetProcAddress( "glDeleteRenderbuffersEXT" );
+
+  bool ok = vglGenFramebuffersEXT && vglBindFramebufferEXT && vglFramebufferTexture2DEXT &&
+            vglCheckFramebufferStatusEXT && vglDeleteFramebuffersEXT && vglGenRenderbuffersEXT &&
+            vglBindRenderbufferEXT && vglRenderbufferStorageEXT && vglFramebufferRenderbufferEXT &&
+            vglDeleteRenderbuffersEXT;
+
+  return ok;
+}
+
+static bool IsEXTInitialized = InitializeEXT();
+
+SVTK_FrameBuffer::SVTK_FrameBuffer()
+  : textureId( 0 ),
+    fboId( 0 ),
+    rboId( 0 )
+{
+}
+
+SVTK_FrameBuffer::~SVTK_FrameBuffer()
+{
+  release();
+}
+
+bool SVTK_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize )
+{
+  char* ext = (char*)glGetString( GL_EXTENSIONS );
+  if( !IsEXTInitialized ||
+      strstr( ext, "GL_EXT_framebuffer_object" ) == NULL )
+  {
+    MESSAGE( "Initializing OpenGL FrameBuffer extension failed" );
+    return false;
+  }
+
+  // create a texture object
+  glEnable( GL_TEXTURE_2D );
+  glGenTextures( 1, &textureId );
+  glBindTexture( GL_TEXTURE_2D, textureId );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, xSize, ySize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
+  glBindTexture( GL_TEXTURE_2D, 0 );
+
+  // create a renderbuffer object to store depth info
+  vglGenRenderbuffersEXT( 1, &rboId );
+  vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rboId );
+  vglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, xSize, ySize );
+  vglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
+
+  // create a framebuffer object
+  vglGenFramebuffersEXT( 1, &fboId );
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+
+  // attach the texture to FBO color attachment point
+  vglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0 );
+
+  // attach the renderbuffer to depth attachment point
+  vglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId );
+
+  // check FBO status
+  GLenum status = vglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
+
+  // Unbind FBO
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+
+  return status == GL_FRAMEBUFFER_COMPLETE_EXT;
+}
+
+void SVTK_FrameBuffer::release()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  glDeleteTextures( 1, &textureId );
+  textureId = 0;
+
+  vglDeleteFramebuffersEXT( 1, &fboId );
+  fboId = 0;
+
+  vglDeleteRenderbuffersEXT( 1, &rboId );
+  rboId = 0;
+}
+
+void SVTK_FrameBuffer::bind()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId );
+}
+
+void SVTK_FrameBuffer::unbind()
+{
+  if( !IsEXTInitialized )
+    return;
+
+  vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+}
diff --git a/src/SVTK/SVTK_FrameBuffer.h b/src/SVTK/SVTK_FrameBuffer.h
new file mode 100644 (file)
index 0000000..07224e0
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+//  File   : SVTK_FrameBuffer.h
+//  Module : SALOME
+//
+#ifndef SVTK_FRAMEBUFFER_H
+#define SVTK_FRAMEBUFFER_H
+
+#include "SVTK.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <GL/gl.h>
+
+class SVTK_EXPORT SVTK_FrameBuffer
+{
+public:
+  SVTK_FrameBuffer();
+  ~SVTK_FrameBuffer();
+
+  bool init( const GLsizei&, const GLsizei& );
+  void release();
+
+  void bind();
+  void unbind();
+
+private:
+  GLuint textureId;
+  GLuint fboId;
+  GLuint rboId;
+};
+
+#endif
index 3093d1ba5c41e6f65b3fcd0e0da76d85225c6240..abfe67de31b79b73d05ed293c7ae11b2ee593773 100755 (executable)
@@ -73,6 +73,7 @@
 #include "SVTK_Selector.h"
 #include "SVTK_Recorder.h"
 #include "SVTK_RecorderDlg.h"
+#include "SVTK_FrameBuffer.h"
 
 #include "SALOME_ListIteratorOfListIO.hxx"
 
@@ -862,17 +863,61 @@ void SVTK_ViewWindow::RemoveActor( VTKViewer_Actor* theActor,
   emit actorRemoved(theActor);
 }
 
+/*!
+  Auxiliary method intended to dump contents of the view to an image
+*/
+QImage SVTK_ViewWindow::dumpViewContent()
+{
+  vtkRenderWindow* aWindow = getRenderWindow();
+  int* aSize = aWindow->GetSize();
+  int aWidth = aSize[0];
+  int aHeight = aSize[1];
+  
+  SVTK_FrameBuffer aFrameBuffer;
+  if( aFrameBuffer.init( aWidth, aHeight ) )
+  {
+    glPushAttrib( GL_VIEWPORT_BIT );
+    glViewport( 0, 0, aWidth, aHeight );
+    aFrameBuffer.bind();
+
+    // draw scene
+    aWindow->Render();
+
+    aFrameBuffer.unbind();
+    glPopAttrib();
+
+    QImage anImage( aWidth, aHeight, QImage::Format_RGB32 );
+
+    aFrameBuffer.bind();
+    glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
+    aFrameBuffer.unbind();
+
+    anImage = anImage.rgbSwapped();
+    anImage = anImage.mirrored();
+    return anImage;
+  }
+
+  // if frame buffers are unsupported, use old functionality
+  unsigned char *aData = 
+    aWindow->GetRGBACharPixelData( 0, 0, aWidth-1, aHeight-1, 0 );
+  
+  QImage anImage( aData, aWidth, aHeight, QImage::Format_ARGB32 );
+
+  anImage = anImage.rgbSwapped();
+  anImage = anImage.mirrored();
+  return anImage;
+}
+
 /*!
   \return QImage, containing all scene rendering in window
 */
 QImage SVTK_ViewWindow::dumpView()
 {
-//   if ( myMainWindow->getToolBar()->testAttribute(Qt::WA_UnderMouse) || myDumpImage.isNull() )
-//     return myMainWindow->dumpView();
-  
-//   return myDumpImage;
-  QPixmap px = QPixmap::grabWindow( GetInteractor()->winId() );
-  return px.toImage();
+  if( myDumpImage.isNull() )
+    return dumpViewContent();
+
+  RefreshDumpImage();
+  return myDumpImage;
 }
 
 QString SVTK_ViewWindow::filter() const
@@ -919,9 +964,7 @@ bool SVTK_ViewWindow::dumpViewToFormat( const QImage& img, const QString& fileNa
 */
 void SVTK_ViewWindow::RefreshDumpImage()
 {
-  //myDumpImage = myMainWindow->dumpView();
-  QPixmap px = QPixmap::grabWindow( GetInteractor()->winId() );
-  myDumpImage = px.toImage();
+  myDumpImage = dumpViewContent();
 }
 
 /*!
index b3b8ba34e5a6214a8b48a5bed8fe1ea964c0c89b..0afebefcedf4d1c9dd532bc7a33cc48d72fc3d72 100755 (executable)
@@ -345,6 +345,8 @@ protected:
   void doSetVisualParameters( const QString& );
   void SetEventDispatcher(vtkObject* theDispatcher);
 
+  QImage dumpViewContent();
+
   virtual QString filter() const;
   virtual bool dumpViewToFormat( const QImage& img, const QString& fileName, const QString& format );