Russian Qt Forum
Май 09, 2024, 04:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt3D: сцена с большим количеством объектов  (Прочитано 6284 раз)
Oleg3003
Гость
« : Октябрь 25, 2012, 23:43 »

Доброго времени суток,

пишу программу визуализации гасовой сети. Использовал для упрощения работы себе  + дополнительные фьючи 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);
}

жду ваших идей и ответов

С наилучшими пожеланиями

Олег
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Октябрь 27, 2012, 17:13 »

Qt3D никогда не видел, поэтому отвечу исходя из опыта OpenGL. Дорогая операция - загрузка текстур в память карты (вызовы типа glTextImage2D). Поэтому надо убедиться что это делается один раз, а не на каждом view. А чему это соответствует в qt3d - разбирайтесь по исходникам. Каким бы вумным он ни был, а текстуру грузить будет.

По поводу billboard - такой трансформ несложно написать самому, обсуждал на этом форуме
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 24.