Browse Source

Cleanup editor debug icon code to not do constant resizes of billboardsets to zero and back, and to use fixed screen size mode to eliminate need for manual sizing. BillboardSet::SetNumBillboards() is no-op if count remains same. Fix BillboardSet fixed size bug when changing between ortho & perspective camera. Do not care to resize scratch buffer smaller if it's below 1MB. Add scratch buffer debug messages also to OpenGL Graphics class for consistency. Closes #1434.

Lasse Öörni 9 years ago
parent
commit
489356a29f

+ 6 - 1
Source/Urho3D/Graphics/BillboardSet.cpp

@@ -78,6 +78,7 @@ BillboardSet::BillboardSet(Context* context) :
     forceUpdate_(false),
     forceUpdate_(false),
     geometryTypeUpdate_(false),
     geometryTypeUpdate_(false),
     sortThisFrame_(false),
     sortThisFrame_(false),
+    hasOrthoCamera_(false),
     sortFrameNumber_(0),
     sortFrameNumber_(0),
     previousOffset_(Vector3::ZERO)
     previousOffset_(Vector3::ZERO)
 {
 {
@@ -175,13 +176,15 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
     Vector3 worldPos = node_->GetWorldPosition();
     Vector3 worldPos = node_->GetWorldPosition();
     Vector3 offset = (worldPos - frame.camera_->GetNode()->GetWorldPosition());
     Vector3 offset = (worldPos - frame.camera_->GetNode()->GetWorldPosition());
     // Sort if position relative to camera has changed
     // Sort if position relative to camera has changed
-    if (offset != previousOffset_)
+    if (offset != previousOffset_ || frame.camera_->IsOrthographic() != hasOrthoCamera_)
     {
     {
         if (sorted_)
         if (sorted_)
             sortThisFrame_ = true;
             sortThisFrame_ = true;
         if (faceCameraMode_ == FC_DIRECTION)
         if (faceCameraMode_ == FC_DIRECTION)
             bufferDirty_ = true;
             bufferDirty_ = true;
 
 
+        hasOrthoCamera_ = frame.camera_->IsOrthographic();
+
         // Calculate fixed screen size scale factor for billboards if needed
         // Calculate fixed screen size scale factor for billboards if needed
         if (fixedScreenSize_)
         if (fixedScreenSize_)
             CalculateFixedScreenSize(frame);
             CalculateFixedScreenSize(frame);
@@ -251,6 +254,8 @@ void BillboardSet::SetNumBillboards(unsigned num)
         num = MAX_BILLBOARDS;
         num = MAX_BILLBOARDS;
 
 
     unsigned oldNum = billboards_.Size();
     unsigned oldNum = billboards_.Size();
+    if (num == oldNum)
+        return;
 
 
     billboards_.Resize(num);
     billboards_.Resize(num);
 
 

+ 2 - 0
Source/Urho3D/Graphics/BillboardSet.h

@@ -192,6 +192,8 @@ private:
     bool geometryTypeUpdate_;
     bool geometryTypeUpdate_;
     /// Sorting flag. Triggers a vertex buffer rewrite for each view this billboard set is rendered from.
     /// Sorting flag. Triggers a vertex buffer rewrite for each view this billboard set is rendered from.
     bool sortThisFrame_;
     bool sortThisFrame_;
+    /// Whether was last rendered from an ortho camera.
+    bool hasOrthoCamera_;
     /// Frame number on which was last sorted.
     /// Frame number on which was last sorted.
     unsigned sortFrameNumber_;
     unsigned sortFrameNumber_;
     /// Previous offset to camera for determining whether sorting is necessary.
     /// Previous offset to camera for determining whether sorting is necessary.

+ 1 - 1
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -2030,7 +2030,7 @@ void Graphics::CleanupScratchBuffers()
 {
 {
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     {
     {
-        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2)
+        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2 && i->size_ >= 1024 * 1024)
         {
         {
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->size_ = maxScratchBufferRequest_;
             i->size_ = maxScratchBufferRequest_;

+ 1 - 1
Source/Urho3D/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -2250,7 +2250,7 @@ void Graphics::CleanupScratchBuffers()
 {
 {
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     {
     {
-        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2)
+        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2 && i->size_ >= 1024 * 1024)
         {
         {
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->size_ = maxScratchBufferRequest_;
             i->size_ = maxScratchBufferRequest_;

+ 6 - 1
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -2257,6 +2257,9 @@ void* Graphics::ReserveScratchBuffer(unsigned size)
             i->data_ = new unsigned char[size];
             i->data_ = new unsigned char[size];
             i->size_ = size;
             i->size_ = size;
             i->reserved_ = true;
             i->reserved_ = true;
+
+            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(size));
+
             return i->data_.Get();
             return i->data_.Get();
         }
         }
     }
     }
@@ -2291,10 +2294,12 @@ void Graphics::CleanupScratchBuffers()
 {
 {
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     for (Vector<ScratchBuffer>::Iterator i = scratchBuffers_.Begin(); i != scratchBuffers_.End(); ++i)
     {
     {
-        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2)
+        if (!i->reserved_ && i->size_ > maxScratchBufferRequest_ * 2 && i->size_ >= 1024 * 1024)
         {
         {
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->data_ = maxScratchBufferRequest_ > 0 ? new unsigned char[maxScratchBufferRequest_] : 0;
             i->size_ = maxScratchBufferRequest_;
             i->size_ = maxScratchBufferRequest_;
+
+            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(maxScratchBufferRequest_));
         }
         }
     }
     }
 
 

+ 58 - 61
bin/Data/Scripts/Editor/EditorViewDebugIcons.as

@@ -62,39 +62,25 @@ uint timeToNextDebugIconsUpdateSplinePath = 0;
 const int splinePathResolution = 16;
 const int splinePathResolution = 16;
 const float splineStep = 1.0f / splinePathResolution;
 const float splineStep = 1.0f / splinePathResolution;
 bool debugIconsShow = true;
 bool debugIconsShow = true;
-Vector2 debugIconsSize = Vector2(0.015, 0.015);
+Vector2 debugIconsSize = Vector2(64, 64);
 Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
 Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
-Vector2 debugIconsSizeBig = debugIconsSize * 1.5;
-Vector2 debugIconsMaxSize = debugIconsSize * 50;
 VariantMap debugIconsPlacement;
 VariantMap debugIconsPlacement;
 const int debugIconsPlacementIndent = 1.0;
 const int debugIconsPlacementIndent = 1.0;
-const float debugIconsOrthoDistance = 15.0f;   
+const float debugIconsOrthoDistance = 15.0;
+const float debugIconAlphaThreshold = 0.1;
+const float maxDistance = 50.0;
 
 
-Vector2 Max(Vector2 a, Vector2 b) 
-{
-    return (a.length > b.length ? a : b); 
-}
-
-Vector2 Clamp(Vector2 a, Vector2 b) 
-{
-    return Vector2((a.x > b.x ? b.x : a.x),(a.y > b.y ? b.y : a.y));
-}
-
-Vector2 ClampToIconMaxSize(Vector2 a) 
-{
-    return Clamp(a, debugIconsMaxSize);
-}
-
-void CreateDebugIcons(Node@ tempNode) 
+void CreateDebugIcons(Node@ tempNode)
 {
 {
     if (editorScene is null) return;
     if (editorScene is null) return;
     debugIconsSet.Resize(ICON_COUNT);
     debugIconsSet.Resize(ICON_COUNT);
-    for (int i = 0; i < ICON_COUNT; i++)
+    for (int i = 0; i < ICON_COUNT; ++i)
     {
     {
         debugIconsSet[i] = tempNode.CreateComponent("BillboardSet");
         debugIconsSet[i] = tempNode.CreateComponent("BillboardSet");
         debugIconsSet[i].material = cache.GetResource("Material", "Materials/Editor/" + IconsTypesMaterials[i]);
         debugIconsSet[i].material = cache.GetResource("Material", "Materials/Editor/" + IconsTypesMaterials[i]);
         debugIconsSet[i].sorted = true;
         debugIconsSet[i].sorted = true;
         debugIconsSet[i].temporary = true;
         debugIconsSet[i].temporary = true;
+        debugIconsSet[i].fixedScreenSize = true;
         debugIconsSet[i].viewMask = 0x80000000;
         debugIconsSet[i].viewMask = 0x80000000;
     }
     }
 }
 }
@@ -112,11 +98,12 @@ void UpdateViewDebugIcons()
     }
     }
     // Checkout if debugIconsNode do not have any BBS component, add all at once
     // Checkout if debugIconsNode do not have any BBS component, add all at once
     BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
     BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
-    if (isBSExist is null) CreateDebugIcons(debugIconsNode);
+    if (isBSExist is null)
+        CreateDebugIcons(debugIconsNode);
 
 
     if (debugIconsSet[ICON_POINT_LIGHT] !is null)
     if (debugIconsSet[ICON_POINT_LIGHT] !is null)
     {
     {
-        for(int i=0; i < ICON_COUNT; i++)
+        for (int i = 0; i < ICON_COUNT; ++i)
             debugIconsSet[i].enabled = debugIconsShow;
             debugIconsSet[i].enabled = debugIconsShow;
     }
     }
 
 
@@ -126,97 +113,99 @@ void UpdateViewDebugIcons()
     bool isOrthographic = activeViewport.camera.orthographic;
     bool isOrthographic = activeViewport.camera.orthographic;
     debugIconsPlacement.Clear();
     debugIconsPlacement.Clear();
 
 
-    for(int iconType=0; iconType<ICON_COUNT; iconType++)
+    for (int iconType = 0; iconType < ICON_COUNT; ++iconType)
     {
     {
         if (debugIconsSet[iconType] !is null)
         if (debugIconsSet[iconType] !is null)
         {
         {
             // SplinePath update resolution
             // SplinePath update resolution
-            if (iconType == ICON_SPLINE_PATH && timeToNextDebugIconsUpdateSplinePath > time.systemTime) continue;
+            if (iconType == ICON_SPLINE_PATH && timeToNextDebugIconsUpdateSplinePath > time.systemTime)
+                continue;
 
 
             Array<Node@> nodes = editorScene.GetChildrenWithComponent(ComponentTypes[iconType], true);
             Array<Node@> nodes = editorScene.GetChildrenWithComponent(ComponentTypes[iconType], true);
 
 
             // Clear old data
             // Clear old data
             if (iconType == ICON_SPLINE_PATH)
             if (iconType == ICON_SPLINE_PATH)
-                ClearCommit(ICON_SPLINE_PATH, ICON_SPLINE_PATH+1, nodes.length * splinePathResolution);
-            else if (iconType==ICON_POINT_LIGHT || iconType==ICON_SPOT_LIGHT || iconType==ICON_DIRECTIONAL_LIGHT)
-                ClearCommit(ICON_POINT_LIGHT, ICON_DIRECTIONAL_LIGHT+1, nodes.length);
-            else if (iconType==ICON_SOUND_SOURCE || iconType==ICON_SOUND_SOURCE_3D)
-                ClearCommit(ICON_SOUND_SOURCE, ICON_SOUND_SOURCE_3D+1, nodes.length);
+                ClearCommit(ICON_SPLINE_PATH, ICON_SPLINE_PATH + 1, nodes.length * splinePathResolution);
+            else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
+                ClearCommit(ICON_POINT_LIGHT, ICON_DIRECTIONAL_LIGHT + 1, nodes.length);
+            else if (iconType == ICON_SOUND_SOURCE || iconType == ICON_SOUND_SOURCE_3D)
+                ClearCommit(ICON_SOUND_SOURCE, ICON_SOUND_SOURCE_3D + 1, nodes.length);
             else
             else
-                ClearCommit(iconType, iconType+1, nodes.length);
+                ClearCommit(iconType, iconType + 1, nodes.length);
 
 
             if (nodes.length > 0)
             if (nodes.length > 0)
             {
             {
-
                 // Fill with new data
                 // Fill with new data
-                for(uint i = 0;i < nodes.length; i++)
+                for (uint i = 0; i < nodes.length; ++i)
                 {
                 {
                     Component@ component = nodes[i].GetComponent(ComponentTypes[iconType]);
                     Component@ component = nodes[i].GetComponent(ComponentTypes[iconType]);
                     if (component is null) continue;
                     if (component is null) continue;
 
 
                     Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
                     Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
                     float distance = (camPos - nodes[i].worldPosition).length;
                     float distance = (camPos - nodes[i].worldPosition).length;
-                    if (isOrthographic) distance = debugIconsOrthoDistance;
+                    if (isOrthographic)
+                        distance = debugIconsOrthoDistance;
                     int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
                     int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
                     float iconsYPos = 0;
                     float iconsYPos = 0;
 
 
-                    if (iconType==ICON_SPLINE_PATH)
+                    if (iconType == ICON_SPLINE_PATH)
                     {
                     {
                         SplinePath@ sp = cast<SplinePath>(component);
                         SplinePath@ sp = cast<SplinePath>(component);
                         if (sp !is null)
                         if (sp !is null)
+                        {
                             if (sp.length > 0.01f)
                             if (sp.length > 0.01f)
                             {
                             {
-                                for(int step=0; step < splinePathResolution; step++)
+                                for (int step = 0; step < splinePathResolution; step++)
                                 {
                                 {
                                     int index = (i * splinePathResolution) + step;
                                     int index = (i * splinePathResolution) + step;
                                     Vector3 splinePoint = sp.GetPoint(splineStep * step);
                                     Vector3 splinePoint = sp.GetPoint(splineStep * step);
                                     Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
                                     Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
                                     float stepDistance = (camPos - splinePoint).length;
                                     float stepDistance = (camPos - splinePoint).length;
-                                    if (isOrthographic) stepDistance = debugIconsOrthoDistance;
+                                    if (isOrthographic)
+                                        stepDistance = debugIconsOrthoDistance;
 
 
                                     if (step == 0) // SplinePath start
                                     if (step == 0) // SplinePath start
                                     {
                                     {
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
+                                        bb.size = debugIconsSize;
                                         bb.position = splinePoint;
                                         bb.position = splinePoint;
                                     }
                                     }
                                     else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
                                     else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
                                     {
                                     {
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
+                                        bb.size = debugIconsSize;
                                         bb.position = splinePoint;
                                         bb.position = splinePoint;
                                     }
                                     }
                                     else // SplinePath middle points
                                     else // SplinePath middle points
                                     {
                                     {
                                         bb.color = finalIconColor;
                                         bb.color = finalIconColor;
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSizeSmall * stepDistance, debugIconsSizeSmall));
+                                        bb.size = debugIconsSizeSmall;
                                         bb.position = splinePoint;
                                         bb.position = splinePoint;
                                     }
                                     }
                                     bb.enabled = sp.enabled;
                                     bb.enabled = sp.enabled;
                                     // Blend Icon relatively by distance to it
                                     // Blend Icon relatively by distance to it
-                                    bb.color = Color(bb.color.r, bb.color.g, bb.color.b, 1.2f - 1.0f / (debugIconsMaxSize.x / bb.size.x));
-                                    if (bb.color.a < 0.25f) bb.enabled = false;
+                                    bb.color = Color(bb.color.r, bb.color.g, bb.color.b, 1.2f - 1.0f / (maxDistance / stepDistance));
+                                    if (bb.color.a < debugIconAlphaThreshold)
+                                        bb.enabled = false;
                                 }
                                 }
                             }
                             }
+                        }
                     }
                     }
                     else
                     else
                     {
                     {
                         Billboard@ bb = debugIconsSet[iconType].billboards[i];
                         Billboard@ bb = debugIconsSet[iconType].billboards[i];
-                        bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
+                        bb.size = debugIconsSize;
 
 
-                        if (iconType==ICON_PARTICLE_EMITTER)
-                        {
-                            bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
-                        }
-                        else if (iconType==ICON_TRIGGER)
+                        if (iconType == ICON_TRIGGER)
                         {
                         {
                             RigidBody@ rigidbody = cast<RigidBody>(component);
                             RigidBody@ rigidbody = cast<RigidBody>(component);
                             if (rigidbody !is null)
                             if (rigidbody !is null)
                             {
                             {
-                                if (rigidbody.trigger == false) continue;
+                                if (rigidbody.trigger == false)
+                                    continue;
                             }
                             }
                         }
                         }
-                        else if (iconType==ICON_POINT_LIGHT || iconType==ICON_SPOT_LIGHT || iconType==ICON_DIRECTIONAL_LIGHT)
+                        else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
                         {
                         {
                             Light@ light = cast<Light>(component);
                             Light@ light = cast<Light>(component);
                             if (light !is null)
                             if (light !is null)
@@ -228,42 +217,50 @@ void UpdateViewDebugIcons()
                                 else if (light.lightType == LIGHT_SPOT)
                                 else if (light.lightType == LIGHT_SPOT)
                                     bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];
                                     bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];
 
 
-                                bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
                                 finalIconColor = light.effectiveColor;
                                 finalIconColor = light.effectiveColor;
                             }
                             }
                         }
                         }
 
 
                         bb.position = nodes[i].worldPosition;
                         bb.position = nodes[i].worldPosition;
                         // Blend Icon relatively by distance to it
                         // Blend Icon relatively by distance to it
-                        bb.color = Color(finalIconColor.r, finalIconColor.g, finalIconColor.b, 1.2f - 1.0f / (debugIconsMaxSize.x / bb.size.x));
+                        bb.color = Color(finalIconColor.r, finalIconColor.g, finalIconColor.b, 1.2f - 1.0f / (maxDistance / distance));
                         bb.enabled = component.enabled;
                         bb.enabled = component.enabled;
                         // Discard billboard if it almost transparent
                         // Discard billboard if it almost transparent
-                        if (bb.color.a < 0.25f) bb.enabled = false;
-                        IncrementIconPlacement(bb.enabled, nodes[i], 1 );
+                        if (bb.color.a < debugIconAlphaThreshold)
+                            bb.enabled = false;
+                        IncrementIconPlacement(bb.enabled, nodes[i], 1);
                     }
                     }
                 }
                 }
                 Commit(iconType, iconType+1);
                 Commit(iconType, iconType+1);
                 // SplinePath update resolution
                 // SplinePath update resolution
-                if (iconType == ICON_SPLINE_PATH) timeToNextDebugIconsUpdateSplinePath = time.systemTime + stepDebugIconsUpdateSplinePath;
+                if (iconType == ICON_SPLINE_PATH)
+                    timeToNextDebugIconsUpdateSplinePath = time.systemTime + stepDebugIconsUpdateSplinePath;
             }
             }
         }
         }
     }
     }
     timeToNextDebugIconsUpdate = time.systemTime + stepDebugIconsUpdate;
     timeToNextDebugIconsUpdate = time.systemTime + stepDebugIconsUpdate;
 }
 }
 
 
-void ClearCommit(int begin, int end, int newlength)
+void ClearCommit(int begin, int end, int newLength)
 {
 {
-    for(int i=begin;i<end;i++)
+    for (int i = begin; i < end; ++i)
     {
     {
-        debugIconsSet[i].numBillboards = 0;
-        debugIconsSet[i].Commit();
-        debugIconsSet[i].numBillboards = newlength;
+        BillboardSet@ iconSet = debugIconsSet[i];
+        iconSet.numBillboards = newLength;
+
+        for (int j = 0; j < newLength; ++j)
+        {
+            Billboard@ bb = iconSet.billboards[j];
+            bb.enabled = false;
+        }
+
+        iconSet.Commit();
     }
     }
 }
 }
 
 
 void Commit(int begin, int end)
 void Commit(int begin, int end)
 {
 {
-    for(int i=begin;i<end;i++)
+    for (int i = begin; i < end; ++i)
     {
     {
         debugIconsSet[i].Commit();
         debugIconsSet[i].Commit();
     }
     }