【问题标题】:Custom QQuick3DGeometry does not display自定义 QQuick3DGeometry 不显示
【发布时间】:2021-06-02 08:59:42
【问题描述】:

尝试为 QtQuick3D 实现自定义几何体:

mycustomgeometry.h:

#ifndef MYCUSTOMGEOMETRY_H
#define MYCUSTOMGEOMETRY_H

#include <QQuick3DGeometry>

class MyCustomGeometry : public QQuick3DGeometry
{
    Q_OBJECT
public:
    MyCustomGeometry();
    virtual ~MyCustomGeometry();

signals:

public slots:
    void setData(QByteArray vertexData, QByteArray indexData);

};

#endif // MYCUSTOMGEOMETRY_H

mycustomgeometry.cpp:

#include "mycustomgeometry.h"

#include <QVector3D>

// simulate data coming from my application (should look like a cut cuboid)
static unsigned char vertexData[] = {
    0x00, 0x00, 0xe0, 0xb3, 0x8c, 0xca, 0x4c, 0xbd, 0x1c, 0x63, 0x89, 0x3d,
    0x00, 0x00, 0x60, 0x35, 0x0c, 0xcf, 0x4c, 0x3d, 0xa4, 0x61, 0x89, 0x3d,
    0x64, 0x2e, 0x37, 0xbd, 0xb8, 0xcc, 0x4c, 0xbd, 0x00, 0x2a, 0xb7, 0xbc,
    0x68, 0x2d, 0x37, 0xbd, 0xe4, 0xcc, 0x4c, 0x3d, 0xe0, 0x2f, 0xb7, 0xbc,
    0x80, 0x2d, 0x37, 0x3d, 0xa4, 0xcb, 0x4c, 0xbd, 0x18, 0x2f, 0x37, 0x3d,
    0x80, 0x2e, 0x37, 0x3d, 0xf0, 0xcd, 0x4c, 0x3d, 0x28, 0x2c, 0x37, 0x3d,
    0xd8, 0x2c, 0x37, 0x3d, 0xf8, 0xce, 0x4c, 0xbd, 0xa0, 0x61, 0x89, 0xbd,
    0xd8, 0x2d, 0x37, 0x3d, 0xa4, 0xca, 0x4c, 0x3d, 0x20, 0x63, 0x89, 0xbd
};
static unsigned char indexData[] = {
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
    0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
    0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
    0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
    0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
};

MyCustomGeometry::MyCustomGeometry()
{
    QByteArray v(reinterpret_cast<char*>(::vertexData), sizeof(::vertexData));
    QByteArray i(reinterpret_cast<char*>(::indexData), sizeof(::indexData));
    setData(v, i);
}

MyCustomGeometry::~MyCustomGeometry()
{
}

void MyCustomGeometry::setData(QByteArray vertexData, QByteArray indexData)
{
    clear();
    setPrimitiveType(PrimitiveType::Triangles);
    addAttribute(Attribute::PositionSemantic, 0, Attribute::F32Type);
    addAttribute(Attribute::IndexSemantic, 0, Attribute::U32Type);
    addAttribute(Attribute::NormalSemantic, 0, Attribute::F32Type);
    setVertexData(vertexData);
    setIndexData(indexData);
    setStride(sizeof(float) * 3);

    QVector3D boundsMin, boundsMax;
    auto vertices = reinterpret_cast<const float*>(vertexData.constData());
    for(size_t i = 0; i < vertexData.length() / sizeof(float); i += 3)
    {
        for(size_t j = 0; j < 3; j++)
        {
            boundsMin[j] = (std::min(vertices[i + j], i == 0 ? vertices[i + j] : boundsMin[j]));
            boundsMax[j] = (std::max(vertices[i + j], i == 0 ? vertices[i + j] : boundsMax[j]));
        }
    }
    setBounds(boundsMin, boundsMax);
}

main.qml:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick3D 1.15
import QtQuick3D.Helpers 1.15
import QtQuick.Controls 2.15
import MyCustomGeometry 1.0

Window {
    id: mainWindow
    width: 400
    height: 300
    visible: true
    flags: Qt.Tool
    title: qsTr("3D demo")

    View3D {
        id: view
        anchors.fill: parent
        camera: camera
        renderMode: View3D.Overlay

        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, 200, 300)
            eulerRotation.x: -30
        }

        WasdController {
            controlledObject: camera
            mouseEnabled: true
        }

        DirectionalLight {
            eulerRotation.x: -30
        }

        Model {
            id: cube
            objectName: "cube"
            visible: true
            position: Qt.vector3d(-100, 0, 0)
            scale: Qt.vector3d(slider.k, slider.k, slider.k)
            source: "#Cube"
            materials: [DefaultMaterial {diffuseColor: "red"}]
            eulerRotation.y: 90
        }

        Model {
            id: sphere
            objectName: "sphere"
            visible: true
            position: Qt.vector3d(100, 0, 0)
            scale: Qt.vector3d(slider.k, slider.k, slider.k)
            //source: "#Sphere"
            geometry: MyCustomGeometry {}
            materials: [DefaultMaterial {diffuseColor: "blue"}]
            eulerRotation.y: 90
        }
    }

    Slider {
        id: slider
        property real k: Math.pow(10, slider.value)
        from: -3; to: 6; value: 3
    }
}

立方体和球体(在评论 geometry: 和取消评论 source: 时)正确显示。

但具有自定义几何形状的模型没有。

我也尝试使用 16 位整数作为索引,但得到了相同的结果。

编辑:在 Qt 6.0.0 上测试并且可以正常工作,所以这是一个仅限于 Qt 5.15.2 的问题

【问题讨论】:

    标签: qt qml qtquick3d


    【解决方案1】:

    如果根据QTBUG-89420 设置name 属性,它也适用于Qt 5:

    MyCustomGeometry::MyCustomGeometry()
    {
        QByteArray v(reinterpret_cast<char*>(::vertexData), sizeof(::vertexData));
        QByteArray i(reinterpret_cast<char*>(::indexData), sizeof(::indexData));
        setData(v, i);
        setName("MyCustomGeometry");
    }
    

    【讨论】:

      猜你喜欢
      • 2023-02-26
      • 2015-03-16
      • 2015-10-31
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      相关资源
      最近更新 更多