Browse Source

Fix Drawable2D bounding box update and attribute network propagation.

Yao Wei Tjong 姚伟忠 11 years ago
parent
commit
ff1f9fc7d8

+ 62 - 28
Source/Engine/Urho2D/Drawable2D.cpp

@@ -48,7 +48,9 @@ Drawable2D::Drawable2D(Context* context) :
     blendMode_(BLEND_REPLACE),
     zValue_(0.0f),
     vertexBuffer_(new VertexBuffer(context_)),
-    geometryDirty_(true)
+    verticesDirty_(true),
+    geometryDirty_(true),
+    materialUpdatePending_(false)
 {
     geometry_ = new Geometry(context);
     batches_.Resize(1);
@@ -65,14 +67,17 @@ void Drawable2D::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_FLOAT, "Unit Per Pixel", GetUnitPerPixel, SetUnitPerPixel, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Sprite", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Drawable2D, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
-    ENUM_ACCESSOR_ATTRIBUTE(Drawable2D, "Blend Mode", GetBlendMode, SetBlendMode, BlendMode, blendModeNames, 0, AM_DEFAULT);
+    ENUM_ACCESSOR_ATTRIBUTE(Drawable2D, "Blend Mode", GetBlendMode, SetBlendModeAttr, BlendMode, blendModeNames, 0, AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(Drawable2D, Drawable);
 }
 
 void Drawable2D::ApplyAttributes()
 {
-    UpdateVertices();
-    UpdateMaterial();
+    if (materialUpdatePending_)
+    {
+        materialUpdatePending_ = false;
+        UpdateMaterial();
+    }
 }
 
 void Drawable2D::UpdateBatches(const FrameInfo& frame)
@@ -142,8 +147,8 @@ UpdateGeometryType Drawable2D::GetUpdateGeometryType()
 void Drawable2D::SetUnitPerPixel(float unitPerPixel)
 {
     unitPerPixel_ = Max(1.0f, unitPerPixel);
-    MarkVerticesDirty();
-    MarkGeometryDirty();
+    OnMarkedDirty(node_);
+    MarkNetworkUpdate();
 }
 
 void Drawable2D::SetSprite(Sprite2D* sprite)
@@ -152,42 +157,45 @@ void Drawable2D::SetSprite(Sprite2D* sprite)
         return;
 
     sprite_ = sprite;
-    MarkVerticesDirty();
-    MarkGeometryDirty();
+    OnMarkedDirty(node_);
     UpdateMaterial();
+    MarkNetworkUpdate();
 }
 
 void Drawable2D::SetMaterial(Material* material)
 {
-    if (material != material_)
-    {
-        material_ = material;
-        // If a null material was specified, create one with defaults, otherwise clone the material so that
-        // the diffuse texture can be changed according to the sprite being used
-        if (!material_)
-            CreateDefaultMaterial();
-        else
-            batches_[0].material_ = material_->Clone();
-        
-        UpdateMaterial();
-    }
+    if (material == material_)
+        return;
+
+    material_ = material;
+    // If a null material was specified, create one with defaults, otherwise clone the material so that
+    // the diffuse texture can be changed according to the sprite being used
+    if (!material_)
+        CreateDefaultMaterial();
+    else
+        batches_[0].material_ = material_->Clone();
+    UpdateMaterial();
+    MarkNetworkUpdate();
 }
 
 void Drawable2D::SetBlendMode(BlendMode mode)
 {
-    if (blendMode_ != mode)
-    {
-        blendMode_ = mode;
-        UpdateMaterial();
-    }
+    if (mode == blendMode_)
+        return;
+
+    blendMode_ = mode;
+    UpdateMaterial();
+    MarkNetworkUpdate();
 }
 
 void Drawable2D::SetZValue(float zValue)
 {
-    zValue_ = zValue;
+    if (zValue == zValue_)
+        return;
 
-    MarkVerticesDirty();
-    MarkGeometryDirty();
+    zValue_ = zValue;
+    OnMarkedDirty(node_);
+    MarkNetworkUpdate();
 }
 
 Material* Drawable2D::GetMaterial() const
@@ -197,6 +205,9 @@ Material* Drawable2D::GetMaterial() const
 
 void Drawable2D::SetSpriteAttr(ResourceRef value)
 {
+    // Delay applying material update
+    materialUpdatePending_ = true;
+
     ResourceCache* cache = GetSubsystem<ResourceCache>();
 
     if (value.type_ == Sprite2D::GetTypeStatic())
@@ -238,6 +249,9 @@ ResourceRef Drawable2D::GetSpriteAttr() const
 
 void Drawable2D::SetMaterialAttr(ResourceRef value)
 {
+    // Delay applying material update
+    materialUpdatePending_ = true;
+
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SetMaterial(cache->GetResource<Material>(value.name_));
 }
@@ -247,6 +261,22 @@ ResourceRef Drawable2D::GetMaterialAttr() const
     return GetResourceRef(material_, Material::GetTypeStatic());
 }
 
+void Drawable2D::SetBlendModeAttr(BlendMode mode)
+{
+    // Delay applying material update
+    materialUpdatePending_ = true;
+
+    SetBlendMode(mode);
+}
+
+void Drawable2D::OnMarkedDirty(Node* node)
+{
+    Drawable::OnMarkedDirty(node);
+
+    verticesDirty_ = true;
+    geometryDirty_ = true;
+}
+
 void Drawable2D::OnWorldBoundingBoxUpdate()
 {
     if (verticesDirty_)
@@ -283,6 +313,10 @@ void Drawable2D::CreateDefaultMaterial()
 
 void Drawable2D::UpdateMaterial()
 {
+    // Delay the material update
+    if (materialUpdatePending_)
+        return;
+
     Material* material = batches_[0].material_;
     assert(material);
     

+ 6 - 4
Source/Engine/Urho2D/Drawable2D.h

@@ -85,16 +85,16 @@ public:
     void SetMaterialAttr(ResourceRef value);
     /// Return material attribute.
     ResourceRef GetMaterialAttr() const;
+    /// Set blend mode attribute.
+    void SetBlendModeAttr(BlendMode mode);
 
 protected:
+    /// Handle node transform being dirtied.
+    virtual void OnMarkedDirty(Node* node);
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     /// Update vertices.
     virtual void UpdateVertices() = 0;
-    /// Mark vertices dirty.
-    void MarkVerticesDirty() { verticesDirty_ = true; }
-    /// Mark geometry dirty.
-    void MarkGeometryDirty() { geometryDirty_ = true; }
     /// Create a default material when a material is not specified.
     void CreateDefaultMaterial();
     /// Update the material's properties (blend mode and texture).
@@ -121,6 +121,8 @@ protected:
     bool verticesDirty_;
     /// Geometry dirty flag.
     bool geometryDirty_;
+    /// Material update pending flag.
+    bool materialUpdatePending_;
 };
 
 }

+ 11 - 8
Source/Engine/Urho2D/ParticleEmitter2D.cpp

@@ -121,13 +121,17 @@ void ParticleEmitter2D::Update(const FrameInfo& frame)
             lifeTime_ = Max(0.0f, lifeTime_ - timeStep);
     }
 
-    MarkVerticesDirty();
-    OnMarkedDirty(node_);    
+    OnMarkedDirty(node_);
 }
 
 void ParticleEmitter2D::SetModel(ParticleModel2D* model)
 {
+    if (model == model_)
+        return;
+
     model_ = model;
+    MarkNetworkUpdate();
+
     if (!model_)
         return;
 
@@ -223,10 +227,10 @@ void ParticleEmitter2D::UpdateVertices()
         float add = (c + s) * p.size_ * 0.5f;
         float sub = (c - s) * p.size_ * 0.5f;
 
-        vertex0.position_ = Vector3(p.position_.x_ - sub, p.position_.y_ - add, 0.0f) * unitPerPixel_;
-        vertex1.position_ = Vector3(p.position_.x_ - add, p.position_.y_ + sub, 0.0f) * unitPerPixel_;
-        vertex2.position_ = Vector3(p.position_.x_ + sub, p.position_.y_ + add, 0.0f) * unitPerPixel_;
-        vertex3.position_ = Vector3(p.position_.x_ + add, p.position_.y_ - sub, 0.0f) * unitPerPixel_;
+        vertex0.position_ = Vector3(p.position_.x_ - sub, p.position_.y_ - add, zValue_) * unitPerPixel_;
+        vertex1.position_ = Vector3(p.position_.x_ - add, p.position_.y_ + sub, zValue_) * unitPerPixel_;
+        vertex2.position_ = Vector3(p.position_.x_ + sub, p.position_.y_ + add, zValue_) * unitPerPixel_;
+        vertex3.position_ = Vector3(p.position_.x_ + add, p.position_.y_ - sub, zValue_) * unitPerPixel_;
 
         vertex0.color_ = vertex1.color_ = vertex2.color_  = vertex3.color_ = p.color_.ToUInt();
 
@@ -236,8 +240,7 @@ void ParticleEmitter2D::UpdateVertices()
         vertices_.Push(vertex3);
     }
 
-    MarkGeometryDirty();
-
+    geometryDirty_ = true;
     verticesDirty_ = false;
 }
 

+ 8 - 6
Source/Engine/Urho2D/StaticSprite2D.cpp

@@ -62,8 +62,8 @@ void StaticSprite2D::SetFlip(bool flipX, bool flipY)
 
     flipX_ = flipX;
     flipY_ = flipY;
-    MarkVerticesDirty();
-    MarkGeometryDirty();
+    OnMarkedDirty(node_);
+    MarkNetworkUpdate();
 }
 
 void StaticSprite2D::SetFlipX(bool flipX)
@@ -78,9 +78,12 @@ void StaticSprite2D::SetFlipY(bool flipY)
 
 void StaticSprite2D::SetColor(const Color& color)
 {
+    if (color == color_)
+        return;
+
     color_ = color;
-    MarkVerticesDirty();
-    MarkGeometryDirty();
+    OnMarkedDirty(node_);
+    MarkNetworkUpdate();
 }
 
 void StaticSprite2D::UpdateVertices()
@@ -163,8 +166,7 @@ void StaticSprite2D::UpdateVertices()
     vertices_.Push(vertex2);
     vertices_.Push(vertex3);
 
-    MarkGeometryDirty();
-
+    geometryDirty_ = true;
     verticesDirty_ = false;
 }