PDA

View Full Version : Snap openGL image with transparent background



aftos
30th June 2014, 06:40
Hi all,
i'm trying to capture an image from a QGLWidget's back buffer (so, no redraw must be seen from user) into a QImage having a transparent background, but the alpha value always return 255. Here's what i did (till now):

I have reimplemented QGLWidget to myGLWidget:


myGLWidget::myGLWidget
{
setAutoBufferSwap(false);
takingSnapshot = false; // member variable. When taking snapshot turns true
}

void myGLWidget::initializeGL()
{
glClearColor(1., 1., 1., 0.);
}

void myGLWidget::resizeGL(int ww, int hh)
{
glViewport(0, 0, (GLint)ww, (GLint)hh);
}

void myGLWidget::paintGL()
{
qDebug() << "paintGL";

glPushAttrib(GL_TRANSFORM_BIT);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glOrtho(-1., 1., -1., 1., -1., 1.);


/* Clear screen */
if (takingSnapshot) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0., 0., 1., 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);
} else {
glClearColor(1., 1., 0., 1.);
glClear(GL_COLOR_BUFFER_BIT);
}


/* Begin Draw */
glColor4f(1., 0., 0., 1.);
glLineWidth(10);

glBegin(GL_LINES);
glVertex2f(-0.3, 0.0);
glVertex2f(0.3, 0.0);
glEnd();

glEnable(GL_BLEND);
glColor4f(0., 1., 0., 0.4);
glRotatef(90., 0., 0., 1.);
glBegin(GL_LINES);
glVertex2f(-0.3, 0.0);
glVertex2f(0.3, 0.0);
glEnd();

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();

glPopAttrib();
glDisable(GL_BLEND);

if (!takingSnapshot) {
swapBuffers();
} else {
qDebug() << "Finished drawing after snapshot\n";
}
}


And here is my mainWindow ( MainWindow : public QMainWindow):


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
mainFrame = new QFrame(this);
setCentralWidget(mainFrame);

mainLay = new QVBoxLayout(mainFrame);
mainFrame->setLayout(mainLay);

glw = new myGLWidget(mainFrame);
snap = new QPushButton("Snap", mainFrame);
label = new QLabel(mainFrame);

mainLay->addWidget(glw);
mainLay->addWidget(snap);
mainLay->addWidget(label);

mainFrame->show();
glw->show();
snap->show();
label->show();

QObject::connect(snap,SIGNAL(clicked()),this,SLOT( takeImage()));
}

static QImage createQImage(const unsigned char *image2, int ww, int hh)
{
/* Do some stuff here with "image2" */
/* and return the final image */
}

void MainWindow::takeImage()
{
int ww = glw->width();
int hh = glw->height();
QImage finalImage;
GLubyte *image = (GLubyte *)malloc(ww * hh * sizeof(GLubyte) * 4);

glw->takingSnapshot = true;
glPushAttrib(GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT); // readBuffer + drawBuffer
glReadBuffer(GL_BACK);
glDrawBuffer(GL_BACK);
qDebug() << "takeImage, will call updateGL";

glw->updateGL();
glReadPixels(0,0,ww,hh,GL_RGBA,GL_UNSIGNED_BYTE,im age);

finalImage = createQImage(image, ww, hh);

if (!finalImage.isNull()) {
QPixmap pix;
pix.convertFromImage(finalImage);
label->setPixmap(pix);
}
glPopAttrib();
glw->takingSnapshot = false;
if (image) free(image);
}


In function "createQImage", when i loop the pixels of "image2" and test the alpha value, as i said before, it is always 255! In order to check if i do something wrong with the created QImage in "createQImage", i forced a block of pixels to have 0 alpha and my final QImage had that block with 100% transparency.

Any ideas?

aftos
1st July 2014, 10:28
Bah! I solved it. Alpha buffer is disabled by default. I needed to enable it. It works fine :)