diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2012-01-25 19:18:25 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-09 07:32:07 +0100 |
commit | 298b86b95bd42d12e15e8d8a137cd9bee21d6094 (patch) | |
tree | 6ac8ee1d463f419966d64756452849d36913a885 /src/quick/items | |
parent | 3233e8052d2d25fd36567f67f9cd314cf0eaef92 (diff) |
Use QDeclarativePixmap in the Particle System
This allows for source URLs to come from network sources.
Change-Id: I416edca010e77e507598eaf4eead4291f044f379
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/qquicksprite.cpp | 8 | ||||
-rw-r--r-- | src/quick/items/qquicksprite_p.h | 8 | ||||
-rw-r--r-- | src/quick/items/qquickspriteengine.cpp | 76 | ||||
-rw-r--r-- | src/quick/items/qquickspriteengine_p.h | 18 | ||||
-rw-r--r-- | src/quick/items/qquickspriteimage.cpp | 10 |
5 files changed, 94 insertions, 26 deletions
diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp index 46d1944dc1..4de7880916 100644 --- a/src/quick/items/qquicksprite.cpp +++ b/src/quick/items/qquicksprite.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qquicksprite_p.h" +#include <qdeclarative.h> #include <QDebug> QT_BEGIN_NAMESPACE @@ -255,4 +256,11 @@ int QQuickSprite::variedDuration() const //Deals with precedence when multiple d return QQuickStochasticState::variedDuration() * m_frames; } +void QQuickSprite::startImageLoading() +{ + m_pix.clear(this); + if (!m_source.isEmpty()) + m_pix.load(qmlEngine(this), m_source); +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h index bf0a4651f5..4c5e5ff58e 100644 --- a/src/quick/items/qquicksprite_p.h +++ b/src/quick/items/qquicksprite_p.h @@ -46,6 +46,7 @@ #include <QUrl> #include <QVariantMap> #include <QDeclarativeListProperty> +#include <QtQuick/private/qdeclarativepixmapcache_p.h> #include "qquickspriteengine_p.h" QT_BEGIN_HEADER @@ -90,7 +91,6 @@ public: return m_frameWidth; } - bool reverse() const { return m_reverse; @@ -181,6 +181,7 @@ public slots: if (m_source != arg) { m_source = arg; emit sourceChanged(arg); + startImageLoading(); } } @@ -200,7 +201,6 @@ public slots: } } - void setReverse(bool arg) { if (m_reverse != arg) { @@ -273,6 +273,9 @@ public slots: } } +private slots: + void startImageLoading(); + private: friend class QQuickImageParticle; friend class QQuickSpriteImage; @@ -295,6 +298,7 @@ private: int m_frameDuration; int m_frameDurationVariation; bool m_frameSync; + QDeclarativePixmap m_pix; }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index a076a0cc61..c19a5e65c9 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -41,6 +41,8 @@ #include "qquickspriteengine_p.h" #include "qquicksprite_p.h" +#include <qdeclarativeinfo.h> +#include <qdeclarative.h> #include <QDebug> #include <QPainter> #include <QSet> @@ -100,12 +102,12 @@ QQuickStochasticEngine::~QQuickStochasticEngine() } QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent) - : QQuickStochasticEngine(parent) + : QQuickStochasticEngine(parent), m_startedImageAssembly(false) { } QQuickSpriteEngine::QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent) - : QQuickStochasticEngine(parent) + : QQuickStochasticEngine(parent), m_startedImageAssembly(false) { foreach (QQuickSprite* sprite, sprites) m_states << (QQuickStochasticState*)sprite; @@ -305,16 +307,35 @@ void QQuickStochasticEngine::setGoal(int state, int sprite, bool jump) return; } -QImage QQuickSpriteEngine::assembledImage() +QDeclarativePixmap::Status QQuickSpriteEngine::status()//Composed status of all Sprites { - int h = 0; - int w = 0; - m_maxFrames = 0; - m_imageStateCount = 0; - int maxSize = 0; + if (!m_startedImageAssembly) + return QDeclarativePixmap::Null; + int null, loading, ready; + null = loading = ready = 0; + foreach (QQuickSprite* s, m_sprites) { + switch (s->m_pix.status()) { + case QDeclarativePixmap::Null : null++; break; + case QDeclarativePixmap::Loading : loading++; break; + case QDeclarativePixmap::Error : return QDeclarativePixmap::Error; + case QDeclarativePixmap::Ready : ready++; break; + } + } + if (null) + return QDeclarativePixmap::Null; + if (loading) + return QDeclarativePixmap::Loading; + if (ready) + return QDeclarativePixmap::Ready; + return QDeclarativePixmap::Null; +} - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); - //qDebug() << "MAX TEXTURE SIZE" << maxSize; +void QQuickSpriteEngine::startAssemblingImage() +{ + if (m_startedImageAssembly) + return; + + //This could also trigger the start of the image loading in Sprites, however that currently happens in Sprite::setSource foreach (QQuickStochasticState* s, m_states){ QQuickSprite* sprite = qobject_cast<QQuickSprite*>(s); if (sprite) @@ -322,18 +343,35 @@ QImage QQuickSpriteEngine::assembledImage() else qDebug() << "Error: Non-sprite in QQuickSpriteEngine"; } + m_startedImageAssembly = true; +} +QImage QQuickSpriteEngine::assembledImage() +{ + QDeclarativePixmap::Status stat = status(); + if (stat == QDeclarativePixmap::Error) + foreach (QQuickSprite* s, m_sprites) + if (s->m_pix.isError()) + qmlInfo(s) << s->m_pix.error(); + + if (stat != QDeclarativePixmap::Ready) + return QImage(); + + int h = 0; + int w = 0; + m_maxFrames = 0; + m_imageStateCount = 0; + int maxSize = 0; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); + //qDebug() << "MAX TEXTURE SIZE" << maxSize; foreach (QQuickSprite* state, m_sprites){ if (state->frames() > m_maxFrames) m_maxFrames = state->frames(); - QImage img(state->source().toLocalFile()); - if (img.isNull()) { - qWarning() << "SpriteEngine: loading image failed..." << state->source().toLocalFile(); - return QImage(); - } + QImage img = state->m_pix.image(); - //Check that the frame sizes are the same within one engine + //Check that the frame sizes are the same within one sprite if (!state->m_frameWidth) state->m_frameWidth = img.width() / state->frames(); @@ -347,10 +385,10 @@ QImage QQuickSpriteEngine::assembledImage() int rowsNeeded = helper::divRoundUp(state->frames(), (maxSize / state->frameWidth())); if (h + rowsNeeded * state->frameHeight() > maxSize){ if (rowsNeeded * state->frameHeight() > maxSize) - qWarning() << "SpriteEngine: Animation too large to fit in one texture:" << state->source().toLocalFile(); + qmlInfo(state) << "SpriteEngine: Animation too large to fit in one texture:" << state->source().toLocalFile(); else - qWarning() << "SpriteEngine: Animations too large to fit in one texture, pushed over the edge by:" << state->source().toLocalFile(); - qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; + qmlInfo(state) << "SpriteEngine: Animations too large to fit in one texture, pushed over the edge by:" << state->source().toLocalFile(); + qmlInfo(state) << "SpriteEngine: Your texture max size today is " << maxSize; } state->m_generatedCount = rowsNeeded; h += state->frameHeight() * rowsNeeded; diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h index 34de7282ec..500d526da5 100644 --- a/src/quick/items/qquickspriteengine_p.h +++ b/src/quick/items/qquickspriteengine_p.h @@ -50,6 +50,7 @@ #include <QDeclarativeListProperty> #include <QImage> #include <QPair> +#include <QtQuick/private/qdeclarativepixmapcache_p.h> QT_BEGIN_HEADER @@ -61,7 +62,7 @@ class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //Currently for i Q_OBJECT Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged) Q_PROPERTY(int durationVariation READ durationVariation WRITE setDurationVariation NOTIFY durationVariationChanged) - //Note than manually advanced sprites need to query this variable and implement own behaviour for it + //Note that manually advanced sprites need to query this variable and implement own behaviour for it Q_PROPERTY(bool randomStart READ randomStart WRITE setRandomStart NOTIFY randomStartChanged) Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) @@ -268,21 +269,30 @@ public: int spriteState(int sprite=0); int spriteStart(int sprite=0); int spriteFrames(int sprite=0); - int spriteDuration(int sprite=0);//Full duration, not per frame + int spriteDuration(int sprite=0); int spriteX(int sprite=0); int spriteY(int sprite=0); int spriteWidth(int sprite=0); int spriteHeight(int sprite=0); int spriteCount();//Like state count int maxFrames(); - QString realName(int sprite=0);//Gives the parent sprite name for pseudosprites - QImage assembledImage(); virtual void restart(int index=0); virtual void advance(int index=0); + + //Similar API to QDeclarativePixmap for async loading convenience + bool isNull() { return status() == QDeclarativePixmap::Null; } + bool isReady() { return status() == QDeclarativePixmap::Ready; } + bool isLoading() { return status() == QDeclarativePixmap::Loading; } + bool isError() { return status() == QDeclarativePixmap::Error; } + QDeclarativePixmap::Status status();//Composed status of all Sprites + void startAssemblingImage(); + QImage assembledImage(); + private: int pseudospriteProgress(int,int,int*rd=0); QList<QQuickSprite*> m_sprites; + bool m_startedImageAssembly; }; //Common use is to have your own list property which is transparently an engine diff --git a/src/quick/items/qquickspriteimage.cpp b/src/quick/items/qquickspriteimage.cpp index 755c41d031..1b3b57710a 100644 --- a/src/quick/items/qquickspriteimage.cpp +++ b/src/quick/items/qquickspriteimage.cpp @@ -49,6 +49,7 @@ #include <QtQuick/qsgtexturematerial.h> #include <QtQuick/qsgtexture.h> #include <QtQuick/qquickcanvas.h> +#include <QtDeclarative/qdeclarativeinfo.h> #include <QFile> #include <cmath> #include <qmath.h> @@ -324,7 +325,14 @@ static QSGGeometry::AttributeSet SpriteImage_AttributeSet = QSGGeometryNode* QQuickSpriteImage::buildNode() { if (!m_spriteEngine) { - qWarning() << "SpriteImage: No sprite engine..."; + qmlInfo(this) << "No sprite engine..."; + return 0; + } else if (m_spriteEngine->status() == QDeclarativePixmap::Null) { + m_spriteEngine->startAssemblingImage(); + update();//Schedule another update, where we will check again + return 0; + } else if (m_spriteEngine->status() == QDeclarativePixmap::Loading) { + update();//Schedule another update, where we will check again return 0; } |