OSDN Git Service

Check if VBO upload succeeded before using buffers.
authorLatif Khalifa <latifer@streamgrid.net>
Thu, 18 Aug 2011 07:19:23 +0000 (07:19 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Thu, 18 Aug 2011 07:19:23 +0000 (07:19 +0000)
Hopefully cures some of the VBO related crashes.

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

Radegast/GUI/Rendering/Compat.cs
Radegast/GUI/Rendering/Rendering.cs
Radegast/GUI/Rendering/RenderingHelpers.cs

index c7b5d4f..5c610b9 100644 (file)
@@ -75,6 +75,33 @@ namespace Radegast.Rendering
                 GL.Arb.BufferData<T2>((BufferTargetArb)(int)target, size, data, (BufferUsageArb)(int)usage);
             }
         }
+
+        public static int BufferSize(BufferTarget target)
+        {
+            int ret = 0;
+            if (RenderSettings.CoreVBOPresent)
+            {
+                GL.GetBufferParameter(target, BufferParameterName.BufferSize, out ret);
+            }
+            else
+            {
+                GL.Arb.GetBufferParameter((ArbVertexBufferObject)(int)target, BufferParameterNameArb.BufferSize, out ret);
+            }
+            return ret;
+        }
+
+        public static void DeleteBuffer(int id)
+        {
+            if (RenderSettings.CoreVBOPresent)
+            {
+                GL.DeleteBuffers(1, ref id);
+            }
+            else
+            {
+                GL.Arb.DeleteBuffers(1, ref id);
+            }
+        }
+
         #endregion VBO functions
 
         #region Occlusion query functions
index dfd42f5..522ecce 100644 (file)
@@ -2057,6 +2057,7 @@ namespace Radegast.Rendering
         Bitmap terrainImage = null;\r
         int terrainVBO = -1;\r
         int terrainIndexVBO = -1;\r
+        bool terrainVBOFailed = false;\r
         bool terrainInProgress = false;\r
         bool terrainTextureNeedsUpdate = false;\r
         float terrainTimeSinceUpdate = RenderSettings.MinimumTimeBetweenTerrainUpdated + 1f; // Update terrain om first run\r
@@ -2216,7 +2217,7 @@ namespace Radegast.Rendering
                 GL.BindTexture(TextureTarget.Texture2D, terrainTexture);\r
             }\r
 \r
-            if (!RenderSettings.UseVBO)\r
+            if (!RenderSettings.UseVBO || terrainVBOFailed)\r
             {\r
                 unsafe\r
                 {\r
@@ -2242,6 +2243,12 @@ namespace Radegast.Rendering
                     Compat.GenBuffers(out terrainVBO);\r
                     Compat.BindBuffer(BufferTarget.ArrayBuffer, terrainVBO);\r
                     Compat.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(terrainVertices.Length * ColorVertex.Size), terrainVertices, BufferUsageHint.StaticDraw);\r
+                    if (Compat.BufferSize(BufferTarget.ArrayBuffer) != terrainVertices.Length * ColorVertex.Size)\r
+                    {\r
+                        terrainVBOFailed = true;\r
+                        Compat.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
+                        terrainVBO = -1;\r
+                    }\r
                 }\r
                 else\r
                 {\r
@@ -2253,21 +2260,30 @@ namespace Radegast.Rendering
                     Compat.GenBuffers(out terrainIndexVBO);\r
                     Compat.BindBuffer(BufferTarget.ElementArrayBuffer, terrainIndexVBO);\r
                     Compat.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(terrainIndices.Length * sizeof(ushort)), terrainIndices, BufferUsageHint.StaticDraw);\r
+                    if (Compat.BufferSize(BufferTarget.ElementArrayBuffer) != terrainIndices.Length * sizeof(ushort))\r
+                    {\r
+                        terrainVBOFailed = true;\r
+                        Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
+                        terrainIndexVBO = -1;\r
+                    }\r
                 }\r
                 else\r
                 {\r
                     Compat.BindBuffer(BufferTarget.ElementArrayBuffer, terrainIndexVBO);\r
                 }\r
 \r
-                GL.NormalPointer(NormalPointerType.Float, ColorVertex.Size, (IntPtr)12);\r
-                GL.TexCoordPointer(2, TexCoordPointerType.Float, ColorVertex.Size, (IntPtr)(24));\r
-                if (pass == RenderPass.Picking)\r
+                if (!terrainVBOFailed)\r
                 {\r
-                    GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertex.Size, (IntPtr)32);\r
-                }\r
-                GL.VertexPointer(3, VertexPointerType.Float, ColorVertex.Size, (IntPtr)(0));\r
+                    GL.NormalPointer(NormalPointerType.Float, ColorVertex.Size, (IntPtr)12);\r
+                    GL.TexCoordPointer(2, TexCoordPointerType.Float, ColorVertex.Size, (IntPtr)(24));\r
+                    if (pass == RenderPass.Picking)\r
+                    {\r
+                        GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertex.Size, (IntPtr)32);\r
+                    }\r
+                    GL.VertexPointer(3, VertexPointerType.Float, ColorVertex.Size, (IntPtr)(0));\r
 \r
-                GL.DrawElements(BeginMode.Triangles, terrainIndices.Length, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
+                    GL.DrawElements(BeginMode.Triangles, terrainIndices.Length, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
+                }\r
 \r
                 Compat.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
                 Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
@@ -2532,7 +2548,7 @@ namespace Radegast.Rendering
                     GL.Color4(faceColor);\r
                 }\r
 \r
-                if (!RenderSettings.UseVBO)\r
+                if (!RenderSettings.UseVBO || data.VBOFailed)\r
                 {\r
                     Vertex[] verts = face.Vertices.ToArray();\r
                     ushort[] indices = face.Indices.ToArray();\r
@@ -2551,15 +2567,16 @@ namespace Radegast.Rendering
                 }\r
                 else\r
                 {\r
-                    data.CheckVBO(face);\r
-                    Compat.BindBuffer(BufferTarget.ArrayBuffer, data.VertexVBO);\r
-                    Compat.BindBuffer(BufferTarget.ElementArrayBuffer, data.IndexVBO);\r
-                    GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)12);\r
-                    GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)(24));\r
-                    GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, (IntPtr)(0));\r
-\r
-                    GL.DrawElements(BeginMode.Triangles, face.Indices.Count, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
+                    if (data.CheckVBO(face))\r
+                    {\r
+                        Compat.BindBuffer(BufferTarget.ArrayBuffer, data.VertexVBO);\r
+                        Compat.BindBuffer(BufferTarget.ElementArrayBuffer, data.IndexVBO);\r
+                        GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)12);\r
+                        GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)(24));\r
+                        GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, (IntPtr)(0));\r
 \r
+                        GL.DrawElements(BeginMode.Triangles, face.Indices.Count, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
+                    }\r
                     Compat.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
                     Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
 \r
@@ -2717,7 +2734,7 @@ namespace Radegast.Rendering
             GL.PushMatrix();\r
             GL.MultMatrix(Math3D.CreateSRTMatrix(scale, prim.RenderRotation, prim.RenderPosition));\r
 \r
-            if (RenderSettings.UseVBO)\r
+            if (RenderSettings.UseVBO && !occludedVBOFailed)\r
             {\r
                 GL.DrawElements(BeginMode.Quads, RHelp.CubeIndices.Length, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
             }\r
@@ -2731,6 +2748,7 @@ namespace Radegast.Rendering
 \r
         int boundingBoxVBO = -1;\r
         int boundingBoxVIndexVBO = -1;\r
+        bool occludedVBOFailed = false;\r
 \r
         private void RenderOccludedObjects()\r
         {\r
@@ -2741,13 +2759,19 @@ namespace Radegast.Rendering
             GL.Disable(EnableCap.CullFace);\r
             GL.Disable(EnableCap.Lighting);\r
 \r
-            if (RenderSettings.UseVBO)\r
+            if (RenderSettings.UseVBO && !occludedVBOFailed)\r
             {\r
                 if (boundingBoxVBO == -1)\r
                 {\r
                     Compat.GenBuffers(out boundingBoxVBO);\r
                     Compat.BindBuffer(BufferTarget.ArrayBuffer, boundingBoxVBO);\r
                     Compat.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(sizeof(float) * RHelp.CubeVertices.Length), RHelp.CubeVertices, BufferUsageHint.StaticDraw);\r
+                    if (Compat.BufferSize(BufferTarget.ArrayBuffer) != sizeof(float) * RHelp.CubeVertices.Length)\r
+                    {\r
+                        occludedVBOFailed = true;\r
+                        Compat.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
+                        boundingBoxVBO = -1;\r
+                    }\r
                 }\r
                 else\r
                 {\r
@@ -2759,6 +2783,12 @@ namespace Radegast.Rendering
                     Compat.GenBuffers(out boundingBoxVIndexVBO);\r
                     Compat.BindBuffer(BufferTarget.ElementArrayBuffer, boundingBoxVIndexVBO);\r
                     Compat.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(sizeof(ushort) * RHelp.CubeIndices.Length), RHelp.CubeIndices, BufferUsageHint.StaticDraw);\r
+                    if (Compat.BufferSize(BufferTarget.ElementArrayBuffer) != sizeof(ushort) * RHelp.CubeIndices.Length)\r
+                    {\r
+                        occludedVBOFailed = true;\r
+                        Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
+                        boundingBoxVIndexVBO = -1;\r
+                    }\r
                 }\r
                 else\r
                 {\r
index 6b944d8..d4d7da1 100644 (file)
@@ -35,7 +35,7 @@ namespace Radegast.Rendering
         public static int Size = 36;\r
     }\r
 \r
-    public class FaceData\r
+    public class FaceData : IDisposable\r
     {\r
         public float[] Vertices;\r
         public ushort[] Indices;\r
@@ -49,8 +49,15 @@ namespace Radegast.Rendering
         public static int VertexSize = 32; // sizeof (vertex), 2  x vector3 + 1 x vector2 = 8 floats x 4 bytes = 32 bytes \r
         public TextureAnimationInfo AnimInfo;\r
         public int QueryID = 0;\r
+        public bool VBOFailed = false;\r
 \r
-        public void CheckVBO(Face face)\r
+        public void Dispose()\r
+        {\r
+            if (VertexVBO != -1) Compat.DeleteBuffer(VertexVBO);\r
+            if (IndexVBO != -1) Compat.DeleteBuffer(IndexVBO);\r
+        }\r
+\r
+        public bool CheckVBO(Face face)\r
         {\r
             if (VertexVBO == -1)\r
             {\r
@@ -58,6 +65,14 @@ namespace Radegast.Rendering
                 Compat.GenBuffers(out VertexVBO);\r
                 Compat.BindBuffer(BufferTarget.ArrayBuffer, VertexVBO);\r
                 Compat.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vArray.Length * VertexSize), vArray, BufferUsageHint.StaticDraw);\r
+                if (Compat.BufferSize(BufferTarget.ArrayBuffer) != vArray.Length * VertexSize)\r
+                {\r
+                    VBOFailed = true;\r
+                    Compat.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
+                    Compat.DeleteBuffer(VertexVBO);\r
+                    VertexVBO = -1;\r
+                    return false;\r
+                }\r
             }\r
 \r
             if (IndexVBO == -1)\r
@@ -66,7 +81,17 @@ namespace Radegast.Rendering
                 Compat.GenBuffers(out IndexVBO);\r
                 Compat.BindBuffer(BufferTarget.ElementArrayBuffer, IndexVBO);\r
                 Compat.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(iArray.Length * sizeof(ushort)), iArray, BufferUsageHint.StaticDraw);\r
+                if (Compat.BufferSize(BufferTarget.ElementArrayBuffer) != iArray.Length * sizeof(ushort))\r
+                {\r
+                    VBOFailed = true;\r
+                    Compat.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
+                    Compat.DeleteBuffer(IndexVBO);\r
+                    IndexVBO = -1;\r
+                    return false;\r
+                }\r
             }\r
+\r
+            return true;\r
         }\r
     }\r
 \r