Alternative to renderPixmap() when porting QGLWidget from Qt4 to Qt5

86 Views Asked by At

With Qt4, I had a custom class inherited from QGLWidget that tesselated polygons in paintGL(), which I then call renderPixmap() to output as an image. When I ported the code over to Qt5, renderPixmap() produces a blank image. I've tried following alternative ways to produce an image such as using QOpenGLFrameBufferObject https://bugreports.qt.io/browse/QTBUG-33186 and here https://bugreports.qt.io/browse/QTBUG-47185inheriting from QOpenGLWidget and using grab() or grabFrameBuffer() and nothing seems to work. I don't fully understand the code, just that it worked in Qt4. Please advise on what to change to output the tesselated polygons as an image in Qt5.

`

class MyGLWidget : public QGLWidget
{
    Q_OBJECT
public:
    MyGLWidget(const std::vector<BPolygon*> &polys) : QGLWidget(), mPolys(polys)

    void paintGL() override;
    void initializeGL() override;
    void resizeGL( int w, int h ) override;

private:
    std::vector<BPolygon *> mPolys;
};


void MyGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();
    glEnable(GL_CULL_FACE);
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

    MyTessellator tess;
    tess.boundary(false);
    tess.winding(GLU_TESS_WINDING_NONZERO);
    tess.beginPolygon();

    for(unsigned int i=0;i<mPolys.size();i++)
    {
        tess.beginContour();

        for(BPoint* p = mPolys[i]->first;p;)
        {
            tess.vertex(IceVector3(p->x,p->y,0.0));
            p = p->next;
            if(p == m_rvecPoly[i]->first)break;
        }

        tess.endContour();
    }

    tess.endPolygon();
}

void MyGLWidget::initializeGL()
{
    glClearColor(0, 0, 0, 0);
    glMatrixMode(GL_MODELVIEW);
    glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}

void MyGLWidget::resizeGL( int w, int h )
{
    glViewport(0, 0, w, h);
}

void MakeImage(const std::vector<BPolygon*>& polys, int w, int h)
{
    MyGLWidget mglWidget(polys);
    QPixmap pixmap = mglWidget.renderPixmap(w, h);
    QImage image2 = pixmap.toImage();
}

`

I've tried modifying the above to use QFrameBufferObject but it still produces a blank image:

`


void MyGLWidget::makeImage(const QString& imgFileName, w, h)
{
  makeCurrent(); // have to call this or the QOpengFLFramebufferObject crashes
  initializeGL();
  resizeGL(w, h);
  // Set the rendering engine to the size of the image to render
  // Also set the format so that the depth buffer will work
  QOpenGLFramebufferObjectFormat format;
  LogStatus("create");
  format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
  LogStatus("attach");

  QOpenGLFramebufferObject qfb(w, h, format);
  LogStatus("init");
  resizeGL(w, h);
  qfb.bind();
  LogStatus("bind");

  // If the frame buffer does not work then return an empty image
  if (!qfb.isValid())
  {
    LogStatus("qfb is not valid");
    return;
  }

  paintGL();

  QImage image2 = qfb.toImage();
  image2.save(imgFileName);

  qfb.release();
  LogStatus("released");

  qfb.bindDefault();
  doneCurrent();

}

void MakeImage(const std::vector<BPolygon*>& polys, const QString filename, int w, int h)
{
    MyGLWidget mglWidget(polys);
    mglWidget.makeImage(filename, w, h);

`

0

There are 0 best solutions below