首先我试着描述我想要的东西:
我想在背景中的某个地方设置一个(基于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但AA:
现在的大问题是,当试图同时渲染OpenGl和Svg时,不会渲染Opengl - 因为缺少上下文并且svg被完美渲染,或者渲染了opengl并且svg没有被正确地抗锯齿。
那么任何让antaliasing正确编辑的想法?
完整的项目(准备好日食 - 用cmake制作)
和截图
和预建的可执行文件
在这里链接:
https://www.dropbox.com/s/giqynqfuq2yl8li/SampleCode.zip