Ver código fonte

Added List::Resize().
Store light queues into a list instead of a vector for cleaner code.
Fixed copy-pasting local nodes in editor not making the components local.

Lasse Öörni 14 anos atrás
pai
commit
4c3be1f600

+ 10 - 0
Engine/Container/List.h

@@ -276,6 +276,16 @@ public:
             EraseNode(Head());
     }
     
+    /// Resize the list by removing or adding items at the end.
+    void Resize(unsigned newSize)
+    {
+        while (size_ > newSize)
+            Pop();
+        
+        while (size_ < newSize)
+            InsertNode(Tail(), T());
+    }
+    
     /// Return iterator to value, or to the end if not found.
     Iterator Find(const T& value)
     {

+ 3 - 2
Engine/Graphics/Light.cpp

@@ -36,6 +36,7 @@
 #include "DebugNew.h"
 
 static const LightType DEFAULT_LIGHTTYPE = LIGHT_POINT;
+static const float DEFAULT_RANGE = 10.0f;
 static const float DEFAULT_FOV = 30.0f;
 static const float DEFAULT_CONSTANTBIAS = 0.0001f;
 static const float DEFAULT_SLOPESCALEDBIAS = 0.5f;
@@ -82,7 +83,7 @@ Light::Light(Context* context) :
     Drawable(context),
     lightType_(DEFAULT_LIGHTTYPE),
     specularIntensity_(0.0f),
-    range_(0.0f),
+    range_(DEFAULT_RANGE),
     fov_(DEFAULT_FOV),
     aspectRatio_(1.0f),
     fadeDistance_(0.0f),
@@ -108,7 +109,7 @@ void Light::RegisterObject(Context* context)
     ENUM_ACCESSOR_ATTRIBUTE(Light, "Light Type", GetLightType, SetLightType, LightType, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_COLOR, "Color", color_, Color(), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot FOV", GetFov, SetFov, float, DEFAULT_FOV, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);

+ 3 - 3
Engine/Graphics/Renderer.cpp

@@ -470,11 +470,11 @@ unsigned Renderer::GetNumShadowMaps(bool allViews) const
     
     for (unsigned i = 0; i < lastView; ++i)
     {
-        const Vector<LightBatchQueue>& lightQueues = views_[i]->GetLightQueues();
+        const List<LightBatchQueue>& lightQueues = views_[i]->GetLightQueues();
         
-        for (unsigned j = 0; j < lightQueues.Size(); ++j)
+        for (List<LightBatchQueue>::ConstIterator i = lightQueues.Begin(); i != lightQueues.End(); ++i)
         {
-            if (lightQueues[j].shadowMap_)
+            if (i->shadowMap_)
                 ++numShadowMaps;
         }
     }

+ 31 - 49
Engine/Graphics/View.cpp

@@ -134,18 +134,12 @@ void SortBatchQueueBackToFrontWork(const WorkItem* item, unsigned threadIndex)
     queue->SortBackToFront();
 }
 
-void SortLightQueuesWork(const WorkItem* item, unsigned threadIndex)
+void SortLightQueueWork(const WorkItem* item, unsigned threadIndex)
 {
     LightBatchQueue* start = reinterpret_cast<LightBatchQueue*>(item->start_);
-    LightBatchQueue* end = reinterpret_cast<LightBatchQueue*>(item->end_);
-    
-    while (start != end)
-    {
-        for (unsigned i = 0; i < start->shadowSplits_.Size(); ++i)
-            start->shadowSplits_[i].shadowBatches_.SortFrontToBack();
-        start->litBatches_.SortFrontToBack();
-        ++start;
-    }
+    for (unsigned i = 0; i < start->shadowSplits_.Size(); ++i)
+        start->shadowSplits_[i].shadowBatches_.SortFrontToBack();
+    start->litBatches_.SortFrontToBack();
 }
 
 OBJECTTYPESTATIC(View);
@@ -512,14 +506,10 @@ void View::GetBatches()
     
     // Build light queues and lit batches
     {
-        // Preallocate enough light queues so that we can store pointers to them without having to worry about the
-        // vector reallocating itself
-        lightQueues_.Resize(lights_.Size());
-        unsigned lightQueueCount = 0;
         bool fallback = graphics_->GetFallback();
         
         maxLightsDrawables_.Clear();
-        lightQueueIndex_.Clear();
+        lightQueueMapping_.Clear();
         
         for (Vector<LightQueryResult>::ConstIterator i = lightQueryResults_.Begin(); i != lightQueryResults_.End(); ++i)
         {
@@ -532,9 +522,10 @@ void View::GetBatches()
             Light* light = query.light_;
             unsigned shadowSplits = query.numSplits_;
             
-            // Initialize light queue. Store pointer-to-index mapping so that the queue can be found later
-            LightBatchQueue& lightQueue = lightQueues_[lightQueueCount];
-            lightQueueIndex_[light] = lightQueueCount;
+            // Initialize light queue. Store light-to-queue mapping so that the queue can be found later
+            lightQueues_.Resize(lightQueues_.Size() + 1);
+            LightBatchQueue& lightQueue = lightQueues_.Back();
+            lightQueueMapping_[light] = &lightQueue;
             lightQueue.light_ = light;
             lightQueue.litBatches_.Clear();
             
@@ -611,12 +602,7 @@ void View::GetBatches()
                 else
                     maxLightsDrawables_.Insert(drawable);
             }
-            
-            ++lightQueueCount;
         }
-        
-        // Resize the light queue vector now that final size is known
-        lightQueues_.Resize(lightQueueCount);
     }
     
     // Process drawables with limited light count
@@ -634,9 +620,9 @@ void View::GetBatches()
             {
                 Light* light = lights[i];
                 // Find the correct light queue again
-                Map<Light*, unsigned>::Iterator j = lightQueueIndex_.Find(light);
-                if (j != lightQueueIndex_.End())
-                    GetLitBatches(drawable, lightQueues_[j->second_]);
+                Map<Light*, LightBatchQueue*>::Iterator j = lightQueueMapping_.Find(light);
+                if (j != lightQueueMapping_.End())
+                    GetLitBatches(drawable, *(j->second_));
             }
         }
     }
@@ -735,12 +721,11 @@ void View::UpdateGeometries()
         queue->AddWorkItem(item);
         item.start_ = &postAlphaQueue_;
         queue->AddWorkItem(item);
-
-        if (lightQueues_.Size())
+        
+        for (List<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
         {
-            item.workFunction_ = SortLightQueuesWork;
-            item.start_ = &lightQueues_.Front();
-            item.end_ = &lightQueues_.Back() + 1;
+            item.workFunction_ = SortLightQueueWork;
+            item.start_ = &(*i);
             queue->AddWorkItem(item);
         }
     }
@@ -854,11 +839,10 @@ void View::RenderBatches()
     {
         PROFILE(RenderShadowMaps);
         
-        for (unsigned i = 0; i < lightQueues_.Size(); ++i)
+        for (List<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
         {
-            LightBatchQueue& queue = lightQueues_[i];
-            if (queue.shadowMap_)
-                RenderShadowMap(queue);
+            if (i->shadowMap_)
+                RenderShadowMap(*i);
         }
     }
     
@@ -880,20 +864,18 @@ void View::RenderBatches()
         // Render shadow maps + opaque objects' shadowed additive lighting
         PROFILE(RenderLights);
         
-        for (unsigned i = 0; i < lightQueues_.Size(); ++i)
+        for (List<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
         {
-            LightBatchQueue& queue = lightQueues_[i];
-            
             // If reusing shadowmaps, render each of them before the lit batches
-            if (renderer_->GetReuseShadowMaps() && queue.shadowMap_)
+            if (renderer_->GetReuseShadowMaps() && i->shadowMap_)
             {
-                RenderShadowMap(queue);
+                RenderShadowMap(*i);
                 graphics_->SetRenderTarget(0, renderTarget_);
                 graphics_->SetDepthStencil(depthStencil_);
                 graphics_->SetViewport(screenRect_);
             }
             
-            RenderLightBatchQueue(queue.litBatches_, queue.light_);
+            RenderLightBatchQueue(i->litBatches_, i->light_);
         }
     }
     
@@ -1754,11 +1736,11 @@ void View::PrepareInstancingBuffer()
     totalInstances += baseQueue_.GetNumInstances(renderer_);
     totalInstances += preAlphaQueue_.GetNumInstances(renderer_);
     
-    for (unsigned i = 0; i < lightQueues_.Size(); ++i)
+    for (List<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
     {
-        for (unsigned j = 0; j < lightQueues_[i].shadowSplits_.Size(); ++j)
-            totalInstances += lightQueues_[i].shadowSplits_[j].shadowBatches_.GetNumInstances(renderer_);
-        totalInstances += lightQueues_[i].litBatches_.GetNumInstances(renderer_);
+        for (unsigned j = 0; j < i->shadowSplits_.Size(); ++j)
+            totalInstances += i->shadowSplits_[j].shadowBatches_.GetNumInstances(renderer_);
+        totalInstances += i->litBatches_.GetNumInstances(renderer_);
     }
     
     // If fail to set buffer size, fall back to per-group locking
@@ -1772,11 +1754,11 @@ void View::PrepareInstancingBuffer()
             baseQueue_.SetTransforms(renderer_, lockedData, freeIndex);
             preAlphaQueue_.SetTransforms(renderer_, lockedData, freeIndex);
             
-            for (unsigned i = 0; i < lightQueues_.Size(); ++i)
+            for (List<LightBatchQueue>::Iterator i = lightQueues_.Begin(); i != lightQueues_.End(); ++i)
             {
-                for (unsigned j = 0; j < lightQueues_[i].shadowSplits_.Size(); ++j)
-                    lightQueues_[i].shadowSplits_[j].shadowBatches_.SetTransforms(renderer_, lockedData, freeIndex);
-                lightQueues_[i].litBatches_.SetTransforms(renderer_, lockedData, freeIndex);
+                for (unsigned j = 0; j < i->shadowSplits_.Size(); ++j)
+                    i->shadowSplits_[j].shadowBatches_.SetTransforms(renderer_, lockedData, freeIndex);
+                i->litBatches_.SetTransforms(renderer_, lockedData, freeIndex);
             }
             
             instancingBuffer->Unlock();

+ 4 - 4
Engine/Graphics/View.h

@@ -112,7 +112,7 @@ public:
     /// Return lights.
     const PODVector<Light*>& GetLights() const { return lights_; }
     /// Return light batch queues.
-    const Vector<LightBatchQueue>& GetLightQueues() const { return lightQueues_; }
+    const List<LightBatchQueue>& GetLightQueues() const { return lightQueues_; }
     
 private:
     /// Query the octree for drawable objects.
@@ -242,8 +242,8 @@ private:
     PODVector<Light*> lights_;
     /// Drawables that limit their maximum light count.
     HashSet<Drawable*> maxLightsDrawables_;
-    /// Light queue indices of processed lights.
-    Map<Light*, unsigned> lightQueueIndex_;
+    /// Lookup map for the processed lights' light queues.
+    Map<Light*, LightBatchQueue*> lightQueueMapping_;
     /// Cache for light scissor queries.
     HashMap<Light*, Rect> lightScissorCache_;
     /// Base pass batches.
@@ -257,7 +257,7 @@ private:
     /// Intermediate light processing results.
     Vector<LightQueryResult> lightQueryResults_;
     /// Light queues.
-    Vector<LightBatchQueue> lightQueues_;
+    List<LightBatchQueue> lightQueues_;
     /// Current stencil value for light optimization.
     unsigned char lightStencilValue_;
     /// Camera zone's override flag.

+ 5 - 4
Engine/Scene/Node.cpp

@@ -900,7 +900,7 @@ bool Node::Load(Deserializer& source, bool readChildren)
     {
         VectorBuffer compBuffer(source, source.ReadVLE());
         ShortStringHash newType = compBuffer.ReadShortStringHash();
-        Component* newComponent = CreateComponent(newType, compBuffer.ReadUInt(), REPLICATED);
+        Component* newComponent = CreateComponent(newType, compBuffer.ReadUInt(), id_ < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
         if (newComponent)
         {
             if (!newComponent->Load(compBuffer))
@@ -914,7 +914,7 @@ bool Node::Load(Deserializer& source, bool readChildren)
     unsigned numChildren = source.ReadVLE();
     for (unsigned i = 0; i < numChildren; ++i)
     {
-        Node* newNode = CreateChild(source.ReadUInt(), REPLICATED);
+        Node* newNode = CreateChild(source.ReadUInt(), id_ < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
         if (!newNode->Load(source))
             return false;
     }
@@ -935,7 +935,8 @@ bool Node::LoadXML(const XMLElement& source, bool readChildren)
     while (compElem)
     {
         String typeName = compElem.GetString("type");
-        Component* newComponent = CreateComponent(ShortStringHash(compElem.GetString("type")), compElem.GetInt("id"), REPLICATED);
+        Component* newComponent = CreateComponent(ShortStringHash(compElem.GetString("type")), compElem.GetInt("id"),
+            id_ < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
         if (newComponent)
         {
             if (!newComponent->LoadXML(compElem))
@@ -951,7 +952,7 @@ bool Node::LoadXML(const XMLElement& source, bool readChildren)
     XMLElement childElem = source.GetChild("node");
     while (childElem)
     {
-        Node* newNode = CreateChild(childElem.GetInt("id"), REPLICATED);
+        Node* newNode = CreateChild(childElem.GetInt("id"), id_ < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
         if (!newNode->LoadXML(childElem))
             return false;