I am trying to use QT3D to display a point cloud. In order to test the rendering, i created a simple QT3D project with a main.cpp file and a main.qml file. I understand that QT3D is different from QTQuick3D and in order to use QT3D types within a QTQuick application, these types need to be contained within a Scene3D object, hence the following setup.
Main.qml
import QtQuick 2.2 as QQ2
//! [0]
import Qt3D.Core 2.0
import Qt3D.Render 2.0
//! [0]
import Qt3D.Input 2.0
import Qt3D.Extras 2.15
import QtQuick.Scene3D
QQ2.Window {
visible: true
Scene3D {
visible: true
anchors.fill: parent
Entity {
id: rootEntity
property int pointCount: 10000 // Number of points in the cloud
function generateVetexData() {
// var vertexData = new Float32Array([ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0
// ]);
var vertexData = new Float32Array(pointCount * 9); // 9 floats per vertex
for (var i = 0; i < pointCount; i++) {
var x = Math.random() * 20 - 10; // Random x position between -10 and 10
var y = Math.random() * 20 - 10; // Random y position between -10 and 10
var z = Math.random() * 20 - 10; // Random z position between -10 and 10
var r = Math.random(); // Random red color value
var g = Math.random(); // Random green color value
var b = Math.random(); // Random blue color value
var nx = 0.0; // Normal x
var ny = 1.0; // Normal y
var nz = 0.0; // Normal z
//var intensity = Math.random(); // Random intensity
// Set the vertex data
vertexData[i * 10 + 0] = x;
vertexData[i * 10 + 1] = y;
vertexData[i * 10 + 2] = z;
vertexData[i * 10 + 3] = r;
vertexData[i * 10 + 4] = g;
vertexData[i * 10 + 5] = b;
vertexData[i * 10 + 6] = nx;
vertexData[i * 10 + 7] = ny;
vertexData[i * 10 + 8] = nz;
}
return vertexData;
}
RenderSettings {
id: renderSettings
activeFrameGraph: ForwardRenderer {
clearColor: "black"
camera: camera
showDebugOverlay: true
}
}
// Camera
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 75
aspectRatio: 16 / 9
nearPlane: 0.01
farPlane: 1000.0
position: Qt.vector3d(0.0, 10.0, -50.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
viewCenter: Qt.vector3d(0.0, 0.0, 10.0)
}
// Light
DirectionalLight {
id: light
worldDirection: Qt.vector3d(-1.0, -1.0, -1.0)
intensity: 1.0
}
TorusMesh {
id: torusMesh
radius: 5
minorRadius: 1
rings: 100
slices: 20
}
// Material
PhongMaterial {
id: phongMaterial
ambient: "gray"
diffuse: "white"
specular: "lightgray"
shininess: 50.0
}
Buffer {
id: vertexBuffer
usage: Buffer.ReadWrite
data: rootEntity.generateVetexData()
}
// Geometry for point cloud
GeometryRenderer {
id: pointCloudRenderer
instanceCount: 1
primitiveType: GeometryRenderer.Points
geometry: Geometry {
id: pointCloudGeometry
attributes: [
// Position attribute
Attribute {
name: defaultPositionAttributeName
attributeType: Attribute.VertexAttribute
buffer: vertexBuffer
byteOffset: 0
byteStride: 36 // 3 (position) + 3 (color) + 3 (normal) = 9 floats * 4 bytes
vertexBaseType: Attribute.Float
vertexSize: 3
count: rootEntity.pointCount
},
// Color attribute
Attribute {
name: defaultColorAttributeName
attributeType: Attribute.VertexAttribute
buffer: vertexBuffer
byteOffset: 12 // 3 (position) * 4 bytes
byteStride: 36 // 3 (position) + 3 (color) + 3 (normal) = 9 floats * 4 bytes
vertexBaseType: Attribute.Float
vertexSize: 3
count: rootEntity.pointCount
},
// Normal attribute
Attribute {
name: defaultNormalAttributeName
attributeType: Attribute.VertexAttribute
buffer: vertexBuffer
byteOffset: 24 // 3 (position) + 3 (color) * 4 bytes
byteStride: 36 // 3 (position) + 3 (color) + 3 (normal) = 9 floats * 4 bytes
vertexBaseType: Attribute.Float
vertexSize: 3
count: rootEntity.pointCount
}
]
}
}
// Transform
Transform {
id: transform
scale3D: Qt.vector3d(1.0, 1.0, 1.0)
}
// Camera Controller
OrbitCameraController {
camera: camera
}
components: [renderSettings, pointCloudRenderer, transform, torusMesh, light]
}
}
}
Main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSurfaceFormat>
#include <QOpenGLContext>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QSurfaceFormat format;
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
}
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSamples(4);
QSurfaceFormat::setDefaultFormat(format);
QQmlApplicationEngine engine;
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreationFailed,
&app,
[]() { QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
My build kit is QT6.7, a lot of examples online seem to be using old QT versions and quite a few things seem to have changed. When I run this app, nothing gets rendered, just a blank screen. Is this setup correct, or am I missing something.