Use framebuffer object as fallback for off-screen rendering
This commit is contained in:
parent
e5224f1140
commit
c6b02da648
|
@ -29,6 +29,7 @@
|
|||
# include <QByteArray>
|
||||
# include <QDateTime>
|
||||
# include <QImage>
|
||||
# include <QGLFramebufferObject>
|
||||
#endif
|
||||
|
||||
#include "Thumbnail.h"
|
||||
|
@ -85,24 +86,17 @@ void Thumbnail::SaveDocFile (Base::Writer &writer) const
|
|||
if (!this->viewer)
|
||||
return;
|
||||
QImage img;
|
||||
try {
|
||||
this->viewer->savePicture(this->size, this->size, View3DInventorViewer::Current, img);
|
||||
// Alternative way of off-screen rendering
|
||||
#if 0
|
||||
QGLFramebufferObject fbo(this->size, this->size,QGLFramebufferObject::Depth);
|
||||
fbo.bind();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDepthRange(0.1,1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
SoGLRenderAction gl(SbViewportRegion(this->size,this->size));
|
||||
gl.apply(this->viewer->getSceneManager()->getSceneGraph());
|
||||
fbo.release();
|
||||
img = fbo.toImage();
|
||||
#endif
|
||||
if (App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Document")->GetBool("DisablePBuffers",false)) {
|
||||
this->createThumbnailFromFramebuffer(img);
|
||||
}
|
||||
catch (...) {
|
||||
return; // offscreen rendering failed
|
||||
else {
|
||||
try {
|
||||
this->viewer->savePicture(this->size, this->size, View3DInventorViewer::Current, img);
|
||||
}
|
||||
catch (...) {
|
||||
this->createThumbnailFromFramebuffer(img);
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap px = Gui::BitmapFactory().pixmap(App::Application::Config()["AppIcon"].c_str());
|
||||
|
@ -126,3 +120,11 @@ void Thumbnail::SaveDocFile (Base::Writer &writer) const
|
|||
void Thumbnail::RestoreDocFile(Base::Reader &reader)
|
||||
{
|
||||
}
|
||||
|
||||
void Thumbnail::createThumbnailFromFramebuffer(QImage& img) const
|
||||
{
|
||||
// Alternative way of off-screen rendering
|
||||
QGLFramebufferObject fbo(this->size, this->size,QGLFramebufferObject::Depth);
|
||||
this->viewer->renderToFramebuffer(&fbo);
|
||||
img = fbo.toImage();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <Base/Persistence.h>
|
||||
#include <QUrl>
|
||||
|
||||
class QImage;
|
||||
|
||||
namespace Gui {
|
||||
class View3DInventorViewer;
|
||||
|
||||
|
@ -53,6 +55,9 @@ public:
|
|||
void RestoreDocFile(Base::Reader &reader);
|
||||
//@}
|
||||
|
||||
private:
|
||||
void createThumbnailFromFramebuffer(QImage&) const;
|
||||
|
||||
private:
|
||||
QUrl uri;
|
||||
View3DInventorViewer* viewer;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
# include <QAction>
|
||||
# include <QApplication>
|
||||
# include <QFileInfo>
|
||||
# include <QGLFramebufferObject>
|
||||
# include <QKeyEvent>
|
||||
# include <QEvent>
|
||||
# include <QDropEvent>
|
||||
|
@ -483,12 +484,38 @@ void View3DInventor::print(QPrinter* printer)
|
|||
QImage img;
|
||||
QPainter p(printer);
|
||||
QRect rect = printer->pageRect();
|
||||
_viewer->savePicture(rect.width(), rect.height(), View3DInventorViewer::White, img);
|
||||
|
||||
if (App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Document")->GetBool("DisablePBuffers",false)) {
|
||||
previewFromFramebuffer(rect, img);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
_viewer->savePicture(rect.width(), rect.height(), View3DInventorViewer::White, img);
|
||||
}
|
||||
catch (...) {
|
||||
previewFromFramebuffer(rect, img);
|
||||
}
|
||||
}
|
||||
|
||||
p.drawImage(0,0,img);
|
||||
p.end();
|
||||
#endif
|
||||
}
|
||||
|
||||
void View3DInventor::previewFromFramebuffer(const QRect& rect, QImage& img)
|
||||
{
|
||||
QGLFramebufferObject fbo(rect.width(), rect.height(), QGLFramebufferObject::Depth);
|
||||
const SbColor col = _viewer->getBackgroundColor();
|
||||
bool on = _viewer->hasGradientBackground();
|
||||
_viewer->setBackgroundColor(SbColor(1.0f,1.0f,1.0f));
|
||||
_viewer->setGradientBackground(false);
|
||||
_viewer->renderToFramebuffer(&fbo);
|
||||
_viewer->setBackgroundColor(col);
|
||||
_viewer->setGradientBackground(on);
|
||||
img = fbo.toImage();
|
||||
}
|
||||
|
||||
// **********************************************************************************
|
||||
|
||||
bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
|
||||
|
|
|
@ -127,6 +127,7 @@ protected:
|
|||
void focusInEvent (QFocusEvent * e);
|
||||
void customEvent (QEvent * e);
|
||||
void contextMenuEvent (QContextMenuEvent*e);
|
||||
void previewFromFramebuffer(const QRect&, QImage&);
|
||||
|
||||
/// handle to the viewer parameter group
|
||||
ParameterGrp::handle hGrp;
|
||||
|
|
|
@ -430,6 +430,11 @@ void View3DInventorViewer::setGradientBackground(bool on)
|
|||
backgroundroot->removeChild(pcBackGround);
|
||||
}
|
||||
|
||||
bool View3DInventorViewer::hasGradientBackground() const
|
||||
{
|
||||
return (backgroundroot->findChild(pcBackGround) != -1);
|
||||
}
|
||||
|
||||
void View3DInventorViewer::setGradientBackgroundColor(const SbColor& fromColor,
|
||||
const SbColor& toColor)
|
||||
{
|
||||
|
@ -577,7 +582,6 @@ void View3DInventorViewer::savePicture(const char* filename, int w, int h,
|
|||
throw Base::Exception("Offscreen rendering failed");
|
||||
// set matrix for miba
|
||||
renderer._Matrix = camera->getViewVolume().getMatrix();
|
||||
//bool ok = renderer.writeToImageFile(filename, filetypeextension);
|
||||
renderer.writeToImageFile(filename, comment);
|
||||
root->unref();
|
||||
}
|
||||
|
@ -941,6 +945,8 @@ void View3DInventorViewer::renderToFramebuffer(QGLFramebufferObject* fbo)
|
|||
{
|
||||
this->glLockNormal();
|
||||
fbo->bind();
|
||||
int width = fbo->size().width();
|
||||
int height = fbo->size().height();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
@ -948,12 +954,13 @@ void View3DInventorViewer::renderToFramebuffer(QGLFramebufferObject* fbo)
|
|||
glEnable(GL_LINE_SMOOTH);
|
||||
|
||||
const SbColor col = this->getBackgroundColor();
|
||||
glClearColor(col[0], col[1], col[2], 0.0f);
|
||||
glViewport(0, 0, width, height);
|
||||
glClearColor(col[0], col[1], col[2], 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glDepthRange(0.1,1.0);
|
||||
|
||||
SoGLRenderAction gl(SbViewportRegion(fbo->size().width(),fbo->size().height()));
|
||||
SoGLRenderAction gl(SbViewportRegion(width, height));
|
||||
gl.apply(this->backgroundroot);
|
||||
gl.apply(this->getSceneManager()->getSceneGraph());
|
||||
gl.apply(this->foregroundroot);
|
||||
|
|
|
@ -269,6 +269,7 @@ public:
|
|||
void viewSelection();
|
||||
|
||||
void setGradientBackground(bool b);
|
||||
bool hasGradientBackground() const;
|
||||
void setGradientBackgroundColor(const SbColor& fromColor,
|
||||
const SbColor& toColor);
|
||||
void setGradientBackgroundColor(const SbColor& fromColor,
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#ifndef __InventorAll__
|
||||
# include "InventorAll.h"
|
||||
# include <sstream>
|
||||
# include <QImage>
|
||||
# include <QGLFramebufferObject>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -556,6 +558,37 @@ Py::Object View3DInventorPy::isAnimationEnabled(const Py::Tuple& args)
|
|||
return Py::Boolean(ok ? true : false);
|
||||
}
|
||||
|
||||
void View3DInventorPy::createImageFromFramebuffer(int backgroundType, int width, int height, QImage& img)
|
||||
{
|
||||
QGLFramebufferObject fbo(width, height, QGLFramebufferObject::Depth);
|
||||
const SbColor col = _view->getViewer()->getBackgroundColor();
|
||||
bool on = _view->getViewer()->hasGradientBackground();
|
||||
|
||||
switch(backgroundType){
|
||||
case 0: // Current
|
||||
break;
|
||||
case 1: // Black
|
||||
_view->getViewer()->setBackgroundColor(SbColor(0.0f,0.0f,0.0f));
|
||||
_view->getViewer()->setGradientBackground(false);
|
||||
break;
|
||||
case 2: // White
|
||||
_view->getViewer()->setBackgroundColor(SbColor(1.0f,1.0f,1.0f));
|
||||
_view->getViewer()->setGradientBackground(false);
|
||||
break;
|
||||
case 3: // Transparent
|
||||
_view->getViewer()->setBackgroundColor(SbColor(1.0f,1.0f,1.0f));
|
||||
_view->getViewer()->setGradientBackground(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_view->getViewer()->renderToFramebuffer(&fbo);
|
||||
_view->getViewer()->setBackgroundColor(col);
|
||||
_view->getViewer()->setGradientBackground(on);
|
||||
img = fbo.toImage();
|
||||
}
|
||||
|
||||
Py::Object View3DInventorPy::saveImage(const Py::Tuple& args)
|
||||
{
|
||||
char *cFileName,*cImageType="Current",*cComment="$MIBA";
|
||||
|
@ -587,24 +620,23 @@ Py::Object View3DInventorPy::saveImage(const Py::Tuple& args)
|
|||
else
|
||||
throw Py::Exception("Parameter 4 have to be (Current|Black|White|Transparent)");
|
||||
#endif
|
||||
if (App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Document")->GetBool("DisablePBuffers",false)) {
|
||||
QImage img;
|
||||
createImageFromFramebuffer(t, w, h, img);
|
||||
img.save(QString::fromUtf8(cFileName));
|
||||
return Py::None();
|
||||
}
|
||||
|
||||
try {
|
||||
QColor c;
|
||||
_view->getViewer()->savePicture(cFileName,w,h,t,cComment);
|
||||
return Py::None();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Log("Try disabling the use of pbuffers, set the environment variables\n"
|
||||
"COIN_GLXGLUE_NO_PBUFFERS=1\n"
|
||||
"COIN_GLXGLUE_NO_GLX13_PBUFFERS=1\n"
|
||||
"and re-run the application.\n");
|
||||
throw Py::Exception(e.what());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
throw Py::Exception(e.what());
|
||||
}
|
||||
catch(...) {
|
||||
throw Py::Exception("Unknown C++ exception");
|
||||
catch (const Base::Exception&) {
|
||||
QImage img;
|
||||
createImageFromFramebuffer(t, w, h, img);
|
||||
img.save(QString::fromUtf8(cFileName));
|
||||
return Py::None();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <CXX/Extensions.hxx>
|
||||
|
||||
class SoEventCallback;
|
||||
class QImage;
|
||||
|
||||
namespace Gui {
|
||||
|
||||
|
@ -102,6 +103,7 @@ private:
|
|||
typedef PyObject* (*method_varargs_handler)(PyObject *_self, PyObject *_args);
|
||||
static method_varargs_handler pycxx_handler;
|
||||
static PyObject *method_varargs_ext_handler(PyObject *_self, PyObject *_args);
|
||||
void createImageFromFramebuffer(int backgroundType, int width, int height, QImage&);
|
||||
|
||||
private:
|
||||
std::list<PyObject*> callbacks;
|
||||
|
|
Loading…
Reference in New Issue
Block a user