From 017265b9383cbd616aaa2f5fee17dae8e28a161b Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 23 Aug 2011 18:20:58 +1000 Subject: Switch from textures to uniform arrays for size/opacity tables Change-Id: Iafc5eaa80f68345cc3b14fe0b2d997c1af435419 Reviewed-on: http://codereview.qt.nokia.com/3388 Reviewed-by: Qt Sanity Bot Reviewed-by: Alan Alpert --- .../particles/defaultshaders/imagefragment.shader | 15 +---- .../particles/defaultshaders/imagevertex.shader | 6 ++ src/declarative/particles/qsgimageparticle.cpp | 73 +++++++++++----------- src/declarative/particles/qsgpointattractor_p.h | 2 +- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/declarative/particles/defaultshaders/imagefragment.shader b/src/declarative/particles/defaultshaders/imagefragment.shader index 5286c8519a..c2341fe6ff 100644 --- a/src/declarative/particles/defaultshaders/imagefragment.shader +++ b/src/declarative/particles/defaultshaders/imagefragment.shader @@ -16,8 +16,6 @@ varying lowp float fFade; #ifdef TABLE varying lowp vec2 tt; uniform sampler2D colortable; -uniform sampler2D opacitytable; -uniform sampler2D sizetable; #endif void main() { @@ -25,20 +23,13 @@ void main() { gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), tt.y) * fColor * texture2D(colortable, tt) - * (texture2D(opacitytable, tt).w * qt_Opacity); + * qt_Opacity; #else #ifdef TABLE - highp vec2 tex = (((fTex - 0.5) / texture2D(sizetable, tt).w) + 0.5); - lowp vec4 color; - if(tex.x < 1.0 && tex.x > 0.0 && tex.y < 1.0 && tex.y > 0.0){//No CLAMP_TO_BORDER in ES2, so have to do it ourselves - color = texture2D(texture, tex);//TODO: Replace with uniform array in vertex shader - }else{ - color = vec4(0.,0.,0.,0.); - } - gl_FragColor = color + gl_FragColor = texture2D(texture, fTex) * fColor * texture2D(colortable, tt) - * (texture2D(opacitytable,tt).w * qt_Opacity); + * qt_Opacity; #else #ifdef DEFORM gl_FragColor = (texture2D(texture, fTex)) * fColor * qt_Opacity; diff --git a/src/declarative/particles/defaultshaders/imagevertex.shader b/src/declarative/particles/defaultshaders/imagevertex.shader index a572d73050..e1033c9165 100644 --- a/src/declarative/particles/defaultshaders/imagevertex.shader +++ b/src/declarative/particles/defaultshaders/imagevertex.shader @@ -20,6 +20,8 @@ uniform highp mat4 qt_Matrix; uniform highp float timestamp; #ifdef TABLE varying lowp vec2 tt;//y is progress if Sprite mode +uniform highp float sizetable[64]; +uniform highp float opacitytable[64]; #endif #ifdef SPRITE varying highp vec4 fTexS; @@ -69,6 +71,10 @@ void main() { highp float fadeIn = min(t * 10., 1.); highp float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.); +#ifdef TABLE + currentSize = currentSize * sizetable[int(floor(t*64.))]; + fade = fade * opacitytable[int(floor(t*64.))]; +#endif if (entry == 1.) fade = fadeIn * fadeOut; else if(entry == 2.) diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp index f2fb289ab5..3b58bfc208 100644 --- a/src/declarative/particles/qsgimageparticle.cpp +++ b/src/declarative/particles/qsgimageparticle.cpp @@ -62,25 +62,27 @@ DEFINE_BOOL_CONFIG_OPTION(qmlParticlesDebug, QML_PARTICLES_DEBUG) #else #define SHADER_DEFINES "" #endif + +//TODO: Make it larger on desktop? Requires fixing up shader code with the same define +#define UNIFORM_ARRAY_SIZE 64 + const float CONV = 0.017453292519943295; class ImageMaterialData { public: ImageMaterialData() - : texture(0), colortable(0), sizetable(0), opacitytable(0) + : texture(0), colorTable(0) {} ~ImageMaterialData(){ delete texture; - delete colortable; - delete sizetable; - delete opacitytable; + delete colorTable; } QSGTexture *texture; - QSGTexture *colortable; - QSGTexture *sizetable; - QSGTexture *opacitytable; + QSGTexture *colorTable; + float sizeTable[UNIFORM_ARRAY_SIZE]; + float opacityTable[UNIFORM_ARRAY_SIZE]; qreal timestamp; qreal entry; @@ -126,24 +128,17 @@ public: program()->bind(); program()->setUniformValue("texture", 0); program()->setUniformValue("colortable", 1); - program()->setUniformValue("sizetable", 2); - program()->setUniformValue("opacitytable", 3); glFuncs = QGLContext::currentContext()->functions(); m_timestamp_id = program()->uniformLocation("timestamp"); m_entry_id = program()->uniformLocation("entry"); + m_sizetable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("opacitytable"); } void updateState(const TabledMaterialData* d, const TabledMaterialData*) { glFuncs->glActiveTexture(GL_TEXTURE1); - d->colortable->bind(); - - glFuncs->glActiveTexture(GL_TEXTURE2); - d->sizetable->bind(); + d->colorTable->bind(); - glFuncs->glActiveTexture(GL_TEXTURE3); - d->opacitytable->bind(); - - // make sure we end by setting GL_TEXTURE0 as active texture glFuncs->glActiveTexture(GL_TEXTURE0); d->texture->bind(); @@ -151,10 +146,14 @@ public: program()->setUniformValue("framecount", (float) 1); program()->setUniformValue("animcount", (float) 1); program()->setUniformValue(m_entry_id, (float) d->entry); + program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, UNIFORM_ARRAY_SIZE, 1); + program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); } int m_entry_id; int m_timestamp_id; + int m_sizetable_id; + int m_opacitytable_id; QByteArray m_vertex_code; QByteArray m_fragment_code; QGLFunctions* glFuncs; @@ -253,24 +252,18 @@ public: program()->bind(); program()->setUniformValue("texture", 0); program()->setUniformValue("colortable", 1); - program()->setUniformValue("sizetable", 2); - program()->setUniformValue("opacitytable", 3); glFuncs = QGLContext::currentContext()->functions(); m_timestamp_id = program()->uniformLocation("timestamp"); m_framecount_id = program()->uniformLocation("framecount"); m_animcount_id = program()->uniformLocation("animcount"); m_entry_id = program()->uniformLocation("entry"); + m_sizetable_id = program()->uniformLocation("sizetable"); + m_opacitytable_id = program()->uniformLocation("sizetable"); } void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) { glFuncs->glActiveTexture(GL_TEXTURE1); - d->colortable->bind(); - - glFuncs->glActiveTexture(GL_TEXTURE2); - d->sizetable->bind(); - - glFuncs->glActiveTexture(GL_TEXTURE3); - d->opacitytable->bind(); + d->colorTable->bind(); // make sure we end by setting GL_TEXTURE0 as active texture glFuncs->glActiveTexture(GL_TEXTURE0); @@ -280,12 +273,16 @@ public: program()->setUniformValue(m_framecount_id, (float) d->framecount); program()->setUniformValue(m_animcount_id, (float) d->animcount); program()->setUniformValue(m_entry_id, (float) d->entry); + program()->setUniformValueArray(m_sizetable_id, (float*) d->sizeTable, 64, 1); + program()->setUniformValueArray(m_opacitytable_id, (float*) d->opacityTable, UNIFORM_ARRAY_SIZE, 1); } int m_timestamp_id; int m_framecount_id; int m_animcount_id; int m_entry_id; + int m_sizetable_id; + int m_opacitytable_id; QByteArray m_vertex_code; QByteArray m_fragment_code; QGLFunctions* glFuncs; @@ -431,6 +428,18 @@ public: QGLFunctions* glFuncs; }; +void fillUniformArrayFromImage(float* array, const QImage& img, int size) +{ + if (img.isNull()){ + for (int i=0; i(m_material)->colortable = sceneGraphEngine()->createTextureFromImage(colortable); - getState(m_material)->sizetable = sceneGraphEngine()->createTextureFromImage(sizetable); - getState(m_material)->opacitytable = sceneGraphEngine()->createTextureFromImage(opacitytable); + getState(m_material)->colorTable = sceneGraphEngine()->createTextureFromImage(colortable); + fillUniformArrayFromImage(getState(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE); + fillUniformArrayFromImage(getState(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE); case Deformable: if (!m_material) m_material = DeformableMaterial::createMaterial(); diff --git a/src/declarative/particles/qsgpointattractor_p.h b/src/declarative/particles/qsgpointattractor_p.h index 932a3081d6..95716483ed 100644 --- a/src/declarative/particles/qsgpointattractor_p.h +++ b/src/declarative/particles/qsgpointattractor_p.h @@ -55,7 +55,7 @@ class QSGPointAttractorAffector : public QSGParticleAffector //Like Gravitational singularity, but linear to distance instead of quadratic //And affects ds/dt, not da/dt Q_PROPERTY(qreal strength READ strength WRITE setStrength NOTIFY strengthChanged) - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged)//TODO: Change to pointX, pointY Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) Q_PROPERTY(PhysicsAffects physics READ physics WRITE setPhysics NOTIFY physicsChanged) Q_PROPERTY(Proportion proportionalToDistance READ proportionalToDistance WRITE setProportionalToDistance NOTIFY proportionalToDistanceChanged) -- cgit v1.2.3