Browse Source

Remove Sprite2D from Drawable2D, make Drawable2D more general.

aster2013 11 years ago
parent
commit
fb07e32cdd

+ 4 - 9
Source/Engine/LuaScript/pkgs/Urho2D/Drawable2D.pkg

@@ -9,21 +9,16 @@ class Drawable2D : public Drawable
 public:
 public:
     void SetLayer(int layer);
     void SetLayer(int layer);
     void SetOrderInLayer(int orderInLayer);
     void SetOrderInLayer(int orderInLayer);
-    void SetSprite(Sprite2D* sprite);
+    void SetTexture(Texture2D* texture);
     void SetBlendMode(BlendMode mode);
     void SetBlendMode(BlendMode mode);
-    void SetMaterial(Material* material);
-
+    
     int GetLayer() const;
     int GetLayer() const;
     int GetOrderInLayer() const;
     int GetOrderInLayer() const;
-    Sprite2D* GetSprite() const;
     Texture2D* GetTexture() const;
     Texture2D* GetTexture() const;
     BlendMode GetBlendMode() const;
     BlendMode GetBlendMode() const;
-    Material* GetMaterial() const;
-
+    
     tolua_property__get_set int layer;
     tolua_property__get_set int layer;
     tolua_property__get_set int orderInLayer;
     tolua_property__get_set int orderInLayer;
-    tolua_property__get_set Sprite2D* sprite;
-    tolua_readonly tolua_property__get_set Texture2D* texture;
+    tolua_property__get_set Texture2D* texture;
     tolua_property__get_set BlendMode blendMode;
     tolua_property__get_set BlendMode blendMode;
-    tolua_property__get_set Material* material;
 };
 };

+ 3 - 0
Source/Engine/LuaScript/pkgs/Urho2D/ParticleEmitter2D.pkg

@@ -5,6 +5,9 @@ class ParticleEmitter2D : public Drawable2D
 public:
 public:
     void SetEffect(ParticleEffect2D* effect);
     void SetEffect(ParticleEffect2D* effect);
     ParticleEffect2D* GetEffect() const;
     ParticleEffect2D* GetEffect() const;
+    void SetSprite(Sprite2D* sprite);
+    Sprite2D* GetSprite() const;
 
 
     tolua_property__get_set ParticleEffect2D* effect;
     tolua_property__get_set ParticleEffect2D* effect;
+    tolua_property__get_set Sprite2D* sprite;
 };
 };

+ 3 - 0
Source/Engine/LuaScript/pkgs/Urho2D/StaticSprite2D.pkg

@@ -3,15 +3,18 @@ $#include "StaticSprite2D.h"
 class StaticSprite2D : public Drawable2D
 class StaticSprite2D : public Drawable2D
 {    
 {    
 public:
 public:
+    void SetSprite(Sprite2D* sprite);
     void SetFlip(bool flipX, bool flipY);
     void SetFlip(bool flipX, bool flipY);
     void SetFlipX(bool flipX);
     void SetFlipX(bool flipX);
     void SetFlipY(bool flipY);
     void SetFlipY(bool flipY);
     void SetColor(const Color& color);
     void SetColor(const Color& color);
 
 
+    Sprite2D* GetSprite() const;
     bool GetFlipX() const;
     bool GetFlipX() const;
     bool GetFlipY() const;
     bool GetFlipY() const;
     const Color& GetColor() const;
     const Color& GetColor() const;
     
     
+    tolua_property__get_set Sprite2D* sprite;
     tolua_property__get_set bool flipX;
     tolua_property__get_set bool flipX;
     tolua_property__get_set bool flipY;
     tolua_property__get_set bool flipY;
     tolua_property__get_set Color& color;
     tolua_property__get_set Color& color;

+ 6 - 2
Source/Engine/Script/Urho2DAPI.cpp

@@ -95,8 +95,8 @@ template <class T> void RegisterDrawable2D(asIScriptEngine* engine, const char*
     engine->RegisterObjectMethod(className, "int get_layer() const", asMETHOD(T, GetLayer), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_layer() const", asMETHOD(T, GetLayer), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_orderInLayer(int)", asMETHOD(T, SetOrderInLayer), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_orderInLayer(int)", asMETHOD(T, SetOrderInLayer), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_orderInLayer() const", asMETHOD(T, GetOrderInLayer), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int get_orderInLayer() const", asMETHOD(T, GetOrderInLayer), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void set_sprite(Sprite2D@+)", asMETHOD(T, SetSprite), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "Sprite2D@+ get_sprite() const", asMETHOD(T, GetSprite), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void set_texture(Texture2D@+)", asMETHOD(T, SetTexture), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "Texture2D@+ get_texture() const", asMETHOD(T, GetTexture), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_blendMode(BlendMode)", asMETHOD(T, SetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_blendMode(BlendMode)", asMETHOD(T, SetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "BlendMode get_blendMode() const", asMETHOD(T, GetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "BlendMode get_blendMode() const", asMETHOD(T, GetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_material(Material@+)", asMETHOD(T, SetMaterial), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_material(Material@+)", asMETHOD(T, SetMaterial), asCALL_THISCALL);
@@ -115,6 +115,8 @@ template <class T> void RegisterStaticSprite2D(asIScriptEngine* engine, const ch
 {
 {
     RegisterDrawable2D<T>(engine, className);
     RegisterDrawable2D<T>(engine, className);
     RegisterSubclass<StaticSprite2D, T>(engine, "StaticSprite2D", className);
     RegisterSubclass<StaticSprite2D, T>(engine, "StaticSprite2D", className);
+    engine->RegisterObjectMethod(className, "void set_sprite(Sprite2D@+)", asMETHOD(T, SetSprite), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "Sprite2D@+ get_sprite() const", asMETHOD(T, GetSprite), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void SetFlip(bool, bool)", asMETHOD(T, SetFlip), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void SetFlip(bool, bool)", asMETHOD(T, SetFlip), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_flipX(bool)", asMETHOD(T, SetFlipX), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_flipX(bool)", asMETHOD(T, SetFlipX), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_flipX() const", asMETHOD(T, GetFlipX), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool get_flipX() const", asMETHOD(T, GetFlipX), asCALL_THISCALL);
@@ -192,6 +194,8 @@ static void RegisterParticleEmitter2D(asIScriptEngine* engine)
     RegisterDrawable2D<ParticleEmitter2D>(engine, "ParticleEmitter2D");
     RegisterDrawable2D<ParticleEmitter2D>(engine, "ParticleEmitter2D");
     engine->RegisterObjectMethod("ParticleEmitter2D", "void set_effect(ParticleEffect2D@+)", asMETHOD(ParticleEmitter2D, SetEffect), asCALL_THISCALL);
     engine->RegisterObjectMethod("ParticleEmitter2D", "void set_effect(ParticleEffect2D@+)", asMETHOD(ParticleEmitter2D, SetEffect), asCALL_THISCALL);
     engine->RegisterObjectMethod("ParticleEmitter2D", "ParticleEffect2D@+ get_effect() const", asMETHOD(ParticleEmitter2D, GetEffect), asCALL_THISCALL);
     engine->RegisterObjectMethod("ParticleEmitter2D", "ParticleEffect2D@+ get_effect() const", asMETHOD(ParticleEmitter2D, GetEffect), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ParticleEmitter2D", "void set_sprite(Sprite2D@+)", asMETHOD(ParticleEmitter2D, SetSprite), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ParticleEmitter2D", "Sprite2D@+ get_sprite() const", asMETHOD(ParticleEmitter2D, GetSprite), asCALL_THISCALL);
 }
 }
 
 
 static void FakeAddRef(void* ptr)
 static void FakeAddRef(void* ptr)

+ 8 - 48
Source/Engine/Urho2D/Drawable2D.cpp

@@ -66,7 +66,6 @@ void Drawable2D::RegisterObject(Context* context)
 {
 {
     ACCESSOR_ATTRIBUTE("Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Layer", GetLayer, SetLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Order in Layer", GetOrderInLayer, SetOrderInLayer, int, 0, AM_DEFAULT);
-    MIXED_ACCESSOR_ATTRIBUTE("Sprite", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
     ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendModeAttr, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
     ENUM_ACCESSOR_ATTRIBUTE("Blend Mode", GetBlendMode, SetBlendModeAttr, BlendMode, blendModeNames, BLEND_ALPHA, AM_DEFAULT);
     MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
     MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(Drawable);
     COPY_BASE_ATTRIBUTES(Drawable);
@@ -118,12 +117,12 @@ void Drawable2D::SetOrderInLayer(int orderInLayer)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
-void Drawable2D::SetSprite(Sprite2D* sprite)
+void Drawable2D::SetTexture(Texture2D* texture)
 {
 {
-    if (sprite == sprite_)
+    if (texture == texture_)
         return;
         return;
 
 
-    sprite_ = sprite;
+    texture_ = texture;
 
 
     verticesDirty_ = true;
     verticesDirty_ = true;
     OnMarkedDirty(node_);
     OnMarkedDirty(node_);
@@ -155,6 +154,11 @@ void Drawable2D::SetMaterial(Material* material)
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
+Texture2D* Drawable2D::GetTexture() const
+{
+    return texture_;
+}
+
 Material* Drawable2D::GetMaterial() const
 Material* Drawable2D::GetMaterial() const
 {
 {
     return material_;
     return material_;
@@ -172,50 +176,6 @@ const Vector<Vertex2D>& Drawable2D::GetVertices()
     return vertices_;
     return vertices_;
 }
 }
 
 
-void Drawable2D::SetSpriteAttr(const ResourceRef& value)
-{
-    // Delay applying material update
-    materialUpdatePending_ = true;
-
-    ResourceCache* cache = GetSubsystem<ResourceCache>();
-
-    if (value.type_ == Sprite2D::GetTypeStatic())
-    {
-        SetSprite(cache->GetResource<Sprite2D>(value.name_));
-        return;
-    }
-
-    if (value.type_ == SpriteSheet2D::GetTypeStatic())
-    {
-        // value.name_ include sprite speet name and sprite name.
-        Vector<String> names = value.name_.Split('@');
-        if (names.Size() != 2)
-            return;
-
-        const String& spriteSheetName = names[0];
-        const String& spriteName = names[1];
-
-        SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(spriteSheetName);
-        if (!spriteSheet)
-            return;
-
-        SetSprite(spriteSheet->GetSprite(spriteName));
-    }
-}
-
-ResourceRef Drawable2D::GetSpriteAttr() const
-{
-    SpriteSheet2D* spriteSheet = 0;
-    if (sprite_)
-        spriteSheet = sprite_->GetSpriteSheet();
-
-    if (!spriteSheet)
-        return GetResourceRef(sprite_, Sprite2D::GetTypeStatic());
-
-    // Combine sprite sheet name and sprite name as resource name.
-    return ResourceRef(spriteSheet->GetType(), spriteSheet->GetName() + "@" + sprite_->GetName());
-}
-
 void Drawable2D::SetBlendModeAttr(BlendMode mode)
 void Drawable2D::SetBlendModeAttr(BlendMode mode)
 {
 {
     // Delay applying material update
     // Delay applying material update

+ 20 - 12
Source/Engine/Urho2D/Drawable2D.h

@@ -23,14 +23,28 @@
 #pragma once
 #pragma once
 
 
 #include "Drawable.h"
 #include "Drawable.h"
-#include "Sprite2D.h"
+#include "GraphicsDefs.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
 class Renderer2D;
 class Renderer2D;
+class Texture2D;
 class VertexBuffer;
 class VertexBuffer;
 
 
+/// 2D vertex.
+struct Vertex2D
+{
+    /// Position.
+    Vector3 position_;
+    /// Color.
+    unsigned color_;
+    /// UV.
+    Vector2 uv_;
+};
+
+static const unsigned MASK_VERTEX2D = MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1;
+
 /// Pixel size (equal 0.01f).
 /// Pixel size (equal 0.01f).
 extern URHO3D_API const float PIXEL_SIZE;
 extern URHO3D_API const float PIXEL_SIZE;
 
 
@@ -56,8 +70,8 @@ public:
     void SetLayer(int layer);
     void SetLayer(int layer);
     /// Set order in layer.
     /// Set order in layer.
     void SetOrderInLayer(int orderInLayer);
     void SetOrderInLayer(int orderInLayer);
-    /// Set sprite.
-    void SetSprite(Sprite2D* sprite);
+    /// Set texture.
+    void SetTexture(Texture2D* texture);
     /// Set blend mode.
     /// Set blend mode.
     void SetBlendMode(BlendMode mode);
     void SetBlendMode(BlendMode mode);
     /// Set material.
     /// Set material.
@@ -67,10 +81,8 @@ public:
     int GetLayer() const { return layer_; }
     int GetLayer() const { return layer_; }
     /// Return order in layer.
     /// Return order in layer.
     int GetOrderInLayer() const { return orderInLayer_; }
     int GetOrderInLayer() const { return orderInLayer_; }
-    /// Return sprite.
-    Sprite2D* GetSprite() const { return sprite_; }
     /// Return texture.
     /// Return texture.
-    Texture2D* GetTexture() const { return sprite_ ? sprite_->GetTexture() : 0; }
+    Texture2D* GetTexture() const;
     /// Return blend mode.
     /// Return blend mode.
     BlendMode GetBlendMode() const { return blendMode_; }
     BlendMode GetBlendMode() const { return blendMode_; }
     /// Return material.
     /// Return material.
@@ -85,10 +97,6 @@ public:
     /// Return visibility.
     /// Return visibility.
     bool GetVisibility() const { return visibility_; }
     bool GetVisibility() const { return visibility_; }
 
 
-    /// Set sprite attribute.
-    void SetSpriteAttr(const ResourceRef& value);
-    /// Return sprite attribute.
-    ResourceRef GetSpriteAttr() const;
     /// Set blend mode attribute.
     /// Set blend mode attribute.
     void SetBlendModeAttr(BlendMode mode);
     void SetBlendModeAttr(BlendMode mode);
     /// Set material attribute.
     /// Set material attribute.
@@ -110,8 +118,8 @@ protected:
     int layer_;
     int layer_;
     /// Order in layer.
     /// Order in layer.
     int orderInLayer_;
     int orderInLayer_;
-    /// Sprite.
-    SharedPtr<Sprite2D> sprite_;
+    /// Texture.
+    SharedPtr<Texture2D> texture_;
     /// Material. If null, use a default material. If non-null, use a clone of this for updating the diffuse texture.
     /// Material. If null, use a default material. If non-null, use a clone of this for updating the diffuse texture.
     SharedPtr<Material> material_;
     SharedPtr<Material> material_;
     /// Blend mode.
     /// Blend mode.

+ 29 - 0
Source/Engine/Urho2D/ParticleEmitter2D.cpp

@@ -28,6 +28,7 @@
 #include "ResourceCache.h"
 #include "ResourceCache.h"
 #include "Scene.h"
 #include "Scene.h"
 #include "SceneEvents.h"
 #include "SceneEvents.h"
+#include "Sprite2D.h"
 
 
 #include "DebugNew.h"
 #include "DebugNew.h"
 
 
@@ -55,6 +56,7 @@ void ParticleEmitter2D::RegisterObject(Context* context)
     context->RegisterFactory<ParticleEmitter2D>(URHO2D_CATEGORY);
     context->RegisterFactory<ParticleEmitter2D>(URHO2D_CATEGORY);
 
 
     MIXED_ACCESSOR_ATTRIBUTE("Particle Effect", GetParticleEffectAttr, SetParticleEffectAttr, ResourceRef, ResourceRef(ParticleEffect2D::GetTypeStatic()), AM_DEFAULT);
     MIXED_ACCESSOR_ATTRIBUTE("Particle Effect", GetParticleEffectAttr, SetParticleEffectAttr, ResourceRef, ResourceRef(ParticleEffect2D::GetTypeStatic()), AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Sprite ", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(Drawable2D);
     COPY_BASE_ATTRIBUTES(Drawable2D);
 }
 }
 
 
@@ -144,6 +146,16 @@ void ParticleEmitter2D::SetEffect(ParticleEffect2D* model)
     emissionTime_ = effect_->GetDuration();
     emissionTime_ = effect_->GetDuration();
 }
 }
 
 
+void ParticleEmitter2D::SetSprite(Sprite2D* sprite)
+{
+    if (sprite == sprite_)
+        return;
+
+    sprite_ = sprite;
+
+    SetTexture(sprite_ ? sprite_->GetTexture() : 0);
+}
+
 void ParticleEmitter2D::SetMaxParticles(unsigned maxParticles)
 void ParticleEmitter2D::SetMaxParticles(unsigned maxParticles)
 {
 {
     maxParticles = Max(maxParticles, 1);
     maxParticles = Max(maxParticles, 1);
@@ -159,6 +171,11 @@ ParticleEffect2D* ParticleEmitter2D::GetEffect() const
     return effect_;
     return effect_;
 }
 }
 
 
+Sprite2D* ParticleEmitter2D::GetSprite() const
+{
+    return sprite_;
+}
+
 void ParticleEmitter2D::SetParticleEffectAttr(const ResourceRef& value)
 void ParticleEmitter2D::SetParticleEffectAttr(const ResourceRef& value)
 {
 {
     materialUpdatePending_ = true;
     materialUpdatePending_ = true;
@@ -172,6 +189,18 @@ ResourceRef ParticleEmitter2D::GetParticleEffectAttr() const
     return GetResourceRef(effect_, ParticleEffect2D::GetTypeStatic());
     return GetResourceRef(effect_, ParticleEffect2D::GetTypeStatic());
 }
 }
 
 
+void ParticleEmitter2D::SetSpriteAttr(const ResourceRef& value)
+{
+    Sprite2D* sprite = Sprite2D::LoadFromResourceRef(this, value);
+    if (sprite)
+        SetSprite(sprite);
+}
+
+ResourceRef ParticleEmitter2D::GetSpriteAttr() const
+{
+    return Sprite2D::SaveToResourceRef(sprite_);
+}
+
 void ParticleEmitter2D::OnNodeSet(Node* node)
 void ParticleEmitter2D::OnNodeSet(Node* node)
 {
 {
     Drawable2D::OnNodeSet(node);
     Drawable2D::OnNodeSet(node);

+ 12 - 0
Source/Engine/Urho2D/ParticleEmitter2D.h

@@ -28,6 +28,7 @@ namespace Urho3D
 {
 {
 
 
 class ParticleEffect2D;
 class ParticleEffect2D;
+class Sprite2D;
 
 
 /// 2D particle.
 /// 2D particle.
  struct Particle2D
  struct Particle2D
@@ -91,10 +92,15 @@ public:
 
 
     /// Set particle effect.
     /// Set particle effect.
     void SetEffect(ParticleEffect2D* effect);
     void SetEffect(ParticleEffect2D* effect);
+    /// Set sprite.
+    void SetSprite(Sprite2D* sprite);
     /// Set max particles.
     /// Set max particles.
     void SetMaxParticles(unsigned maxParticles);
     void SetMaxParticles(unsigned maxParticles);
+
     /// Return particle effect.
     /// Return particle effect.
     ParticleEffect2D* GetEffect() const;
     ParticleEffect2D* GetEffect() const;
+    /// Return sprite.
+    Sprite2D* GetSprite() const;
     /// Return max particles.
     /// Return max particles.
     unsigned GetMaxParticles() const { return particles_.Size(); }
     unsigned GetMaxParticles() const { return particles_.Size(); }
 
 
@@ -102,6 +108,10 @@ public:
     void SetParticleEffectAttr(const ResourceRef& value);
     void SetParticleEffectAttr(const ResourceRef& value);
     /// Return particle model attr.
     /// Return particle model attr.
     ResourceRef GetParticleEffectAttr() const;
     ResourceRef GetParticleEffectAttr() const;
+    /// Set sprite attribute.
+    void SetSpriteAttr(const ResourceRef& value);
+    /// Return sprite attribute.
+    ResourceRef GetSpriteAttr() const;
 
 
 private:
 private:
     /// Handle node being assigned.
     /// Handle node being assigned.
@@ -119,6 +129,8 @@ private:
 
 
     /// Particle effect.
     /// Particle effect.
     SharedPtr<ParticleEffect2D> effect_;
     SharedPtr<ParticleEffect2D> effect_;
+    /// Sprite.
+    SharedPtr<Sprite2D> sprite_;
     /// Num particles.
     /// Num particles.
     int numParticles_;
     int numParticles_;
     /// Emission time.
     /// Emission time.

+ 44 - 0
Source/Engine/Urho2D/Sprite2D.cpp

@@ -23,6 +23,7 @@
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "Context.h"
 #include "Context.h"
 #include "Deserializer.h"
 #include "Deserializer.h"
+#include "ResourceCache.h"
 #include "Sprite2D.h"
 #include "Sprite2D.h"
 #include "SpriteSheet2D.h"
 #include "SpriteSheet2D.h"
 #include "Texture2D.h"
 #include "Texture2D.h"
@@ -109,4 +110,47 @@ void Sprite2D::SetSpriteSheet(SpriteSheet2D* spriteSheet)
     spriteSheet_ = spriteSheet;
     spriteSheet_ = spriteSheet;
 }
 }
 
 
+ResourceRef Sprite2D::SaveToResourceRef(Sprite2D* sprite)
+{
+    SpriteSheet2D* spriteSheet = 0;
+    if (sprite)
+        spriteSheet = sprite->GetSpriteSheet();
+
+    if (!spriteSheet)
+        return GetResourceRef(sprite, Sprite2D::GetTypeStatic());
+
+    // Combine sprite sheet name and sprite name as resource name.
+    return ResourceRef(spriteSheet->GetType(), spriteSheet->GetName() + "@" + sprite->GetName());
+}
+
+Sprite2D* Sprite2D::LoadFromResourceRef(Object* object, const ResourceRef& value)
+{
+    if (!object)
+        return 0;
+
+    ResourceCache* cache = object->GetSubsystem<ResourceCache>();
+
+    if (value.type_ == Sprite2D::GetTypeStatic())
+        return cache->GetResource<Sprite2D>(value.name_);
+
+    if (value.type_ == SpriteSheet2D::GetTypeStatic())
+    {
+        // value.name_ include sprite sheet name and sprite name.
+        Vector<String> names = value.name_.Split('@');
+        if (names.Size() != 2)
+            return 0;
+
+        const String& spriteSheetName = names[0];
+        const String& spriteName = names[1];
+
+        SpriteSheet2D* spriteSheet = cache->GetResource<SpriteSheet2D>(spriteSheetName);
+        if (!spriteSheet)
+            return 0;
+
+        return spriteSheet->GetSprite(spriteName);
+    }
+
+    return 0;
+}
+
 }
 }

+ 5 - 14
Source/Engine/Urho2D/Sprite2D.h

@@ -22,7 +22,6 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "GraphicsDefs.h"
 #include "Resource.h"
 #include "Resource.h"
 
 
 namespace Urho3D
 namespace Urho3D
@@ -31,19 +30,6 @@ namespace Urho3D
 class SpriteSheet2D;
 class SpriteSheet2D;
 class Texture2D;
 class Texture2D;
 
 
-/// 2D vertex.
-struct Vertex2D
-{
-    /// Position.
-    Vector3 position_;
-    /// Color.
-    unsigned color_;
-    /// UV.
-    Vector2 uv_;
-};
-
-static const unsigned MASK_VERTEX2D = MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1;
-
 /// Sprite.
 /// Sprite.
 class URHO3D_API Sprite2D : public Resource
 class URHO3D_API Sprite2D : public Resource
 {
 {
@@ -84,6 +70,11 @@ public:
     /// Return sprite sheet.
     /// Return sprite sheet.
     SpriteSheet2D* GetSpriteSheet() const { return spriteSheet_; }
     SpriteSheet2D* GetSpriteSheet() const { return spriteSheet_; }
 
 
+    /// Save sprite to ResourceRef.
+    static ResourceRef SaveToResourceRef(Sprite2D* sprite);
+    /// Load sprite from ResourceRef.
+    static Sprite2D* LoadFromResourceRef(Object* object, const ResourceRef& value);
+
 private:
 private:
     /// Texture.
     /// Texture.
     SharedPtr<Texture2D> texture_;
     SharedPtr<Texture2D> texture_;

+ 29 - 0
Source/Engine/Urho2D/StaticSprite2D.cpp

@@ -52,12 +52,24 @@ StaticSprite2D::~StaticSprite2D()
 void StaticSprite2D::RegisterObject(Context* context)
 void StaticSprite2D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<StaticSprite2D>(URHO2D_CATEGORY);
     context->RegisterFactory<StaticSprite2D>(URHO2D_CATEGORY);
+
+    MIXED_ACCESSOR_ATTRIBUTE("Sprite", GetSpriteAttr, SetSpriteAttr, ResourceRef, ResourceRef(Sprite2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Flip X", GetFlipX, SetFlipX, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Flip Y", GetFlipY, SetFlipY, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE("Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
     COPY_BASE_ATTRIBUTES(Drawable2D);
     COPY_BASE_ATTRIBUTES(Drawable2D);
 }
 }
 
 
+void StaticSprite2D::SetSprite(Sprite2D* sprite)
+{
+    if (sprite == sprite_)
+        return;
+
+    sprite_ = sprite;
+
+    SetTexture(sprite_ ? sprite_->GetTexture() : 0);
+}
+
 void StaticSprite2D::SetFlip(bool flipX, bool flipY)
 void StaticSprite2D::SetFlip(bool flipX, bool flipY)
 {
 {
     if (flipX == flipX_ && flipY == flipY_)
     if (flipX == flipX_ && flipY == flipY_)
@@ -113,6 +125,23 @@ void StaticSprite2D::SetHotSpot(const Vector2& hotspot)
     }
     }
 }
 }
 
 
+Sprite2D* StaticSprite2D::GetSprite() const
+{
+    return sprite_;
+}
+
+void StaticSprite2D::SetSpriteAttr(const ResourceRef& value)
+{
+    Sprite2D* sprite = Sprite2D::LoadFromResourceRef(this, value);
+    if (sprite)
+        SetSprite(sprite);
+}
+
+ResourceRef StaticSprite2D::GetSpriteAttr() const
+{
+    return Sprite2D::SaveToResourceRef(sprite_);
+}
+
 void StaticSprite2D::OnWorldBoundingBoxUpdate()
 void StaticSprite2D::OnWorldBoundingBoxUpdate()
 {
 {
     boundingBox_.Clear();
     boundingBox_.Clear();

+ 14 - 1
Source/Engine/Urho2D/StaticSprite2D.h

@@ -27,6 +27,8 @@
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
+class Sprite2D;
+
 /// Static sprite component.
 /// Static sprite component.
 class URHO3D_API StaticSprite2D : public Drawable2D
 class URHO3D_API StaticSprite2D : public Drawable2D
 {
 {
@@ -40,6 +42,8 @@ public:
     /// Register object factory. Drawable2D must be registered first.
     /// Register object factory. Drawable2D must be registered first.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
 
 
+    /// Set sprite.
+    void SetSprite(Sprite2D* sprite);
     /// Set flip.
     /// Set flip.
     void SetFlip(bool flipX, bool flipY);
     void SetFlip(bool flipX, bool flipY);
     /// Set flip X.
     /// Set flip X.
@@ -52,7 +56,9 @@ public:
     void SetUseHotSpot(bool useHotSpot);
     void SetUseHotSpot(bool useHotSpot);
     /// Set hot spot.
     /// Set hot spot.
     void SetHotSpot(const Vector2& hotspot);
     void SetHotSpot(const Vector2& hotspot);
-
+    
+    /// Return sprite.
+    Sprite2D* GetSprite() const;
     /// Return flip X.
     /// Return flip X.
     bool GetFlipX() const { return flipX_; }
     bool GetFlipX() const { return flipX_; }
     /// Return flip Y.
     /// Return flip Y.
@@ -64,12 +70,19 @@ public:
     /// Return hot spot.
     /// Return hot spot.
     const Vector2& GetHotSpot() const { return hotSpot_; }
     const Vector2& GetHotSpot() const { return hotSpot_; }
 
 
+    /// Set sprite attribute.
+    void SetSpriteAttr(const ResourceRef& value);
+    /// Return sprite attribute.
+    ResourceRef GetSpriteAttr() const;
+
 protected:
 protected:
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     virtual void OnWorldBoundingBoxUpdate();
     /// Update vertices.
     /// Update vertices.
     virtual void UpdateVertices();
     virtual void UpdateVertices();
 
 
+    /// Sprite.
+    SharedPtr<Sprite2D> sprite_;
     /// Flip X.
     /// Flip X.
     bool flipX_;
     bool flipX_;
     /// Flip Y.
     /// Flip Y.