I just recently started to use QT3D for a sideproject at work. And i'm surprised how fast you get something that looks pretty decent (at least for my case).
But i still have an issue with rendering speed and CPU usage.
I've written a small test program to showcase this (see below).
As we use Ubuntu i though it may be an issue with the NVIDIA driver but i tested it at home on my Windows PC as well.
And had the same results:
CPU usage is very high - 100% on one Core all the time.
GPU usage show no real difference if the application is running or not.
So my best guess is that it uses software rendering instead of the hardware?
Any ideas?
The example just draws 2000 Cuboids with random sizes on random positions with a light source above.
#include <QGuiApplication>
#include <QRandomGenerator>
#include <QHBoxLayout>
#include <Qt3DRender/QCamera>
#include <Qt3DCore/QEntity>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtGui/QScreen>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DRender/QPointLight>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>
int main(int argc, char **argv)
{
//basic window/widget stuff
QApplication app(argc, argv);
Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
QWidget *container = QWidget::createWindowContainer(view);
QSize screenSize = view->screen()->size();
container->setMinimumSize(QSize(200, 100));
container->setMaximumSize(screenSize);
QWidget *widget = new QWidget;
QHBoxLayout *hLayout = new QHBoxLayout(widget);
hLayout->addWidget(container, 1);
//root entity
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
view->setRootEntity(rootEntity);
//setup camera
view->camera()->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 10.0f, 5000.0f);
view->camera()->setPosition(QVector3D(0, 0, 3000));
view->camera()->setUpVector(QVector3D(0, 1, 0));
view->camera()->setViewCenter(QVector3D(0, 0, 0));
//orbit camera controller
Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
camController->setCamera(view->camera());
camController->setLookSpeed(500);
//add light
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
light->setColor("white");
light->setIntensity(1);
lightEntity->addComponent(light);
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
lightTransform->setTranslation(QVector3D(0, 5000, 0));
lightEntity->addComponent(lightTransform);
//add objects
QRandomGenerator rng(1234);
for(int i = 0; i <= 2000; i++)
{
Qt3DCore::QEntity* shapeEntity = new Qt3DCore::QEntity(rootEntity);
Qt3DExtras::QCuboidMesh* mesh = new Qt3DExtras::QCuboidMesh();
mesh->setXExtent(int(rng.generate() % 30)+20);
mesh->setYExtent(int(rng.generate() % 30)+20);
mesh->setZExtent(int(rng.generate() % 30)+20);
shapeEntity->addComponent(mesh);
Qt3DExtras::QDiffuseSpecularMaterial *material = new Qt3DExtras::QDiffuseSpecularMaterial();
material->setAmbient(QColor(Qt::red).darker(150));
material->setDiffuse(QColor(Qt::red));
shapeEntity->addComponent(material);
Qt3DCore::QTransform* pTrans = new Qt3DCore::QTransform();
pTrans->setTranslation(QVector3D(int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000));
shapeEntity->addComponent(pTrans);
}
//show
widget->show();
widget->resize(1200, 800);
return app.exec();
}
Related
everyone! I try to set a click property to a QMediaPlayer Element, but I can not find the mode to make it, and if I try to put a button in front to Video, the button puts behind to video, even with
button->raise();
videoWidget->lower();
And If I put a Button to fullscreen the screen turns in black and don't shows the video
this id the code of the video player
QMediaPlayer *player = new QMediaPlayer(this);
QVideoWidget *vw = new QVideoWidget(this);
QMediaPlaylist *PlayList = new QMediaPlaylist(this);
PlayList->addMedia(QUrl::fromLocalFile("/home/user/Videos/video.mp4"));
PlayList->setPlaybackMode(QMediaPlaylist::Loop);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(vw);
player->setVideoOutput(vw);
player->setPlaylist(PlayList);
vw->setGeometry(0,0,800,480);
vw->show();
player->play();
One possible solution is to create a widget where the QVideoWidget is placed through a layout, the button is also added and we change the position through the resizeEvent() event.
#include <QApplication>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
#include <QVideoWidget>
#include <QDebug>
class VideoWidgetButton: public QWidget{
QPushButton *btn;
QVideoWidget *vw;
QMediaPlayer *player;
public:
VideoWidgetButton(QWidget *parent=Q_NULLPTR):QWidget(parent){
setLayout(new QVBoxLayout);
layout()->setContentsMargins(0, 0, 0, 0);
vw = new QVideoWidget(this);
btn = new QPushButton(this);
btn->setIcon(QIcon(":/icons/tux.jpeg"));
btn->resize(QSize(128, 128));
btn->setIconSize(QSize(128, 128));
connect(btn, &QPushButton::clicked, [](){
qDebug()<<"clicked";
});
layout()->addWidget(vw);
player = new QMediaPlayer(this);
player->setVideoOutput(vw);
QMediaPlaylist *playList = new QMediaPlaylist(this);
playList->addMedia(QUrl("qrc:/video/SampleVideo_1280x720_1mb.mp4"));
playList->setPlaybackMode(QMediaPlaylist::Loop);
player->setPlaylist(playList);
player->play();
}
protected:
void resizeEvent(QResizeEvent *ev){
btn->move(rect().bottomRight()-btn->rect().bottomRight());
return QWidget::resizeEvent(ev);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VideoWidgetButton w;
w.resize(640, 480);
w.show();
return a.exec();
}
The complete example can be found in the following link.
I am trying to create a minimal obj file viewer. Following is my code mostly copy pasted with some minor modifications.
#include <QGuiApplication>
#include <QApplication>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DRender/qrenderaspect.h>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QMaterial>
#include <Qt3DRender/QMesh>
#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QOrbitCameraController>
#include <Qt3DExtras/QPhongMaterial>
Qt3DCore::QEntity* createTestScene()
{
Qt3DCore::QEntity* root = new Qt3DCore::QEntity;
Qt3DCore::QEntity* torus = new Qt3DCore::QEntity(root);
Qt3DRender::QMesh* mesh = new Qt3DRender::QMesh(root);
mesh->setSource(QUrl::fromLocalFile("/Users/neel/model.obj"));
Qt3DCore::QTransform* transform = new Qt3DCore::QTransform;
// transform->setScale3D(QVector3D(1.5, 1, 0.5));
transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1,0,0), 45.f ));
Qt3DRender::QMaterial* material = new Qt3DExtras::QPhongMaterial(root);
torus->addComponent(mesh);
torus->addComponent(transform);
torus->addComponent(material);
return root;
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
Qt3DExtras::Qt3DWindow view;
Qt3DCore::QEntity* scene = createTestScene();
// camera
Qt3DRender::QCamera *camera = view.camera();
camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
camera->setPosition(QVector3D(0, 0, 40.0f));
camera->setViewCenter(QVector3D(0, 0, 0));
// manipulator
Qt3DExtras::QOrbitCameraController* manipulator = new Qt3DExtras::QOrbitCameraController(scene);
manipulator->setLinearSpeed(50.f);
manipulator->setLookSpeed(180.f);
manipulator->setCamera(camera);
view.setRootEntity(scene);
view.show();
return app.exec();
}
With the above I can load obj files but there are two problems.
I can Pan and zoom the model, however I cannot rotate using my mouse or trackpad. How can I add that functionality.
My obj files have different colours in them. With this code what I see is only black in. the entire model. In other obj viewers I can see multiple colours.
you need to look on the sceneloader function in Qt for such loading process.
i mean with mtl fui
QPropertyAnimation produces periodic flicker/drag effect during animation of longer duration of about 1 second or two. For small duration animation (about 500 ms or less) the QPropertyAnimation produces smooth animation without that specific flicker/drag effect. That flicker/drag like effect appears round about every 500ms. And i need to come across some solution as soon as possible. I have attached the minimal compilable example reproducing the problem. Please have a look and help.
I am using Qt5.5 in Windows10, i use both MinGW and Visual Studio 2013 compilers, Core i5 Laptop.
#include <QCoreApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QPropertyAnimation>
#include <QApplication>
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0) : QWidget(parent) {
QVBoxLayout *l = new QVBoxLayout(this);
placeholder = new QWidget;
placeholder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
l->addWidget(placeholder);
QPushButton *b = new QPushButton;
l->addWidget(b);
b->setText("click");
connect(b, SIGNAL(clicked()), this, SLOT(nextPage()));
current = 0;
}
public slots:
void nextPage() {
QWidget *newPage = new QLabel("page");
newPage->setAutoFillBackground(true);
QStringList c = QColor::colorNames();
QPalette p = newPage->palette();
p.setColor(QPalette::Window, QColor(c.at(qrand() % c.size())));
newPage->setPalette(p);
newPage->setParent(placeholder);
QPropertyAnimation *anim = new QPropertyAnimation(newPage, "geometry", newPage);
QRect start = placeholder->rect();
start.setTopLeft(start.topRight());
newPage->setGeometry(start);
anim->setStartValue(start);
anim->setEndValue(placeholder->rect());
anim->setDuration(4000);
anim->start();
if(current) {
QPropertyAnimation *anim = new QPropertyAnimation(current, "geometry", current);
anim->setStartValue(placeholder->rect());
QRect r = placeholder->rect();
r.translate(-r.width(), 0);
anim->setEndValue(r);
anim->setDuration(4000);
connect(anim, SIGNAL(finished()), current, SLOT(deleteLater()));
anim->start();
}
current = newPage;
current->show();
}
private:
QWidget *placeholder;
QWidget *current;
};
#include "main.moc"
int main(int argc, char **argv) {
QApplication app(argc, argv);
Widget w;
w.show();
return app.exec();
}
probably a simple question: I just created a new project in Qt creator and I set it to use QWidget when I created it, now how do I get rid of the window that it automatically creates when I run it? I also created my own QWidget window which I want to be the only window.
#include "widget.h"
#include <QtGui>
Widget::Widget()
{
QWidget* window = new QWidget;
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
window->setLayout(layout);
window->show();
}
Widget::~Widget()
{
}
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
change it like this
Widget::Widget()
{
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
this->setLayout(layout);
}
and try to have some time on look and try some of Qt Example (you can find it in Qt Creator)
and there is about 100 short video to learn quickly basic stuff on Qt
Qt is fun, enjoy it.
Here is an equivalent extracted code:
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QTextBrowser>
#include <QTextEdit>
class ChatMessageEdit : public QTextEdit {
public:
ChatMessageEdit(QWidget* parent) : QTextEdit(parent) { }
virtual QSize sizeHint() const { return QSize(0, 25); }
};
int main(int argc, char** argv) {
QApplication app(argc, argv);
QWidget* widget = new QWidget;
QVBoxLayout* layout = new QVBoxLayout;
QTextBrowser* log = new QTextBrowser(widget);
layout->addWidget(log, 1);
ChatMessageEdit* editor = new ChatMessageEdit(widget);
editor->setMinimumHeight(editor->sizeHint().height()); // empty
layout->addWidget(editor);
widget->setLayout(layout);
widget->show();
return app.exec();
}
The minimum size for editor is 25px, and so is it's minimal size. But by some strange reason it is created with a size about 100px that is always preferred to my size hint. Everything other is working as expected: expanding (size hint isn't really fixed in my application), shrinking etc. I tried changing size policy, but with abolutely no result.
This was the minumumSizeHint() method. I overloaded it to return sizeHint(), and everything is working as expected now.
You are also overlooking how layouts work. Please read up here on why your sizes are not being respected in a layout.