#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Qt3DCore::QEntity* createTriangleMesh(bool isIndexed = false) { auto lineMat = new Qt3DExtras::QDiffuseSpecularMaterial; lineMat->setDiffuse(QColor(Qt::red)); auto geometry = new Qt3DRender::QGeometry; const quint32 elementSize = 3; const quint32 stride = elementSize * sizeof(float); auto vertexBuffer = new Qt3DRender::QBuffer(geometry); auto positionAttribute = new Qt3DRender::QAttribute; positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); positionAttribute->setVertexSize(3); positionAttribute->setByteStride(stride); positionAttribute->setBuffer(vertexBuffer); geometry->addAttribute(positionAttribute); float vertices[] = { 1,2,0, 0,0,0, 1,-2,0, 4,-2,0, 5,0,0, 4,2,0 }; auto numVertices = (sizeof(vertices) / sizeof(vertices[0])) / 3; QByteArray vertexBufferData; vertexBufferData.resize(static_cast(numVertices * stride)); memcpy(vertexBufferData.data(), vertices, numVertices * stride); vertexBuffer->setData(vertexBufferData); positionAttribute->setCount(static_cast(numVertices)); auto geometryRenderer = new Qt3DRender::QGeometryRenderer; // uncommenting the following line work around the bug //geometryRenderer->setVertexCount(numVertices); geometryRenderer->setRestartIndexValue(-1); geometryRenderer->setPrimitiveRestartEnabled(true); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); if (isIndexed) { auto indexBuffer = new Qt3DRender::QBuffer(geometry); auto indexAttribute = new Qt3DRender::QAttribute; indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setVertexSize(1); indexAttribute->setByteStride(indexAttribute->vertexSize() * sizeof(uint32_t)); indexAttribute->setBuffer(indexBuffer); geometry->addAttribute(indexAttribute); uint32_t indices[] = { 0, 1, 2, 3, 4, 5 }; auto numIndices = sizeof(indices) / sizeof(indices[0]); QByteArray indexBufferData; indexBufferData.resize(static_cast(numIndices * sizeof(uint32_t))); memcpy(indexBufferData.data(), indices, numIndices * sizeof(uint32_t)); indexBuffer->setData(indexBufferData); indexAttribute->setCount(static_cast(numIndices)); } geometryRenderer->setGeometry(geometry); auto meshEntity = new Qt3DCore::QEntity; meshEntity->addComponent(geometryRenderer); meshEntity->addComponent(lineMat); return meshEntity; } Qt3DCore::QEntity* createLineMesh(bool isIndexed = false) { auto lineMat = new Qt3DExtras::QDiffuseSpecularMaterial; lineMat->setDiffuse(QColor(Qt::red)); auto geometry = new Qt3DRender::QGeometry; auto vertexBuffer = new Qt3DRender::QBuffer(geometry); auto indexBuffer = new Qt3DRender::QBuffer(geometry); const quint32 elementSize = 3; const quint32 stride = elementSize * sizeof(float); auto positionAttribute = new Qt3DRender::QAttribute; positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName()); positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); positionAttribute->setVertexSize(3); positionAttribute->setByteStride(stride); positionAttribute->setBuffer(vertexBuffer); geometry->addAttribute(positionAttribute); float vertices[] = { 0,0,0, 1,0,0, 0,0,0, 0,1,0, 0,0,0, 0,0,1 }; auto numVertices = (sizeof(vertices) / sizeof(vertices[0])) / 3; QByteArray vertexBufferData; vertexBufferData.resize(static_cast(numVertices * stride)); memcpy(vertexBufferData.data(), vertices, numVertices * stride); vertexBuffer->setData(vertexBufferData); positionAttribute->setCount(static_cast(numVertices)); auto geometryRenderer = new Qt3DRender::QGeometryRenderer; // uncommenting the following line work around the bug //geometryRenderer->setVertexCount(numVertices); geometryRenderer->setRestartIndexValue(-1); geometryRenderer->setPrimitiveRestartEnabled(true); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines); if (isIndexed) { auto indexAttribute = new Qt3DRender::QAttribute; indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setVertexSize(1); indexAttribute->setByteStride(indexAttribute->vertexSize() * sizeof(uint32_t)); indexAttribute->setBuffer(indexBuffer); geometry->addAttribute(indexAttribute); uint32_t indices[] = { 0, 1, 2, 3, 4, 5 }; auto numIndices = sizeof(indices) / sizeof(indices[0]); QByteArray indexBufferData; indexBufferData.resize(static_cast(numIndices * sizeof(uint32_t))); memcpy(indexBufferData.data(), indices, numIndices * sizeof(uint32_t)); indexBuffer->setData(indexBufferData); indexAttribute->setCount(static_cast(numIndices)); } geometryRenderer->setGeometry(geometry); auto meshEntity = new Qt3DCore::QEntity; meshEntity->addComponent(geometryRenderer); meshEntity->addComponent(lineMat); return meshEntity; } int main(int argc, char* argv[]) { QApplication a(argc, argv); auto view = new Qt3DExtras::Qt3DWindow(); auto rootEntity = new Qt3DCore::QEntity(); view->setRootEntity(rootEntity); auto camera = view->camera(); camera->lens()->setPerspectiveProjection(45.0f, 1., 0.1f, 10000.0f); camera->setPosition(QVector3D(0, 0, 5)); camera->setUpVector(QVector3D(0, 1, 0)); camera->setViewCenter(QVector3D(0, 0, 0)); auto camController = new Qt3DExtras::QOrbitCameraController(rootEntity); camController->setCamera(camera); bool showBug = true; auto lines = createLineMesh(!showBug); lines->setParent(rootEntity); auto triangles = createTriangleMesh(!showBug); triangles->setParent(rootEntity); auto container = QWidget::createWindowContainer(view); QFrame frame; frame.setLayout(new QVBoxLayout); frame.layout()->addWidget(container); frame.resize(QSize(400, 300)); QTimer::singleShot(100, [&]() { camera->viewAll(); }); frame.show(); return a.exec(); }