Qt Quick 3D - HelloCube Example

Demonstrates how to render 2D and 3D objects together in Qt Quick 3D.

HelloCube demonstrates how to render a 3D cube with 2D items in Qt Quick 3D.

Draw 2D Items

We set up the entire scene in the main.qml file.

To be able to use the types in the QtQuick3D module, we must import it:


  import QtQuick3D 1.14

  Window {
      id: window
      width: 640
      height: 640
      visible: true
      color: "black"

      Rectangle {
          id: qt_logo
          width: 230
          height: 230
          anchors.top: parent.top
          anchors.left: parent.left
          anchors.margins: 10
          color: "black"

          property int angle: 0

          //! [offscreenSurface]
          layer.enabled: true
          //! [offscreenSurface]

          //! [2d]
          Image {
              anchors.fill: parent
              source: "qt_logo.png"
          }
          Text {
              id: text
              anchors.bottom: parent.bottom
              anchors.left: parent.left
              color: "white"
              font.pixelSize: 17
              text: qsTr("The Future is Written with Qt")
          }
          //! [2d]

          //! [2danimation]
          transform: Rotation {
              id: rotation
              origin.x: qt_logo.width / 2
              origin.y: qt_logo.height / 2
              axis { x: 1; y: 0; z: 0 }
              angle: qt_logo.angle
          }

          states: [
              State {
                  name: "flipped";
                  PropertyChanges { target: rotation; angle: 180 }
              }
          ]

          PropertyAnimation {
              id: flip1
              target: rotation
              property: "angle"
              duration: 600
              to: 180
              from: 0
          }
          PropertyAnimation {
              id: flip2
              target: rotation
              property: "angle"
              duration: 600
              to: 360
              from: 180
          }
          //! [2danimation]
      }

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

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

          DirectionalLight {
              rotation: Qt.vector3d(30, 0, 0)
          }

          Model {
              //! [3dcube]
              id: cube
              visible: true
              position: Qt.vector3d(0, 0, 0)
              source: "#Cube"
              materials: [ DefaultMaterial {
                      diffuseMap: Texture {
                          id: texture
                          sourceItem: qt_logo
                          flipV: true
                      }
                  }
              ]
              rotation: Qt.vector3d(0, 90, 0)
              //! [3dcube]

              SequentialAnimation on rotation {
                  loops: Animation.Infinite
                  PropertyAnimation {
                      duration: 5000
                      to: Qt.vector3d(360, 0, 360)
                      from: Qt.vector3d(0, 0, 0)
                  }
              }
          }
      }

      MouseArea {
          anchors.fill: qt_logo
          onClicked: {
              if (qt_logo.state == "flipped") {
                  qt_logo.state = "";
                  flip2.start();
                  texture.flipV = true;
              } else {
                  qt_logo.state = "flipped";
                  flip1.start();
                  texture.flipV = false;
              }
          }
      }

  }

We define simple QtQuick Items with an Image and a Text on a Rectangle.


  Image {
      anchors.fill: parent
      source: "qt_logo.png"
  }
  Text {
      id: text
      anchors.bottom: parent.bottom
      anchors.left: parent.left
      color: "white"
      font.pixelSize: 17
      text: qsTr("The Future is Written with Qt")
  }

This simple rectangle has two animations for flipping vertically.


  transform: Rotation {
      id: rotation
      origin.x: qt_logo.width / 2
      origin.y: qt_logo.height / 2
      axis { x: 1; y: 0; z: 0 }
      angle: qt_logo.angle
  }

  states: [
      State {
          name: "flipped";
          PropertyChanges { target: rotation; angle: 180 }
      }
  ]

  PropertyAnimation {
      id: flip1
      target: rotation
      property: "angle"
      duration: 600
      to: 180
      from: 0
  }
  PropertyAnimation {
      id: flip2
      target: rotation
      property: "angle"
      duration: 600
      to: 360
      from: 180
  }

Draw a 3D Cube

Drawing a cube is very simple. After defining a Camera, and a Light, we make a cube with a built-in Model. In this example, we render previous 2D Rectangle on this cube surface as a diffuse Texture. Back to the properties of the Rectangle, you can see layer.enabled. This property makes the 2D item as a offscreen surface.


  layer.enabled: true

Normally the texture is shown upside down due to the difference of coordinates between the 2D image and the 3D texture. So, we use the Texture.flipV property to flip it.


  id: cube
  visible: true
  position: Qt.vector3d(0, 0, 0)
  source: "#Cube"
  materials: [ DefaultMaterial {
          diffuseMap: Texture {
              id: texture
              sourceItem: qt_logo
              flipV: true
          }
      }
  ]
  rotation: Qt.vector3d(0, 90, 0)

Files:

Images: