Qt Scene Graph渲染方式在不同系统的差异
Qt Scene Graph是Qt5提出的新渲染底层,它是Qt Quick在绝大多数平台上渲染的基础(Qt4的是依赖Qt Graphics View)。了解和学习Qt的SceneGraph,怎么也不为过。最近我发现一个现象,那就是Qt Scene Graph在不同平台上的渲染流程是不一样的。通常情况下这没什么,可是它会影响Qt Quick的一些特定的类,比如说Animator。
蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/48278951。欢迎同行前来探讨。
首先来认识一下Qt5.2引入的一个类(事实上Qt 5.5我才看到它),叫Animator,它的作用和Animation非常相似,除了不能反向运动、值不在中途更新等。它的原理是将动画分配到不同的渲染线程来完成,借助OpenGL的着色器设置,将渲染的压力分摊到其它的线程中了,听起来很好,不过我们在使用的过程中,和Animation类相差无几。那差别究竟在哪儿呢?下面我来制作一个小的例子,这个例子将模拟复杂的运算,然后看复杂运算究竟会不会影响Animator的操作。
首先是C++的部分,很简单的一个类,以上下文变量的方式注入QML环境中:
// TestObject.h
#ifndef TESTOBJECT_H
#define TESTOBJECT_H
#include <QObject>
class TestObject : public QObject
{
Q_OBJECT
public:
explicit TestObject(QObject *parent = 0);
Q_INVOKABLE void longOperation( void );
signals:
public slots:
};
#endif // TESTOBJECT_H
// TestObject.cpp
#include <QCoreApplication>
#include "TestObject.h"
TestObject::TestObject(QObject *parent) : QObject(parent)
{
}
void TestObject::longOperation( void )
{
for ( int i = 3; i < 100000; ++i )
{
srand( i++ );
int output = rand( );
qDebug( "rand output is: %d", output );
}
}
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "TestObject.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<TestObject>( "Test",
0,
1,
"TestObject" );
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
这里使用TestObject::longOperation( )来模拟复杂的运算,然后我们在QML中找一个按钮触发这个运算:
// main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import Test 0.1
Window
{
visible: true
width: 270
height: 480
Rectangle
{
id: rotatingBox
width: 150
height: 150
color: "lightsteelblue"
RotationAnimator
{
target: rotatingBox
from: 0
to: 360
duration: 1000
loops: Animator.Infinite
running: true
}
}
Button
{
anchors.centerIn: parent
text: "A long operation"
onClicked:
{
to.longOperation( );
}
}
TestObject
{
id: to
}
}
对,我们对名为“A long operation”的按钮进行复杂运算的模拟。在按下这个按钮的时候,将会执行复杂的运算。我们首先在Windows上测试:结果是这样的:
实际运行时我们发现&