OSDN Git Service

Implemented prim sorting.
authorLatif Khalifa <latifer@streamgrid.net>
Mon, 11 Jul 2011 05:57:40 +0000 (05:57 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Mon, 11 Jul 2011 05:57:40 +0000 (05:57 +0000)
Renders prims with alpha from the farthest from the camera to the closest.
Prims without alpha the other way around.

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

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

index f6d8fcb..004983a 100644 (file)
@@ -108,7 +108,7 @@ namespace Radegast.Rendering
         System.Diagnostics.Stopwatch renderTimer;\r
         double lastFrameTime = 0d;\r
         double advTimerTick = 0d;\r
-        float minLODFactor = 0.01f;\r
+        float minLODFactor = 0.0001f;\r
 \r
         float[] lightPos = new float[] { 128f, 128f, 5000f, 0f };\r
         float ambient = 0.26f;\r
@@ -841,7 +841,7 @@ namespace Radegast.Rendering
                     {\r
                         img = OpenMetaverse.Imaging.LoadTGAClass.LoadTGA(byteData);\r
                     }\r
-                    \r
+\r
                     Bitmap bitmap = (Bitmap)img;\r
 \r
                     item.Data.TextureInfo.HasAlpha = hasAlpha;\r
@@ -864,7 +864,7 @@ namespace Radegast.Rendering
             ThreadPool.QueueUserWorkItem(sync =>\r
             {\r
                 List<Primitive> mainPrims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll((Primitive root) => root.ParentID == 0);\r
-                foreach(Primitive mainPrim in mainPrims)\r
+                foreach (Primitive mainPrim in mainPrims)\r
                 {\r
                     UpdatePrimBlocking(mainPrim);\r
                     Client.Network.CurrentSim.ObjectsPrimitives\r
@@ -873,7 +873,7 @@ namespace Radegast.Rendering
                 }\r
 \r
                 List<Avatar> avis = Client.Network.CurrentSim.ObjectsAvatars.FindAll((Avatar a) => true);\r
-                foreach(Avatar avatar in avis)\r
+                foreach (Avatar avatar in avis)\r
                 {\r
                     UpdatePrimBlocking(avatar);\r
                     Client.Network.CurrentSim.ObjectsPrimitives\r
@@ -1566,9 +1566,8 @@ namespace Radegast.Rendering
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Shininess, 0f);\r
         }\r
 \r
-        float LODFactor(Vector3 pos, Vector3 primScale, float radius)\r
+        float LODFactor(float distance, Vector3 primScale, float radius)\r
         {\r
-            float distance = Vector3.Distance(Camera.Position, pos);\r
             float scale = primScale.X;\r
             if (primScale.Y > scale) scale = primScale.Y;\r
             if (primScale.Z > scale) scale = primScale.Z;\r
@@ -1718,285 +1717,315 @@ namespace Radegast.Rendering
             GL.PopAttrib();\r
         }\r
 \r
-        private void RenderObjects(RenderPass pass)\r
+        void RenderPrim(RenderPrimitive mesh, RenderPass pass, int primNr)\r
         {\r
-            lock (Prims)\r
-            {\r
-                GL.EnableClientState(ArrayCap.VertexArray);\r
-                GL.EnableClientState(ArrayCap.TextureCoordArray);\r
-                GL.EnableClientState(ArrayCap.NormalArray);\r
+            Primitive prim = mesh.Prim;\r
+            RenderPrimitive parent = null;\r
+            RenderAvatar parentav = null;\r
 \r
-                int primNr = 0;\r
-                foreach (RenderPrimitive mesh in Prims.Values)\r
-                {\r
-                    primNr++;\r
-                    Primitive prim = mesh.Prim;\r
-                    RenderPrimitive parent = null;\r
-                    RenderAvatar parentav = null;\r
-\r
-                    if (prim.ParentID != 0 && !Prims.TryGetValue(prim.ParentID, out parent) && !Avatars.TryGetValue(prim.ParentID, out parentav)) continue;\r
-                    Vector3 primPos = PrimPos(prim);\r
+            if (prim.ParentID != 0 && !Prims.TryGetValue(prim.ParentID, out parent) && !Avatars.TryGetValue(prim.ParentID, out parentav)) return;\r
 \r
-                    // Don't render objects too small to matter\r
-                    if (LODFactor(primPos, prim.Scale, mesh.BoundingVolume.R) < minLODFactor) continue;\r
+            // Don't render objects too small to matter\r
+            if (LODFactor(mesh.DistanceSquared, prim.Scale, mesh.BoundingVolume.R) < minLODFactor) return;\r
 \r
-                    // Don't render objects not in the field of view\r
-                    if (!Frustum.ObjectInFrustum(primPos, mesh.BoundingVolume, prim.Scale)) continue;\r
+            // Don't render objects not in the field of view\r
+            if (!Frustum.ObjectInFrustum(mesh.SimPosition, mesh.BoundingVolume, prim.Scale)) return;\r
 \r
-                    // Individual prim matrix\r
-                    GL.PushMatrix();\r
+            // Individual prim matrix\r
+            GL.PushMatrix();\r
 \r
-                    //TODO we really need a scene graph but for the moment simple if/else logic checks and parent finding are used\r
-                    if (prim.ParentID != 0) // Does this prim have a parent\r
+            //TODO we really need a scene graph but for the moment simple if/else logic checks and parent finding are used\r
+            if (prim.ParentID != 0) // Does this prim have a parent\r
+            {\r
+                if (parent != null) // Check the parent is valid\r
+                {\r
+                    if (parent.Prim.ParentID != 0) // Does the parent have a parent? if so it must be an avatar \r
                     {\r
-                        if (parent != null) // Check the parent is valid\r
-                        {\r
-                            if (parent.Prim.ParentID != 0) // Does the parent have a parent? if so it must be an avatar \r
-                            {\r
-                                if (Avatars.TryGetValue(parent.Prim.ParentID, out parentav)) // Get the parent avatar\r
-                                {\r
-                                    // Child prims of parents that have avatar as parent\r
-\r
-                                    if (prim.PrimData.AttachmentPoint >= AttachmentPoint.HUDCenter2 && prim.PrimData.AttachmentPoint <= AttachmentPoint.HUDBottomRight)\r
-                                    {\r
-                                        // Child HUD elements\r
-                                    }\r
-                                    else\r
-                                    {\r
-                                        //This is a child prim attachment\r
-\r
-                                        // Apply prim translation and rotation relative to the root prim\r
-                                        GL.MultMatrix(Math3D.CreateTranslationMatrix(parentav.avatar.Position));\r
-                                        GL.MultMatrix(Math3D.CreateRotationMatrix(parentav.avatar.Rotation));\r
-\r
-                                        int attachment_index = (int)parent.Prim.PrimData.AttachmentPoint;\r
-                                        if (attachment_index > GLAvatar.attachment_points.Count())\r
-                                        {\r
-                                            // invalid LL attachment point\r
-                                            continue;\r
-                                        }\r
-\r
-                                        attachment_point apoint = GLAvatar.attachment_points[attachment_index];\r
-\r
-                                        Vector3 point = parentav.glavatar.skel.getOffset(apoint.joint) + apoint.position;\r
-                                        Quaternion qrot = parentav.glavatar.skel.getRotation(apoint.joint) * apoint.rotation;\r
-                                        //Vector3 point = Bone.getOffset(apoint.joint) + apoint.position;\r
-                                        // Quaternion qrot = Bone.getRotation(apoint.joint) * apoint.rotation;\r
-\r
-                                        GL.MultMatrix(Math3D.CreateTranslationMatrix(point));\r
-                                        GL.MultMatrix(Math3D.CreateRotationMatrix(qrot));\r
-\r
-                                        // Apply prim translation and rotation relative to the root prim\r
-                                        GL.MultMatrix(Math3D.CreateTranslationMatrix(parent.Prim.Position));\r
-                                        GL.MultMatrix(Math3D.CreateRotationMatrix(parent.Prim.Rotation));\r
-                                    }\r
-                                }\r
-                            }\r
-                            else // This prims parent does not have a parent there for its a regular prim and this must be its child\r
-                            {\r
-                                // Regular child prim\r
-                                // Apply prim translation and rotation relative to the root prim\r
-                                GL.MultMatrix(Math3D.CreateTranslationMatrix(parent.Prim.Position));\r
-                                GL.MultMatrix(Math3D.CreateRotationMatrix(parent.Prim.Rotation));\r
-                            }\r
-                        }\r
-                        else // This prim has a parent but does not have a parent in the ObjectsList, its parent is therefor parentav from the avatars list \r
+                        if (Avatars.TryGetValue(parent.Prim.ParentID, out parentav)) // Get the parent avatar\r
                         {\r
-                            //Root prims with avatar as parent\r
+                            // Child prims of parents that have avatar as parent\r
 \r
                             if (prim.PrimData.AttachmentPoint >= AttachmentPoint.HUDCenter2 && prim.PrimData.AttachmentPoint <= AttachmentPoint.HUDBottomRight)\r
                             {\r
-                                // Root HUD elements\r
+                                // Child HUD elements\r
                             }\r
                             else\r
                             {\r
-                                // Root attachments\r
+                                //This is a child prim attachment\r
 \r
                                 // Apply prim translation and rotation relative to the root prim\r
                                 GL.MultMatrix(Math3D.CreateTranslationMatrix(parentav.avatar.Position));\r
                                 GL.MultMatrix(Math3D.CreateRotationMatrix(parentav.avatar.Rotation));\r
 \r
-                                int attachment_index = (int)prim.PrimData.AttachmentPoint;\r
+                                int attachment_index = (int)parent.Prim.PrimData.AttachmentPoint;\r
                                 if (attachment_index > GLAvatar.attachment_points.Count())\r
                                 {\r
                                     // invalid LL attachment point\r
-                                    continue;\r
+                                    return;\r
                                 }\r
 \r
                                 attachment_point apoint = GLAvatar.attachment_points[attachment_index];\r
 \r
-                                //Vector3 point = Bone.getOffset(apoint.joint) + apoint.position;\r
-                                //Quaternion qrot = Bone.getRotation(apoint.joint) * apoint.rotation;\r
                                 Vector3 point = parentav.glavatar.skel.getOffset(apoint.joint) + apoint.position;\r
                                 Quaternion qrot = parentav.glavatar.skel.getRotation(apoint.joint) * apoint.rotation;\r
+                                //Vector3 point = Bone.getOffset(apoint.joint) + apoint.position;\r
+                                // Quaternion qrot = Bone.getRotation(apoint.joint) * apoint.rotation;\r
 \r
                                 GL.MultMatrix(Math3D.CreateTranslationMatrix(point));\r
                                 GL.MultMatrix(Math3D.CreateRotationMatrix(qrot));\r
+\r
+                                // Apply prim translation and rotation relative to the root prim\r
+                                GL.MultMatrix(Math3D.CreateTranslationMatrix(parent.Prim.Position));\r
+                                GL.MultMatrix(Math3D.CreateRotationMatrix(parent.Prim.Rotation));\r
                             }\r
                         }\r
                     }\r
+                    else // This prims parent does not have a parent there for its a regular prim and this must be its child\r
+                    {\r
+                        // Regular child prim\r
+                        // Apply prim translation and rotation relative to the root prim\r
+                        GL.MultMatrix(Math3D.CreateTranslationMatrix(parent.Prim.Position));\r
+                        GL.MultMatrix(Math3D.CreateRotationMatrix(parent.Prim.Rotation));\r
+                    }\r
+                }\r
+                else // This prim has a parent but does not have a parent in the ObjectsList, its parent is therefor parentav from the avatars list \r
+                {\r
+                    //Root prims with avatar as parent\r
 \r
+                    if (prim.PrimData.AttachmentPoint >= AttachmentPoint.HUDCenter2 && prim.PrimData.AttachmentPoint <= AttachmentPoint.HUDBottomRight)\r
+                    {\r
+                        // Root HUD elements\r
+                    }\r
+                    else\r
+                    {\r
+                        // Root attachments\r
 \r
-                    // Prim roation and position\r
-                    GL.MultMatrix(Math3D.CreateTranslationMatrix(prim.Position));\r
-                    GL.MultMatrix(Math3D.CreateRotationMatrix(prim.Rotation));\r
+                        // Apply prim translation and rotation relative to the root prim\r
+                        GL.MultMatrix(Math3D.CreateTranslationMatrix(parentav.avatar.Position));\r
+                        GL.MultMatrix(Math3D.CreateRotationMatrix(parentav.avatar.Rotation));\r
 \r
-                    // Prim scaling\r
-                    GL.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z);\r
+                        int attachment_index = (int)prim.PrimData.AttachmentPoint;\r
+                        if (attachment_index > GLAvatar.attachment_points.Count())\r
+                        {\r
+                            // invalid LL attachment point\r
+                            return;\r
+                        }\r
 \r
-                    // Do we have animated texture on this face\r
-                    bool animatedTexture = false;\r
+                        attachment_point apoint = GLAvatar.attachment_points[attachment_index];\r
 \r
-                    // Draw the prim faces\r
-                    for (int j = 0; j < mesh.Faces.Count; j++)\r
-                    {\r
-                        Primitive.TextureEntryFace teFace = mesh.Prim.Textures.FaceTextures[j];\r
-                        Face face = mesh.Faces[j];\r
-                        FaceData data = (FaceData)mesh.Faces[j].UserData;\r
-                        \r
-                        if (teFace == null)\r
-                            teFace = mesh.Prim.Textures.DefaultTexture;\r
+                        //Vector3 point = Bone.getOffset(apoint.joint) + apoint.position;\r
+                        //Quaternion qrot = Bone.getRotation(apoint.joint) * apoint.rotation;\r
+                        Vector3 point = parentav.glavatar.skel.getOffset(apoint.joint) + apoint.position;\r
+                        Quaternion qrot = parentav.glavatar.skel.getRotation(apoint.joint) * apoint.rotation;\r
 \r
-                        if (teFace == null)\r
-                            continue;\r
+                        GL.MultMatrix(Math3D.CreateTranslationMatrix(point));\r
+                        GL.MultMatrix(Math3D.CreateRotationMatrix(qrot));\r
+                    }\r
+                }\r
+            }\r
 \r
-                        // Don't render transparent faces\r
-                        if (data.TextureInfo.FullAlpha || teFace.RGBA.A <= 0.01f) continue;\r
 \r
-                        int lightsEnabled;\r
-                        GL.GetInteger(GetPName.Lighting, out lightsEnabled);\r
+            // Prim roation and position\r
+            GL.MultMatrix(Math3D.CreateTranslationMatrix(prim.Position));\r
+            GL.MultMatrix(Math3D.CreateRotationMatrix(prim.Rotation));\r
 \r
-                        if (pass != RenderPass.Picking)\r
-                        {\r
-                            bool belongToAlphaPass = (teFace.RGBA.A < 0.99) || data.TextureInfo.HasAlpha;\r
+            // Prim scaling\r
+            GL.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z);\r
 \r
-                            if (belongToAlphaPass && pass != RenderPass.Alpha) continue;\r
-                            if (!belongToAlphaPass && pass == RenderPass.Alpha) continue;\r
+            // Do we have animated texture on this face\r
+            bool animatedTexture = false;\r
 \r
-                            if (teFace.Fullbright && lightsEnabled != 0)\r
-                            {\r
-                                GL.Disable(EnableCap.Lighting);\r
-                            }\r
+            // Draw the prim faces\r
+            for (int j = 0; j < mesh.Faces.Count; j++)\r
+            {\r
+                Primitive.TextureEntryFace teFace = mesh.Prim.Textures.FaceTextures[j];\r
+                Face face = mesh.Faces[j];\r
+                FaceData data = (FaceData)mesh.Faces[j].UserData;\r
 \r
-                            switch (teFace.Shiny)\r
-                            {\r
-                                case Shininess.High:\r
-                                    GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.94f);\r
-                                    break;\r
+                if (teFace == null)\r
+                    teFace = mesh.Prim.Textures.DefaultTexture;\r
 \r
-                                case Shininess.Medium:\r
-                                    GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.64f);\r
-                                    break;\r
+                if (teFace == null)\r
+                    continue;\r
 \r
-                                case Shininess.Low:\r
-                                    GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.24f);\r
-                                    break;\r
+                // Don't render transparent faces\r
+                if (data.TextureInfo.FullAlpha || teFace.RGBA.A <= 0.01f) continue;\r
 \r
+                int lightsEnabled;\r
+                GL.GetInteger(GetPName.Lighting, out lightsEnabled);\r
 \r
-                                case Shininess.None:\r
-                                default:\r
-                                    GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0f);\r
-                                    break;\r
-                            }\r
+                if (pass != RenderPass.Picking)\r
+                {\r
+                    bool belongToAlphaPass = (teFace.RGBA.A < 0.99) || data.TextureInfo.HasAlpha;\r
 \r
-                            var faceColor = new float[] { teFace.RGBA.R, teFace.RGBA.G, teFace.RGBA.B, teFace.RGBA.A };\r
-                            GL.Color4(faceColor);\r
+                    if (belongToAlphaPass && pass != RenderPass.Alpha) continue;\r
+                    if (!belongToAlphaPass && pass == RenderPass.Alpha) continue;\r
 \r
-                            GL.Material(MaterialFace.Front, MaterialParameter.Specular, new float[] { 0.5f, 0.5f, 0.5f, 1f });\r
+                    if (teFace.Fullbright && lightsEnabled != 0)\r
+                    {\r
+                        GL.Disable(EnableCap.Lighting);\r
+                    }\r
 \r
-                            if (data.TextureInfo.TexturePointer != 0)\r
-                            {\r
-                                // Is this face using texture animation\r
-                                if ((prim.TextureAnim.Flags & Primitive.TextureAnimMode.ANIM_ON) != 0\r
-                                    && (prim.TextureAnim.Face == j || prim.TextureAnim.Face == 255))\r
-                                {\r
-                                    if (data.AnimInfo == null)\r
-                                    {\r
-                                        data.AnimInfo = new TextureAnimationInfo();\r
-                                    }\r
-                                    data.AnimInfo.PrimAnimInfo = prim.TextureAnim;\r
-                                    data.AnimInfo.Step(lastFrameTime);\r
-                                    animatedTexture = true;\r
-                                }\r
-                                else if (data.AnimInfo != null) // Face texture not animated. Do we have previous anim setting?\r
-                                {\r
-                                    data.AnimInfo = null;\r
-                                }\r
+                    switch (teFace.Shiny)\r
+                    {\r
+                        case Shininess.High:\r
+                            GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.94f);\r
+                            break;\r
 \r
-                                GL.Enable(EnableCap.Texture2D);\r
-                                GL.BindTexture(TextureTarget.Texture2D, data.TextureInfo.TexturePointer);\r
-                            }\r
-                            else\r
-                            {\r
-                                GL.Disable(EnableCap.Texture2D);\r
-                            }\r
+                        case Shininess.Medium:\r
+                            GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.64f);\r
+                            break;\r
 \r
-                        }\r
-                        else\r
-                        {\r
-                            data.PickingID = primNr;\r
-                            var primNrBytes = Utils.Int16ToBytes((short)primNr);\r
-                            var faceColor = new byte[] { primNrBytes[0], primNrBytes[1], (byte)j, 255 };\r
-                            GL.Color4(faceColor);\r
-                        }\r
+                        case Shininess.Low:\r
+                            GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.24f);\r
+                            break;\r
 \r
-                        if (!useVBO)\r
-                        {\r
-                            Vertex[] verts = face.Vertices.ToArray();\r
 \r
-                            unsafe\r
+                        case Shininess.None:\r
+                        default:\r
+                            GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0f);\r
+                            break;\r
+                    }\r
+\r
+                    var faceColor = new float[] { teFace.RGBA.R, teFace.RGBA.G, teFace.RGBA.B, teFace.RGBA.A };\r
+                    GL.Color4(faceColor);\r
+\r
+                    GL.Material(MaterialFace.Front, MaterialParameter.Specular, new float[] { 0.5f, 0.5f, 0.5f, 1f });\r
+\r
+                    if (data.TextureInfo.TexturePointer != 0)\r
+                    {\r
+                        // Is this face using texture animation\r
+                        if ((prim.TextureAnim.Flags & Primitive.TextureAnimMode.ANIM_ON) != 0\r
+                            && (prim.TextureAnim.Face == j || prim.TextureAnim.Face == 255))\r
+                        {\r
+                            if (data.AnimInfo == null)\r
                             {\r
-                                fixed (float* normalPtr = &verts[0].Normal.X)\r
-                                fixed (float* texPtr = &verts[0].TexCoord.X)\r
-                                {\r
-                                    GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)normalPtr);\r
-                                    GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)texPtr);\r
-                                    GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, verts);\r
-                                    GL.DrawElements(BeginMode.Triangles, data.Indices.Length, DrawElementsType.UnsignedShort, data.Indices);\r
-                                }\r
+                                data.AnimInfo = new TextureAnimationInfo();\r
                             }\r
+                            data.AnimInfo.PrimAnimInfo = prim.TextureAnim;\r
+                            data.AnimInfo.Step(lastFrameTime);\r
+                            animatedTexture = true;\r
                         }\r
-                        else\r
+                        else if (data.AnimInfo != null) // Face texture not animated. Do we have previous anim setting?\r
                         {\r
-                            data.CheckVBO(face);\r
-                            GL.BindBuffer(BufferTarget.ArrayBuffer, data.VertexVBO);\r
-                            GL.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
+                            data.AnimInfo = null;\r
+                        }\r
 \r
-                            GL.DrawElements(BeginMode.Triangles, face.Indices.Count, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
+                        GL.Enable(EnableCap.Texture2D);\r
+                        GL.BindTexture(TextureTarget.Texture2D, data.TextureInfo.TexturePointer);\r
+                    }\r
+                    else\r
+                    {\r
+                        GL.Disable(EnableCap.Texture2D);\r
+                    }\r
 \r
-                            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
-                            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
+                }\r
+                else\r
+                {\r
+                    data.PickingID = primNr;\r
+                    var primNrBytes = Utils.Int16ToBytes((short)primNr);\r
+                    var faceColor = new byte[] { primNrBytes[0], primNrBytes[1], (byte)j, 255 };\r
+                    GL.Color4(faceColor);\r
+                }\r
 \r
-                        }\r
+                if (!useVBO)\r
+                {\r
+                    Vertex[] verts = face.Vertices.ToArray();\r
 \r
-                        if (teFace.Fullbright && lightsEnabled != 0)\r
+                    unsafe\r
+                    {\r
+                        fixed (float* normalPtr = &verts[0].Normal.X)\r
+                        fixed (float* texPtr = &verts[0].TexCoord.X)\r
                         {\r
-                            GL.Enable(EnableCap.Lighting);\r
+                            GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)normalPtr);\r
+                            GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)texPtr);\r
+                            GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, verts);\r
+                            GL.DrawElements(BeginMode.Triangles, data.Indices.Length, DrawElementsType.UnsignedShort, data.Indices);\r
                         }\r
                     }\r
+                }\r
+                else\r
+                {\r
+                    data.CheckVBO(face);\r
+                    GL.BindBuffer(BufferTarget.ArrayBuffer, data.VertexVBO);\r
+                    GL.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.BindTexture(TextureTarget.Texture2D, 0);\r
-                    ResetMaterial();\r
+                    GL.DrawElements(BeginMode.Triangles, face.Indices.Count, DrawElementsType.UnsignedShort, IntPtr.Zero);\r
 \r
-                    // Reset texture coordinates if we modified them in texture animation\r
-                    if (animatedTexture)\r
-                    {\r
-                        GL.MatrixMode(MatrixMode.Texture);\r
-                        GL.LoadIdentity();\r
-                        GL.MatrixMode(MatrixMode.Modelview);\r
-                    }\r
+                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);\r
+                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);\r
 \r
-                    // Pop the prim matrix\r
-                    GL.PopMatrix();\r
                 }\r
-                GL.Disable(EnableCap.Texture2D);\r
-                GL.DisableClientState(ArrayCap.VertexArray);\r
-                GL.DisableClientState(ArrayCap.TextureCoordArray);\r
-                GL.DisableClientState(ArrayCap.NormalArray);\r
+\r
+                if (teFace.Fullbright && lightsEnabled != 0)\r
+                {\r
+                    GL.Enable(EnableCap.Lighting);\r
+                }\r
+            }\r
+\r
+            GL.BindTexture(TextureTarget.Texture2D, 0);\r
+            ResetMaterial();\r
+\r
+            // Reset texture coordinates if we modified them in texture animation\r
+            if (animatedTexture)\r
+            {\r
+                GL.MatrixMode(MatrixMode.Texture);\r
+                GL.LoadIdentity();\r
+                GL.MatrixMode(MatrixMode.Modelview);\r
+            }\r
+\r
+            // Pop the prim matrix\r
+            GL.PopMatrix();\r
+        }\r
+\r
+        void SortPrims()\r
+        {\r
+            lock (Prims)\r
+            {\r
+                SortedPrims = new List<RenderPrimitive>(Prims.Count);\r
+                foreach (RenderPrimitive prim in Prims.Values)\r
+                {\r
+                    prim.SimPosition = PrimPos(prim.Prim);\r
+                    prim.DistanceSquared = Vector3.DistanceSquared(Camera.RenderPosition, prim.SimPosition);\r
+                    SortedPrims.Add(prim);\r
+                }\r
+                // RenderPrimitive class has IComparable implementation\r
+                // that allows sorting by distance\r
+                SortedPrims.Sort();\r
+            }\r
+        }\r
+\r
+        private void RenderObjects(RenderPass pass)\r
+        {\r
+            GL.EnableClientState(ArrayCap.VertexArray);\r
+            GL.EnableClientState(ArrayCap.TextureCoordArray);\r
+            GL.EnableClientState(ArrayCap.NormalArray);\r
+\r
+            // When rendering alpha faces, draw from back towards the camers\r
+            // otherwise from those closest to camera, to the farthest\r
+            int nrPrims = SortedPrims.Count;\r
+            if (pass == RenderPass.Picking || pass == RenderPass.Simple)\r
+            {\r
+                for (int i = 0; i < nrPrims; i++)\r
+                {\r
+                    RenderPrim(SortedPrims[i], pass, i);\r
+                }\r
             }\r
+            else if (pass == RenderPass.Alpha)\r
+            {\r
+                for (int i = nrPrims - 1; i >= 0; i--)\r
+                {\r
+                    RenderPrim(SortedPrims[i], pass, i);\r
+                }\r
+            }\r
+\r
+            GL.Disable(EnableCap.Texture2D);\r
+            GL.DisableClientState(ArrayCap.VertexArray);\r
+            GL.DisableClientState(ArrayCap.TextureCoordArray);\r
+            GL.DisableClientState(ArrayCap.NormalArray);\r
         }\r
 \r
         void DrawWaterQuad(float x, float y, float z)\r
@@ -2066,6 +2095,8 @@ namespace Radegast.Rendering
                 Camera.Step(lastFrameTime);\r
             }\r
 \r
+            SortPrims();\r
+\r
             if (picking)\r
             {\r
                 RenderObjects(RenderPass.Picking);\r
index d085f1b..be9cfa4 100644 (file)
@@ -287,6 +287,7 @@ namespace Radegast.Rendering
     {\r
         public Primitive Prim;\r
         public List<Face> Faces;\r
+        public Vector3 SimPosition;\r
         public float DistanceSquared;\r
         public BoundingVolume BoundingVolume;\r
 \r
@@ -304,6 +305,13 @@ namespace Radegast.Rendering
             else\r
                 return 0;\r
         }\r
+\r
+        public override string ToString()\r
+        {\r
+            uint id = Prim == null ? 0 : Prim.LocalID;\r
+            double distance = Math.Sqrt(DistanceSquared);\r
+            return string.Format("LocalID: {0}, distance {0.00}", id, distance);\r
+        }\r
     }\r
 \r
     public static class Render\r