1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
// Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QGuiApplication>
#include <QTimer>
#include <QOpenGLContext>
#include <QWindow>
#include <qmath.h>
#include <Qt3DCore/QNode>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DExtras/QTorusMesh>
#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DExtras/QPhongMaterial>
#include <Qt3DRender/QCamera>
#include <Qt3DRender/QCameraLens>
#include <Qt3DRender/QCameraSelector>
#include <Qt3DRender/QMesh>
#include <Qt3DRender/QPointLight>
#include <Qt3DRender/QRenderAspect>
#include <Qt3DRender/QRenderSettings>
#include <Qt3DRender/QRenderSurfaceSelector>
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/abstractrenderer_p.h>
class ManualRenderer
{
public:
ManualRenderer()
: m_aspectEngine(new Qt3DCore::QAspectEngine())
, m_renderAspect(new Qt3DRender::QRenderAspect(Qt3DRender::QRenderAspect::Manual))
, m_renderer(nullptr)
{
}
~ManualRenderer() {
m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr());
m_aspectEngine->unregisterAspect(m_renderAspect);
delete m_renderAspect;
delete m_aspectEngine;
}
void initialize(QWindow *window, QOpenGLContext *glCtx)
{
m_aspectEngine->registerAspect(m_renderAspect);
m_aspectEngine->setRunMode(Qt3DCore::QAspectEngine::Manual);
Qt3DRender::QRenderAspectPrivate *dRenderAspect = static_cast<decltype(dRenderAspect)>
(Qt3DRender::QRenderAspectPrivate::get(m_renderAspect));
m_renderer = dRenderAspect->m_renderer;
m_renderer->setOpenGLContext(glCtx);
m_renderer->initialize();
m_rootEntity.reset(createSceneTree(window));
m_aspectEngine->setRootEntity(m_rootEntity);
}
void render() {
qDebug() << Q_FUNC_INFO << "Updating Scene";
updateScene();
qDebug() << Q_FUNC_INFO << "Processing Frame";
// Launch jobs to process the frame
m_aspectEngine->processFrame();
qDebug() << Q_FUNC_INFO << "Rendering Frame";
// Submit Render Queues
m_renderer->render(true);
}
private:
Qt3DCore::QEntity *createSceneTree(QWindow *surface) {
// Root entity in the 3D scene.
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity;
auto camera = new Qt3DRender::QCamera(rootEntity);
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));
// Torus
Qt3DCore::QEntity *torusEntity = new Qt3DCore::QEntity(rootEntity);
auto material = new Qt3DExtras::QPhongMaterial(rootEntity);
auto torusTransform = new Qt3DCore::QTransform;
auto torusMesh = new Qt3DExtras::QTorusMesh;
torusMesh->setRadius(5);
torusMesh->setMinorRadius(1);
torusMesh->setRings(100);
torusMesh->setSlices(20);
torusTransform->setScale3D(QVector3D(1.5, 1, 0.5));
torusTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 45.0f));
torusEntity->addComponent(torusMesh);
torusEntity->addComponent(material);
torusEntity->addComponent(torusTransform);
// FrameGraph
auto forwardRenderer = new Qt3DExtras::QForwardRenderer();
forwardRenderer->setSurface(surface);
forwardRenderer->setCamera(camera);
forwardRenderer->setClearColor(QColor(Qt::black));
auto renderSettings = new Qt3DRender::QRenderSettings();
renderSettings->setActiveFrameGraph(forwardRenderer);
rootEntity->addComponent(renderSettings);
return rootEntity;
}
void updateScene()
{
static int angle = 0;
// Update camera position
auto camera = m_rootEntity->findChild<Qt3DRender::QCamera *>();
Q_ASSERT(camera);
const double angleRad = qDegreesToRadians(double(angle));
const QVector3D newPos(qSin(angleRad), 0.0, qCos(angleRad));
camera->setPosition(newPos * 40.0f);
qDebug() << Q_FUNC_INFO << "Camera Transform Matrix" << camera->transform()->matrix();
qDebug() << Q_FUNC_INFO << "Camera ViewMatrix" << camera->viewMatrix();
angle = (angle + 1) % 360;
}
Qt3DCore::QEntityPtr m_rootEntity;
Qt3DCore::QAspectEngine *m_aspectEngine;
Qt3DRender::QRenderAspect *m_renderAspect;
Qt3DRender::Render::AbstractRenderer *m_renderer;
};
int main(int ac, char **av)
{
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
#if QT_CONFIG(opengles2)
format.setRenderableType(QSurfaceFormat::OpenGLES);
#else
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
format.setVersion(4, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
}
#endif
format.setDepthBufferSize(24);
format.setSamples(4);
format.setStencilBufferSize(8);
QSurfaceFormat::setDefaultFormat(format);
QGuiApplication app(ac, av);
QWindow win;
win.setSurfaceType(QSurface::OpenGLSurface);
win.resize(1024, 768);
win.setFormat(format);
win.show();
QOpenGLContext ctx;
ctx.setFormat(format);
const bool ctxCreated = ctx.create();
if (!ctxCreated) {
qWarning() << "Failed to create GL context";
return -1;
}
ManualRenderer renderer;
renderer.initialize(&win, &ctx);
QTimer t;
QObject::connect(&t, &QTimer::timeout, [&] { renderer.render(); });
t.start(16);
return app.exec();
}
|