OSDN Git Service

* Rename BoundingSphere -> BoundingVolume
authorLatif Khalifa <latifer@streamgrid.net>
Mon, 11 Jul 2011 04:25:28 +0000 (04:25 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Mon, 11 Jul 2011 04:25:28 +0000 (04:25 +0000)
* Temp put draw distance at 96
* Do frustrum and LOD culling for whole prims and not per FaceData

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

Radegast/GUI/Rendering/Frustum.cs
Radegast/GUI/Rendering/Rendering.cs
Radegast/GUI/Rendering/RenderingHelpers.cs

index d758eef..ad2c870 100644 (file)
@@ -148,12 +148,12 @@ namespace Radegast.Rendering
             return d + radius; // palauta matka kameraan
         }
 
-        public static bool ObjectInFrustum(Vector3 position, BoundingSphere bound, Vector3 scale)
+        public static bool ObjectInFrustum(Vector3 position, BoundingVolume bound, Vector3 scale)
         {
             return ObjectInFrustum(position.X, position.Y, position.Z, bound, scale);
         }
 
-        public static bool ObjectInFrustum(float x, float y, float z, BoundingSphere bound, Vector3 scale)
+        public static bool ObjectInFrustum(float x, float y, float z, BoundingVolume bound, Vector3 scale)
         {
             if (bound == null) return true;
             float max = scale.X;
@@ -164,7 +164,7 @@ namespace Radegast.Rendering
         }
     }
 
-    public class BoundingSphere
+    public class BoundingVolume
     {
         public Vector3 Min = new Vector3(99999, 99999, 99999);
         public Vector3 Max = new Vector3(-99999, -99999, -99999);
@@ -184,11 +184,11 @@ namespace Radegast.Rendering
             }
 
             Vector3 dist = Max - Min;
-            R = Vector3.Distance(Min, Max);
+            R = dist.Length();
             mesh.Center = Min + (dist / 2);
         }
 
-        public void AddVolume(BoundingSphere vol)
+        public void AddVolume(BoundingVolume vol)
         {
             if (vol.Min.X < this.Min.X) this.Min.X = vol.Min.X;
             if (vol.Min.Y < this.Min.Y) this.Min.Y = vol.Min.Y;
@@ -197,7 +197,8 @@ namespace Radegast.Rendering
             if (vol.Max.X > this.Max.X) this.Max.X = vol.Max.X;
             if (vol.Max.Y > this.Max.Y) this.Max.Y = vol.Max.Y;
             if (vol.Max.Z > this.Max.Z) this.Max.Z = vol.Max.Z;
-            R = Vector3.Distance(Min, Max);
+            Vector3 dist = Max - Min;
+            R = dist.Length();
         }
 
         //public void CreateBoundingVolume(Model mesh, Vector3 min, Vector3 max)
index d1c6951..1b1abff 100644 (file)
@@ -76,7 +76,7 @@ namespace Radegast.Rendering
         /// <summary>\r
         /// Object from up to this distance from us will be rendered\r
         /// </summary>\r
-        public float DrawDistance = 48f;\r
+        public float DrawDistance = 96f;\r
 \r
         /// <summary>\r
         /// List of prims in the scene\r
@@ -108,7 +108,7 @@ namespace Radegast.Rendering
         System.Diagnostics.Stopwatch renderTimer;\r
         double lastFrameTime = 0d;\r
         double advTimerTick = 0d;\r
-        float minLODFactor = 0.005f;\r
+        float minLODFactor = 0.01f;\r
 \r
         float[] lightPos = new float[] { 128f, 128f, 5000f, 0f };\r
         float ambient = 0.26f;\r
@@ -804,9 +804,9 @@ namespace Radegast.Rendering
                 {\r
                     ManagedImage mi;\r
                     Image img;\r
-                    OpenJPEG.DecodeToImage(item.TextureData, out mi, out img);\r
+                    if (!OpenJPEG.DecodeToImage(item.TextureData, out mi, out img)) continue;\r
                     Bitmap bitmap = (Bitmap)img;\r
-\r
+                    \r
                     bool hasAlpha;\r
                     if (bitmap.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb)\r
                     {\r
@@ -1546,6 +1546,149 @@ namespace Radegast.Rendering
             return scale * radius * radius / distance;\r
         }\r
 \r
+        void RenderSphere(float cx, float cy, float cz, float r, int p)\r
+        {\r
+            GL.PushAttrib(AttribMask.AllAttribBits);\r
+            GL.Disable(EnableCap.Fog);\r
+            GL.Disable(EnableCap.Texture2D);\r
+            GL.Disable(EnableCap.Dither);\r
+            GL.Disable(EnableCap.Lighting);\r
+            GL.Disable(EnableCap.LineStipple);\r
+            GL.Disable(EnableCap.PolygonStipple);\r
+            GL.Disable(EnableCap.CullFace);\r
+            GL.Disable(EnableCap.Blend);\r
+            GL.Disable(EnableCap.AlphaTest);\r
+            GL.Disable(EnableCap.DepthTest);\r
+\r
+            const float TWOPI = 6.28318530717958f;\r
+            const float PIDIV2 = 1.57079632679489f;\r
+\r
+            float theta1 = 0.0f;\r
+            float theta2 = 0.0f;\r
+            float theta3 = 0.0f;\r
+\r
+            float ex = 0.0f;\r
+            float ey = 0.0f;\r
+            float ez = 0.0f;\r
+\r
+            float px = 0.0f;\r
+            float py = 0.0f;\r
+            float pz = 0.0f;\r
+\r
+            // Disallow a negative number for radius.\r
+            if (r < 0)\r
+                r = -r;\r
+\r
+            // Disallow a negative number for precision.\r
+            if (p < 0)\r
+                p = -p;\r
+\r
+            // If the sphere is too small, just render a OpenGL point instead.\r
+            if (p < 4 || r <= 0)\r
+            {\r
+                GL.Begin(BeginMode.Points);\r
+                GL.Vertex3(cx, cy, cz);\r
+                GL.End();\r
+                return;\r
+            }\r
+\r
+            for (int i = 0; i < p / 2; ++i)\r
+            {\r
+                theta1 = i * TWOPI / p - PIDIV2;\r
+                theta2 = (i + 1) * TWOPI / p - PIDIV2;\r
+\r
+                GL.Begin(BeginMode.TriangleStrip);\r
+                {\r
+                    for (int j = 0; j <= p; ++j)\r
+                    {\r
+                        theta3 = j * TWOPI / p;\r
+\r
+                        ex = (float)(Math.Cos(theta2) * Math.Cos(theta3));\r
+                        ey = (float)Math.Sin(theta2);\r
+                        ez = (float)(Math.Cos(theta2) * Math.Sin(theta3));\r
+                        px = cx + r * ex;\r
+                        py = cy + r * ey;\r
+                        pz = cz + r * ez;\r
+\r
+                        GL.Normal3(ex, ey, ez);\r
+                        GL.TexCoord2(-(j / (float)p), 2 * (i + 1) / (float)p);\r
+                        GL.Vertex3(px, py, pz);\r
+\r
+                        ex = (float)(Math.Cos(theta1) * Math.Cos(theta3));\r
+                        ey = (float)Math.Sin(theta1);\r
+                        ez = (float)(Math.Cos(theta1) * Math.Sin(theta3));\r
+                        px = cx + r * ex;\r
+                        py = cy + r * ey;\r
+                        pz = cz + r * ez;\r
+\r
+                        GL.Normal3(ex, ey, ez);\r
+                        GL.TexCoord2(-(j / (float)p), 2 * i / (float)p);\r
+                        GL.Vertex3(px, py, pz);\r
+                    }\r
+                }\r
+                GL.End();\r
+            }\r
+            GL.PopAttrib();\r
+        }\r
+\r
+\r
+        void RenderBoundingBox(BoundingVolume bbox)\r
+        {\r
+            GL.PushAttrib(AttribMask.AllAttribBits);\r
+            GL.Disable(EnableCap.Fog);\r
+            GL.Disable(EnableCap.Texture2D);\r
+            GL.Disable(EnableCap.Dither);\r
+            GL.Disable(EnableCap.Lighting);\r
+            GL.Disable(EnableCap.LineStipple);\r
+            GL.Disable(EnableCap.PolygonStipple);\r
+            GL.Disable(EnableCap.CullFace);\r
+            GL.Disable(EnableCap.Blend);\r
+            GL.Disable(EnableCap.AlphaTest);\r
+\r
+            GL.Begin(BeginMode.Quads);\r
+            var bmin = bbox.Min;\r
+            var bmax = bbox.Max;\r
+\r
+            //front\r
+            GL.Vertex3(bmin.X, bmin.Y, bmin.Z);\r
+            GL.Vertex3(bmax.X, bmin.Y, bmin.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmin.Z);\r
+            GL.Vertex3(bmin.X, bmax.Y, bmin.Z);\r
+\r
+            // back\r
+            GL.Vertex3(bmin.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmax.Z);\r
+            GL.Vertex3(bmin.X, bmax.Y, bmax.Z);\r
+\r
+            // up\r
+            GL.Vertex3(bmin.X, bmax.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmin.Z);\r
+            GL.Vertex3(bmin.X, bmax.Y, bmin.Z);\r
+\r
+            // down\r
+            GL.Vertex3(bmin.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmin.Y, bmin.Z);\r
+            GL.Vertex3(bmin.X, bmin.Y, bmin.Z);\r
+\r
+            // left side\r
+            GL.Vertex3(bmin.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmin.X, bmax.Y, bmax.Z);\r
+            GL.Vertex3(bmin.X, bmax.Y, bmin.Z);\r
+            GL.Vertex3(bmin.X, bmin.Y, bmin.Z);\r
+\r
+            // rigth side\r
+            GL.Vertex3(bmax.X, bmin.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmax.Z);\r
+            GL.Vertex3(bmax.X, bmax.Y, bmin.Z);\r
+            GL.Vertex3(bmax.X, bmin.Y, bmin.Z);\r
+\r
+            GL.End();\r
+            GL.PopAttrib();\r
+        }\r
+\r
         private void RenderObjects(RenderPass pass)\r
         {\r
             lock (Prims)\r
@@ -1565,6 +1708,12 @@ namespace Radegast.Rendering
                     if (prim.ParentID != 0 && !Prims.TryGetValue(prim.ParentID, out parent) && !Avatars.TryGetValue(prim.ParentID, out parentav)) continue;\r
                     Vector3 primPos = PrimPos(prim);\r
 \r
+                    // Don't render objects too small to matter\r
+                    if (LODFactor(primPos, prim.Scale, mesh.BoundingVolume.R) < minLODFactor) continue;\r
+\r
+                    // Don't render objects not in the field of view\r
+                    if (!Frustum.ObjectInFrustum(primPos, mesh.BoundingVolume, prim.Scale)) continue;\r
+\r
                     // Individual prim matrix\r
                     GL.PushMatrix();\r
 \r
@@ -1676,12 +1825,6 @@ namespace Radegast.Rendering
                         Face face = mesh.Faces[j];\r
                         FaceData data = (FaceData)mesh.Faces[j].UserData;\r
 \r
-                        // Don't render objects too small to matter\r
-                        if (LODFactor(primPos, prim.Scale, data.BoundingVolume.R) < minLODFactor) continue;\r
-\r
-                        // Don't render objects not in the field of view\r
-                        if (!Frustum.ObjectInFrustum(primPos, data.BoundingVolume, prim.Scale)) continue;\r
-\r
                         if (teFace == null)\r
                             teFace = mesh.Prim.Textures.DefaultTexture;\r
 \r
@@ -2048,7 +2191,7 @@ namespace Radegast.Rendering
             }\r
 \r
             // Calculate bounding volumes for each prim and adjust textures\r
-            rprim.BoundingVolume = new BoundingSphere();\r
+            rprim.BoundingVolume = new BoundingVolume();\r
             for (int j = 0; j < rprim.Faces.Count; j++)\r
             {\r
                 Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j);\r
index ccf5c6c..7529a2e 100644 (file)
@@ -23,7 +23,7 @@ namespace Radegast.Rendering
         public int VertexVBO = -1;\r
         public int IndexVBO = -1;\r
         public TextureInfo TextureInfo = new TextureInfo();\r
-        public BoundingSphere BoundingVolume = new BoundingSphere();\r
+        public BoundingVolume BoundingVolume = new BoundingVolume();\r
         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 bool Occluded = false;\r
@@ -286,7 +286,7 @@ namespace Radegast.Rendering
         public Primitive Prim;\r
         public List<Face> Faces;\r
         public float DistanceSquared;\r
-        public BoundingSphere BoundingVolume;\r
+        public BoundingVolume BoundingVolume;\r
 \r
         public virtual void Dispose()\r
         {\r