#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:
Теперь большая проблема заключается в том, что при попытке одновременного отображения OpenGL и Svg либо Opengl не отображается из-за отсутствия контекста, и svg отображается идеально, либо opengl отображается, а svg сглаживается неправильно.
Итак, есть идеи, как правильно выполнить рандомизацию сглаживания?
Полный проект (готовый для eclipse, созданный с помощью cmake)
, скриншоты
и готовый исполняемый
файл находятся по ссылке здесь:
Комментарии:
1. вы когда-нибудь решали эту проблему?