Qt qml 3D Render
main.cpp
//main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "triangleitem.h"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType< TriangleItem >("Shapes", 1, 0, "Triangle");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
//main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import Shapes 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Rectangle{
anchors.fill: parent
Triangle{
id: d3DRenderer
anchors.fill: parent
anchors.margins: 100
}
Text{
text: "3D & qml"
font.pixelSize: 48
font.bold: true
color: "black"
anchors.bottom: d3DRenderer.bottom
anchors.horizontalCenter: d3DRenderer.horizontalCenter
}
}
}
triangleitem.h
//triangleitem.h
#ifndef TRIANGLEITEM_H
#define TRIANGLEITEM_H
#include <QQuickItem>
#include <QQuickPaintedItem>
class TriangleItem : public QQuickItem
{
Q_OBJECT
public:
TriangleItem(QQuickItem* parent = 0);
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
protected slots:
void updateColors();
private:
float m_colorHue;
};
#endif // TRIANGLEITEM_H
triangleitem.cpp
//triangleitem.cpp
#include "triangleitem.h"
#include <QPainter>
#include <QSGFlatColorMaterial>
#include <QSGGeometryNode>
#include <QSGVertexColorMaterial>
#include <QTimer>
#include <QDebug>
TriangleItem::TriangleItem(QQuickItem *parent)
: QQuickItem( parent )
{
setFlag(QQuickItem::ItemHasContents, true);
QTimer *timer = new QTimer( this );
connect(timer, &QTimer::timeout, this, &TriangleItem::updateColors);
timer->start(16);
}
void TriangleItem::updateColors()
{
m_colorHue += 0.5f;
m_colorHue = fmod(m_colorHue, 360.0f);
update();
}
// HSV2RGB assuming S and V to be 1
static QRgb hue2rgb(float hue)
{
hue = fmod(hue, 360.0f);
hue /= 60.0f;
const int i = int(hue);
hue = 1.0f - fabs(fmod(hue, 2.0f) - 1.0f);
const int h = int(hue * 255);
switch (i) {
case 0:
return qRgb(255, h, 0);
case 1:
return qRgb(h, 255, 0);
case 2:
return qRgb(0, 255, h);
case 3:
return qRgb(0, h, 255);
case 4:
return qRgb(h, 0, 255);
case 5:
return qRgb(255, 0, h);
}
return QRgb(0);
}
QSGNode *TriangleItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
if(width() <= 0 || height() <=0){
delete oldNode;
return 0;
}
QSGNode *rootNode = static_cast< QSGNode* >( oldNode );
QSGTransformNode *transformNode;
QSGGeometryNode *triangleNode;
//parent/child organization is: rootNode -> transformNode -> trangleNode
if( Q_LIKELY(rootNode) ){
transformNode = static_cast< QSGTransformNode* >(rootNode->firstChild());
triangleNode = static_cast< QSGGeometryNode* >(transformNode->firstChild());
}else{
rootNode = new QSGNode;
transformNode = new QSGTransformNode;
transformNode->setFlag(QSGNode::OwnedByParent, true);
rootNode->appendChildNode(transformNode);
triangleNode = new QSGGeometryNode;
triangleNode->setFlag(QSGNode::OwnedByParent, true);
triangleNode->setFlag(QSGNode::OwnsGeometry, true);
triangleNode->setFlag(QSGNode::OwnsOpaqueMaterial, true);
QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 3);
triangleNode->setGeometry( geometry );
QSGVertexColorMaterial *material = new QSGVertexColorMaterial;
triangleNode->setMaterial( material );
transformNode->appendChildNode(triangleNode);
}
// rotate the triangle around the center of the item
QMatrix4x4 rotationMatrix;
rotationMatrix.translate(width() / 2, height() / 2);
rotationMatrix.rotate(m_colorHue, QVector3D(0, 0, 1));
rotationMatrix.translate(-width() / 2, -height() / 2);
transformNode->setMatrix(rotationMatrix);
transformNode->markDirty(QSGNode::DirtyMatrix);
QSGGeometry::ColoredPoint2D *points = triangleNode->geometry()->vertexDataAsColoredPoint2D();
QRgb color = hue2rgb(m_colorHue);
points[0].x = 0;
points[0].y = height();
points[0].r = qRed(color);
points[0].g = qGreen(color);
points[0].b = qBlue(color);
points[0].a = qAlpha(color);
color = hue2rgb(m_colorHue + 120);
points[1].x = width();
points[1].y = height();
points[1].r = qRed(color);
points[1].g = qGreen(color);
points[1].b = qBlue(color);
points[1].a = qAlpha(color);
color = hue2rgb(m_colorHue + 240);
points[2].x = width() / 2.0f;
points[2].y = 0;
points[2].r = qRed(color);
points[2].g = qGreen(color);
points[2].b = qBlue(color);
points[2].a = qAlpha(color);
// tell QSGGeometry it needs to reupload vertex data
triangleNode->geometry()->markVertexDataDirty();
//tell the QSGNode to trigger a geometry update ( which will see the vertex data marked as dirty)
triangleNode->markDirty(QSGNode::DirtyGeometry);
return rootNode;
}
效果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/bb7d105fe2894ccf83527112f3fe6029.png#pic_center)