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
{\r
img = OpenMetaverse.Imaging.LoadTGAClass.LoadTGA(byteData);\r
}\r
- \r
+\r
Bitmap bitmap = (Bitmap)img;\r
\r
item.Data.TextureInfo.HasAlpha = hasAlpha;\r
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
}\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
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
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
Camera.Step(lastFrameTime);\r
}\r
\r
+ SortPrims();\r
+\r
if (picking)\r
{\r
RenderObjects(RenderPass.Picking);\r