From 79ae5e39c09f0ef35fde91d78d2a451062da3c52 Mon Sep 17 00:00:00 2001 From: ouv Date: Mon, 18 Jan 2010 16:42:58 +0000 Subject: [PATCH] Issue 0020645: EDF VISU SMESH: the dump view command does not remove popup menu --- configure.ac | 1 + src/Makefile.am | 4 +- src/OCCViewer/Makefile.am | 4 +- src/OCCViewer/OCCViewer_ViewWindow.cxx | 37 ++++- src/OpenGLUtils/Makefile.am | 38 +++++ src/OpenGLUtils/OpenGLUtils.h | 39 +++++ src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx | 151 ++++++++++++++++++++ src/OpenGLUtils/OpenGLUtils_FrameBuffer.h | 50 +++++++ src/SVTK/Makefile.am | 6 +- src/SVTK/SVTK_ViewWindow.cxx | 27 ++++ 10 files changed, 347 insertions(+), 10 deletions(-) create mode 100755 src/OpenGLUtils/Makefile.am create mode 100755 src/OpenGLUtils/OpenGLUtils.h create mode 100755 src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx create mode 100755 src/OpenGLUtils/OpenGLUtils_FrameBuffer.h diff --git a/configure.ac b/configure.ac index 865c233e1..a666c53d5 100644 --- a/configure.ac +++ b/configure.ac @@ -633,6 +633,7 @@ AC_OUTPUT([ \ src/ResExporter/Makefile \ src/TOOLSGUI/Makefile \ src/Event/Makefile \ + src/OpenGLUtils/Makefile \ src/Session/Makefile \ src/SalomeApp/Makefile \ src/SalomeApp/Test/Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index d322b8a97..7ebc87fed 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,7 +28,7 @@ ## # Common packages ## -SUBDIRS_COMMON = CASCatch Qtx Style DDS QDS ObjBrowser SUIT SUITApp STD CAF CAM LogWindow Prs Event +SUBDIRS_COMMON = CASCatch Qtx Style DDS QDS ObjBrowser SUIT SUITApp STD CAF CAM LogWindow Prs Event OpenGLUtils ## # SALOME object @@ -120,6 +120,6 @@ SUBDIRS = $(SUBDIRS_COMMON) $(SUBDIRS_OBJECT) $(SUBDIRS_GLVIEWER) $(SUBDIRS_VTKV $(SUBDIRS_PLOT2DVIEWER) $(SUBDIRS_SUPERVGRAPHVIEWER) $(SUBDIRS_QXGRAPHVIEWER) $(SUBDIRS_PYCONSOLE) \ $(SUBDIRS_LIGHT) $(SUBDIRS_CORBA) $(SUBDIRS_PY_LIGHT) -DIST_SUBDIRS = CASCatch Qtx Style DDS QDS ObjBrowser SUIT SUITApp STD CAF CAM LogWindow Prs Event \ +DIST_SUBDIRS = CASCatch Qtx Style DDS QDS ObjBrowser SUIT SUITApp STD CAF CAM LogWindow Prs Event OpenGLUtils \ OBJECT GLViewer VTKViewer SVTK OCCViewer SOCC Plot2d SPlot2d SUPERVGraph QxGraph QxScene \ PyInterp PyConsole LightApp ResExporter TOOLSGUI Session SalomeApp SALOME_SWIG SALOME_PY SALOME_PYQT diff --git a/src/OCCViewer/Makefile.am b/src/OCCViewer/Makefile.am index 00ddf2311..c2041a5d8 100755 --- a/src/OCCViewer/Makefile.am +++ b/src/OCCViewer/Makefile.am @@ -106,7 +106,7 @@ nodist_salomeres_DATA = \ OCCViewer_msg_en.qm libOCCViewer_la_CPPFLAGS = $(QT_INCLUDES) $(OGL_INCLUDES) $(CAS_CPPFLAGS) \ - -I$(srcdir)/../SUIT -I$(srcdir)/../Qtx + -I$(srcdir)/../SUIT -I$(srcdir)/../Qtx -I$(srcdir)/../OpenGLUtils libOCCViewer_la_LDFLAGS = $(OGL_LIBS) $(QT_MT_LIBS) $(CAS_KERNEL) $(CAS_VIEWER) -libOCCViewer_la_LIBADD = ../Qtx/libqtx.la ../SUIT/libsuit.la +libOCCViewer_la_LIBADD = ../Qtx/libqtx.la ../SUIT/libsuit.la ../OpenGLUtils/libOpenGLUtils.la diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 977c462b8..7bef0551e 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -43,6 +43,8 @@ #include #include +#include + #include #include #include @@ -1432,22 +1434,49 @@ QImage OCCViewer_ViewWindow::dumpView() Handle(V3d_View) view = myViewPort->getView(); if ( view.IsNull() ) return QImage(); + int aWidth = myViewPort->width(); + int aHeight = myViewPort->height(); QApplication::syncX(); view->Update(); + + OpenGLUtils_FrameBuffer aFrameBuffer; + if( aFrameBuffer.init( aWidth, aHeight ) ) + { + glPushAttrib( GL_VIEWPORT_BIT ); + glViewport( 0, 0, aWidth, aHeight ); + aFrameBuffer.bind(); + + // draw scene + view->Redraw(); + + 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 view->Redraw(); - unsigned char* data = new unsigned char[ (myViewPort->width()*myViewPort->height())*4 ]; + unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft()); - glReadPixels( p.x(), p.y(), myViewPort->width(), myViewPort->height(), GL_RGBA, GL_UNSIGNED_BYTE, + glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); - QImage anImage( data, myViewPort->width(), myViewPort->height(), QImage::Format_ARGB32 ); + QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); anImage = anImage.mirrored(); anImage = anImage.rgbSwapped(); return anImage; - } bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, diff --git a/src/OpenGLUtils/Makefile.am b/src/OpenGLUtils/Makefile.am new file mode 100755 index 000000000..8ad207b19 --- /dev/null +++ b/src/OpenGLUtils/Makefile.am @@ -0,0 +1,38 @@ +# Copyright (C) 2007-2008 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 +# +# File : Makefile.am +# Author : Oleg UVAROV +# Module : SALOME +# $Header$ +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = libOpenGLUtils.la + +salomeinclude_HEADERS = \ + OpenGLUtils_FrameBuffer.h + +dist_libOpenGLUtils_la_SOURCES = \ + OpenGLUtils_FrameBuffer.cxx + +libOpenGLUtils_la_CPPFLAGS = $(OGL_INCLUDES) +libOpenGLUtils_la_LDFLAGS = $(OGL_LIBS) diff --git a/src/OpenGLUtils/OpenGLUtils.h b/src/OpenGLUtils/OpenGLUtils.h new file mode 100755 index 000000000..4a4cb8b49 --- /dev/null +++ b/src/OpenGLUtils/OpenGLUtils.h @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2008 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 +// +#if !defined ( OPENGLUTILS_H ) +#define OPENGLUTILS_H + +#ifdef WIN32 +# if defined OPENGLUTILS_EXPORTS || defined OpenGLUtils_EXPORTS +# define OPENGLUTILS_EXPORT __declspec(dllexport) +# else +# define OPENGLUTILS_EXPORT __declspec(dllimport) +# endif +#else +# define OPENGLUTILS_EXPORT +#endif + +#if defined WIN32 +#pragma warning ( disable: 4251 ) +#endif + +#endif // OPENGLUTILS_H diff --git a/src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx new file mode 100755 index 000000000..164003661 --- /dev/null +++ b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.cxx @@ -0,0 +1,151 @@ +// Copyright (C) 2007-2008 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 +// +// File : OpenGLUtils_FrameBuffer.cxx +// Module : SALOME +// +#include "OpenGLUtils_FrameBuffer.h" + +#define GL_GLEXT_PROTOTYPES +#include + +#ifndef WNT +# ifndef GLX_GLXEXT_LEGACY +# define GLX_GLXEXT_LEGACY +# endif +# include +# include +#else +# include +#endif + +PFNGLGENFRAMEBUFFERSEXTPROC vglGenFramebuffersEXT = NULL; +PFNGLBINDFRAMEBUFFEREXTPROC vglBindFramebufferEXT = NULL; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC vglFramebufferTexture2DEXT = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC vglCheckFramebufferStatusEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC vglDeleteFramebuffersEXT = NULL; +PFNGLGENRENDERBUFFERSEXTPROC vglGenRenderbuffersEXT = NULL; +PFNGLBINDRENDERBUFFEREXTPROC vglBindRenderbufferEXT = NULL; +PFNGLRENDERBUFFERSTORAGEEXTPROC vglRenderbufferStorageEXT = NULL; +PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC vglFramebufferRenderbufferEXT = NULL; +PFNGLDELETEFRAMEBUFFERSEXTPROC 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(); + +OpenGLUtils_FrameBuffer::OpenGLUtils_FrameBuffer() + : textureId( 0 ), + fboId( 0 ), + rboId( 0 ) +{ +} + +OpenGLUtils_FrameBuffer::~OpenGLUtils_FrameBuffer() +{ + release(); +} + +bool OpenGLUtils_FrameBuffer::init( const GLsizei& xSize, const GLsizei& ySize ) +{ + if( !IsEXTInitialized ) + 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 OpenGLUtils_FrameBuffer::release() +{ + glDeleteTextures( 1, &textureId ); + textureId = 0; + + vglDeleteFramebuffersEXT( 1, &fboId ); + fboId = 0; + + vglDeleteRenderbuffersEXT( 1, &rboId ); + rboId = 0; +} + +void OpenGLUtils_FrameBuffer::bind() +{ + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboId ); +} + +void OpenGLUtils_FrameBuffer::unbind() +{ + vglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); +} diff --git a/src/OpenGLUtils/OpenGLUtils_FrameBuffer.h b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.h new file mode 100755 index 000000000..b45e4bf1c --- /dev/null +++ b/src/OpenGLUtils/OpenGLUtils_FrameBuffer.h @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 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 +// +// File : OpenGLUtils_FrameBuffer.h +// Module : SALOME +// +#ifndef OPENGLUTILS_FRAMEBUFFER_H +#define OPENGLUTILS_FRAMEBUFFER_H + +#include "OpenGLUtils.h" + +#include + +class OPENGLUTILS_EXPORT OpenGLUtils_FrameBuffer +{ +public: + OpenGLUtils_FrameBuffer(); + ~OpenGLUtils_FrameBuffer(); + + bool init( const GLsizei&, const GLsizei& ); + void release(); + + void bind(); + void unbind(); + +private: + GLuint textureId; + GLuint fboId; + GLuint rboId; +}; + +#endif diff --git a/src/SVTK/Makefile.am b/src/SVTK/Makefile.am index 27976ea9d..b418bc123 100755 --- a/src/SVTK/Makefile.am +++ b/src/SVTK/Makefile.am @@ -144,7 +144,8 @@ libSVTK_la_CPPFLAGS = \ -I$(srcdir)/../SUIT \ -I$(srcdir)/../OBJECT \ -I$(srcdir)/../Prs \ - -I$(srcdir)/../VTKViewer + -I$(srcdir)/../VTKViewer \ + -I$(srcdir)/../OpenGLUtils libSVTK_la_LDFLAGS = \ $(VTK_LIBS) $(OGL_LIBS) \ @@ -153,7 +154,8 @@ libSVTK_la_LDFLAGS = \ libSVTK_la_LIBADD = ../Qtx/libqtx.la ../SUIT/libsuit.la ../OBJECT/libSalomeObject.la \ - ../Prs/libSalomePrs.la ../VTKViewer/libVTKViewer.la + ../Prs/libSalomePrs.la ../VTKViewer/libVTKViewer.la \ + ../OpenGLUtils/libOpenGLUtils.la # Executable bin_PROGRAMS = SVTK diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 2fdc252a6..ab1628603 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -82,6 +82,8 @@ #include "VTKViewer_Algorithm.h" #include "SVTK_Functor.h" +#include + namespace SVTK { @@ -828,6 +830,31 @@ QImage SVTK_ViewWindow::dumpViewContent() int aWidth = aSize[0]; int aHeight = aSize[1]; + OpenGLUtils_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 ); -- 2.39.2