فهرست منبع

Use index buffer in DrawableProxy2D.

aster2013 11 سال پیش
والد
کامیت
d7a3b4336d
2فایلهای تغییر یافته به همراه80 افزوده شده و 28 حذف شده
  1. 76 27
      Source/Engine/Urho2D/DrawableProxy2D.cpp
  2. 4 1
      Source/Engine/Urho2D/DrawableProxy2D.h

+ 76 - 27
Source/Engine/Urho2D/DrawableProxy2D.cpp

@@ -26,6 +26,7 @@
 #include "Drawable2D.h"
 #include "Drawable2D.h"
 #include "DrawableProxy2D.h"
 #include "DrawableProxy2D.h"
 #include "Geometry.h"
 #include "Geometry.h"
+#include "IndexBuffer.h"
 #include "Log.h"
 #include "Log.h"
 #include "Material.h"
 #include "Material.h"
 #include "Node.h"
 #include "Node.h"
@@ -39,6 +40,7 @@ namespace Urho3D
 
 
 DrawableProxy2D::DrawableProxy2D(Context* context) :
 DrawableProxy2D::DrawableProxy2D(Context* context) :
     Drawable(context, DRAWABLE_GEOMETRY),
     Drawable(context, DRAWABLE_GEOMETRY),
+    indexBuffer_(new IndexBuffer(context_)),
     vertexBuffer_(new VertexBuffer(context_)),
     vertexBuffer_(new VertexBuffer(context_)),
     orderDirty_(true)
     orderDirty_(true)
 {
 {
@@ -86,52 +88,98 @@ void DrawableProxy2D::UpdateGeometry(const FrameInfo& frame)
     if (vertexCount == 0)
     if (vertexCount == 0)
         return;
         return;
 
 
-    vertexCount = vertexCount / 4 * 6;
+    unsigned indexCount = vertexCount / 4 * 6;
+    if (indexBuffer_->GetIndexCount() < indexCount)
+    {
+        bool largeIndices = indexCount > 0xFFFF;
+        indexBuffer_->SetSize(indexCount, largeIndices, true);
+        void* buffer = indexBuffer_->Lock(0, indexCount, true);
+        if (buffer)
+        {
+            unsigned quadCount = indexCount / 6;
+            if (largeIndices)
+            {
+                unsigned* dest = reinterpret_cast<unsigned*>(buffer);
+                for (unsigned i = 0; i < quadCount; ++i)
+                {
+                    unsigned base = i * 4;
+                    dest[0] = base;
+                    dest[1] = base + 1;
+                    dest[2] = base + 2;
+                    dest[3] = base;
+                    dest[4] = base + 2;
+                    dest[5] = base + 3;
+                    dest += 6;
+                }
+            }
+            else
+            {
+                unsigned short* dest = reinterpret_cast<unsigned short*>(buffer);
+                for (unsigned i = 0; i < quadCount; ++i)
+                {
+                    unsigned base = i * 4;
+                    dest[0] = (unsigned short)(base);
+                    dest[1] = (unsigned short)(base + 1);
+                    dest[2] = (unsigned short)(base + 2);
+                    dest[3] = (unsigned short)(base);
+                    dest[4] = (unsigned short)(base + 2);
+                    dest[5] = (unsigned short)(base + 3);
+                    dest += 6;
+                }
+            }
+
+            indexBuffer_->Unlock();
+        }
+        else
+        {
+            LOGERROR("Failed to lock index buffer");
+            return;
+        }
+    }
+
+    if (vertexBuffer_->GetVertexCount() < vertexCount)
+        vertexBuffer_->SetSize(vertexCount, MASK_VERTEX2D);
 
 
-    vertexBuffer_->SetSize(vertexCount, MASK_VERTEX2D);
     Vertex2D* dest = reinterpret_cast<Vertex2D*>(vertexBuffer_->Lock(0, vertexCount, true));
     Vertex2D* dest = reinterpret_cast<Vertex2D*>(vertexBuffer_->Lock(0, vertexCount, true));
     if (dest)
     if (dest)
     {
     {
-        unsigned start = 0;
-        unsigned count = 0;
         Material* material = 0;
         Material* material = 0;
+        unsigned iStart = 0;
+        unsigned iCount = 0;
+        unsigned vStart = 0;
+        unsigned vCount = 0;
 
 
         for (unsigned d = 0; d < drawables_.Size(); ++d)
         for (unsigned d = 0; d < drawables_.Size(); ++d)
         {
         {
-            Material* currMaterial = drawables_[d]->GetUsedMaterial();
+            Material* usedMaterial = drawables_[d]->GetUsedMaterial();
             const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();
             const Vector<Vertex2D>& vertices = drawables_[d]->GetVertices();
-            if (!currMaterial || vertices.Empty())
+            if (!usedMaterial || vertices.Empty())
                 continue;
                 continue;
 
 
-            if (material != currMaterial)
+            if (material != usedMaterial)
             {
             {
                 if (material)
                 if (material)
                 {
                 {
-                    AddBatch(material, start, count);
-                    start += count;
-                    count = 0;
+                    AddBatch(material, iStart, iCount, vStart, vCount);
+                    iStart += iCount;
+                    iCount = 0;
+                    vStart += vCount;
+                    vCount = 0;
                 }
                 }
 
 
-                material = currMaterial;
+                material = usedMaterial;
             }
             }
 
 
-            for (unsigned i = 0; i < vertices.Size(); i += 4)
-            {
-                dest[0] = vertices[i + 0];
-                dest[1] = vertices[i + 1];
-                dest[2] = vertices[i + 2];
-
-                dest[3] = vertices[i + 0];
-                dest[4] = vertices[i + 2];
-                dest[5] = vertices[i + 3];
-                dest += 6;
-            }
+            for (unsigned i = 0; i < vertices.Size(); ++i)
+                dest[i] = vertices[i];
+            dest += vertices.Size();
 
 
-            count += vertices.Size() / 4 * 6;
+            iCount += vertices.Size() / 4 * 6;
+            vCount += vertices.Size();
         }
         }
 
 
         if (material)
         if (material)
-            AddBatch(material, start, count);
+            AddBatch(material, iStart, iCount, vStart, vCount);
 
 
         vertexBuffer_->Unlock();
         vertexBuffer_->Unlock();
     }
     }
@@ -175,9 +223,9 @@ void DrawableProxy2D::OnWorldBoundingBoxUpdate()
     worldBoundingBox_ = boundingBox_;
     worldBoundingBox_ = boundingBox_;
 }
 }
 
 
-void DrawableProxy2D::AddBatch(Material* material, unsigned vertexStart, unsigned vertexCount)
+void DrawableProxy2D::AddBatch(Material* material, unsigned indexStart, unsigned indexCount, unsigned vertexStart, unsigned vertexCount)
 {
 {
-    if (!material)
+    if (!material || indexCount == 0 || vertexCount == 0)
         return;
         return;
 
 
     materials_.Push(SharedPtr<Material>(material));
     materials_.Push(SharedPtr<Material>(material));
@@ -186,11 +234,12 @@ void DrawableProxy2D::AddBatch(Material* material, unsigned vertexStart, unsigne
     if (geometries_.Size() < batchSize)
     if (geometries_.Size() < batchSize)
     {
     {
         SharedPtr<Geometry> geometry(new Geometry(context_));
         SharedPtr<Geometry> geometry(new Geometry(context_));
+        geometry->SetIndexBuffer(indexBuffer_);
         geometry->SetVertexBuffer(0, vertexBuffer_, MASK_VERTEX2D);
         geometry->SetVertexBuffer(0, vertexBuffer_, MASK_VERTEX2D);
         geometries_.Push(geometry);
         geometries_.Push(geometry);
     }
     }
 
 
-    geometries_[batchSize - 1]->SetDrawRange(TRIANGLE_LIST, 0, 0, vertexStart, vertexCount);
+    geometries_[batchSize - 1]->SetDrawRange(TRIANGLE_LIST, indexStart, indexCount, vertexStart, vertexCount);
 }
 }
 
 
 }
 }

+ 4 - 1
Source/Engine/Urho2D/DrawableProxy2D.h

@@ -28,6 +28,7 @@ namespace Urho3D
 {
 {
 
 
 class Drawable2D;
 class Drawable2D;
+class IndexBuffer;
 class VertexBuffer;
 class VertexBuffer;
 
 
 /// Proxy for 2D visible components.
 /// Proxy for 2D visible components.
@@ -61,8 +62,10 @@ protected:
     /// Recalculate the world-space bounding box.
     /// Recalculate the world-space bounding box.
     virtual void OnWorldBoundingBoxUpdate();
     virtual void OnWorldBoundingBoxUpdate();
     /// Add batch.
     /// Add batch.
-    void AddBatch(Material* material, unsigned vertexStart, unsigned vertexCount);
+    void AddBatch(Material* material, unsigned indexStart, unsigned indexCount, unsigned vertexStart, unsigned vertexCount);
 
 
+    /// Index buffer.
+    SharedPtr<IndexBuffer> indexBuffer_;
     /// Vertex buffer.
     /// Vertex buffer.
     SharedPtr<VertexBuffer> vertexBuffer_;
     SharedPtr<VertexBuffer> vertexBuffer_;
     /// Materials.
     /// Materials.