带有QGLWidget的QGraphicsScene作为视口无法正确渲染QSvgRenderer抗锯齿

时间:2014-06-26 14:31:44

标签: linux qgraphicsscene qt4.8 qglwidget

首先我试着描述我想要的东西:
我想在背景中的某个地方设置一个(基于qt 4.8的[可以但不能])Opengl-able上下文。然后第一层有一个透明ROUND的图像!!你可以看到OpenGl上下文的洞。在静态图像之上有一些逻辑按钮。

我做了什么:
我尝试在opengl风景前面用QSvgRenderer渲染一个Svg OpenGl Scenery在QGraphicsView中绘制,QGLWidget为Viewport。

int main(int argc, char **argv){

    QApplication app(argc, argv);

    GraphicsView view;
    //trying to get the anitaliasing to work
    view.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );

    QGLWidget* glwid = new QGLWidget( QGLFormat( QGL::SampleBuffers | QGL::AlphaChannel | QGL::Rgba ));

    //Set Multisampling
    QGLFormat frm = glwid->format();
    glwid->format().setSamples(4);
    glwid->setFormat(frm);

    //set the GlViewport
    view.setViewport(glwid); //--> SvgRendering works with no anti aliasing but glRendering does.

    //view.setViewport(new QWidget);  //--> SvgRendering with Antialiasing works

    view.setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    view.setScene(new OpenGLScene(view.rect()));
    view.show();

    return app.exec();

}

场景看起来像这样

#include "openglscene.h"
#include "PotentioMeter.h"

#include <QtGui>
#include <QtOpenGL>
#include <GL/glu.h>

#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE  0x809D
#endif


OpenGLScene::OpenGLScene(const QRectF &rect)
    : m_backgroundColor(0, 170, 255)
    , m_distance(1.4f)
{
    //One or more Widgets And buttons with svg special Looking (because of scaling)
    PotentioMeter* pm = new PotentioMeter( );
    pm->setAttribute(Qt::WA_TranslucentBackground, true);
    pm->resize(500,500);

    addWidget(pm);

    QPushButton *backgroundButton = new QPushButton(tr("Choose background color"));
    connect(backgroundButton, SIGNAL(clicked()), this, SLOT(setBackgroundColor()));
    backgroundButton->move(900,20);
    addWidget(backgroundButton);

    //Where should be the gl things drawn
    rGlViewport = QRectF(100, 100,rect.width()/2,rect.height()/2);

    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    const int UPDATE_RATE_25HZ_IN_MSEC = 40;
    timer->start(UPDATE_RATE_25HZ_IN_MSEC);
}

//dummy gl drawing function
void OpenGLScene::pyramid(QColor* color)
{
  glScalef(0.5,0.5,0.5);
  glPushMatrix();
  glRotatef(++angle, 0.0, 1.0, 0.0);
  glBegin( GL_TRIANGLES );
  glColor4f(color->redF(),color->greenF(),color->blueF(),1);
  glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 1.f, 0.0f );
  glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.0f );
  glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f);
  glColor4f(color->redF(),color->greenF(),color->blueF(),1);
  glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 1.0f, 0.0f);
  glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.0f);
  glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 0.0f, -1.0f, -1.0f);
  glColor4f(color->redF(),color->greenF(),color->blueF(),1);
  glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 1.0f, 0.0f);
  glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 0.0f, -1.0f, -1.0f);
  glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f);
  glColor4f(color->redF(),color->greenF(),color->blueF(),1);
  glColor3f( 1.0f, 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.0f);
  glColor3f( 0.0f, 1.0f, 0.0f ); glVertex3f( 0.0f, -1.0f, -1.0f);
  glColor3f( 0.0f, 0.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f);
  glEnd();
  glPopMatrix();

}

void
OpenGLScene::drawBackground(QPainter *painter, const QRectF & f)
{
  //check painter
  if (painter->paintEngine()->type() != QPaintEngine::OpenGL
      && painter->paintEngine()->type() != QPaintEngine::OpenGL2)
    {
      qWarning(
          "OpenGLScene: drawBackground needs a QGLWidget to be set as viewport on the graphics view");
      return;
}

  //check viewport
  if (f != myViewport)
    {
      myViewport = f;
    }

  //desperately trying to do antialiasing
  painter->setRenderHint(QPainter::Antialiasing);
  painter->setRenderHint(QPainter::HighQualityAntialiasing);

  glClearColor(m_backgroundColor.redF() + .2, m_backgroundColor.greenF() - .2, m_backgroundColor.blueF() + .2, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glFrustum(-1, 1, -1, 1, -1000.0, 1000.0);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glEnable(GL_MULTISAMPLE);

  glViewport(rGlViewport.x(), rGlViewport.y(), rGlViewport.width(),
      rGlViewport.height());

  //draw some gl stuff
  pyramid(&m_backgroundColor);

  glViewport(myViewport.x(), myViewport.y(), myViewport.width(),
  myViewport.height());

  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

}

void
OpenGLScene::setBackgroundColor()
{
  const QColor color = QColorDialog::getColor(m_backgroundColor);
  if (color.isValid())
    {
      m_backgroundColor = color;
    }
}

GL但没有AA: GL but no AA

没有GL但AA: No GL but AA


现在的大问题是,当试图同时渲染OpenGl和Svg时,不会渲染Opengl - 因为缺少上下文并且svg被完美渲染,或者渲染了opengl并且svg没有被正确地抗锯齿。
那么任何让antaliasing正确编辑的想法?

完整的项目(准备好日食 - 用cmake制作)
和截图 和预建的可执行文件
在这里链接:

https://www.dropbox.com/s/giqynqfuq2yl8li/SampleCode.zip

0 个答案:

没有答案