gpt4 book ai didi

c++ - 如何在 C++ 的精确帧中设置 QQuickItem 位置?

转载 作者:行者123 更新时间:2023-11-30 05:42:24 29 4
gpt4 key购买 nike

我的移动应用程序使用 QML 范式下的 OpenGL

我的 GL 场景的相机方向与移动设备的运动传感器(磁力计和加速度计)同步。我还在该 3D 场景的顶部显示一个 2D 标签,其在屏幕上的位置需要对应于我的 GL 场景中给定的 3D 位置。这些标签是我从应用程序的 C++ 端控制的常规 QML 项目。

为此,我直接连接到 QQuickWindow::beforeSynchronising() 信号,其中相机方向与运动传感器同步。然后,我在屏幕上投影一个 3D 点以找到标签的位置,最后调用 QQuickItem::setPosition()

GL 场景像往常一样使用直接连接到 QQuickWindow::beforeRendering() 信号进行渲染。

MyAppController::MyAppController() : QObject() {
connect(window, SIGNAL(beforeSynchronising()), this, SLOT(sync()), Qt::DirectConnection);
connect(window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection);

m_camera = ...; // create camera
m_scene = ...; // create GL scene
m_quickItem = ...; // load label QML item

// start updating the window at a constant frame rate
QTimer* timer = new QTimer(this);
connect (timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000.0 / 60.0); // 60 FPS
}

MyAppController::sync() {
m_camera->syncWithMotionSensor();

// use camera matrix to calculate the projection of a 3D point on the screen
QPointF pos = ...;
m_quickItem->setPosition(pos); // set the label position
}

MyAppController::render() {
m_scene->draw(); // OpenGL code
}

一切都很好,除了我的标签似乎比我的 GL 场景晚了一帧,我想我明白为什么:从 QSGRendering 线程调用 QQuickItem::setPosition() 显然是QSGNode 来不及更新该帧。为该项目安排了更新,但直到下一帧才会生效。因此有 1 帧延迟。

您可能认为这还不错,但是,它确实产生了一种奇怪的效果并且无助于阅读标签上的内容,因为眼睛也在跟随背景(请记住相机与设备运动传感器同步) .

我尝试使用 QQuickWindow::afterAnimating() 信号,但延迟更大。这是正常的,因为这个信号是从 GUI 线程发出的,因此我们对 QSGRenderThread 将同步的帧的控制更少。

所以我的问题是,如何从 C++ 实现 QML 项在精确框架中的定位?这甚至可以使用 QML 吗?如果我的标签是纯 C++ QQuickItems 并且我使用我自己的函数来确保 QSGNode 将接收更新而不是调用 setPosition() 会更好吗?

最佳答案

所以答案是在渲染 GL 场景之后简单地同步相机和标签的位置。这样我们就可以确保在下一帧中标签的位置将被考虑在内。最终解决方案如下所示:

MyAppController::sync() {
m_scene->prepare(); // uses the camera matrix from previous frame
m_camera->syncWithMotionSensor(); // update camera matrix
// use camera matrix to calculate the projection of a 3D point on the screen
QPointF pos = ...;
m_quickItem->setPosition(pos); // set the label position, will be updated on the next frame
}

MyAppController::render() {
m_scene->draw(); // execute OpenGL code
}

关于c++ - 如何在 C++ 的精确帧中设置 QQuickItem 位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30676393/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com