dmuratshin 8 лет назад
Родитель
Сommit
4a079158ac

+ 1 - 1
examples/Demo/src/TestPerf.h

@@ -49,7 +49,7 @@ public:
                 spSprite sprite = new Sprite;
                 sprite->setResAnim(resources.getResAnim("anim"));
                 sprite->setAnchor(Vector2(0.5f, 0.5f));
-                sprite->setSize(getStage()->getSize()/20);
+                sprite->setSize(getStage()->getSize() / 20);
                 sprite->setPosition(scalar::randFloat(0, (float)getWidth()), scalar::randFloat(0, (float)getHeight()));
                 content->addChild(sprite);
             }

+ 34 - 66
examples/Demo/src/TestUserShader.h

@@ -1,56 +1,29 @@
 #pragma once
 #include "test.h"
 
-template <class T>
-class IsSame
-{
-public:
-    static bool isSame(const T& a, const T &b)
-    {
-        return a.isSame(b);
-    }
-};
-template <class T>
-bool isSameF(const T &a, const T & b)
-{
-    return a.isSame(b);
-}
 
 class MyTestMat : public MaterialTX<STDMatData>
 {
 public:
-    Vector4 uniform;
-
-    //MyTestMat():MaterialTX<STDMatData>( {}
-    MyTestMat() {}
-    MyTestMat(const MyTestMat &other)
-    {
-        _data = other._data;
-        _data.init(_hash);
+    MATX(MyTestMat);
 
-        typedef bool(*fcmp)(const MyTestMat& a, const MyTestMat& b);
-        fcmp fn = &IsSame<MyTestMat>::isSame;
-        _compare = (compare)(fn);
+    Vector4 uniform = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
 
-        hash_combine(_hash, _compare);
 
-  //      hash_combine(hash, uniform.x, uniform.y, uniform.z, uniform.w);
+    void rehash(size_t& hash) const override
+    {
+        data.init(hash);
+        hash_combine(hash, uniform.x, uniform.y, uniform.z, uniform.w);
     }
 
-    bool isSame(const MyTestMat& other) const
+    static bool cmp(const MyTestMat& a, const MyTestMat& b)
     {
-        if (MaterialTX<STDMatData>::cmp(*this, other))
+        if (!MaterialTX<STDMatData>::cmp(a, b))
             return false;
 
-        return uniform == other.uniform;
+        return a.uniform == b.uniform;
     }
 
-    MyTestMat* clone() const override
-    {
-        return new MyTestMat(*this);
-    }
-    
-
     void apply()
     {
         MaterialTX<STDMatData>::apply();
@@ -73,53 +46,38 @@ public:
 
     void _start(Actor& actor) override
     {
-        actor.setName("zzz");
         Sprite& spr = (Sprite&)actor;
 
         MyTestMat my;
-        my._data = spr._mat->_data;
+        my.data = spr._mat->data;
+        my.data.us = _program;
+        my.uniform = _val;
 
         spr._mat = mc().add2(my);
-//        MyTestMat data;
-        //data = spr._mat->_data;
-        //spr._mat = mc().add(data);
-        //actor.setMaterial(this);
     }
 
     void _update(Actor& actor, const UpdateState& us) override
     {
-        _val = lerp(Vector4(1, 1, 1, 0), Vector4(0, 0, 0, 0),  _percent);
-    }
+        Sprite& spr = (Sprite&)actor;
 
-    void _done(Actor& actor, const UpdateState& us) override
-    {
-        actor.setMaterial(0);
-    }
+        _val = lerp(Vector4(1, 1, 1, 0), Vector4(0, 0, 0, 0),  _percent);
 
-    void setUniforms(IVideoDriver* driver, ShaderProgram* prog)
-    {
-        driver->setUniform("userValue", _val);
-    }
+        MyTestMat my;
+        my.data = spr._mat->data;
+        my.data.us = _program;
+        my.uniform = _val;
 
-    /*
-    void apply(Material* prev) override
-    {
-        STDRenderer* renderer = STDRenderer::getCurrent();
-        _program->setShaderUniformsCallback(CLOSURE(this, &TweenShader::setUniforms));
-        renderer->setUberShaderProgram(_program);
-    }
 
-    void doRender(Sprite* s, const RenderState& rs) override
-    {
-        STDMaterial::instance->doRender(s, rs);
+        spr._mat = mc().add2(my);
     }
 
-    void finish() override
+    void _done(Actor& actor, const UpdateState& us) override
     {
-        STDRenderer* renderer = STDRenderer::getCurrent();
-        renderer->drawBatch();
+        Sprite& spr = (Sprite&)actor;
+        STDMaterialX mat;
+        mat.data = spr._mat->data;
+        spr._mat = mc().add2(mat);
     }
-    */
 };
 
 
@@ -181,6 +139,8 @@ public:
             toggle("->shader:invert", 0, _shaderInvert)
         };
         addToggle("shader", t, 3);
+
+        addButton("blend", "blend");
     }
 
     ~TestUserShader()
@@ -200,4 +160,12 @@ public:
             _sprite->addTween2(new TweenShader(shader), TweenOptions(3000).twoSides(true).loops(-1));
         }
     }
+
+    void clicked(string id)
+    {
+        if (id == "blend")
+        {
+            _sprite->setBlendMode(blend_disabled);
+        }
+    }
 };

+ 1 - 1
examples/Demo/src/main.cpp

@@ -30,7 +30,7 @@ int mainloop()
 
     if (core::beginRendering())
     {
-        Color clearColor(32, 32, 32, 255);
+        Color clearColor(233, 32, 32, 255);
         Rect viewport(Point(0, 0), core::getDisplaySize());
         // Render all actors inside the stage. Actor::render will also be called for all its children
         getStage()->render(clearColor, viewport);

+ 3 - 3
oxygine/src/oxygine/ColorRectSprite.cpp

@@ -13,10 +13,10 @@ namespace oxygine
 
     ColorRectSprite::ColorRectSprite()
     {
-        STDMatData data;
-        data._base = STDRenderer::white;
+        STDMaterialX mat;
+        mat.data._base = STDRenderer::white;
 
-        _mat = mc().add(data);
+        _mat = mc().add2(mat);
     }
 
     ColorRectSprite::~ColorRectSprite()

+ 13 - 2
oxygine/src/oxygine/MaterialX.cpp

@@ -17,25 +17,29 @@ namespace oxygine
             return false;
         if (_flags != b._flags)
             return false;
+        if (us != b.us)
+            return false;
         return true;
     }
 
-    STDMatData::STDMatData() : _blend(blend_alpha), _flags(0)
+    STDMatData::STDMatData() : _blend(blend_alpha), _flags(0), us(&STDRenderer::uberShader)
     {
 
     }
 
-    void STDMatData::init(size_t& hash)
+    void STDMatData::init(size_t& hash) const
     {
         hash_combine(hash, _base.get());
         hash_combine(hash, _alpha.get());
         hash_combine(hash, (int)_blend);
         hash_combine(hash, _flags);
+        hash_combine(hash, us);
     }
 
     void STDMatData::apply()
     {
         STDRenderer* r = STDRenderer::getCurrent();
+        r->setUberShaderProgram(us);
         r->setShaderFlags(_flags);
         r->setTextureNew(UberShaderProgram::SAMPLER_BASE, _base);
         r->setTextureNew(UberShaderProgram::SAMPLER_ALPHA, _alpha);
@@ -58,4 +62,11 @@ namespace oxygine
 
     }
 
+    oxygine::MaterialX& MaterialX::operator=(const MaterialX& r)
+    {
+        _compare = r._compare;
+        _hash = r._hash;
+        return *this;
+    }
+
 }

+ 60 - 28
oxygine/src/oxygine/MaterialX.h

@@ -5,6 +5,25 @@
 namespace oxygine
 {
 
+
+#define MATX(cl) \
+    cl(){\
+        typedef bool (*fn)(const cl&a, const cl&b);\
+        fn f = &cl::cmp;\
+        _compare = (compare)f;\
+    }\
+    void copyFrom(const MaterialX &r) override {*this = (cl&)r;}\
+    cl* clone() const override {return new cl(*this);}\
+    void update(size_t &hash, compare &cm) const override {\
+        typedef bool (*fn)(const cl&a, const cl&b);\
+        fn f = &cl::cmp;\
+        cm = (compare)f;\
+        hash = 0;\
+        rehash(hash);\
+    }
+
+
+
     class MaterialX : public ref_counter
     {
     public:
@@ -12,6 +31,8 @@ namespace oxygine
         typedef bool(*compare)(const MaterialX* a, const MaterialX* b);
 
         MaterialX();
+
+        MaterialX& operator = (const MaterialX& r);
         MaterialX(compare cmp);
         MaterialX(const MaterialX& other);
 
@@ -19,8 +40,10 @@ namespace oxygine
         compare _compare;
 
         virtual void apply() = 0;
-        //virtual void init(size_t &);
         virtual MaterialX* clone() const = 0;
+        virtual void copyFrom(const MaterialX& r) = 0;
+        virtual void update(size_t& hash, compare&) const = 0;
+        virtual void rehash(size_t& hash) const = 0;
     };
 
     typedef intrusive_ptr<MaterialX> spMaterialX;
@@ -59,39 +82,33 @@ namespace oxygine
     class MaterialTX : public MaterialX
     {
     public:
+        MATX(MaterialTX<T>);
 
         typedef bool(*fcmp)(const MaterialTX<T>& a, const MaterialTX<T>& b);
 
-        T _data;
+        T data;
 
-        MaterialTX() {}
 
-        MaterialTX(const T& data) : _data(data)
+        MaterialTX(const T& dat) : data(dat)
         {
-            _data.init(_hash);
-
-            fcmp fn = &MaterialTX<T>::cmp;
-            _compare = (compare)(fn);
+        }
 
-            hash_combine(_hash, _compare);
+        void rehash(size_t& hash) const override
+        {
+            data.init(hash);
         }
 
         template<class C>
         static bool cmp(const MaterialTX<C>& a, const MaterialTX<C>& b)
         {
-            return a._data.isSame(b._data);
+            return a.data.isSame(b.data);
         }
 
         void apply() override
         {
-            _data.apply();
+            data.apply();
         }
 
-        MaterialTX<T>* clone() const override
-        {
-            MaterialTX<T>* copy = new MaterialTX<T>(*this);
-            return copy;
-        }
     };
 
 
@@ -114,13 +131,17 @@ namespace oxygine
         spNativeTexture _base;
         spNativeTexture _alpha;
         blend_mode      _blend;
+        UberShaderProgram* us;
         int             _flags;
 
-        void init(size_t& hash);
+        void init(size_t& hash) const;
         void apply();
         bool isSame(const STDMatData& b) const;
     };
 
+
+    typedef MaterialTX<STDMatData> STDMaterialX;
+
     typedef intrusive_ptr< MaterialTX<STDMatData> > spSTDMaterialX;
 
     class MaterialCache
@@ -130,28 +151,39 @@ namespace oxygine
         typedef std::vector<spMaterialX> materials;
         materials _materials;
 
-        template<class T>
-        intrusive_ptr< MaterialTX<T> > add(const T& other)
-        {
-            MaterialTX<T> mat(other);
-            return add2(mat);
-        }
 
         template<class T>
         intrusive_ptr<T> add2(const T& other)
         {
-            for (auto m : _materials)
+            size_t hash;
+            MaterialX::compare cm;
+            other.update(hash, cm);
+
+            T* fre = 0;
+            for (auto m_ : _materials)
             {
-                if (m->_compare != other._compare)
+                MaterialX* mat = m_.get();
+                if (mat->_compare != cm)
                     continue;
-                if (m->_hash != other._hash)
+                if (mat->_ref_counter == 2)
+                    fre = (T*)mat;
+                if (mat->_hash != hash)
                     continue;
-                bool same = m->_compare(m.get(), &other);
+                bool same = cm(mat, &other);
                 if (same)
-                    return (T*)m.get();
+                    return (T*)mat;
+            }
+            if (fre)
+            {
+                fre->copyFrom(other);
+                fre->_hash = hash;
+                fre->_compare = cm;
+                return fre;
             }
 
             T* copy = other.clone();
+            copy->_hash = hash;
+            copy->_compare = cm;
             _materials.push_back(copy);
 
             return copy;

+ 2 - 2
oxygine/src/oxygine/STDRenderer.cpp

@@ -602,7 +602,7 @@ namespace oxygine
 
     void STDRenderer::setShaderFlags(int flags)
     {
-        ShaderProgram* sp = STDRenderer::uberShader.getShaderProgram(_baseShaderFlags | flags);
+        ShaderProgram* sp = _uberShader->getShaderProgram(_baseShaderFlags | flags);
         if (_program != sp)
         {
             _driver->setShaderProgram(sp);
@@ -729,7 +729,7 @@ namespace oxygine
         if (_uberShader == pr)
             return;
 
-        drawBatch();
+        //drawBatch();
         _uberShader = pr;
     }
 

+ 6 - 5
oxygine/src/oxygine/Sprite.cpp

@@ -224,12 +224,13 @@ namespace oxygine
 
 
 
-        STDMatData data = _mat->_data;
-        data._base = _frame.getDiffuse().base;
-        data._alpha = _frame.getDiffuse().alpha;
-        data._flags = _frame.getDiffuse().premultiplied ? 0 : UberShaderProgram::ALPHA_PREMULTIPLY;
+        STDMaterialX mat;
+        mat.data = _mat->data;
+        mat.data._base = _frame.getDiffuse().base;
+        mat.data._alpha = _frame.getDiffuse().alpha;
+        mat.data._flags = _frame.getDiffuse().premultiplied ? 0 : UberShaderProgram::ALPHA_PREMULTIPLY;
 
-        _mat = mc().add(data);
+        _mat = mc().add2(mat);
 
         animFrameChanged(_frame);
     }

+ 1 - 1
oxygine/src/oxygine/TextField.cpp

@@ -328,7 +328,7 @@ namespace oxygine
                 _root = new text::TextNode(_text.c_str());
             }
 
-            text::Aligner rd(_style, _mat->_data , font, scale, getSize());
+            text::Aligner rd(_style, _mat->data , font, scale, getSize());
             rd.begin();
             _root->resize(rd);
             rd.end();

+ 6 - 7
oxygine/src/oxygine/VisualStyle.cpp

@@ -14,10 +14,10 @@ namespace oxygine
 
     VStyleActor::VStyleActor()
     {
-        STDMatData data;
-        data._blend = blend_premultiplied_alpha;
+        MaterialTX<STDMatData> mat;
+        mat.data._blend = blend_premultiplied_alpha;
 
-        _mat = mc().add(data);
+        _mat = mc().add2(mat);
     }
 
     void VStyleActor::copyFrom(const VStyleActor& src, cloneOptions opt)
@@ -91,10 +91,9 @@ namespace oxygine
     {
         _vstyle.setBlendMode(mode);
 
-        STDMatData data = _mat->_data;
-        data._blend = mode;
-
-        _mat = mc().add(data);
+        _mat = _mat->clone();
+        _mat->data._blend = mode;
+        _mat = mc().add2(*_mat.get());
 
         blendModeChanged(mode);
     }

+ 4 - 3
oxygine/src/oxygine/text_utils/Node.cpp

@@ -199,11 +199,12 @@ namespace oxygine
                             }
                         }
 
-                        STDMatData data = rd.data;
-                        data._base = gl->texture;
+                        MaterialTX<STDMatData> mat;
+                        mat.data = rd.data;
+                        mat.data._base = gl->texture;
 
 
-                        s.materialX = mc().add(data);
+                        s.materialX = mc().add2(mat);
                     }
                     ++i;
                     if (i < 0)