Qt3D: Draw Grid/Axis Lines?
-
Does anyone know a relatively easy way to just render axis/grid lines for X,Y,Z in a Qt3D OpenGL scene? I made a simple model viewer that opens wavefront .obj files and it would be nice to have the axis lines.
-
@oblivioncth There is no easy way.
-
Hi! I know this is old, but in case somebody falls on this one day, here is a solution (made from example here: https://www.youtube.com/watch?v=dWqXLDiL-qk)
First, a method to draw a line:
#include <Qt3DCore/QEntity> #include <Qt3DCore/QTransform> #include <Qt3DExtras/QPhongMaterial> #include <Qt3DRender/QAttribute> #include <Qt3DRender/QBuffer> #include <Qt3DRender/QGeometry> void drawLine(const QVector3D& start, const QVector3D& end, const QColor& color, Q3DCore::QEntity *_rootEntity) { auto *geometry = new Qt3DRender::QGeometry(_rootEntity); // position vertices (start and end) QByteArray bufferBytes; bufferBytes.resize(3 * 2 * sizeof(float)); // start.x, start.y, start.end + end.x, end.y, end.z float *positions = reinterpret_cast<float*>(bufferBytes.data()); *positions++ = start.x(); *positions++ = start.y(); *positions++ = start.z(); *positions++ = end.x(); *positions++ = end.y(); *positions++ = end.z(); auto *buf = new Qt3DRender::QBuffer(geometry); buf->setData(bufferBytes); auto *positionAttribute = new Qt3DRender::QAttribute(geometry); positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); positionAttribute->setVertexSize(3); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setBuffer(buf); positionAttribute->setByteStride(3 * sizeof(float)); positionAttribute->setCount(2); geometry->addAttribute(positionAttribute); // We add the vertices in the geometry // connectivity between vertices QByteArray indexBytes; indexBytes.resize(2 * sizeof(unsigned int)); // start to end unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data()); *indices++ = 0; *indices++ = 1; auto *indexBuffer = new Qt3DRender::QBuffer(geometry); indexBuffer->setData(indexBytes); auto *indexAttribute = new Qt3DRender::QAttribute(geometry); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setBuffer(indexBuffer); indexAttribute->setCount(2); geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry // mesh auto *line = new Qt3DRender::QGeometryRenderer(_rootEntity); line->setGeometry(geometry); line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines); auto *material = new Qt3DExtras::QPhongMaterial(_rootEntity); material->setAmbient(color); // entity auto *lineEntity = new Qt3DCore::QEntity(_rootEntity); lineEntity->addComponent(line); lineEntity->addComponent(material); }
Now we can draw the origin:
auto *root = new Qt3DCore::QEntity(); // draw origin drawLine({ 0, 0, 0 }, { 1, 0, 0 }, Qt::red, root); // X drawLine({ 0, 0, 0 }, { 0, 1, 0 }, Qt::green, root); // Y drawLine({ 0, 0, 0 }, { 0, 0, 1 }, Qt::blue, root); // Z
-
Now, I'd like to print the label of the axis next to them ("X" next to the X axis) with a
QText2DEntity
but I can't find a way to do it... See https://forum.qt.io/topic/92944/qt3d-how-to-print-text-qtext2dentity -
@zespy
This is absolutely brilliant explanation and example.
I know the topic is old now, but still a valid reference. Hence i thought to share the correction i had to do on buffer type [I assume its deprecated now], respectively :auto *buf = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry); auto *indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, geometry);
Mine is Qt 5.9 on Win 10.
-
@zespy Hi
I'm trying to use your code for my application. My goal is to insert grid behind an STL image, but it doesn't work and I don't know why.
I copied and pasted drawLine in the main. I also watched the example on youtube and I used his Qt example (basicshapes). So, when I run the project, it compiles without problems, but there is only my STL image without the grid. -
@giusirux When I call
setInstanceCount(1)
I saw the rendered lines. Not sure what other function do in this code, didn't test them.Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer; customMeshRenderer->setInstanceCount(1); customMeshRenderer->setIndexOffset(0); customMeshRenderer->setFirstInstance(0); customMeshRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); customMeshRenderer->setGeometry(customGeometry); customMeshRenderer->setVertexCount(12);