workaround to create images with transparent background
This commit is contained in:
@@ -478,6 +478,9 @@ void
|
||||
SoQtOffscreenRenderer::setBackgroundColor(const SbColor4f & color)
|
||||
{
|
||||
PRIVATE(this)->backgroundcolor = color;
|
||||
PRIVATE(this)->backgroundopaque = color;
|
||||
if (color[3] < 1.0)
|
||||
PRIVATE(this)->backgroundopaque.setValue(1,1,1,1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -556,8 +559,11 @@ SoQtOffscreenRenderer::makePixelBuffer(int width, int height, int samples)
|
||||
viewport.setWindowSize(width, height);
|
||||
|
||||
QGLFormat fmt;
|
||||
//With enabled alpha a transparent background is supported but
|
||||
//at the same time breaks semi-transparent models
|
||||
// With enabled alpha a transparent background is supported but
|
||||
// at the same time breaks semi-transparent models. A workaround
|
||||
// is to use a certain background color using GL_RGB as texture
|
||||
// format and in the output image search for the above color and
|
||||
// replaces it with the color requested by the user.
|
||||
//fmt.setAlpha(true);
|
||||
if (samples > 0) {
|
||||
fmt.setSampleBuffers(true);
|
||||
@@ -586,8 +592,11 @@ SoQtOffscreenRenderer::makeFrameBuffer(int width, int height, int samples)
|
||||
QtGLFramebufferObjectFormat fmt;
|
||||
fmt.setSamples(samples);
|
||||
fmt.setAttachment(QtGLFramebufferObject::Depth);
|
||||
//With enabled alpha a transparent background is supported but
|
||||
//at the same time breaks semi-transparent models
|
||||
// With enabled alpha a transparent background is supported but
|
||||
// at the same time breaks semi-transparent models. A workaround
|
||||
// is to use a certain background color using GL_RGB as texture
|
||||
// format and in the output image search for the above color and
|
||||
// replaces it with the color requested by the user.
|
||||
#if defined(HAVE_QT5_OPENGL)
|
||||
//fmt.setInternalTextureFormat(GL_RGBA32F_ARB);
|
||||
fmt.setInternalTextureFormat(GL_RGB32F_ARB);
|
||||
@@ -654,10 +663,10 @@ SoQtOffscreenRenderer::renderFromBase(SoBase * base)
|
||||
this->renderaction->setCacheContext(cache_context);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(this->backgroundcolor[0],
|
||||
this->backgroundcolor[1],
|
||||
this->backgroundcolor[2],
|
||||
this->backgroundcolor[3]);
|
||||
glClearColor(this->backgroundopaque[0],
|
||||
this->backgroundopaque[1],
|
||||
this->backgroundopaque[2],
|
||||
this->backgroundopaque[3]);
|
||||
|
||||
// needed to clear viewport after glViewport() is called from
|
||||
// SoGLRenderAction
|
||||
@@ -764,6 +773,30 @@ SoQtOffscreenRenderer::writeToImage (QImage& img) const
|
||||
#else
|
||||
img = this->glImage;
|
||||
#endif
|
||||
if (PRIVATE(this)->backgroundcolor[3] < 1.0) {
|
||||
QColor c1, c2;
|
||||
c1.setRedF(PRIVATE(this)->backgroundcolor[0]);
|
||||
c1.setGreenF(PRIVATE(this)->backgroundcolor[1]);
|
||||
c1.setBlueF(PRIVATE(this)->backgroundcolor[2]);
|
||||
c1.setAlphaF(PRIVATE(this)->backgroundcolor[3]);
|
||||
c2.setRedF(PRIVATE(this)->backgroundopaque[0]);
|
||||
c2.setGreenF(PRIVATE(this)->backgroundopaque[1]);
|
||||
c2.setBlueF(PRIVATE(this)->backgroundopaque[2]);
|
||||
c2.setAlphaF(PRIVATE(this)->backgroundopaque[3]);
|
||||
|
||||
QRgb rgba = c1.rgba();
|
||||
QRgb rgb = c2.rgb();
|
||||
QRgb * bits = (QRgb*) img.bits();
|
||||
int height = img.height();
|
||||
int width = img.width();
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (*bits == rgb)
|
||||
*bits = rgba;
|
||||
bits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -143,6 +143,7 @@ private:
|
||||
|
||||
SbViewportRegion viewport;
|
||||
SbColor4f backgroundcolor;
|
||||
SbColor4f backgroundopaque;
|
||||
SoGLRenderAction * renderaction;
|
||||
SbBool didallocation;
|
||||
SbBool pbuffer;
|
||||
|
||||
@@ -1420,8 +1420,11 @@ void View3DInventorViewer::imageFromFramebuffer(int width, int height, int sampl
|
||||
QtGLFramebufferObjectFormat fboFormat;
|
||||
fboFormat.setSamples(samples);
|
||||
fboFormat.setAttachment(QtGLFramebufferObject::Depth);
|
||||
//With enabled alpha a transparent background is supported but
|
||||
//at the same time breaks semi-transparent models
|
||||
// With enabled alpha a transparent background is supported but
|
||||
// at the same time breaks semi-transparent models. A workaround
|
||||
// is to use a certain background color using GL_RGB as texture
|
||||
// format and in the output image search for the above color and
|
||||
// replaces it with the color requested by the user.
|
||||
#if defined(HAVE_QT5_OPENGL)
|
||||
//fboFormat.setInternalTextureFormat(GL_RGBA32F_ARB);
|
||||
fboFormat.setInternalTextureFormat(GL_RGB32F_ARB);
|
||||
@@ -1434,8 +1437,14 @@ void View3DInventorViewer::imageFromFramebuffer(int width, int height, int sampl
|
||||
const QColor col = backgroundColor();
|
||||
bool on = hasGradientBackground();
|
||||
|
||||
if (bgcolor.isValid()) {
|
||||
setBackgroundColor(bgcolor);
|
||||
int alpha = 255;
|
||||
QColor bgopaque = bgcolor;
|
||||
if (bgopaque.isValid()) {
|
||||
// force an opaque background color
|
||||
alpha = bgopaque.alpha();
|
||||
if (alpha < 255)
|
||||
bgopaque.setRgb(255,255,255);
|
||||
setBackgroundColor(bgopaque);
|
||||
setGradientBackground(false);
|
||||
}
|
||||
|
||||
@@ -1443,6 +1452,20 @@ void View3DInventorViewer::imageFromFramebuffer(int width, int height, int sampl
|
||||
setBackgroundColor(col);
|
||||
setGradientBackground(on);
|
||||
img = fbo.toImage();
|
||||
|
||||
// if background color isn't opaque manipulate the image
|
||||
if (alpha < 255) {
|
||||
QRgb rgba = bgcolor.rgba();
|
||||
QRgb rgb = bgopaque.rgb();
|
||||
QRgb * bits = (QRgb*) img.bits();
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
if (*bits == rgb)
|
||||
*bits = rgba;
|
||||
bits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View3DInventorViewer::renderToFramebuffer(QtGLFramebufferObject* fbo)
|
||||
|
||||
Reference in New Issue
Block a user