dmuratshin 8 年之前
父节点
当前提交
cccb42b262

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

@@ -59,7 +59,7 @@ public:
         text->setText("Oxygine. Masked sky demo");
         text->setStyle(style);
 
-        //text->addTween(TweenOutline(Color::Green), 3000, -1, true);
+        text->addTween(TweenOutline(Color::Green), 3000, -1, true);
 
         const Test::toggle sm[] = {Test::toggle("hide mask", 0), Test::toggle("show mask", 1), };
         addToggle("show_mask", sm, 2);

+ 5 - 0
oxygine/src/oxygine/MaskedRenderer.h

@@ -80,4 +80,9 @@ namespace oxygine
         Vector3 _msk[4];
         Vector4 _clipMask;
     };
+
+    class ApplyMask
+    {
+    public:
+    };
 }

+ 81 - 27
oxygine/src/oxygine/STDMaterial.cpp

@@ -11,6 +11,8 @@
 #include "ClipRectActor.h"
 #include "core/oxygine.h"
 #include "res/ResFont.h"
+#include "core/UberShaderProgram.h"
+#include "core/NativeTexture.h"
 
 namespace oxygine
 {
@@ -87,48 +89,100 @@ namespace oxygine
 
     void STDMaterial::render(MaskedSprite* sprite, const RenderState& parentRS)
     {
-        spSprite mask = sprite->getMask();
-        if (mask && mask->getAnimFrame().getDiffuse().base)
+        spSprite maskSprite = sprite->getMask();
+
+        const Diffuse& df = maskSprite->getAnimFrame().getDiffuse();
+
+        if (!maskSprite || !df.base)
         {
-            MaterialX::null->apply();
+            sprite->Sprite::render(parentRS);
+            return;
+        }
+
 
-            Transform t = mask->computeGlobalTransform();
+        MaterialX::null->apply();
 
-            RectF maskDest = mask->getDestRect();
-            RectF maskSrc = mask->getSrcRect();
+        Transform world = maskSprite->computeGlobalTransform();
 
-            const Diffuse& df = mask->getAnimFrame().getDiffuse();
+        RectF maskDest = maskSprite->getDestRect();
+        RectF maskSrc = maskSprite->getSrcRect();
 
-            bool useR = sprite->getUseRChannel();
-            bool rchannel       = useR ? true    : (df.alpha ? true     : false);
-            spNativeTexture msk = useR ? df.base : (df.alpha ? df.alpha : df.base);
 
-            STDRenderer* original = STDRenderer::getCurrent();
+        bool useR           = sprite->getUseRChannel();
+        bool rchannel               = useR ? true    : (df.alpha ? true     : false);
+        spNativeTexture maskTexture = useR ? df.base : (df.alpha ? df.alpha : df.base);
 
-            original->flush();
-            original->end();
+        STDRenderer* renderer = STDRenderer::getCurrent();
 
 
 
-            MaskedRenderer mr(msk, maskSrc, maskDest, t, rchannel, original->getDriver());
-            original->swapVerticesData(mr);
+#if 1
+        ClipUV clipUV = ClipUV(
+                            world.transform(maskDest.getLeftTop()),
+                            world.transform(maskDest.getRightTop()),
+                            world.transform(maskDest.getLeftBottom()),
+                            maskSrc.getLeftTop(),
+                            maskSrc.getRightTop(),
+                            maskSrc.getLeftBottom());
 
-            mr.setViewProj(original->getViewProjection());
-            mr.begin();
+        Vector2 v(1.0f / maskTexture->getWidth(), 1.0f / maskTexture->getHeight());
+        maskSrc.expand(v, v);
 
-            RenderState rs = parentRS;
-            sprite->Sprite::render(rs);
-            mr.end();
 
-            MaterialX::null->apply();
 
-            original->swapVerticesData(mr);
-            original->begin();
-        }
-        else
+        int sflags = renderer->getBaseShaderFlags();
+        int baseShaderFlags = sflags;
+
+        baseShaderFlags |= UberShaderProgram::MASK;
+        if (rchannel)
+            baseShaderFlags |= UberShaderProgram::MASK_R_CHANNEL;
+
+        Vector3 msk[4];
+
+        clipUV.get(msk);
+        Vector4 clipMask = Vector4(maskSrc.getLeft(), maskSrc.getTop(), maskSrc.getRight(), maskSrc.getBottom());
+
+        rc().setTexture(UberShaderProgram::SAMPLER_MASK, maskTexture);
+
+
+
+        ShaderProgramChangedHook hook;
+        hook.hook = [&]()
         {
-            sprite->Sprite::render(parentRS);
-        }
+
+            IVideoDriver::instance->setUniform("clip_mask", clipMask);
+            IVideoDriver::instance->setUniform("msk", msk, 4);
+
+        };
+
+
+        renderer->pushShaderSetHook(&hook);
+        renderer->setBaseShaderFlags(baseShaderFlags);
+
+        sprite->Sprite::render(parentRS);
+
+        MaterialX::null->apply();
+
+        renderer->popShaderSetHook();
+        renderer->setBaseShaderFlags(sflags);
+#else
+
+        MaskedRenderer mr(maskTexture, maskSrc, maskDest, world, rchannel, renderer->getDriver());
+        renderer->swapVerticesData(mr);
+
+        mr.setViewProj(renderer->getViewProjection());
+        mr.begin();
+
+        RenderState rs = parentRS;
+        sprite->Sprite::render(rs);
+        mr.end();
+
+        MaterialX::null->apply();
+
+        renderer->swapVerticesData(mr);
+        renderer->begin();
+#endif
+
     }
 
     void STDMaterial::doRender(Sprite* sprite, const RenderState& rs)

+ 35 - 1
oxygine/src/oxygine/STDRenderer.cpp

@@ -261,8 +261,15 @@ namespace oxygine
     {
         if (rc().setShader(prog))
         {
-            _driver->setUniform("mat", _vp);
+            //_driver->setUniform("mat", _vp);
             shaderProgramChanged();
+
+            ShaderProgramChangedHook* hook = _sphookFirst;
+            while (hook)
+            {
+                hook->hook();
+                hook = hook->next;
+            }
         }
     }
 
@@ -306,6 +313,19 @@ namespace oxygine
         setViewProj(viewProj);
     }
 
+    void STDRenderer::pushShaderSetHook(ShaderProgramChangedHook* hook)
+    {
+        _sphookLast->next = hook;
+        hook->prev = _sphookLast;
+        _sphookLast = hook;
+    }
+
+    void STDRenderer::popShaderSetHook()
+    {
+        _sphookLast = _sphookLast->prev;
+        _sphookLast->next = 0;
+    }
+
     void STDRenderer::resetSettings()
     {
         xresetSettings();
@@ -438,6 +458,14 @@ namespace oxygine
         _uberShader = &uberShader;
         _transform.identity();
         _baseShaderFlags = 0;
+
+        _sphookFirst = this;
+        _sphookLast  = this;
+
+        hook = [ = ]()
+        {
+            _driver->setUniform("mat", _vp);
+        };
     }
 
 
@@ -559,4 +587,10 @@ namespace oxygine
 
         _uberShader = pr;
     }
+
+    void STDRenderer::setBaseShaderFlags(unsigned int fl)
+    {
+        _baseShaderFlags = fl;
+    }
+
 }

+ 19 - 1
oxygine/src/oxygine/STDRenderer.h

@@ -27,7 +27,18 @@ namespace oxygine
 
     RenderStateCache& rc();
 
-    class STDRenderer : public IElementRenderer
+    class ShaderProgramChangedHook
+    {
+    public:
+        ShaderProgramChangedHook(): prev(0), next(0) {}
+
+        ShaderProgramChangedHook* prev;
+        ShaderProgramChangedHook* next;
+
+        std::function< void() > hook;
+    };
+
+    class STDRenderer : public IElementRenderer, public ShaderProgramChangedHook
     {
     public:
 
@@ -65,11 +76,13 @@ namespace oxygine
         IVideoDriver*               getDriver();
         const AffineTransform&      getTransform() const { return _transform; }
         const VertexDeclaration*    getVertexDeclaration() const { return _vdecl; }
+        unsigned int                getBaseShaderFlags() const { return _baseShaderFlags; }
 
         void setShaderFlags(unsigned int);
         void setViewProj(const Matrix& viewProj);
         void setVertexDeclaration(const VertexDeclaration* decl);
         void setUberShaderProgram(UberShaderProgram* pr);
+        void setBaseShaderFlags(unsigned int fl);
 
         /**Sets World transformation.*/
         void setTransform(const Transform& world);
@@ -101,6 +114,9 @@ namespace oxygine
         OXYGINE_DEPRECATED
         void setViewProjTransform(const Matrix& viewProj);
 
+        void pushShaderSetHook(ShaderProgramChangedHook* hook);
+        void popShaderSetHook();
+
     protected:
         virtual void shaderProgramChanged() {}
 
@@ -124,6 +140,8 @@ namespace oxygine
         virtual void xbegin();
         virtual void xresetSettings();
 
+        ShaderProgramChangedHook* _sphookFirst;
+        ShaderProgramChangedHook* _sphookLast;
 
         UberShaderProgram* _uberShader;
 

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

@@ -103,8 +103,8 @@ namespace oxygine
 
     void VStyleActor::setMat(spSTDMaterialX mat)
     {
-        if (_mat == mat)
-            return;
+        //if (_mat == mat)
+        //    return;
         _mat = mat;
         matChanged();
     }