浏览代码

Reverted the change to not support fallback data mode in index & vertex buffers, as it broke AssetImporter.
Add resource hashes from ResourceRef or ResourceRefList attributes to ResourceCache in Serializable::LoadXML(), so that resources created during runtime will load properly.
Do not automatically assign the scene root node name when saving a scene in the editor.
Add the DebugRenderer component to the saved scene in AssetImporter, as it is needed in editing.

Lasse Öörni 14 年之前
父节点
当前提交
d94b865fce

+ 1 - 1
Bin/Data/Scripts/Editor/EditorImport.as

@@ -64,7 +64,7 @@ void ImportScene(const String&in fileName)
         {
             String currentFileName = sceneFileName;
             LoadScene(tempSceneName);
-            fileSystem.Delete(tempSceneName);
+            fileSystem.Delete(tempSceneName);          
             sceneFileName = currentFileName;
             UpdateWindowTitle();
         }

+ 1 - 3
Bin/Data/Scripts/Editor/EditorScene.as

@@ -23,7 +23,7 @@ void CreateScene()
     selectedNode = null;
 
     // Create a scene with default values, these will be overridden when loading scenes
-    editorScene = Scene("Urho3D Editor");
+    editorScene = Scene("");
     Octree@ octree = editorScene.CreateComponent("Octree");
     PhysicsWorld@ physicsWorld = editorScene.CreateComponent("PhysicsWorld");
     octree.Resize(BoundingBox(-1000.0, 1000.0), 8);
@@ -181,8 +181,6 @@ void SaveScene(const String&in fileName)
     if (fileName.empty || GetFileName(fileName).empty)
         return;
 
-    editorScene.name = GetFileName(fileName);
-
     File file(fileName, FILE_WRITE);
     String extension = GetExtension(fileName);
     if (extension != ".xml")

+ 38 - 26
Engine/Graphics/Direct3D9/D3D9IndexBuffer.cpp

@@ -79,6 +79,8 @@ void IndexBuffer::Release()
         ((IDirect3DIndexBuffer9*)object_)->Release();
         object_ = 0;
     }
+    
+    fallbackData_.Reset();
 }
 
 bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
@@ -127,7 +129,7 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count)
 
 void* IndexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
 {
-    if (!object_)
+    if (!object_ && !fallbackData_)
         return 0;
 
     if (locked_)
@@ -143,20 +145,26 @@ void* IndexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
     }
     
     void* hwData = 0;
-    DWORD flags = 0;
-    
-    if (mode == LOCK_DISCARD && usage_ & D3DUSAGE_DYNAMIC)
-        flags = D3DLOCK_DISCARD;
-    if (mode == LOCK_NOOVERWRITE && usage_ & D3DUSAGE_DYNAMIC)
-        flags = D3DLOCK_NOOVERWRITE;
-    if (mode == LOCK_READONLY)
-        flags = D3DLOCK_READONLY;
-        
-    if (FAILED(((IDirect3DIndexBuffer9*)object_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags)))
+    
+    if (object_)
     {
-        LOGERROR("Could not lock index buffer");
-        return 0;
+        DWORD flags = 0;
+        
+        if (mode == LOCK_DISCARD && usage_ & D3DUSAGE_DYNAMIC)
+            flags = D3DLOCK_DISCARD;
+        if (mode == LOCK_NOOVERWRITE && usage_ & D3DUSAGE_DYNAMIC)
+            flags = D3DLOCK_NOOVERWRITE;
+        if (mode == LOCK_READONLY)
+            flags = D3DLOCK_READONLY;
+        
+        if (FAILED(((IDirect3DIndexBuffer9*)object_)->Lock(start * indexSize_, count * indexSize_, &hwData, flags)))
+        {
+            LOGERROR("Could not lock index buffer");
+            return 0;
+        }
     }
+    else
+        hwData = fallbackData_.Get() + start * indexSize_;
     
     locked_ = true;
     return hwData;
@@ -166,7 +174,8 @@ void IndexBuffer::Unlock()
 {
     if (locked_)
     {
-        ((IDirect3DIndexBuffer9*)object_)->Unlock();
+        if (object_)
+            ((IDirect3DIndexBuffer9*)object_)->Unlock();
         locked_ = false;
     }
 }
@@ -227,21 +236,24 @@ bool IndexBuffer::Create()
     
     if (!indexCount_)
         return true;
-    if (!graphics_)
-        return false;
     
-    IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-    if (!device || FAILED(device->CreateIndexBuffer(
-        indexCount_ * indexSize_,
-        usage_,
-        indexSize_ == sizeof(unsigned) ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
-        (D3DPOOL)pool_,
-        (IDirect3DIndexBuffer9**)&object_,
-        0)))
+    if (graphics_)
     {
-        LOGERROR("Could not create index buffer");
-        return false;
+        IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
+        if (!device || FAILED(device->CreateIndexBuffer(
+            indexCount_ * indexSize_,
+            usage_,
+            indexSize_ == sizeof(unsigned) ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
+            (D3DPOOL)pool_,
+            (IDirect3DIndexBuffer9**)&object_,
+            0)))
+        {
+            LOGERROR("Could not create index buffer");
+            return false;
+        }
     }
+    else
+        fallbackData_ = new unsigned char[indexCount_ * indexSize_];
     
     return true;
 }

+ 2 - 0
Engine/Graphics/Direct3D9/D3D9IndexBuffer.h

@@ -74,6 +74,8 @@ private:
     /// Create buffer.
     bool Create();
     
+    /// Fallback data when operating with a null graphics subsystem.
+    SharedArrayPtr<unsigned char> fallbackData_;
     /// Memory pool.
     unsigned pool_;
     /// Usage type.

+ 37 - 25
Engine/Graphics/Direct3D9/D3D9VertexBuffer.cpp

@@ -118,6 +118,8 @@ void VertexBuffer::Release()
         ((IDirect3DVertexBuffer9*)object_)->Release();
         object_ = 0;
     }
+    
+    fallbackData_.Reset();
 }
 
 bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
@@ -191,7 +193,7 @@ void VertexBuffer::SetMorphRangeResetData(const SharedArrayPtr<unsigned char>& d
 
 void* VertexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
 {
-    if (!object_)
+    if (!object_ && !fallbackData_)
         return 0;
 
     if (locked_)
@@ -207,20 +209,26 @@ void* VertexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
     }
     
     void* hwData = 0;
-    DWORD flags = 0;
-    
-    if (mode == LOCK_DISCARD && usage_ & D3DUSAGE_DYNAMIC)
-        flags = D3DLOCK_DISCARD;
-    if (mode == LOCK_NOOVERWRITE && usage_ & D3DUSAGE_DYNAMIC)
-        flags = D3DLOCK_NOOVERWRITE;
-    if (mode == LOCK_READONLY)
-        flags = D3DLOCK_READONLY;
     
-    if (FAILED(((IDirect3DVertexBuffer9*)object_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags)))
+    if (object_)
     {
-        LOGERROR("Could not lock vertex buffer");
-        return 0;
+        DWORD flags = 0;
+        
+        if (mode == LOCK_DISCARD && usage_ & D3DUSAGE_DYNAMIC)
+            flags = D3DLOCK_DISCARD;
+        if (mode == LOCK_NOOVERWRITE && usage_ & D3DUSAGE_DYNAMIC)
+            flags = D3DLOCK_NOOVERWRITE;
+        if (mode == LOCK_READONLY)
+            flags = D3DLOCK_READONLY;
+        
+        if (FAILED(((IDirect3DVertexBuffer9*)object_)->Lock(start * vertexSize_, count * vertexSize_, &hwData, flags)))
+        {
+            LOGERROR("Could not lock vertex buffer");
+            return 0;
+        }
     }
+    else
+        hwData = fallbackData_.Get() + start * vertexSize_;
     
     locked_ = true;
     return hwData;
@@ -230,7 +238,8 @@ void VertexBuffer::Unlock()
 {
     if (locked_)
     {
-        ((IDirect3DVertexBuffer9*)object_)->Unlock();
+        if (object_)
+            ((IDirect3DVertexBuffer9*)object_)->Unlock();
         locked_ = false;
     }
 }
@@ -314,21 +323,24 @@ bool VertexBuffer::Create()
     
     if (!vertexCount_ || !elementMask_)
         return true;
-    if (!graphics_)
-        return false;
     
-    IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
-    if (!device || FAILED(device->CreateVertexBuffer(
-        vertexCount_ * vertexSize_,
-        usage_,
-        0,
-        (D3DPOOL)pool_,
-        (IDirect3DVertexBuffer9**)&object_,
-        0)))
+    if (graphics_)
     {
-        LOGERROR("Could not create vertex buffer");
-        return false;
+        IDirect3DDevice9* device = graphics_->GetImpl()->GetDevice();
+        if (!device || FAILED(device->CreateVertexBuffer(
+            vertexCount_ * vertexSize_,
+            usage_,
+            0,
+            (D3DPOOL)pool_,
+            (IDirect3DVertexBuffer9**)&object_,
+            0)))
+        {
+            LOGERROR("Could not create vertex buffer");
+            return false;
+        }
     }
+    else
+        fallbackData_ = new unsigned char[vertexCount_ * vertexSize_];
     
     return true;
 }

+ 2 - 0
Engine/Graphics/Direct3D9/D3D9VertexBuffer.h

@@ -103,6 +103,8 @@ private:
     /// Create buffer.
     bool Create();
     
+    /// Fallback data when operating with a null graphics subsystem.
+    SharedArrayPtr<unsigned char> fallbackData_;
     /// Morph vertex range reset data.
     SharedArrayPtr<unsigned char> morphRangeResetData_;
     /// Memory pool.

+ 22 - 54
Engine/Graphics/Model.cpp

@@ -86,8 +86,6 @@ bool Model::Load(Deserializer& source)
         return false;
     }
     
-    bool headless = GetSubsystem<Graphics>() == 0;
-    
     geometries_.Clear();
     geometryBoneMappings_.Clear();
     morphs_.Clear();
@@ -113,43 +111,19 @@ bool Model::Load(Deserializer& source)
         buffer->SetMorphRange(morphStart, morphCount);
         
         unsigned vertexSize = buffer->GetVertexSize();
-        if (!headless)
+        unsigned char* data = (unsigned char*)buffer->Lock(0, vertexCount, LOCK_NORMAL);
+        if (data)
         {
-            unsigned char* data = (unsigned char*)buffer->Lock(0, vertexCount, LOCK_NORMAL);
-            if (data)
+            source.Read(data, vertexCount * vertexSize);
+            // If there is a morph range, make a copy of the data so that the morph range can be reset
+            if (morphCount)
             {
-                source.Read(data, vertexCount * vertexSize);
-                // If there is a morph range, make a copy of the data so that the morph range can be reset
-                if (morphCount)
-                {
-                    SharedArrayPtr<unsigned char> morphResetData(new unsigned char[morphCount * vertexSize]);
-                    memcpy(morphResetData.Get(), &data[morphStart * vertexSize], morphCount * vertexSize);
-                    buffer->SetMorphRangeResetData(morphResetData);
-                }
-            
-                // Copy the raw position data for CPU-side operations
-                SharedArrayPtr<unsigned char> rawVertexData(new unsigned char[3 * sizeof(float) * vertexCount]);
-                float* rawDest = (float*)rawVertexData.Get();
-                for (unsigned i = 0; i < vertexCount; ++i)
-                {
-                    float* rawSrc = (float*)&data[i * vertexSize];
-                    *rawDest++ = *rawSrc++;
-                    *rawDest++ = *rawSrc++;
-                    *rawDest++ = *rawSrc++;
-                }
-                rawVertexDatas.Push(rawVertexData);
-                
-                buffer->Unlock();
+                SharedArrayPtr<unsigned char> morphResetData(new unsigned char[morphCount * vertexSize]);
+                memcpy(morphResetData.Get(), &data[morphStart * vertexSize], morphCount * vertexSize);
+                buffer->SetMorphRangeResetData(morphResetData);
             }
-            else
-                return false;
-        }
-        else
-        {
-            // In headless mode only store the raw position data for CPU operations
-            SharedArrayPtr<unsigned char> data(new unsigned char[vertexCount * vertexSize]);
-            source.Read(data.Get(), vertexCount * vertexSize);
             
+            // Copy the raw position data for CPU-side operations
             SharedArrayPtr<unsigned char> rawVertexData(new unsigned char[3 * sizeof(float) * vertexCount]);
             float* rawDest = (float*)rawVertexData.Get();
             for (unsigned i = 0; i < vertexCount; ++i)
@@ -160,7 +134,11 @@ bool Model::Load(Deserializer& source)
                 *rawDest++ = *rawSrc++;
             }
             rawVertexDatas.Push(rawVertexData);
+            
+            buffer->Unlock();
         }
+        else
+            return false;
         
         vertexBuffers_.Push(buffer);
     }
@@ -175,30 +153,20 @@ bool Model::Load(Deserializer& source)
         SharedPtr<IndexBuffer> buffer(new IndexBuffer(context_));
         buffer->SetSize(indexCount, indexSize > sizeof(unsigned short));
         
-        if (!headless)
+        unsigned char* data = (unsigned char*)buffer->Lock(0, indexCount, LOCK_NORMAL);
+        if (data)
         {
-            unsigned char* data = (unsigned char*)buffer->Lock(0, indexCount, LOCK_NORMAL);
-            if (data)
-            {
-                source.Read(data, indexCount * indexSize);
+            source.Read(data, indexCount * indexSize);
             
-                // Copy the raw index data for CPU-side operations
-                SharedArrayPtr<unsigned char> rawIndexData(new unsigned char[indexSize * indexCount]);
-                memcpy(rawIndexData.Get(), data, indexSize * indexCount);
-                rawIndexDatas.Push(rawIndexData);
-            
-                buffer->Unlock();
-            }
-            else
-                return false;
-        }
-        else
-        {
-            // In headless mode only store the raw index data for CPU operations
+            // Copy the raw index data for CPU-side operations
             SharedArrayPtr<unsigned char> rawIndexData(new unsigned char[indexSize * indexCount]);
-            source.Read(rawIndexData.Get(), indexSize * indexCount);
+            memcpy(rawIndexData.Get(), data, indexSize * indexCount);
             rawIndexDatas.Push(rawIndexData);
+            
+            buffer->Unlock();
         }
+        else
+            return false;
         
         indexBuffers_.Push(buffer);
     }

+ 42 - 20
Engine/Graphics/OpenGL/OGLIndexBuffer.cpp

@@ -92,6 +92,8 @@ void IndexBuffer::Release()
         glDeleteBuffers(1, &object_);
         object_ = 0;
     }
+    
+    fallbackData_.Reset();
 }
 
 bool IndexBuffer::SetSize(unsigned indexCount, bool largeIndices, bool dynamic)
@@ -120,6 +122,11 @@ bool IndexBuffer::SetData(const void* data)
         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount_ * indexSize_, data, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
         return true;
     }
+    else if (fallbackData_)
+    {
+        memcpy(fallbackData_.Get(), data, indexCount_ * indexSize_);
+        return true;
+    }
     
     return false;
 }
@@ -147,13 +154,18 @@ bool IndexBuffer::SetDataRange(const void* data, unsigned start, unsigned count)
         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, start * indexSize_, indexCount_ * indexSize_, data);
         return true;
     }
+    else if (fallbackData_)
+    {
+        memcpy(fallbackData_.Get() + start * indexSize_, data, indexCount_ * indexSize_);
+        return true;
+    }
     
     return false;
 }
 
 void* IndexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
 {
-    if (!object_)
+    if (!object_ && !fallbackData_)
         return 0;
     
     if (locked_)
@@ -175,15 +187,20 @@ void* IndexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
     else if (mode == LOCK_NORMAL)
         glLockMode = GL_READ_WRITE;
     
-    graphics_->SetIndexBuffer(this);
-    // If locking the whole buffer in discard mode, create a new data store
-    if (mode == LOCK_DISCARD && count == indexCount_)
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount_ * indexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
-    
-    hwData = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, glLockMode);
-    if (!hwData)
-        return 0;
-    hwData = (unsigned char*)hwData + start * indexSize_;
+    if (object_)
+    {
+        graphics_->SetIndexBuffer(this);
+        // If locking the whole buffer in discard mode, create a new data store
+        if (mode == LOCK_DISCARD && count == indexCount_)
+            glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount_ * indexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+        
+        hwData = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, glLockMode);
+        if (!hwData)
+            return 0;
+        hwData = (unsigned char*)hwData + start * indexSize_;
+    }
+    else
+        hwData = fallbackData_.Get() + start * indexSize_;
     
     locked_ = true;
     return hwData;
@@ -193,8 +210,11 @@ void IndexBuffer::Unlock()
 {
     if (locked_)
     {
-        graphics_->SetIndexBuffer(this);
-        glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+        if (object_)
+        {
+            graphics_->SetIndexBuffer(this);
+            glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+        }
         locked_ = false;
     }
 }
@@ -251,14 +271,16 @@ bool IndexBuffer::Create()
         return true;
     }
     
-    if (!graphics_)
-        return false;
-    
-    if (!object_)
-        glGenBuffers(1, &object_);
-    
-    graphics_->SetIndexBuffer(this);
-    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount_ * indexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+    if (graphics_)
+    {
+        if (!object_)
+            glGenBuffers(1, &object_);
+        
+        graphics_->SetIndexBuffer(this);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount_ * indexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+    }
+    else
+        fallbackData_ = new unsigned char[indexCount_ * indexSize_];
     
     return true;
 }

+ 2 - 0
Engine/Graphics/OpenGL/OGLIndexBuffer.h

@@ -74,6 +74,8 @@ private:
     /// Create buffer.
     bool Create();
     
+    /// Fallback data when operating with a null graphics subsystem.
+    SharedArrayPtr<unsigned char> fallbackData_;
     /// Save data when OpenGL context needs to be destroyed and recreated.
     SharedArrayPtr<unsigned char> saveData_;
     /// Number of indices.

+ 42 - 20
Engine/Graphics/OpenGL/OGLVertexBuffer.cpp

@@ -182,6 +182,8 @@ void VertexBuffer::Release()
         glDeleteBuffers(1, &object_);
         object_ = 0;
     }
+    
+    fallbackData_.Reset();
 }
 
 bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
@@ -217,6 +219,11 @@ bool VertexBuffer::SetData(const void* data)
         glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, data, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
         return true;
     }
+    else if (fallbackData_)
+    {
+        memcpy(fallbackData_.Get(), data, vertexCount_ * vertexSize_);
+        return true;
+    }
     
     return false;
 }
@@ -244,6 +251,11 @@ bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count
         glBufferSubData(GL_ARRAY_BUFFER, start * vertexSize_, vertexCount_ * vertexSize_, data);
         return true;
     }
+    else if (fallbackData_)
+    {
+        memcpy(fallbackData_.Get() + start * vertexSize_, data, vertexCount_ * vertexSize_);
+        return true;
+    }
     
     return false;
 }
@@ -268,7 +280,7 @@ void VertexBuffer::SetMorphRangeResetData(const SharedArrayPtr<unsigned char>& d
 
 void* VertexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
 {
-    if (!object_)
+    if (!object_ && !fallbackData_)
         return 0;
     
     if (locked_)
@@ -290,15 +302,20 @@ void* VertexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
     else if (mode == LOCK_NORMAL)
         glLockMode = GL_READ_WRITE;
     
-    glBindBuffer(GL_ARRAY_BUFFER, object_);
-    // If locking the whole buffer in discard mode, create a new data store
-    if (mode == LOCK_DISCARD && count == vertexCount_)
-        glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
-    
-    hwData = glMapBuffer(GL_ARRAY_BUFFER, glLockMode);
-    if (!hwData)
-        return 0;
-    hwData = (unsigned char*)hwData + start * vertexSize_;
+    if (object_)
+    {
+        glBindBuffer(GL_ARRAY_BUFFER, object_);
+        // If locking the whole buffer in discard mode, create a new data store
+        if (mode == LOCK_DISCARD && count == vertexCount_)
+            glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+        
+        hwData = glMapBuffer(GL_ARRAY_BUFFER, glLockMode);
+        if (!hwData)
+            return 0;
+        hwData = (unsigned char*)hwData + start * vertexSize_;
+    }
+    else
+        hwData = fallbackData_.Get() + start * vertexSize_;
     
     locked_ = true;
     return hwData;
@@ -308,8 +325,11 @@ void VertexBuffer::Unlock()
 {
     if (locked_)
     {
-        glBindBuffer(GL_ARRAY_BUFFER, object_);
-        glUnmapBuffer(GL_ARRAY_BUFFER);
+        if (object_)
+        {
+            glBindBuffer(GL_ARRAY_BUFFER, object_);
+            glUnmapBuffer(GL_ARRAY_BUFFER);
+        }
         locked_ = false;
     }
 }
@@ -389,14 +409,16 @@ bool VertexBuffer::Create()
         return true;
     }
     
-    if (!graphics_)
-        return false;
-    
-    if (!object_)
-        glGenBuffers(1, &object_);
-    
-    glBindBuffer(GL_ARRAY_BUFFER, object_);
-    glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+    if (graphics_)
+    {
+        if (!object_)
+            glGenBuffers(1, &object_);
+        
+        glBindBuffer(GL_ARRAY_BUFFER, object_);
+        glBufferData(GL_ARRAY_BUFFER, vertexCount_ * vertexSize_, 0, dynamic_ ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+    }
+    else
+        fallbackData_ = new unsigned char[vertexCount_ * vertexSize_];
     
     return true;
 }

+ 2 - 0
Engine/Graphics/OpenGL/OGLVertexBuffer.h

@@ -109,6 +109,8 @@ private:
     /// Create buffer.
     bool Create();
     
+    /// Fallback data when operating with a null graphics subsystem.
+    SharedArrayPtr<unsigned char> fallbackData_;
     /// Morph vertex range reset data.
     SharedArrayPtr<unsigned char> morphRangeResetData_;
     /// Save data when OpenGL context needs to be destroyed and recreated.

+ 5 - 0
Engine/IO/FileSystem.cpp

@@ -124,6 +124,11 @@ int FileSystem::SystemCommand(const String& commandLine)
 
 int FileSystem::SystemRun(const String& fileName, const Vector<String>& arguments)
 {
+    String fullLine = fileName + " ";
+    for (unsigned i = 0; i < arguments.Size(); ++i)
+        fullLine += arguments[i] + " ";
+    LOGINFO("SystemRun: " + fullLine);
+    
     if (allowedPaths_.Empty())
     {
         String fixedFileName = GetNativePath(fileName);

+ 8 - 8
Engine/Resource/ResourceCache.cpp

@@ -501,6 +501,14 @@ String ResourceCache::GetPreferredResourceDir(const String& path)
     return fixedPath;
 }
 
+void ResourceCache::StoreNameHash(const String& name)
+{
+    if (name.Empty())
+        return;
+    
+    hashToName_[StringHash(name)] = name;
+}
+
 const SharedPtr<Resource>& ResourceCache::FindResource(ShortStringHash type, StringHash nameHash)
 {
     Map<ShortStringHash, ResourceGroup>::Iterator i = resourceGroups_.Find(type);
@@ -584,14 +592,6 @@ void ResourceCache::UpdateResourceGroup(ShortStringHash type)
     }
 }
 
-void ResourceCache::StoreNameHash(const String& name)
-{
-    if (name.Empty())
-        return;
-    
-    hashToName_[StringHash(name)] = name;
-}
-
 void RegisterResourceLibrary(Context* context)
 {
     Image::RegisterObject(context);

+ 3 - 3
Engine/Resource/ResourceCache.h

@@ -72,7 +72,7 @@ public:
     /// Release a resource by name.
     void ReleaseResource(ShortStringHash type, const String& name, bool force = false);
     /// Release a resource by name hash.
-    void ReleaseResource(ShortStringHash type, StringHash nameHash, bool force = false); 
+    void ReleaseResource(ShortStringHash type, StringHash nameHash, bool force = false);
     /// Release all resources of a specific type.
     void ReleaseResources(ShortStringHash type, bool force = false);
     /// Release resources of a specific type and partial name.
@@ -118,6 +118,8 @@ public:
     const String& GetResourceName(StringHash nameHash) const;
     /// Return either the path itself or its parent, based on which of them has recognized resource subdirectories.
     String GetPreferredResourceDir(const String& path);
+    /// Store a hash-to-name mapping.
+    void StoreNameHash(const String& name);
     
 private:
     /// Find a resource.
@@ -126,8 +128,6 @@ private:
     void ReleasePackageResources(PackageFile* package, bool force = false);
     /// Update a resource group. Recalculate memory use and release resources if over memory budget.
     void UpdateResourceGroup(ShortStringHash type);
-    /// Store a hash-to-name mapping.
-    void StoreNameHash(const String& name);
     
     /// Resources by type.
     Map<ShortStringHash, ResourceGroup> resourceGroups_;

+ 14 - 1
Engine/Scene/Serializable.cpp

@@ -25,6 +25,7 @@
 #include "Context.h"
 #include "Deserializer.h"
 #include "Log.h"
+#include "ResourceCache.h"
 #include "Serializable.h"
 #include "Serializer.h"
 #include "XMLElement.h"
@@ -297,8 +298,20 @@ bool Serializable::LoadXML(const XMLElement& source)
                         LOGWARNING("Unknown enum value " + value + " in attribute " + String(attr.name_));
                 }
                 else
+                {
+                    // If attribute is ResourceRef or ResourceRefList, add the resources' hash mappings to the resource cache
+                    // in case we are loading yet unknown resources created during runtime
+                    if (attr.type_ == VAR_RESOURCEREF || attr.type_ == VAR_RESOURCEREFLIST)
+                    {
+                        ResourceCache* cache = GetSubsystem<ResourceCache>();
+                        Vector<String> refs = attrElem.GetString("value").Split(';');
+                        for (unsigned i = 1; i < refs.Size(); ++i)
+                            cache->StoreNameHash(refs[i]);
+                    }
+                    
                     OnSetAttribute(attr, attrElem.GetVariant());
-                
+                }
+
                 found = true;
                 break;
             }

+ 3 - 1
Tools/AssetImporter/AssetImporter.cpp

@@ -23,6 +23,7 @@
 
 #include "Animation.h"
 #include "Context.h"
+#include "DebugRenderer.h"
 #include "File.h"
 #include "FileSystem.h"
 #include "Geometry.h"
@@ -1070,7 +1071,6 @@ void BuildAndSaveScene(OutScene& scene)
     PrintLine("Writing scene");
     
     SharedPtr<Scene> outScene(new Scene(context_));
-    outScene->SetName(GetFileName(scene.outName_));
     
     /// \todo Make the physics properties configurable
     PhysicsWorld* physicsWorld = outScene->CreateComponent<PhysicsWorld>();
@@ -1079,6 +1079,8 @@ void BuildAndSaveScene(OutScene& scene)
     /// \todo Make the octree properties configurable, or detect from the scene contents
     Octree* octree = outScene->CreateComponent<Octree>();
     
+    DebugRenderer* debug = outScene->CreateComponent<DebugRenderer>();
+    
     if (createZone_)
     {
         Node* zoneNode = outScene->CreateChild("Zone", localIDs_ ? LOCAL : REPLICATED);