private static void RenderFace(ref ObjectFace Face, double CameraX, double CameraY, double CameraZ) { if (CullEnabled) { if (!OptionBackfaceCulling || (ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & World.MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); CullEnabled = false; } } else if (OptionBackfaceCulling) { if ((ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & World.MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); CullEnabled = true; } } int r = (int)ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Material; RenderFace(ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Materials[r], ObjectManager.Objects[Face.ObjectIndex].Mesh.Vertices, Face.Wrap, ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex], CameraX, CameraY, CameraZ); }
private static void RenderFace(ref ObjectFace Face, Vector3 Camera, bool IsDebugTouchMode = false) { if (CullEnabled) { if (!OptionBackfaceCulling || (ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & MeshFace.Face2Mask) != 0) { GL.Disable(EnableCap.CullFace); CullEnabled = false; } } else if (OptionBackfaceCulling) { if ((ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & MeshFace.Face2Mask) == 0) { GL.Enable(EnableCap.CullFace); CullEnabled = true; } } int r = (int)ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Material; RenderFace(ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Materials[r], ObjectManager.Objects[Face.ObjectIndex].Mesh.Vertices, Face.Wrap, ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex], Camera, IsDebugTouchMode); }
private static void RenderFace(ref ObjectFace Face, double CameraX, double CameraY, double CameraZ) { if (CullEnabled) { if (!OptionBackfaceCulling || (ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & World.MeshFace.Face2Mask) != 0) { Gl.glDisable(Gl.GL_CULL_FACE); CullEnabled = false; } } else if (OptionBackfaceCulling) { if ((ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Flags & World.MeshFace.Face2Mask) == 0) { Gl.glEnable(Gl.GL_CULL_FACE); CullEnabled = true; } } int r = (int)ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex].Material; RenderFace(ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Materials[r], ObjectManager.Objects[Face.ObjectIndex].Mesh.Vertices, Face.Wrap, ref ObjectManager.Objects[Face.ObjectIndex].Mesh.Faces[Face.FaceIndex], CameraX, CameraY, CameraZ); }
// sort polygons private static void SortPolygons(ObjectFace[] List, int ListCount, double[] ListDistance, int ListOffset, double TimeElapsed) { // calculate distance double cx = World.AbsoluteCameraPosition.X; double cy = World.AbsoluteCameraPosition.Y; double cz = World.AbsoluteCameraPosition.Z; for (int i = 0; i < ListCount; i++) { int o = List[i].ObjectIndex; int f = List[i].FaceIndex; if (ObjectManager.Objects[o].Mesh.Faces[f].Vertices.Length >= 3) { int v0 = ObjectManager.Objects[o].Mesh.Faces[f].Vertices[0].Index; int v1 = ObjectManager.Objects[o].Mesh.Faces[f].Vertices[1].Index; int v2 = ObjectManager.Objects[o].Mesh.Faces[f].Vertices[2].Index; double v0x = ObjectManager.Objects[o].Mesh.Vertices[v0].Coordinates.X; double v0y = ObjectManager.Objects[o].Mesh.Vertices[v0].Coordinates.Y; double v0z = ObjectManager.Objects[o].Mesh.Vertices[v0].Coordinates.Z; double v1x = ObjectManager.Objects[o].Mesh.Vertices[v1].Coordinates.X; double v1y = ObjectManager.Objects[o].Mesh.Vertices[v1].Coordinates.Y; double v1z = ObjectManager.Objects[o].Mesh.Vertices[v1].Coordinates.Z; double v2x = ObjectManager.Objects[o].Mesh.Vertices[v2].Coordinates.X; double v2y = ObjectManager.Objects[o].Mesh.Vertices[v2].Coordinates.Y; double v2z = ObjectManager.Objects[o].Mesh.Vertices[v2].Coordinates.Z; double w1x = v1x - v0x, w1y = v1y - v0y, w1z = v1z - v0z; double w2x = v2x - v0x, w2y = v2y - v0y, w2z = v2z - v0z; double dx = -w1z * w2y + w1y * w2z; double dy = w1z * w2x - w1x * w2z; double dz = -w1y * w2x + w1x * w2y; double t = dx * dx + dy * dy + dz * dz; if (t != 0.0) { t = 1.0 / Math.Sqrt(t); dx *= t; dy *= t; dz *= t; double w0x = v0x - cx, w0y = v0y - cy, w0z = v0z - cz; t = dx * w0x + dy * w0y + dz * w0z; ListDistance[i] = -t * t; } } } // sort Array.Sort<double, ObjectFace>(ListDistance, List, 0, ListCount); // update object list for (int i = 0; i < ListCount; i++) { ObjectList[List[i].ObjectListIndex].FaceListIndices[List[i].FaceIndex] = (i << 2) + ListOffset; } }
// show object internal static void ShowObject(int ObjectIndex, ObjectType Type) { bool Overlay = Type == ObjectType.Overlay; if (ObjectManager.Objects[ObjectIndex] == null) { return; } if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0) { if (ObjectListCount >= ObjectList.Length) { Array.Resize <Object>(ref ObjectList, ObjectList.Length << 1); } ObjectList[ObjectListCount].ObjectIndex = ObjectIndex; ObjectList[ObjectListCount].Type = Type; int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length; ObjectList[ObjectListCount].FaceListIndices = new int[f]; for (int i = 0; i < f; i++) { if (Overlay) { // overlay if (OverlayListCount >= OverlayList.Length) { Array.Resize(ref OverlayList, OverlayList.Length << 1); Array.Resize(ref OverlayListDistance, OverlayList.Length); } OverlayList[OverlayListCount].ObjectIndex = ObjectIndex; OverlayList[OverlayListCount].FaceIndex = i; OverlayList[OverlayListCount].ObjectListIndex = ObjectListCount; ObjectList[ObjectListCount].FaceListIndices[i] = (OverlayListCount << 2) + 3; OverlayListCount++; } else { int k = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material; OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp; bool transparentcolor = false, alpha = false; if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].Color.A != 255) { alpha = true; } else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].BlendMode == MeshMaterialBlendMode.Additive) { alpha = true; } else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].GlowAttenuationData != 0) { alpha = true; } else { if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null) { if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode == null) { // If the object does not have a stored wrapping mode, determine it now for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++) { if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f | ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f) { wrap |= OpenGlTextureWrapMode.RepeatClamp; } if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f | ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f) { wrap |= OpenGlTextureWrapMode.ClampRepeat; } } ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode = wrap; } else { //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer wrap = (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode; } Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode); if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency == TextureTransparencyType.Alpha) { alpha = true; } else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency == TextureTransparencyType.Partial) { transparentcolor = true; } } if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null) { Program.CurrentHost.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture, (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode); if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency == TextureTransparencyType.Alpha) { alpha = true; } else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency == TextureTransparencyType.Partial) { transparentcolor = true; } } } if (alpha) { // alpha if (AlphaListCount >= AlphaList.Length) { Array.Resize(ref AlphaList, AlphaList.Length << 1); Array.Resize(ref AlphaListDistance, AlphaList.Length); } AlphaList[AlphaListCount] = new ObjectFace(); AlphaList[AlphaListCount].ObjectIndex = ObjectIndex; AlphaList[AlphaListCount].FaceIndex = i; AlphaList[AlphaListCount].ObjectListIndex = ObjectListCount; AlphaList[AlphaListCount].Wrap = wrap; ObjectList[ObjectListCount].FaceListIndices[i] = (AlphaListCount << 2) + 2; AlphaListCount++; } else if (transparentcolor) { // transparent color if (TransparentColorListCount >= TransparentColorList.Length) { Array.Resize(ref TransparentColorList, TransparentColorList.Length << 1); Array.Resize(ref TransparentColorListDistance, TransparentColorList.Length); } TransparentColorList[TransparentColorListCount] = new ObjectFace(); TransparentColorList[TransparentColorListCount].ObjectIndex = ObjectIndex; TransparentColorList[TransparentColorListCount].FaceIndex = i; TransparentColorList[TransparentColorListCount].ObjectListIndex = ObjectListCount; TransparentColorList[TransparentColorListCount].Wrap = wrap; ObjectList[ObjectListCount].FaceListIndices[i] = (TransparentColorListCount << 2) + 1; TransparentColorListCount++; } else { // opaque if (OpaqueListCount >= OpaqueList.Length) { Array.Resize(ref OpaqueList, OpaqueList.Length << 1); } OpaqueList[OpaqueListCount] = new ObjectFace(); OpaqueList[OpaqueListCount].ObjectIndex = ObjectIndex; OpaqueList[OpaqueListCount].FaceIndex = i; OpaqueList[OpaqueListCount].ObjectListIndex = ObjectListCount; OpaqueList[OpaqueListCount].Wrap = wrap; ObjectList[ObjectListCount].FaceListIndices[i] = OpaqueListCount << 2; OpaqueListCount++; } } } ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectListCount + 1; ObjectListCount++; } }