QGraphicsScene с QGLWidget в качестве области просмотра не отображает сглаживание QSvgRenderer правильно

#linux #qgraphicsscene #qt4.8 #qglwidget

#linux #qgraphicsscene #qt4.8 #qglwidget

Вопрос:

сначала я пытаюсь описать, что я хочу:
я хочу (на основе qt 4.8 [может, но не должен]) Контекст с поддержкой Opengl установлен где-то в фоновом режиме. Затем на первом слое появляется изображение с прозрачным КРУГОМ!! отверстие, в котором вы можете увидеть контекст OpenGL. и поверх этого статического изображения есть кнопки для некоторой логики.

Что я сделал:
я пытаюсь отобразить Svg с помощью QSvgRenderer перед сценой opengl.
Пейзаж OpenGL рисуется в QGraphicsView с QGLWidget в качестве области просмотра.

 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 amp;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 amp; f)
{
  //check painter
  if (painter->paintEngine()->type() != QPaintEngine::OpenGL
      amp;amp; 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(amp;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, но нет AA

Нет GL, но AA: Нет GL, но AA

Теперь большая проблема заключается в том, что при попытке одновременного отображения OpenGL и Svg либо Opengl не отображается из-за отсутствия контекста, и svg отображается идеально, либо opengl отображается, а svg сглаживается неправильно.
Итак, есть идеи, как правильно выполнить рандомизацию сглаживания?

Полный проект (готовый для eclipse, созданный с помощью cmake)
, скриншоты
и готовый исполняемый
файл находятся по ссылке здесь:

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

Комментарии:

1. вы когда-нибудь решали эту проблему?