Доброго времени суток,
пишу программу визуализации гасовой сети. Использовал для упрощения работы себе + дополнительные фьючи Qt3d. В итоге наткнулся на такую неприятность:
Дано:
Сцена, состоящая в основном из примитивов: 1500 сфер и 1000 цилиндров.
Каждая сфера и цылиндр получают свой цвет в зависимости от исходных данных.
Сцена отрисовывается с одним цветом без проблем, с 15-25 различными цветами немного заметно притормаживание картинки при перемещении или повороте.
При дальнейшем увеличении кол-ва цветов в сцене возрастает замедление реакции на действия пользователя - поворот или перемещение сцены.
Пример кода с использованием qt3d:
#ifndef BUILDER_H
#define BUILDER_H
#include "qglview.h"
QT_BEGIN_NAMESPACE
class QGLSceneNode;
class QGLBuilder;
QT_END_NAMESPACE
class BuilderView : public QGLView
{
Q_OBJECT
public:
BuilderView(const QGLFormat &f, QWidget *parent = 0);
~BuilderView();
protected:
void initializeGL(QGLPainter *painter);
void paintGL(QGLPainter *painter);
private:
QGLSceneNode *buildGeometry();
QGLSceneNode *buildGeometry2(qreal radius = 1.0, int divisions = 5);
QGLSceneNode *canScene;
int mCount;
int mColorCount;
QGLMaterialCollection *mPalette;
void initializePalette();
};
#endif
#include "builder.h"
#include "qglbuilder.h"
#include "qglmaterialcollection.h"
#include "qgltexture2d.h"
#include "qglmaterial.h"
#include "qglscenenode.h"
#include "qgllightmodel.h"
#include "qglsphere.h"
#include "qglcylinder.h"
#include <QtGui/qmatrix4x4.h>
#include <QtCore/qmath.h>
static inline qreal rval()
{
return qreal((qreal(qrand()) / qreal(RAND_MAX)) * 200.0);
}
static inline int ival()
{
return (qreal(qrand()) / qreal(RAND_MAX)) * 255;
}
BuilderView::BuilderView(const QGLFormat &f, QWidget *parent)
: QGLView(f, parent)
, canScene(new QGLSceneNode(this))
{
QGLSceneNode *can = buildGeometry();
//QGLSceneNode *sphere = buildGeometry2();
mPalette = new QGLMaterialCollection(canScene);
mCount = 1000;
mColorCount = 100;
initializePalette();
can->setObjectName("SceneNode Can");
canScene->setObjectName("Root - canScene");
for(int i = 1; i < mCount; i++)
{
QGLSceneNode *node = new QGLSceneNode(canScene);
node->setObjectName("Sphere_r_" + QString::number(i));
node->setPalette(mPalette);
node->setMaterialIndex(i % mColorCount);;
node->setEffect(QGL::LitModulateTexture2D);
node->addNode(can);
{
QMatrix4x4 mat;
mat.translate(1.0f * rval(), 1.0f * rval(), -1.0f * rval());
node->setLocalTransform(mat);
}
node = new QGLSceneNode(canScene);
node->setObjectName("Sphere_b_" + QString::number(i));
node->setPalette(mPalette);
node->setMaterialIndex(i % mColorCount);
node->setEffect(QGL::LitModulateTexture2D);
node->addNode(can);
{
QMatrix4x4 mat;
mat.translate(-1.0f * rval(), -1.0f * rval(), -1.0f * rval());
node->setLocalTransform(mat);
}
}
}
BuilderView::~BuilderView()
{
delete canScene;
}
void BuilderView::initializeGL(QGLPainter *painter)
{
glEnable(GL_CULL_FACE);
camera()->setFieldOfView(45);
camera()->setNearPlane(0.1);
camera()->setFarPlane(5000);
camera()->setEye(QVector3D(0.0, 0.0, 100.0));
}
void BuilderView::paintGL(QGLPainter *painter)
{
canScene->draw(painter);
}
QGLSceneNode *BuilderView::buildGeometry()
{
QGLBuilder builder;
builder << QGLCylinder(1.0f, 1.0f, 5.0f, 32);
return builder.finalizedSceneNode();
}
QGLSceneNode *BuilderView::buildGeometry2(qreal radius, int divisions)
{
QGLBuilder builder;
builder << QGLSphere(radius, divisions);
return builder.finalizedSceneNode();
}
void BuilderView::initializePalette()
{
for(int i = 0; i < mColorCount; i++)
{
QImage image(QSize(1, 6), QImage::Format_ARGB32_Premultiplied);
QPainter painter(&image);
QColor c(ival(), ival(), ival());
QColor c2(ival(), ival(), ival());
QLinearGradient linearGrad(QPointF(0.5, 0), QPointF(0.5, 6));
linearGrad.setColorAt(0, c);
linearGrad.setColorAt(1, c2);
painter.fillRect(image.rect(), linearGrad);
painter.end();
QGLMaterial *m = new QGLMaterial;
//m->setColor(c);
QGLTexture2D *tex = new QGLTexture2D(m);
tex->setImage(image);
m->setTexture(tex);
mPalette->addMaterial(m);
}
}
Предпосылки: собранный qt3d.
В .pro-файле :
QT += core gui opengl
CONFIG += qt3d
Есть ли у кого опыт использования qt3d и может быть идеи, почему это так влияет на отзывчивость сцены!?
Также, чтобы не открывать новую тему есть проблема с QGraphicsBillboardTransform. Добавляю эту трансформацию, а эффекта Billboard не наблюдаю.
Может у кого-то есть идеи!?
Код для Billboard:
#include "netview.h"
#include "qglbuilder.h"
#include "qglsphere.h"
NetView::NetView(QWidget *parent)
: QGLView(parent)
{
QGLBuilder b;
b.addPane(QSizeF(1.0, 1.0));
b.currentNode()->setObjectName("pane");
b.newSection();
b << QGLSphere();
b.currentNode()->setPosition(QVector3D(-1.5, 0.0, 0.0));
mPane = b.finalizedSceneNode();
//create a Billboard transform
mBillboard = new QGraphicsBillboardTransform();
mPane->addTransform(mBillboard);
QGLMaterial *m = new QGLMaterial;
m->setColor(Qt::blue);
mPane->setMaterial(m);
mPane->setEffect(QGL::LitMaterial);
}
void NetView::initializeGL(QGLPainter *painter)
{
}
void NetView::paintGL(QGLPainter *painter)
{
mPane->draw(painter);
}
жду ваших идей и ответов
С наилучшими пожеланиями
Олег