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

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

@@ -192,6 +192,8 @@ private:
     bool geometryTypeUpdate_;
     /// Sorting flag. Triggers a vertex buffer rewrite for each view this billboard set is rendered from.
     bool sortThisFrame_;
+    /// Whether was last rendered from an ortho camera.
+    bool hasOrthoCamera_;
     /// Frame number on which was last sorted.
     unsigned sortFrameNumber_;
     /// 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)
     {
-        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->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)
     {
-        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->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->size_ = size;
             i->reserved_ = true;
+
+            URHO3D_LOGDEBUG("Resized scratch buffer to size " + String(size));
+
             return i->data_.Get();
         }
     }
@@ -2291,10 +2294,12 @@ void Graphics::CleanupScratchBuffers()
 {
     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->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 float splineStep = 1.0f / splinePathResolution;
 bool debugIconsShow = true;
-Vector2 debugIconsSize = Vector2(0.015, 0.015);
+Vector2 debugIconsSize = Vector2(64, 64);
 Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
-Vector2 debugIconsSizeBig = debugIconsSize * 1.5;
-Vector2 debugIconsMaxSize = debugIconsSize * 50;
 VariantMap debugIconsPlacement;
 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;
     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].material = cache.GetResource("Material", "Materials/Editor/" + IconsTypesMaterials[i]);
         debugIconsSet[i].sorted = true;
         debugIconsSet[i].temporary = true;
+        debugIconsSet[i].fixedScreenSize = true;
         debugIconsSet[i].viewMask = 0x80000000;
     }
 }
@@ -112,11 +98,12 @@ void UpdateViewDebugIcons()
     }
     // Checkout if debugIconsNode do not have any BBS component, add all at once
     BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
-    if (isBSExist is null) CreateDebugIcons(debugIconsNode);
+    if (isBSExist is null)
+        CreateDebugIcons(debugIconsNode);
 
     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;
     }
 
@@ -126,97 +113,99 @@ void UpdateViewDebugIcons()
     bool isOrthographic = activeViewport.camera.orthographic;
     debugIconsPlacement.Clear();
 
-    for(int iconType=0; iconType<ICON_COUNT; iconType++)
+    for (int iconType = 0; iconType < ICON_COUNT; ++iconType)
     {
         if (debugIconsSet[iconType] !is null)
         {
             // 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);
 
             // Clear old data
             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
-                ClearCommit(iconType, iconType+1, nodes.length);
+                ClearCommit(iconType, iconType + 1, nodes.length);
 
             if (nodes.length > 0)
             {
-
                 // 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]);
                     if (component is null) continue;
 
                     Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
                     float distance = (camPos - nodes[i].worldPosition).length;
-                    if (isOrthographic) distance = debugIconsOrthoDistance;
+                    if (isOrthographic)
+                        distance = debugIconsOrthoDistance;
                     int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
                     float iconsYPos = 0;
 
-                    if (iconType==ICON_SPLINE_PATH)
+                    if (iconType == ICON_SPLINE_PATH)
                     {
                         SplinePath@ sp = cast<SplinePath>(component);
                         if (sp !is null)
+                        {
                             if (sp.length > 0.01f)
                             {
-                                for(int step=0; step < splinePathResolution; step++)
+                                for (int step = 0; step < splinePathResolution; step++)
                                 {
                                     int index = (i * splinePathResolution) + step;
                                     Vector3 splinePoint = sp.GetPoint(splineStep * step);
                                     Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
                                     float stepDistance = (camPos - splinePoint).length;
-                                    if (isOrthographic) stepDistance = debugIconsOrthoDistance;
+                                    if (isOrthographic)
+                                        stepDistance = debugIconsOrthoDistance;
 
                                     if (step == 0) // SplinePath start
                                     {
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
+                                        bb.size = debugIconsSize;
                                         bb.position = splinePoint;
                                     }
                                     else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
                                     {
                                         bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSize * stepDistance, debugIconsSize));
+                                        bb.size = debugIconsSize;
                                         bb.position = splinePoint;
                                     }
                                     else // SplinePath middle points
                                     {
                                         bb.color = finalIconColor;
-                                        bb.size = ClampToIconMaxSize(Max(debugIconsSizeSmall * stepDistance, debugIconsSizeSmall));
+                                        bb.size = debugIconsSizeSmall;
                                         bb.position = splinePoint;
                                     }
                                     bb.enabled = sp.enabled;
                                     // 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
                     {
                         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);
                             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);
                             if (light !is null)
@@ -228,42 +217,50 @@ void UpdateViewDebugIcons()
                                 else if (light.lightType == LIGHT_SPOT)
                                     bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];
 
-                                bb.size = ClampToIconMaxSize(Max(debugIconsSize * distance, debugIconsSize));
                                 finalIconColor = light.effectiveColor;
                             }
                         }
 
                         bb.position = nodes[i].worldPosition;
                         // 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;
                         // 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);
                 // 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;
 }
 
-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)
 {
-    for(int i=begin;i<end;i++)
+    for (int i = begin; i < end; ++i)
     {
         debugIconsSet[i].Commit();
     }