diff options
author | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-08-31 08:55:16 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@nokia.com> | 2011-08-31 08:55:16 +0200 |
commit | 71478352376022faa9be6d79f2a760c289945ff5 (patch) | |
tree | 0f8ff4a88c1b033367337a93d23a329d145ee903 /src/declarative/particles | |
parent | c38efcb67cf93ba3e91e184c3b891efef4ef75a3 (diff) | |
parent | 05daa9bfe1a03ffe1cc580b6cfd88e093e2493c0 (diff) |
Merge branch 'master' into refactor
Conflicts:
src/3rdparty/v8
src/declarative/declarative.pro
src/declarative/items/qsgcanvas.cpp
src/declarative/items/qsgshadereffectsource_p.h
src/declarative/items/qsgview.cpp
src/declarative/particles/qsgcustomparticle.cpp
src/imports/gestures/gestures.pro
src/imports/particles/particles.pro
src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
src/qtquick1/qtquick1.pro
tests/auto/declarative/examples/examples.pro
tests/auto/declarative/qsglistview/qsglistview.pro
tests/auto/qtquick1/qdeclarativeviewer/qdeclarativeviewer.pro
Change-Id: I423344f83e1835116cad531b877fde6e68a8849a
Diffstat (limited to 'src/declarative/particles')
-rw-r--r-- | src/declarative/particles/defaultshaders/imagevertex.shader | 3 | ||||
-rw-r--r-- | src/declarative/particles/qsgcustomparticle.cpp | 69 | ||||
-rw-r--r-- | src/declarative/particles/qsgimageparticle.cpp | 4 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticleaffector.cpp | 10 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticlesystem_p.h | 1 | ||||
-rw-r--r-- | src/declarative/particles/qsgpointattractor.cpp | 28 | ||||
-rw-r--r-- | src/declarative/particles/qsgpointattractor_p.h | 5 | ||||
-rw-r--r-- | src/declarative/particles/qsgv8particledata.cpp | 4 |
8 files changed, 88 insertions, 36 deletions
diff --git a/src/declarative/particles/defaultshaders/imagevertex.shader b/src/declarative/particles/defaultshaders/imagevertex.shader index e1033c9165..9967ef85a2 100644 --- a/src/declarative/particles/defaultshaders/imagevertex.shader +++ b/src/declarative/particles/defaultshaders/imagevertex.shader @@ -75,8 +75,9 @@ void main() { currentSize = currentSize * sizetable[int(floor(t*64.))]; fade = fade * opacitytable[int(floor(t*64.))]; #endif + if (entry == 1.) - fade = fadeIn * fadeOut; + fade = fade * fadeIn * fadeOut; else if(entry == 2.) currentSize = currentSize * fadeIn * fadeOut; diff --git a/src/declarative/particles/qsgcustomparticle.cpp b/src/declarative/particles/qsgcustomparticle.cpp index db544d20e8..12d32a27b4 100644 --- a/src/declarative/particles/qsgcustomparticle.cpp +++ b/src/declarative/particles/qsgcustomparticle.cpp @@ -45,17 +45,17 @@ QT_BEGIN_NAMESPACE -//TODO: Can we make the code such that you don't have to copy the whole vertex shader just to add one little calculation? //Includes comments because the code isn't self explanatory -static const char qt_particles_default_vertex_code[] = +static const char qt_particles_template_vertex_code[] = "attribute highp vec2 vPos; \n" "attribute highp vec2 vTex; \n" "attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize \n" "attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration \n" + "attribute highp float r; \n" "uniform highp mat4 qt_Matrix; \n" "uniform highp float timestamp; \n" "varying highp vec2 fTex; \n" - "void main() { \n" + "void defaultMain() { \n" " fTex = vTex; \n" " highp float size = vData.z; \n" " highp float endSize = vData.w; \n" @@ -68,6 +68,10 @@ static const char qt_particles_default_vertex_code[] = " + vVec.xy * t * vData.y // apply speed vector.. \n" " + 0.5 * vVec.zw * pow(t * vData.y, 2.); \n" " gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); \n" + "}\n"; +static const char qt_particles_default_vertex_code[] = + "void main() { \n" + " defaultMain(); \n" "}"; static const char qt_particles_default_fragment_code[] =//TODO: Default frag requires source? @@ -78,9 +82,6 @@ static const char qt_particles_default_fragment_code[] =//TODO: Default frag req " gl_FragColor = texture2D(source, fTex) * qt_Opacity; \n" "}"; -static const char qt_position_attribute_name[] = "qt_Vertex"; -static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0"; - static QSGGeometry::Attribute PlainParticle_Attributes[] = { { 0, 2, GL_FLOAT }, // Position { 1, 2, GL_FLOAT }, // TexCoord @@ -157,8 +158,9 @@ void QSGCustomParticle::componentComplete() \qmlproperty string QtQuick.Particles2::CustomParticle::fragmentShader This property holds the fragment shader's GLSL source code. - The default shader passes the texture coordinate along to the fragment - shader as "varying highp vec2 qt_TexCoord0". + The default shader expects the texture coordinate to be passed from the + vertex shader as "varying highp vec2 fTex", and it samples from a + sampler2D named "source". */ void QSGCustomParticle::setFragmentShader(const QByteArray &code) @@ -176,9 +178,41 @@ void QSGCustomParticle::setFragmentShader(const QByteArray &code) \qmlproperty string QtQuick.Particles2::CustomParticle::vertexShader This property holds the vertex shader's GLSL source code. - The default shader expects the texture coordinate to be passed from the - vertex shader as "varying highp vec2 qt_TexCoord0", and it samples from a - sampler2D named "source". + + The default shader passes the texture coordinate along to the fragment + shader as "varying highp vec2 fTex". + + To aid writing a particle vertex shader, the following GLSL code is prepended + to your vertex shader: + \code + attribute highp vec2 vPos; + attribute highp vec2 vTex; + attribute highp vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize + attribute highp vec4 vVec; // x,y = constant speed, z,w = acceleration + attribute highp float r; + uniform highp mat4 qt_Matrix; + uniform highp float timestamp; + varying highp vec2 fTex; + void defaultMain() { + fTex = vTex; + highp float size = vData.z; + highp float endSize = vData.w; + highp float t = (timestamp - vData.x) / vData.y; + highp float currentSize = mix(size, endSize, t * t); + if (t < 0. || t > 1.) + currentSize = 0.; + highp vec2 pos = vPos + - currentSize / 2. + currentSize * vTex // adjust size + + vVec.xy * t * vData.y // apply speed vector.. + + 0.5 * vVec.zw * pow(t * vData.y, 2.); + gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1); + } + \endcode + + defaultMain() is the same code as in the default shader, you can call this for basic + particle functions and then add additional variables for custom effects. Note that + the vertex shader for particles is responsible for simulating the movement of particles + over time, the particle data itself only has the starting position and spawn time. */ void QSGCustomParticle::setVertexShader(const QByteArray &code) @@ -311,6 +345,7 @@ void QSGCustomParticle::updateProperties() vertexCode = qt_particles_default_vertex_code; if (fragmentCode.isEmpty()) fragmentCode = qt_particles_default_fragment_code; + vertexCode = qt_particles_template_vertex_code + vertexCode; m_source.attributeNames.clear(); m_source.attributeNames << "vPos" << "vTex" << "vData" << "vVec" << "r"; @@ -318,10 +353,6 @@ void QSGCustomParticle::updateProperties() lookThroughShaderCode(vertexCode); lookThroughShaderCode(fragmentCode); - if (!m_source.attributeNames.contains(qt_position_attribute_name)) - qWarning("QSGCustomParticle: Missing reference to \'%s\'.", qt_position_attribute_name); - if (!m_source.attributeNames.contains(qt_texcoord_attribute_name)) - qWarning("QSGCustomParticle: Missing reference to \'%s\'.", qt_texcoord_attribute_name); if (!m_source.respectsMatrix) qWarning("QSGCustomParticle: Missing reference to \'qt_Matrix\'."); if (!m_source.respectsOpacity) @@ -352,17 +383,13 @@ void QSGCustomParticle::lookThroughShaderCode(const QByteArray &code) QByteArray name = re.cap(3).toLatin1(); // variable name if (decl == "attribute") { - if (!m_source.attributeNames.contains(name))//TODO: Can they add custom attributes? + if (!m_source.attributeNames.contains(name)) qWarning() << "Custom Particle: Unknown attribute " << name; } else { Q_ASSERT(decl == "uniform");//TODO: Shouldn't assert if (name == "qt_Matrix") { m_source.respectsMatrix = true; - } else if (name == "qt_ModelViewProjectionMatrix") { - // TODO: Remove after grace period. - qWarning("ShaderEffect: qt_ModelViewProjectionMatrix is deprecated. Use qt_Matrix instead."); - m_source.respectsMatrix = true; } else if (name == "qt_Opacity") { m_source.respectsOpacity = true; } else if (name == "timestamp") { @@ -443,7 +470,9 @@ QSGShaderEffectNode* QSGCustomParticle::buildCustomNodes() m_material = new QSGShaderEffectMaterialObject; } + s.vertexCode = qt_particles_template_vertex_code + s.vertexCode; m_material->setProgramSource(s); + foreach (const QString &str, m_particles){ int gIdx = m_system->m_groupIds[str]; int count = m_system->m_groupData[gIdx]->size(); diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp index 737b393de7..853a08a890 100644 --- a/src/declarative/particles/qsgimageparticle.cpp +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -258,7 +258,7 @@ public: m_animcount_id = program()->uniformLocation("animcount"); m_entry_id = program()->uniformLocation("entry"); m_sizetable_id = program()->uniformLocation("sizetable"); - m_opacitytable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("opacitytable"); } void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) { @@ -432,7 +432,7 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size) { if (img.isNull()){ for (int i=0; i<size; i++) - array[i] = 1; + array[i] = 1.0; return; } QImage scaled = img.scaled(size,1); diff --git a/src/declarative/particles/qsgparticleaffector.cpp b/src/declarative/particles/qsgparticleaffector.cpp index 4cb3e49403..331310625f 100644 --- a/src/declarative/particles/qsgparticleaffector.cpp +++ b/src/declarative/particles/qsgparticleaffector.cpp @@ -42,6 +42,7 @@ #include "qsgparticleaffector_p.h" #include <QDebug> QT_BEGIN_NAMESPACE + /*! \qmlclass Affector QSGParticleAffector \inqmlmodule QtQuick.Particles 2 @@ -159,8 +160,10 @@ void QSGParticleAffector::affectSystem(qreal dt) if ((m_onceOff && m_onceOffed.contains(qMakePair(d->group, d->index))) || !d->stillAlive()) continue; - //Need to have previous location for affected. if signal || shape might be faster? - QPointF curPos = QPointF(d->curX(), d->curY()); + //Need to have previous location for affected anyways + QPointF curPos; + if (m_signal || (width() && height())) + curPos = QPointF(d->curX(), d->curY()); if (width() == 0 || height() == 0 || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){ if (m_collisionParticles.isEmpty() || isColliding(d)){ @@ -181,8 +184,9 @@ void QSGParticleAffector::affectSystem(qreal dt) bool QSGParticleAffector::affectParticle(QSGParticleData *d, qreal dt) { if (isAffectConnected()){ + d->update = 0.0; emit affectParticle(d->v8Value(), dt); - return true; + return d->update == 1.0; } return m_signal;//If signalling, then we always 'null affect' it. } diff --git a/src/declarative/particles/qsgparticlesystem_p.h b/src/declarative/particles/qsgparticlesystem_p.h index 9f4020d041..abb7f52c31 100644 --- a/src/declarative/particles/qsgparticlesystem_p.h +++ b/src/declarative/particles/qsgparticlesystem_p.h @@ -202,6 +202,7 @@ public: float r; QSGItem* delegate; int modelIndex; + float update;//Used by custom affectors void debugDump(); bool stillAlive(); diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp index 1a3c3c25c5..21eaeaac12 100644 --- a/src/declarative/particles/qsgpointattractor.cpp +++ b/src/declarative/particles/qsgpointattractor.cpp @@ -65,21 +65,31 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt) { if (m_strength == 0.0) return false; - qreal dx = m_y - d->curX(); - qreal dy = m_x - d->curY(); + qreal dx = m_x - d->curX(); + qreal dy = m_y - d->curY(); qreal r = sqrt((dx*dx) + (dy*dy)); qreal theta = atan2(dy,dx); qreal ds = 0; switch (m_proportionalToDistance){ + case InverseQuadratic: + ds = (m_strength / qMax<qreal>(1.,r*r)); + break; + case InverseLinear: + ds = (m_strength / qMax<qreal>(1.,r)); + break; case Quadratic: - ds = (m_strength / qMax<qreal>(1.,r*r)) * dt; + ds = (m_strength * qMax<qreal>(1.,r*r)); break; - case Linear://also default - default: - ds = (m_strength / qMax<qreal>(1.,r)) * dt; + case Linear: + ds = (m_strength * qMax<qreal>(1.,r)); + break; + default: //also Constant + ds = m_strength; } + ds *= dt; dx = ds * cos(theta); dy = ds * sin(theta); + qreal vx,vy; switch (m_physics){ case Position: d->x = (d->x + dx); @@ -91,8 +101,10 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt) break; case Velocity: //also default default: - d->setInstantaneousVX(d->vx + dx); - d->setInstantaneousVY(d->vy + dy); + vx = d->curVX(); + vy = d->curVY(); + d->setInstantaneousVX(vx + dx); + d->setInstantaneousVY(vy + dy); } return true; diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h index 95716483ed..298965a5c9 100644 --- a/src/declarative/particles/qsgpointattractor_p.h +++ b/src/declarative/particles/qsgpointattractor_p.h @@ -64,8 +64,11 @@ class QSGPointAttractorAffector : public QSGParticleAffector public: enum Proportion{ + Constant, Linear, - Quadratic + Quadratic, + InverseLinear, + InverseQuadratic }; enum PhysicsAffects { diff --git a/src/declarative/particles/qsgv8particledata.cpp b/src/declarative/particles/qsgv8particledata.cpp index b3ff482d8b..72c0b7c2de 100644 --- a/src/declarative/particles/qsgv8particledata.cpp +++ b/src/declarative/particles/qsgv8particledata.cpp @@ -150,6 +150,7 @@ FLOAT_GETTER_AND_SETTER(frameDuration) FLOAT_GETTER_AND_SETTER(frameCount) FLOAT_GETTER_AND_SETTER(animT) FLOAT_GETTER_AND_SETTER(r) +FLOAT_GETTER_AND_SETTER(update) FAKE_FLOAT_GETTER_AND_SETTER(curX, curX, setInstantaneousX) FAKE_FLOAT_GETTER_AND_SETTER(curVX, curVX, setInstantaneousVX) FAKE_FLOAT_GETTER_AND_SETTER(curAX, curAX, setInstantaneousAX) @@ -157,7 +158,7 @@ FAKE_FLOAT_GETTER_AND_SETTER(curY, curY, setInstantaneousY) FAKE_FLOAT_GETTER_AND_SETTER(curVY, curVY, setInstantaneousVY) FAKE_FLOAT_GETTER_AND_SETTER(curAY, curAY, setInstantaneousAY) -//TODO: Non-floats (color) and special floats (curX) once basic floats are working well +//TODO: Non-floats (color, update?) once floats are working well QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) { @@ -189,6 +190,7 @@ QV8ParticleDataDeletable::QV8ParticleDataDeletable(QV8Engine *engine) FLOAT_REGISTER_ACCESSOR(ft, engine, frameCount); FLOAT_REGISTER_ACCESSOR(ft, engine, animT); FLOAT_REGISTER_ACCESSOR(ft, engine, r); + FLOAT_REGISTER_ACCESSOR(ft, engine, update); FLOAT_REGISTER_ACCESSOR(ft, engine, curX); FLOAT_REGISTER_ACCESSOR(ft, engine, curVX); FLOAT_REGISTER_ACCESSOR(ft, engine, curAX); |