summaryrefslogtreecommitdiffstats
path: root/src/imports/particles/coloredparticle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/particles/coloredparticle.cpp')
-rw-r--r--src/imports/particles/coloredparticle.cpp247
1 files changed, 160 insertions, 87 deletions
diff --git a/src/imports/particles/coloredparticle.cpp b/src/imports/particles/coloredparticle.cpp
index 72ebddc3b7..7d0ec4cb0a 100644
--- a/src/imports/particles/coloredparticle.cpp
+++ b/src/imports/particles/coloredparticle.cpp
@@ -1,14 +1,58 @@
-#include <qsgcontext.h>
-#include <adaptationlayer.h>
-#include <node.h>
-#include <texturematerial.h>
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Declarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <qsgnode.h>
+#include <qsgtexturematerial.h>
#include <qsgtexture.h>
#include <QFile>
#include "coloredparticle.h"
#include "particleemitter.h"
+#include <QGLFunctions>
+#include <qsgengine.h>
+
QT_BEGIN_NAMESPACE
-class ParticleTrailsMaterial : public AbstractMaterial
+class ParticleTrailsMaterial : public QSGMaterial
{
public:
ParticleTrailsMaterial()
@@ -17,20 +61,25 @@ public:
setFlag(Blending, true);
}
- virtual AbstractMaterialType *type() const { static AbstractMaterialType type; return &type; }
- virtual AbstractMaterialShader *createShader() const;
- virtual int compare(const AbstractMaterial *other) const
+ ~ParticleTrailsMaterial()
+ {
+ delete texture;
+ }
+
+ virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+ virtual QSGMaterialShader *createShader() const;
+ virtual int compare(const QSGMaterial *other) const
{
return this - static_cast<const ParticleTrailsMaterial *>(other);
}
- QSGTextureRef texture;
+ QSGTexture *texture;
qreal timestamp;
};
-class ParticleTrailsMaterialData : public AbstractMaterialShader
+class ParticleTrailsMaterialData : public QSGMaterialShader
{
public:
ParticleTrailsMaterialData(const char *vertexFile = 0, const char *fragmentFile = 0)
@@ -48,24 +97,24 @@ public:
}
void deactivate() {
- AbstractMaterialShader::deactivate();
+ QSGMaterialShader::deactivate();
for (int i=0; i<8; ++i) {
m_program.setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
}
}
- virtual void updateState(Renderer *renderer, AbstractMaterial *newEffect, AbstractMaterial *, Renderer::Updates updates)
+ virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
{
ParticleTrailsMaterial *m = static_cast<ParticleTrailsMaterial *>(newEffect);
- renderer->glActiveTexture(GL_TEXTURE0);
+ state.context()->functions()->glActiveTexture(GL_TEXTURE0);
m->texture->bind();
- m_program.setUniformValue(m_opacity_id, (float) renderer->renderOpacity());
+ m_program.setUniformValue(m_opacity_id, state.opacity());
m_program.setUniformValue(m_timestamp_id, (float) m->timestamp);
- if (updates & Renderer::UpdateMatrices)
- m_program.setUniformValue(m_matrix_id, renderer->combinedMatrix());
+ if (state.isMatrixDirty())
+ m_program.setUniformValue(m_matrix_id, state.combinedMatrix());
}
virtual void initialize() {
@@ -103,7 +152,7 @@ public:
float ParticleTrailsMaterialData::chunkOfBytes[1024];
-AbstractMaterialShader *ParticleTrailsMaterial::createShader() const
+QSGMaterialShader *ParticleTrailsMaterial::createShader() const
{
return new ParticleTrailsMaterialData;
}
@@ -116,10 +165,19 @@ public:
{
}
- virtual AbstractMaterialType *type() const { static AbstractMaterialType type; return &type; }
- virtual AbstractMaterialShader *createShader() const;
+ ~ParticleTrailsMaterialCT()
+ {
+ delete colortable;
+ delete sizetable;
+ delete opacitytable;
+ }
+
+ virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+ virtual QSGMaterialShader *createShader() const;
- QSGTextureRef colortable;
+ QSGTexture *colortable;
+ QSGTexture *sizetable;
+ QSGTexture *opacitytable;
};
@@ -136,69 +194,53 @@ public:
virtual void initialize() {
ParticleTrailsMaterialData::initialize();
m_colortable_id = m_program.uniformLocation("colortable");
+ m_sizetable_id = m_program.uniformLocation("sizetable");
+ m_opacitytable_id = m_program.uniformLocation("opacitytable");
}
- virtual void updateState(Renderer *renderer, AbstractMaterial *current, AbstractMaterial *old, Renderer::Updates updates)
+ virtual void updateState(const RenderState &state, QSGMaterial *current, QSGMaterial *old)
{
// Bind the texture to unit 1 before calling the base class, so that the
// base class can set active texture back to 0.
ParticleTrailsMaterialCT *m = static_cast<ParticleTrailsMaterialCT *>(current);
- renderer->glActiveTexture(GL_TEXTURE1);
+ state.context()->functions()->glActiveTexture(GL_TEXTURE1);
m->colortable->bind();
m_program.setUniformValue(m_colortable_id, 1);
- ParticleTrailsMaterialData::updateState(renderer, current, old, updates);
+ state.context()->functions()->glActiveTexture(GL_TEXTURE2);
+ m->sizetable->bind();
+ m_program.setUniformValue(m_sizetable_id, 2);
+
+ state.context()->functions()->glActiveTexture(GL_TEXTURE3);
+ m->opacitytable->bind();
+ m_program.setUniformValue(m_opacitytable_id, 3);
+
+ ParticleTrailsMaterialData::updateState(state, current, old);
}
int m_colortable_id;
+ int m_sizetable_id;
+ int m_opacitytable_id;
};
-AbstractMaterialShader *ParticleTrailsMaterialCT::createShader() const
+QSGMaterialShader *ParticleTrailsMaterialCT::createShader() const
{
return new ParticleTrailsMaterialDataCT;
}
-struct Color4ub {
- uchar r;
- uchar g;
- uchar b;
- uchar a;
-};
-
-struct ColoredParticleVertex {
- float x;
- float y;
- float tx;
- float ty;
- float t;
- float lifeSpan;
- float size;
- float endSize;
- float sx;
- float sy;
- float ax;
- float ay;
- Color4ub color;
-};
-
-struct ColoredParticleVertices {
- ColoredParticleVertex v1;
- ColoredParticleVertex v2;
- ColoredParticleVertex v3;
- ColoredParticleVertex v4;
-};
-
-
ColoredParticle::ColoredParticle(QSGItem* parent)
: ParticleType(parent)
, m_do_reset(false)
, m_color(Qt::white)
, m_color_variation(0.5)
- , m_additive(1)
, m_node(0)
, m_material(0)
- , m_alphaVariation(0)
+ , m_alphaVariation(0.0)
+ , m_alpha(1.0)
+ , m_redVariation(0.0)
+ , m_greenVariation(0.0)
+ , m_blueVariation(0.0)
{
setFlag(ItemHasContents);
}
@@ -209,7 +251,7 @@ void ColoredParticle::setImage(const QUrl &image)
return;
m_image_name = image;
emit imageChanged();
- //m_system->pleaseReset();//XXX
+ reset();
}
@@ -219,7 +261,25 @@ void ColoredParticle::setColortable(const QUrl &table)
return;
m_colortable_name = table;
emit colortableChanged();
- //m_system->pleaseReset();//XXX
+ reset();
+}
+
+void ColoredParticle::setSizetable(const QUrl &table)
+{
+ if (table == m_sizetable_name)
+ return;
+ m_sizetable_name = table;
+ emit sizetableChanged();
+ reset();
+}
+
+void ColoredParticle::setOpacitytable(const QUrl &table)
+{
+ if (table == m_opacitytable_name)
+ return;
+ m_opacitytable_name = table;
+ emit opacitytableChanged();
+ reset();
}
void ColoredParticle::setColor(const QColor &color)
@@ -240,15 +300,6 @@ void ColoredParticle::setColorVariation(qreal var)
//m_system->pleaseReset();//XXX
}
-void ColoredParticle::setAdditive(qreal additive)
-{
- if (m_additive == additive)
- return;
- m_additive = additive;
- emit additiveChanged();
- //m_system->pleaseReset();//XXX
-}
-
void ColoredParticle::setCount(int c)
{
ParticleType::setCount(c);
@@ -257,6 +308,7 @@ void ColoredParticle::setCount(int c)
void ColoredParticle::reset()
{
+ ParticleType::reset();
m_pleaseReset = true;
}
@@ -275,10 +327,8 @@ static QSGGeometry::AttributeSet ColoredParticle_AttributeSet =
ColoredParticle_Attributes
};
-GeometryNode* ColoredParticle::buildParticleNode()
+QSGGeometryNode* ColoredParticle::buildParticleNode()
{
- QSGContext *sg = QSGContext::current;
-
if (m_count * 4 > 0xffff) {
printf("ColoredParticle: Too many particles... \n");
return 0;
@@ -349,21 +399,35 @@ GeometryNode* ColoredParticle::buildParticleNode()
m_material = 0;
}
- if (!m_colortable_name.isEmpty()) {
- QImage table(m_colortable_name.toLocalFile());
- if (!table.isNull()) {
- m_material = new ParticleTrailsMaterialCT();
- static_cast<ParticleTrailsMaterialCT *>(m_material)->colortable = sg->createTexture(table);
- }
+ QImage colortable(m_colortable_name.toLocalFile());
+ QImage sizetable(m_sizetable_name.toLocalFile());
+ QImage opacitytable(m_opacitytable_name.toLocalFile());
+ if(!colortable.isNull() || !sizetable.isNull() || !opacitytable.isNull()){
+ //using tabled shaders
+ m_material = new ParticleTrailsMaterialCT();
+ if(colortable.isNull())
+ colortable = QImage(":resources/identitytable.png");
+ if(sizetable.isNull())
+ sizetable = QImage(":resources/identitytable.png");
+ if(opacitytable.isNull())
+ opacitytable = QImage(":resources/defaultFadeInOut.png");
+ Q_ASSERT(!colortable.isNull());
+ Q_ASSERT(!sizetable.isNull());
+ Q_ASSERT(!opacitytable.isNull());
+ ParticleTrailsMaterialCT* ct_material = static_cast<ParticleTrailsMaterialCT *>(m_material);
+ ct_material->colortable = sceneGraphEngine()->createTextureFromImage(colortable);
+ ct_material->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable);
+ ct_material->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable);
}
if (!m_material)
m_material = new ParticleTrailsMaterial();
- m_material->texture = sg->createTexture(image);
+ m_material->texture = sceneGraphEngine()->createTextureFromImage(image);
+ m_material->texture->setFiltering(QSGTexture::Linear);
- m_node = new GeometryNode();
+ m_node = new QSGGeometryNode();
m_node->setGeometry(g);
m_node->setMaterial(m_material);
@@ -372,7 +436,7 @@ GeometryNode* ColoredParticle::buildParticleNode()
return m_node;
}
-Node *ColoredParticle::updatePaintNode(Node *, UpdatePaintNodeData *)
+QSGNode *ColoredParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
{
if(m_pleaseReset){
if(m_node)
@@ -385,11 +449,11 @@ Node *ColoredParticle::updatePaintNode(Node *, UpdatePaintNodeData *)
m_pleaseReset = false;
}
- if(m_system->isRunning())
+ if(m_system && m_system->isRunning())
prepareNextFrame();
if (m_node){
update();
- m_node->markDirty(Node::DirtyMaterial);
+ m_node->markDirty(QSGNode::DirtyMaterial);
}
return m_node;
@@ -408,6 +472,13 @@ void ColoredParticle::prepareNextFrame()
m_material->timestamp = time;
}
+void ColoredParticle::reloadColor(const Color4ub &c, ParticleData* d)
+{
+ ColoredParticleVertices *particles = (ColoredParticleVertices *) m_node->geometry()->vertexData();
+ int pos = particleTypeIndex(d);
+ ColoredParticleVertices &p = particles[pos];
+ p.v1.color = p.v2.color = p.v3.color = p.v4.color = c;
+}
void ColoredParticle::vertexCopy(ColoredParticleVertex &b,const ParticleVertex& a)
{
@@ -432,7 +503,6 @@ void ColoredParticle::reload(ParticleData *d)
int pos = particleTypeIndex(d);
-
ColoredParticleVertices &p = particles[pos];
//Perhaps we could be more efficient?
@@ -450,10 +520,13 @@ void ColoredParticle::load(ParticleData *d)
//Color initialization
// Particle color
Color4ub color;
- color.r = m_color.red() * (1 - m_color_variation) + rand() % 256 * m_color_variation;
- color.g = m_color.green() * (1 - m_color_variation) + rand() % 256 * m_color_variation;
- color.b = m_color.blue() * (1 - m_color_variation) + rand() % 256 * m_color_variation;
- color.a = (1 - m_additive) * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation;
+ qreal redVariation = m_color_variation + m_redVariation;
+ qreal greenVariation = m_color_variation + m_greenVariation;
+ qreal blueVariation = m_color_variation + m_blueVariation;
+ color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation;
+ color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation;
+ color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation;
+ color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation;
ColoredParticleVertices *particles = (ColoredParticleVertices *) m_node->geometry()->vertexData();
ColoredParticleVertices &p = particles[particleTypeIndex(d)];
p.v1.color = p.v2.color = p.v3.color = p.v4.color = color;