/*************************************************************************** * Copyright (c) 2005 Werner Mayer * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef GUI_SOFCOFFSCREENRENDERER_H #define GUI_SOFCOFFSCREENRENDERER_H #include #include #include #ifdef FC_OS_MACOSX # include #else # ifdef FC_OS_WIN32 # include # endif // FC_OS_WIN32 # include #endif // FC_OS_MACOSX #include #include #include class QOpenGLFramebufferObject; namespace Gui { /** * The SoFCOffscreenRenderer class is used for rendering scenes in offscreen buffers. * @author Werner Mayer */ class GuiExport SoFCOffscreenRenderer : public SoOffscreenRenderer { public: /** The SoOffscreenRenderer base class seems to have a huge memory leak. Whenever * an instance is created internal memory doesn't get freed when destroying it. * Thus, SoFCOffscreenRenderer is implemented as singleton to allow one to create only * one global instance. So, the memory is leaking for this instance only. */ static SoFCOffscreenRenderer& instance(); SoFCOffscreenRenderer(const SoFCOffscreenRenderer&) = delete; SoFCOffscreenRenderer& operator=(const SoFCOffscreenRenderer&) = delete; private: static SoFCOffscreenRenderer* inst; protected: /** * Constructor. Argument is the \a viewportregion we should use when rendering. An internal * SoGLRenderAction will be constructed. */ SoFCOffscreenRenderer (const SbViewportRegion &viewportregion); /** * Constructor. Argument is the \a action we should apply to the scene graph when rendering the * scene. Information about the viewport is extracted from the \a action. */ SoFCOffscreenRenderer (SoGLRenderAction *action); /** * Destructor. */ ~SoFCOffscreenRenderer(); public: /** * Writes the rendered image buffer directly into a QImage object * instead of an image file. */ void writeToImage (QImage&) const; /** * Saves the buffer to \a filename, in the filetype specified by \a filetypeextensions. * * Note that you must still specify the full filename for the first argument, i.e. the second argument will * not automatically be attached to the filename -- it is only used to decide the filetype. * * If \a comment is set to '$MIBA' information regarding the MIBA standard is * embedded to the picture, otherwise the \a comment is embedded as is. * The appropriate file format must support embedding meta information which * is provided by JPEG or PNG. * * This does basically the same as writeToFile() unless that all QImage file formats are supported if not * directly supported by Coin3D. */ void writeToImageFile(const char* filename, const char* comment, const SbMatrix& mat, const QImage& img); /** * This method returns all image file formats supported by Coin3D (see getWriteFiletypeInfo()) with all QImage file formats that are * not directly supported by Coin3D, if so. */ QStringList getWriteImageFiletypeInfo(); std::string createMIBA(const SbMatrix& mat) const; }; class GuiExport SoQtOffscreenRenderer { public: SoQtOffscreenRenderer(const SbViewportRegion & viewportregion); SoQtOffscreenRenderer(SoGLRenderAction * action); ~SoQtOffscreenRenderer(); void setViewportRegion(const SbViewportRegion & region); const SbViewportRegion & getViewportRegion() const; void setBackgroundColor(const SbColor4f & color); const SbColor4f & getBackgroundColor() const; void setGLRenderAction(SoGLRenderAction * action); SoGLRenderAction * getGLRenderAction() const; void setNumPasses(const int num); int getNumPasses() const; void setInternalTextureFormat(GLenum internalTextureFormat); GLenum internalTextureFormat() const; SbBool render(SoNode * scene); SbBool render(SoPath * scene); void writeToImage (QImage&) const; QStringList getWriteImageFiletypeInfo() const; private: void init(const SbViewportRegion & vpr, SoGLRenderAction * glrenderaction = nullptr); static void pre_render_cb(void * userdata, SoGLRenderAction * action); SbBool renderFromBase(SoBase * base); void makeFrameBuffer(int width, int height, int samples); QOpenGLFramebufferObject* framebuffer; uint32_t cache_context; // our unique context id SbViewportRegion viewport; SbColor4f backgroundcolor; SbColor4f backgroundopaque; SoGLRenderAction * renderaction; SbBool didallocation; int numSamples; GLenum texFormat; QImage glImage; }; } // namespace Gui #endif // GUI_SOFCOFFSCREENRENDERER_H