Search code examples
qtqmlqt5qt3d

QML 3D basic example


I am trying to create a basic QML application that will load a 3D model from a .obj file and display it on the screen and be able to rotate it along its axes during runtime. I went through some of the Qt examples and came up with the below code - most of which was borrowed from the working examples. But when I run it the model is not rendered properly.

The actual model looks like:

enter image description here

and currently my app shows up like

this.

Here is the QML code -

import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Extras 2.12

Entity {
    id: sceneRoot

    Camera {
        id: camera
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        aspectRatio: 1820 / 1080
        nearPlane: 0.1
        farPlane: 1000.0
        position: Qt.vector3d(0.014, 0.956, 2.178)
        upVector: Qt.vector3d(0.0, 1.0, 0.0)
        viewCenter: Qt.vector3d(0.0, 0.7, 0.0)
    }

    Entity {
        components: [
            DirectionalLight {
                intensity: 0.9
                worldDirection: Qt.vector3d(0, 0.6, -1)
            }
        ]
    }

    RenderSettings {
        id: external_forward_renderer
        activeFrameGraph: ForwardRenderer {
            camera: camera
            clearColor: "transparent"
        }
    }

    Mesh {
        id: roboMesh
        source: "images/robo-obj-pose4/source/d2f0cff60afc40f5afe79156ec7db657.obj"
    }

    Entity {
        id: circleEntity
        property Material roboMaterial: PhongAlphaMaterial {
            alpha: 0.4
            ambient: "black"
            diffuse: "black"
            specular: "black"
            shininess: 10000
        }

        components: [roboMesh, roboMaterial]
    }
}

What am I missing here? Sorry for a really silly question but I am totally new to Qt3D and am confused as to what else needs to go in my code.


Solution

  • You don't necessarily need a material file as suggested by the comments, you can assign generic materials the way you do it you just have some other issues with your code.

    First, you need to add the RenderSettings as a component to the root entity, like so:

    Entity {
        id: sceneRoot
    
        components: [external_forward_renderer]
    
        ...
    

    Secondly, "transparent" is not a valid clear color. Use something like Qt.rgba(0, 0.5, 1, 1).

    Thirdly, you need to add file:// to the beginning of the mesh URL, unless you have the file included in a resources file. At least I needed that prefix, maybe you don't. You can check this by having a look at the application output in QtCreator. If it says "file does not exist" then add this prefix.

    If you still can't see your mesh try adding InputSettings (which have to be added as a component as well) and a OrbitCameraController:

    InputSettings {
        id: inputSettings
    }
    
    OrbitCameraController{
        camera: camera
    }