OSDN Git Service

Throttle terrain updates.
authorLatif Khalifa <latifer@streamgrid.net>
Wed, 3 Aug 2011 04:29:47 +0000 (04:29 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Wed, 3 Aug 2011 04:29:47 +0000 (04:29 +0000)
Upon login we get a lot of individual terrain patches, don't rebuild on each.
Build terrain mesh on a thread.

git-svn-id: https://radegast.googlecode.com/svn/trunk@1055 f7a694da-4d33-11de-9ad6-1127a62b9fcd

Radegast/GUI/Rendering/RenderSettings.cs
Radegast/GUI/Rendering/Rendering.cs

index 3c6cd56..896f6ee 100644 (file)
@@ -51,5 +51,7 @@ namespace Radegast.Rendering
         public static bool OcclusionCullingEnabled = true;
         /// <summary>Should we try to make sure that large prims that are > our draw distance are in view when we are standing on them</summary>
         public static bool HeavierDistanceChecking = true;
+        /// <summary>Minimum time between rebuilding terrain mesh and texture</summary>
+        public static float MinimumTimeBetweenTerrainUpdated = 15f;
     }
 }
index 55040e6..3dd0785 100644 (file)
@@ -320,7 +320,7 @@ namespace Radegast.Rendering
         {\r
             if (e.Simulator.Handle == Client.Network.CurrentSim.Handle)\r
             {\r
-                TerrainModified = true;\r
+                terrainModified = true;\r
             }\r
         }\r
 \r
@@ -1986,7 +1986,7 @@ namespace Radegast.Rendering
         #endregion Keyboard\r
 \r
         #region Terrain\r
-        bool TerrainModified = true;\r
+        bool terrainModified = true;\r
         float[,] heightTable = new float[256, 256];\r
         Face terrainFace;\r
         ushort[] terrainIndices;\r
@@ -1996,6 +1996,9 @@ namespace Radegast.Rendering
         Bitmap terrainImage = null;\r
         int terrainVBO = -1;\r
         int terrainIndexVBO = -1;\r
+        bool terrainInProgress = false;\r
+        bool terrainTextureNeedsUpdate = false;\r
+        float terrainTimeSinceUpdate = RenderSettings.MinimumTimeBetweenTerrainUpdated + 1f; // Update terrain om first run\r
 \r
         private void ResetTerrain()\r
         {\r
@@ -2032,49 +2035,56 @@ namespace Radegast.Rendering
             }\r
 \r
             fetchingTerrainTexture = false;\r
-            TerrainModified = true;\r
+            terrainModified = true;\r
         }\r
 \r
         private void UpdateTerrain()\r
         {\r
             if (Client.Network.CurrentSim == null || Client.Network.CurrentSim.Terrain == null) return;\r
-            int step = 1;\r
 \r
-            for (int x = 0; x < 255; x += step)\r
+            ThreadPool.QueueUserWorkItem(sync =>\r
             {\r
-                for (int y = 0; y < 255; y += step)\r
+                int step = 1;\r
+\r
+                for (int x = 0; x < 255; x += step)\r
                 {\r
-                    float z = 0;\r
-                    int patchNr = ((int)x / 16) * 16 + (int)y / 16;\r
-                    if (Client.Network.CurrentSim.Terrain[patchNr] != null\r
-                        && Client.Network.CurrentSim.Terrain[patchNr].Data != null)\r
+                    for (int y = 0; y < 255; y += step)\r
                     {\r
-                        float[] data = Client.Network.CurrentSim.Terrain[patchNr].Data;\r
-                        z = data[(int)x % 16 * 16 + (int)y % 16];\r
+                        float z = 0;\r
+                        int patchNr = ((int)x / 16) * 16 + (int)y / 16;\r
+                        if (Client.Network.CurrentSim.Terrain[patchNr] != null\r
+                            && Client.Network.CurrentSim.Terrain[patchNr].Data != null)\r
+                        {\r
+                            float[] data = Client.Network.CurrentSim.Terrain[patchNr].Data;\r
+                            z = data[(int)x % 16 * 16 + (int)y % 16];\r
+                        }\r
+                        heightTable[x, y] = z;\r
                     }\r
-                    heightTable[x, y] = z;\r
                 }\r
-            }\r
 \r
-            terrainFace = renderer.TerrainMesh(heightTable, 0f, 255f, 0f, 255f);\r
-            terrainVertices = new ColorVertex[terrainFace.Vertices.Count];\r
-            for (int i = 0; i < terrainFace.Vertices.Count; i++)\r
-            {\r
-                byte[] part = Utils.IntToBytes(i);\r
-                terrainVertices[i] = new ColorVertex()\r
+                terrainFace = renderer.TerrainMesh(heightTable, 0f, 255f, 0f, 255f);\r
+                terrainVertices = new ColorVertex[terrainFace.Vertices.Count];\r
+                for (int i = 0; i < terrainFace.Vertices.Count; i++)\r
                 {\r
-                    Vertex = terrainFace.Vertices[i],\r
-                    Color = new Color4b()\r
+                    byte[] part = Utils.IntToBytes(i);\r
+                    terrainVertices[i] = new ColorVertex()\r
                     {\r
-                        R = part[0],\r
-                        G = part[1],\r
-                        B = part[2],\r
-                        A = 253 // terrain picking\r
-                    }\r
-                };\r
-            }\r
-            terrainIndices = terrainFace.Indices.ToArray();\r
-            TerrainModified = false;\r
+                        Vertex = terrainFace.Vertices[i],\r
+                        Color = new Color4b()\r
+                        {\r
+                            R = part[0],\r
+                            G = part[1],\r
+                            B = part[2],\r
+                            A = 253 // terrain picking\r
+                        }\r
+                    };\r
+                }\r
+                terrainIndices = terrainFace.Indices.ToArray();\r
+                terrainInProgress = false;\r
+                terrainModified = false;\r
+                terrainTextureNeedsUpdate = true;\r
+                terrainTimeSinceUpdate = 0f;\r
+            });\r
         }\r
 \r
         void UpdateTerrainTexture()\r
@@ -2091,12 +2101,32 @@ namespace Radegast.Rendering
                         new float[] { sim.TerrainHeightRange00, sim.TerrainHeightRange01, sim.TerrainHeightRange10, sim.TerrainHeightRange11 });\r
 \r
                     fetchingTerrainTexture = false;\r
+                    terrainTextureNeedsUpdate = false;\r
                 });\r
             }\r
         }\r
 \r
         private void RenderTerrain(RenderPass pass)\r
         {\r
+            terrainTimeSinceUpdate += lastFrameTime;\r
+\r
+            if (terrainModified && terrainTimeSinceUpdate > RenderSettings.MinimumTimeBetweenTerrainUpdated)\r
+            {\r
+                if (!terrainInProgress)\r
+                {\r
+                    terrainInProgress = true;\r
+                    ResetTerrain(false);\r
+                    UpdateTerrain();\r
+                }\r
+            }\r
+\r
+            if (terrainTextureNeedsUpdate)\r
+            {\r
+                UpdateTerrainTexture();\r
+            }\r
+\r
+            if (terrainIndices == null || terrainVertices == null) return;\r
+\r
             GL.Color3(1f, 1f, 1f);\r
             GL.EnableClientState(ArrayCap.VertexArray);\r
             GL.EnableClientState(ArrayCap.TextureCoordArray);\r
@@ -2107,13 +2137,6 @@ namespace Radegast.Rendering
                 GL.ShadeModel(ShadingModel.Flat);\r
             }\r
 \r
-            if (TerrainModified)\r
-            {\r
-                ResetTerrain(false);\r
-                UpdateTerrain();\r
-                UpdateTerrainTexture();\r
-            }\r
-\r
             if (terrainImage != null)\r
             {\r
                 if (terrainTexture != -1)\r
@@ -2188,7 +2211,7 @@ namespace Radegast.Rendering
                 GL.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
                 GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
             }\r
-\r
+            \r
             if (pass == RenderPass.Picking)\r
             {\r
                 GL.DisableClientState(ArrayCap.ColorArray);\r