How to render a OpenGL 2D texture on a QML surface? [closed] - qt

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 27 days ago.
The community is reviewing whether to reopen this question as of 27 days ago.
Improve this question
I have a valid OpenGL 2D texture. What is the best and simplest way to render it on a QML surface? Any simple Qt example(s) that I can refer to?
Basically I have the texture ID which is a GLuint. I do have access to the application's QOpenGLContext* which I believe is necessary to render the texture. Is there a simple example on how to render a texture on QML?
Environment:
MacOS Monterey and Android are my target platforms.
I don't find a straight example of this anywhere.

Below is a QML demo of a spinning 3D cube with the faces replaced with a Texture png.
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
Page {
background: Rectangle { color: "#848895" }
Node {
id: standAloneScene
DirectionalLight { ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0) }
Node {
id: node
Model {
source: "#Cube"
materials: [
DefaultMaterial {
diffuseMap: Texture {
sourceItem: Rectangle {
width: 256
height: 256
color: "#78a"
Image {
anchors.centerIn: parent
width: 224
height: 224
source: "https://stephenquan.github.io/images/qt/madewithqt.png"
}
}
}
}
]
}
}
OrthographicCamera {
id: cameraOrthographicFront
lookAtNode: node
y: 800; z: 1000
}
}
View3D {
anchors.fill: parent
importScene: standAloneScene
camera: cameraOrthographicFront
}
NumberAnimation {
target: node
property: "eulerRotation.y"
loops: Animation.Infinite
running: true
from: 720; to: 0
duration: 10000
}
}
You can Try it Online!
See:
https://doc.qt.io/qt-5/qml-qtquick3d-texture.html
https://doc.qt.io/qt-6/qml-qtquick3d-texture.html
https://doc.qt.io/qt-6/images/madewithqt.png

Related

Display seq 2D images in 3D space with Qml [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 days ago.
Improve this question
I developed software with python and Qml and I want to display a sequence of 2D images (100 slices) in a 3D space with Qml in this software. I think Qt3D or QtQuick 3D modules are proper for that purpose because the following code displays an image in 3D space but cannot figure out how to display a sequence of images.
import QtQuick 2.14
import QtQuick.Window 2.14
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
layer.enabled: true
Image {
anchors.fill: parent
source: "qt_logo.png"
}
}
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 {
id: cube
visible: true
position: Qt.vector3d(0, 0, 0)
source: "#Rectangle"
materials: [ DefaultMaterial {
diffuseMap: Texture {
id: texture
sourceItem: qt_logo
flipV: true
}
}
]
rotation: Qt.vector3d(0, 0, 0)
}
}
}
Edit: I searched a little more and I found the texture3D in the Qt3d module could be a better option for my purpose. But I can't find any example of texture3D in qml. Now the following questions are my problems? 1. How I can generate a texture3D from a stack of 2D images? 2. How I can display a texture3D in qml. 3. Can I generate input data manually for Texture3D (Like 3D array)?
Thank you for your help.
If you're using Texture you can set sourceItem to place any 2D component, including, Rectangle and Image onto a 3D object, such as a "#Cube".
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
Page {
background: Rectangle { color: "#848895" }
Node {
id: standAloneScene
DirectionalLight { ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0) }
Node {
id: node
Model {
source: "#Cube"
materials: [
DefaultMaterial {
diffuseMap: Texture {
sourceItem: MyItem { }
}
}
]
}
}
OrthographicCamera {
id: cameraOrthographicFront
lookAtNode: node
y: 800; z: 1000
}
}
View3D {
anchors.fill: parent
importScene: standAloneScene
camera: cameraOrthographicFront
}
NumberAnimation {
target: node
property: "eulerRotation.y"
loops: Animation.Infinite
running: true
from: 720; to: 0
duration: 10000
}
}
// MyItem.qml
import QtQuick
import QtQuick.Controls
Rectangle {
width: 256
height: 256
color: "#78a"
Repeater {
model: 5
Image {
x: index * 20 + 20
y: index * 20 + 20
width: 128
height: 128
source: "https://stephenquan.github.io/images/qt/madewithqt.png"
}
}
}
You can Try it Online!

QML 3D - change size (expand/reduce) of model rendered in UI to fit in the current window

I am rendering a 3D model using Mesh by reading from a .obj file, and I am trying to change its size dynamically to take the parent window's dimensions. Is there a way to resize the object? Currently when I run the app the model takes roughly half the height and one-third of the width of the main-window, and I am not sure where it picks it up from.
I have tried to use viewportRect in ForwardRenderer but that did not change the display. I was also trying to figure out if zooming with the camera would be possible, but from what I saw in the docs the zoom scale factor needs hardcoded integer values and again I need it to be dynamic.
The current display is like this -
Here is my code -
main.qml
Rectangle {
id: rootWindow
color: "black"
Visualizer {}
}
Visualizer.qml
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Extras 2.12
import Qt3D.Input 2.12
import QtQuick.Scene3D 2.12
import QtQuick 2.12 as QQ2
Scene3D {
id: scene3d
anchors.fill: parent
focus: true
aspects: ["input", "logic"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
Entity {
id: sceneRoot
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
nearPlane: 0.1
farPlane: 1000.0
position: Qt.vector3d(0.0, 0.0, 40.0)
upVector: Qt.vector3d(0.0, 1.0, 0.0)
viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
}
FirstPersonCameraController {
camera: camera
}
components: [
RenderSettings {
activeFrameGraph: ForwardRenderer {
camera: camera
clearColor: "transparent"
Viewport {
id: viewport
normalizedRect: Qt.rect(0, 0, 1, 1)
}
}
},
InputSettings {
id: inputSettings
}
]
PhongMaterial {
id: material
}
Mesh {
id: sphereMesh
// source: "images/face3d/face_bse_mesh.obj"
source: "images/robo-obj-pose4/source/d2f0cff60afc40f5afe79156ec7db657.obj"
}
Transform {
id: modelTransform
property real userAngle: 0.0
matrix: {
var m = Qt.matrix4x4()
m.rotate(userAngle, Qt.vector3d(0, 1, 0))
// m.translate(Qt.vector3d(20, 0, 0))
return m
}
}
QQ2.NumberAnimation {
target: modelTransform
property: "userAngle"
duration: 10000
from: 0
to: 360
loops: QQ2.Animation.Infinite
running: true
}
Entity {
id: sphereEntity
components: [sphereMesh, material, modelTransform]
}
OrbitCameraController{
id: orbitCamera
camera: camera
}
}
}
So after a lot of asking around I have found the solution to this. It's a fairly simple enough trick.
You just need to add the following code in the Mesh, and that takes care of resizing the model in it's containing window.
Mesh {
----
onStatusChanged: {
if(status == Mesh.Ready)
camera.viewAll()
}
}
Sometimes while rendering the model its edges tend to go beyond the boundaries of the parent window. Adding some anchors.margins in the root Scene3D usually takes care of that.

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:
and currently my app shows up like
.
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.
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
}

Docking in QtQuick [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
As far as I understand there is no built-in functionality for dockable containers in QtQuick. I found a few sources where this is added, however I am having trouble deciding which way to go.
https://developer.blackberry.com/native/documentation/dev/custom_components/index.html
How to get a QMainWindow from ApplicationWindow QML file to allow use of QDockWidget with QML files
Can someone recommend a way (or preferably a library) to add docking to QtQuick?
I found a solution that works with multiple windows moving a widget from the main window (docked state) to a new window (undocked state).
Hoping that this is useful to others here is a complete example:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtQuick.Window 2.2
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Window {
width: 100;
height: 100;
visible: false;
id: wnd
Rectangle {
id: greenRect
anchors.fill: parent
}
onClosing: {
blueRect.state = "docked"
}
}
Item {
width: 200; height: 100
Rectangle {
id: redRect
anchors.fill: parent
}
Rectangle {
id: blueRect
width: 50; height: 50
x: 10; y: 10;
color: "blue"
states: [
State {
name: "undocked"
ParentChange { target: blueRect; parent: greenRect; x: 10; y: 10 }
},
State {
name: "docked"
ParentChange { target: blueRect; parent: redRect; x: 10; y: 10 }
}
]
MouseArea {
anchors.fill: parent;
onClicked: {
blueRect.state = "undocked"
wnd.visible = true
}
}
}
}
}

Qt Quick move box with random movements

I'm trying to create a box that has some kind of Brownian motion (i.e. it keeps moving in random fashion) while the user can interact with it.
The interaction part works and is shortened below to resizing the height below.
The browian part doesn't work - I get two warnings at runtime:
[W] unknown:29 - file:.../EvasiveButton.qml:29:76: Unable to assign int to QEasingCurve
[W] unknown:29 - file:.../EvasiveButton.qml:29: ReferenceError: randomNumber is not defined
[W] unknown:24 - file:.../EvasiveButton.qml:24:54: Unable to assign int to QEasingCurve
So it appears i have at least the issue that my function randomNumber is not recognized. But moving it elsewhere doesn't seem to help.
Secondly, where do those warnings for ints to QEasingCurve come from?
The code:
import QtQuick 2.0
import QtQuick.Window 2.0
Rectangle {
width: Screen.width
height: Screen.height
color: "black"
focus: true
Rectangle {
x: 60
y: 60
width: 100
height: 100
color: "red"
MouseArea {
anchors.fill: parent
onClicked: parent.height += 50
}
Behavior on height {
NumberAnimation { duration: 200; easing: Easing.OutInQuint}
}
SequentialAnimation on x {
id: brownianMotionX
loops: Animation.Infinite
NumberAnimation {to: 40+randomNumber(); duration: 200; easing: Easing.OutInQuint}
}
function randomNumber() {
return Math.random() * 10 - 5;
}
}
}
Thanks for your suggestions!
randomNumber() is not available where you are calling it. Either move it up so it's declared before it's used, or give an id to your inner Rectangle to call it explicitly.
The easing errors are because you are trying to assign an easing curve style to a complete QEasingCurve - that's not going to work. So set the curve style specifically:
easing.type: Easing.OutInQuint

Resources