Пример #1
0
 internal static void RenderScene(double TimeElapsed)
 {
     // initialize
     ResetOpenGlState();
     int OpenGlTextureIndex = 0;
     if (World.CurrentBackground.Texture != null) {
         //Textures.LoadTexture(World.CurrentBackground.Texture, Textures.OpenGlTextureWrapMode.RepeatClamp); // TODO
     }
     if (OptionWireframe | OpenGlTextureIndex == 0) {
         if (Game.CurrentFog.Start < Game.CurrentFog.End) {
             const float fogdistance = 600.0f;
             float n = (fogdistance - Game.CurrentFog.Start) / (Game.CurrentFog.End - Game.CurrentFog.Start);
             float cr = n * inv255 * (float)Game.CurrentFog.Color.R;
             float cg = n * inv255 * (float)Game.CurrentFog.Color.G;
             float cb = n * inv255 * (float)Game.CurrentFog.Color.B;
             Gl.glClearColor(cr, cg, cb, 1.0f);
         } else {
             Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
         }
         Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
     } else {
         Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);
     }
     Gl.glPushMatrix();
     MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.ChangeToScenery);
     if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) {
         LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes;
     }
     // set up camera
     double cx = World.AbsoluteCameraPosition.X;
     double cy = World.AbsoluteCameraPosition.Y;
     double cz = World.AbsoluteCameraPosition.Z;
     double dx = World.AbsoluteCameraDirection.X;
     double dy = World.AbsoluteCameraDirection.Y;
     double dz = World.AbsoluteCameraDirection.Z;
     double ux = World.AbsoluteCameraUp.X;
     double uy = World.AbsoluteCameraUp.Y;
     double uz = World.AbsoluteCameraUp.Z;
     Glu.gluLookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz);
     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, new float[] { OptionLightPosition.X, OptionLightPosition.Y, OptionLightPosition.Z, 0.0f });
     // fog
     double fd = Game.NextFog.TrackPosition - Game.PreviousFog.TrackPosition;
     if (fd != 0.0) {
         float fr = (float)((World.CameraTrackFollower.TrackPosition - Game.PreviousFog.TrackPosition) / fd);
         float frc = 1.0f - fr;
         Game.CurrentFog.Start = Game.PreviousFog.Start * frc + Game.NextFog.Start * fr;
         Game.CurrentFog.End = Game.PreviousFog.End * frc + Game.NextFog.End * fr;
         Game.CurrentFog.Color.R = (byte)((float)Game.PreviousFog.Color.R * frc + (float)Game.NextFog.Color.R * fr);
         Game.CurrentFog.Color.G = (byte)((float)Game.PreviousFog.Color.G * frc + (float)Game.NextFog.Color.G * fr);
         Game.CurrentFog.Color.B = (byte)((float)Game.PreviousFog.Color.B * frc + (float)Game.NextFog.Color.B * fr);
     } else {
         Game.CurrentFog = Game.PreviousFog;
     }
     // render background
     if (FogEnabled) {
         Gl.glDisable(Gl.GL_FOG); FogEnabled = false;
     }
     Gl.glDisable(Gl.GL_DEPTH_TEST);
     RenderBackground(dx, dy, dz, TimeElapsed);
     // fog
     double aa = Game.CurrentFog.Start;
     double bb = Game.CurrentFog.End;
     if (Game.CurrentFog.Start < Game.CurrentFog.End & Game.CurrentFog.Start < World.BackgroundImageDistance) {
         if (!FogEnabled) {
             Gl.glFogi(Gl.GL_FOG_MODE, Gl.GL_LINEAR);
         }
         Gl.glFogf(Gl.GL_FOG_START, Game.CurrentFog.Start);
         Gl.glFogf(Gl.GL_FOG_END, Game.CurrentFog.End);
         Gl.glFogfv(Gl.GL_FOG_COLOR, new float[] { inv255 * (float)Game.CurrentFog.Color.R, inv255 * (float)Game.CurrentFog.Color.G, inv255 * (float)Game.CurrentFog.Color.B, 1.0f });
         if (!FogEnabled) {
             Gl.glEnable(Gl.GL_FOG); FogEnabled = true;
         }
     } else if (FogEnabled) {
         Gl.glDisable(Gl.GL_FOG); FogEnabled = false;
     }
     // world layer
     bool optionLighting = OptionLighting;
     LastBoundTexture = null;
     if (OptionLighting) {
         if (!LightingEnabled) {
             Gl.glEnable(Gl.GL_LIGHTING); LightingEnabled = true;
         }
         if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) {
             Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, new float[] { inv255 * (float)OptionAmbientColor.R, inv255 * (float)OptionAmbientColor.G, inv255 * (float)OptionAmbientColor.B, 1.0f });
             Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, new float[] { inv255 * (float)OptionDiffuseColor.R, inv255 * (float)OptionDiffuseColor.G, inv255 * (float)OptionDiffuseColor.B, 1.0f });
         }
     } else if (LightingEnabled) {
         Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false;
     }
     // static opaque
     if (Interface.CurrentOptions.DisableDisplayLists) {
         ResetOpenGlState();
         for (int i = 0; i < StaticOpaque.Length; i++) {
             if (StaticOpaque[i] != null) {
                 if (StaticOpaque[i].List != null) {
                     for (int j = 0; j < StaticOpaque[i].List.FaceCount; j++) {
                         if (StaticOpaque[i].List.Faces[j] != null) {
                             RenderFace(ref StaticOpaque[i].List.Faces[j], cx, cy, cz);
                         }
                     }
                 }
             }
         }
     } else {
         for (int i = 0; i < StaticOpaque.Length; i++) {
             if (StaticOpaque[i] != null) {
                 if (StaticOpaque[i].Update | StaticOpaqueForceUpdate) {
                     StaticOpaque[i].Update = false;
                     if (StaticOpaque[i].OpenGlDisplayListAvailable) {
                         Gl.glDeleteLists(StaticOpaque[i].OpenGlDisplayList, 1);
                         StaticOpaque[i].OpenGlDisplayListAvailable = false;
                     }
                     if (StaticOpaque[i].List.FaceCount != 0) {
                         StaticOpaque[i].OpenGlDisplayList = Gl.glGenLists(1);
                         StaticOpaque[i].OpenGlDisplayListAvailable = true;
                         ResetOpenGlState();
                         Gl.glNewList(StaticOpaque[i].OpenGlDisplayList, Gl.GL_COMPILE);
                         for (int j = 0; j < StaticOpaque[i].List.FaceCount; j++) {
                             if (StaticOpaque[i].List.Faces[j] != null) {
                                 RenderFace(ref StaticOpaque[i].List.Faces[j], cx, cy, cz);
                             }
                         }
                         Gl.glEndList();
                     }
                     StaticOpaque[i].WorldPosition = World.AbsoluteCameraPosition;
                 }
             }
         }
         StaticOpaqueForceUpdate = false;
         for (int i = 0; i < StaticOpaque.Length; i++) {
             if (StaticOpaque[i] != null) {
                 if (StaticOpaque[i].OpenGlDisplayListAvailable) {
                     ResetOpenGlState();
                     Gl.glPushMatrix();
                     Gl.glTranslated(StaticOpaque[i].WorldPosition.X - World.AbsoluteCameraPosition.X, StaticOpaque[i].WorldPosition.Y - World.AbsoluteCameraPosition.Y, StaticOpaque[i].WorldPosition.Z - World.AbsoluteCameraPosition.Z);
                     Gl.glCallList(StaticOpaque[i].OpenGlDisplayList);
                     Gl.glPopMatrix();
                 }
             }
         }
     }
     // dynamic opaque
     ResetOpenGlState();
     for (int i = 0; i < DynamicOpaque.FaceCount; i++) {
         RenderFace(ref DynamicOpaque.Faces[i], cx, cy, cz);
     }
     // dynamic alpha
     ResetOpenGlState();
     SortPolygons(DynamicAlpha);
     if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) {
         Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
         Gl.glDepthMask(Gl.GL_FALSE);
         SetAlphaFunc(Gl.GL_GREATER, 0.0f);
         for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
             RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz);
         }
     } else {
         Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
         SetAlphaFunc(Gl.GL_EQUAL, 1.0f);
         Gl.glDepthMask(Gl.GL_TRUE);
         for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
             int r = (int)ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Faces[DynamicAlpha.Faces[i].FaceIndex].Material;
             if (ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Normal & ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) {
                 if (ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].Color.A == 255) {
                     RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz);
                 }
             }
         }
         Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
         SetAlphaFunc(Gl.GL_LESS, 1.0f);
         Gl.glDepthMask(Gl.GL_FALSE);
         bool additive = false;
         for (int i = 0; i < DynamicAlpha.FaceCount; i++) {
             int r = (int)ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Faces[DynamicAlpha.Faces[i].FaceIndex].Material;
             if (ObjectManager.Objects[DynamicAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Additive) {
                 if (!additive) {
                     UnsetAlphaFunc();
                     additive = true;
                 }
                 RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz);
             } else {
                 if (additive) {
                     SetAlphaFunc(Gl.GL_LESS, 1.0f);
                     additive = false;
                 }
                 RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz);
             }
         }
     }
     // motion blur
     Gl.glDisable(Gl.GL_DEPTH_TEST);
     Gl.glDepthMask(Gl.GL_FALSE);
     SetAlphaFunc(Gl.GL_GREATER, 0.0f);
     if (Interface.CurrentOptions.MotionBlur != Interface.MotionBlurMode.None) {
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING);
             LightingEnabled = false;
         }
         RenderFullscreenMotionBlur();
     }
     // overlay layer
     if (FogEnabled) {
         Gl.glDisable(Gl.GL_FOG); FogEnabled = false;
     }
     Gl.glLoadIdentity();
     MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.ChangeToCab);
     Glu.gluLookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz);
     if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) {
         // 3d cab
         ResetOpenGlState(); // TODO: inserted
         Gl.glDepthMask(Gl.GL_TRUE);
         Gl.glEnable(Gl.GL_DEPTH_TEST);
         Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);
         if (!LightingEnabled) {
             Gl.glEnable(Gl.GL_LIGHTING); LightingEnabled = true;
         }
         OptionLighting = true;
         Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, new float[] { 0.7f, 0.7f, 0.7f, 1.0f });
         Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, new float[] { 0.7f, 0.7f, 0.7f, 1.0f });
         // overlay opaque
         SetAlphaFunc(Gl.GL_GREATER, 0.9f);
         for (int i = 0; i < OverlayOpaque.FaceCount; i++) {
             RenderFace(ref OverlayOpaque.Faces[i], cx, cy, cz);
         }
         // overlay alpha
         SortPolygons(OverlayAlpha);
         if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) {
             Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
             Gl.glDepthMask(Gl.GL_FALSE);
             SetAlphaFunc(Gl.GL_GREATER, 0.0f);
             for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
                 RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
             }
         } else {
             Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
             SetAlphaFunc(Gl.GL_EQUAL, 1.0f);
             Gl.glDepthMask(Gl.GL_TRUE);
             for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
                 int r = (int)ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Faces[OverlayAlpha.Faces[i].FaceIndex].Material;
                 if (ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Normal & ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) {
                     if (ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].Color.A == 255) {
                         RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
                     }
                 }
             }
             Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
             SetAlphaFunc(Gl.GL_LESS, 1.0f);
             Gl.glDepthMask(Gl.GL_FALSE);
             bool additive = false;
             for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
                 int r = (int)ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Faces[OverlayAlpha.Faces[i].FaceIndex].Material;
                 if (ObjectManager.Objects[OverlayAlpha.Faces[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Additive) {
                     if (!additive) {
                         UnsetAlphaFunc();
                         additive = true;
                     }
                     RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
                 } else {
                     if (additive) {
                         SetAlphaFunc(Gl.GL_LESS, 1.0f);
                         additive = false;
                     }
                     RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
                 }
             }
         }
     } else {
         // not a 3d cab
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false; // TODO: was 'true' before
         }
         OptionLighting = false;
         if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND); BlendEnabled = true;
         }
         Gl.glDepthMask(Gl.GL_FALSE);
         Gl.glDisable(Gl.GL_DEPTH_TEST);
         UnsetAlphaFunc();
         SortPolygons(OverlayAlpha);
         for (int i = 0; i < OverlayAlpha.FaceCount; i++) {
             RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz);
         }
     }
     // render overlays
     OptionLighting = optionLighting;
     if (LightingEnabled) {
         Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false;
     }
     if (FogEnabled) {
         Gl.glDisable(Gl.GL_FOG); FogEnabled = false;
     }
     if (BlendEnabled) {
         Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
     }
     UnsetAlphaFunc();
     Gl.glDisable(Gl.GL_DEPTH_TEST);
     RenderOverlays(TimeElapsed);
     // finalize rendering
     Gl.glPopMatrix();
     LoadTexturesImmediately = LoadTextureImmediatelyMode.NoLonger;
 }
Пример #2
0
 // reset opengl state
 private static void ResetOpenGlState()
 {
     LastBoundTexture = null;
     Gl.glEnable(Gl.GL_CULL_FACE); CullEnabled = true;
     Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false;
     Gl.glDisable(Gl.GL_TEXTURE_2D); TexturingEnabled = false;
     Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
     Gl.glDisable(Gl.GL_BLEND); BlendEnabled = false;
     Gl.glEnable(Gl.GL_DEPTH_TEST);
     Gl.glDepthMask(Gl.GL_TRUE);
     Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f }); EmissiveEnabled = false;
     SetAlphaFunc(Gl.GL_GREATER, 0.9f);
 }
Пример #3
0
        private static void RenderFace(ref World.MeshMaterial Material, VertexTemplate[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
        {
            // texture
            if (Material.DaytimeTexture != null)
            {
                if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
                {
                    if (!TexturingEnabled)
                    {
                        GL.Enable(EnableCap.Texture2D);
                        TexturingEnabled = true;
                    }
                    if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
                    {
                        GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                        LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
                    }
                }
                else
                {
                    if (TexturingEnabled)
                    {
                        GL.Disable(EnableCap.Texture2D);
                        TexturingEnabled = false;
                        LastBoundTexture = null;
                    }
                }
            }
            else
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    LastBoundTexture = null;
                }
            }
            // blend mode
            float factor;

            if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
            {
                factor = 1.0f;
                if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
                if (FogEnabled)
                {
                    GL.Disable(EnableCap.Fog);
                }
            }
            else if (Material.NighttimeTexture == null)
            {
                float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                if (blend > 1.0f)
                {
                    blend = 1.0f;
                }
                factor = 1.0f - 0.7f * blend;
            }
            else
            {
                factor = 1.0f;
            }
            if (Material.NighttimeTexture != null)
            {
                if (LightingEnabled)
                {
                    GL.Disable(EnableCap.Lighting);
                    LightingEnabled = false;
                }
            }
            else
            {
                if (OptionLighting & !LightingEnabled)
                {
                    GL.Enable(EnableCap.Lighting);
                    LightingEnabled = true;
                }
            }
            // render daytime polygon
            int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;

            switch (FaceType)
            {
            case World.MeshFace.FaceTypeTriangles:
                GL.Begin(PrimitiveType.Triangles);
                break;

            case World.MeshFace.FaceTypeTriangleStrip:
                GL.Begin(PrimitiveType.TriangleStrip);
                break;

            case World.MeshFace.FaceTypeQuads:
                GL.Begin(PrimitiveType.Quads);
                break;

            case World.MeshFace.FaceTypeQuadStrip:
                GL.Begin(PrimitiveType.QuadStrip);
                break;

            default:
                GL.Begin(PrimitiveType.Polygon);
                break;
            }
            if (Material.GlowAttenuationData != 0)
            {
                float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
                }
            }
            else
            {
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
                }
            }
            if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
            {
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
            }
            else
            {
                GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
            }
            if (Material.DaytimeTexture != null)
            {
                if (LightingEnabled)
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                        GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
                else
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
            }
            else
            {
                if (LightingEnabled)
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
                else
                {
                    for (int j = 0; j < Face.Vertices.Length; j++)
                    {
                        if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                        {
                            ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                            GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                        }
                        GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    }
                }
            }
            GL.End();
            // render nighttime polygon
            if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap))
            {
                if (!TexturingEnabled)
                {
                    GL.Enable(EnableCap.Texture2D);
                    TexturingEnabled = true;
                }
                if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                }
                GL.BindTexture(TextureTarget.Texture2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
                LastBoundTexture = null;
                GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
                GL.Enable(EnableCap.AlphaTest);
                switch (FaceType)
                {
                case World.MeshFace.FaceTypeTriangles:
                    GL.Begin(PrimitiveType.Triangles);
                    break;

                case World.MeshFace.FaceTypeTriangleStrip:
                    GL.Begin(PrimitiveType.TriangleStrip);
                    break;

                case World.MeshFace.FaceTypeQuads:
                    GL.Begin(PrimitiveType.Quads);
                    break;

                case World.MeshFace.FaceTypeQuadStrip:
                    GL.Begin(PrimitiveType.QuadStrip);
                    break;

                default:
                    GL.Begin(PrimitiveType.Polygon);
                    break;
                }
                float alphafactor;
                if (Material.GlowAttenuationData != 0)
                {
                    alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
                    float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }
                    alphafactor *= blend;
                }
                else
                {
                    alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (alphafactor > 1.0f)
                    {
                        alphafactor = 1.0f;
                    }
                }
                if (OptionWireframe)
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, 1.0f);
                }
                else
                {
                    GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
                }

                if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
                }
                else
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                    if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                    {
                        ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                        GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                    }
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                }
                GL.End();
                RestoreAlphaFunc();
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
            }
            // normals
            if (OptionNormals)
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.Begin(PrimitiveType.Lines);
                    GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
                    GL.End();
                }
            }
            // finalize
            if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
            {
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
                if (FogEnabled)
                {
                    GL.Enable(EnableCap.Fog);
                }
            }
        }
Пример #4
0
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     if (Material.DaytimeTexture != null) {
         if (Textures.LoadTexture(Material.DaytimeTexture, wrap)) {
             if (!TexturingEnabled) {
                 Gl.glEnable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = true;
             }
             if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture) {
                 Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                 LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
             }
         } else {
             if (TexturingEnabled) {
                 Gl.glDisable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = false;
                 LastBoundTexture = null;
             }
         }
     } else {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
             LastBoundTexture = null;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         factor = 1.0f;
         if (!BlendEnabled) Gl.glEnable(Gl.GL_BLEND);
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE);
         if (FogEnabled) {
             Gl.glDisable(Gl.GL_FOG);
         }
     } else if (Material.NighttimeTexture == null) {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.7f * blend;
     } else {
         factor = 1.0f;
     }
     if (Material.NighttimeTexture != null) {
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING);
             LightingEnabled = false;
         }
     } else {
         if (OptionLighting & !LightingEnabled) {
             Gl.glEnable(Gl.GL_LIGHTING);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType) {
         case World.MeshFace.FaceTypeTriangles:
             Gl.glBegin(Gl.GL_TRIANGLES);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
             break;
         case World.MeshFace.FaceTypeQuads:
             Gl.glBegin(Gl.GL_QUADS);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             Gl.glBegin(Gl.GL_QUAD_STRIP);
             break;
         default:
             Gl.glBegin(Gl.GL_POLYGON);
             break;
     }
     if (Material.GlowAttenuationData != 0) {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     } else {
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     } else if (EmissiveEnabled) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (Material.DaytimeTexture != null) {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     } else {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     Gl.glEnd();
     // render nighttime polygon
     if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap)) {
         if (!TexturingEnabled) {
             Gl.glEnable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND);
         }
         Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
         LastBoundTexture = null;
         Gl.glAlphaFunc(Gl.GL_GREATER, 0.0f);
         Gl.glEnable(Gl.GL_ALPHA_TEST);
         switch (FaceType) {
             case World.MeshFace.FaceTypeTriangles:
                 Gl.glBegin(Gl.GL_TRIANGLES);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 Gl.glBegin(Gl.GL_QUADS);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 Gl.glBegin(Gl.GL_QUAD_STRIP);
                 break;
             default:
                 Gl.glBegin(Gl.GL_POLYGON);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0) {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         } else {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         } else if (EmissiveEnabled) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         Gl.glEnd();
         RestoreAlphaFunc();
         if (!BlendEnabled) {
             Gl.glDisable(Gl.GL_BLEND);
         }
     }
     // normals
     if (OptionNormals) {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glBegin(Gl.GL_LINES);
             Gl.glColor4f(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             Gl.glEnd();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
         if (!BlendEnabled) Gl.glDisable(Gl.GL_BLEND);
         if (FogEnabled) {
             Gl.glEnable(Gl.GL_FOG);
         }
     }
 }
Пример #5
0
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     if (Material.DaytimeTexture != null)
     {
         if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
         {
             if (!TexturingEnabled)
             {
                 GL.Enable(EnableCap.Texture2D);
                 TexturingEnabled = true;
             }
             if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
             {
                 GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                 LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
             }
         }
         else
         {
             if (TexturingEnabled)
             {
                 GL.Disable(EnableCap.Texture2D);
                 TexturingEnabled = false;
                 LastBoundTexture = null;
             }
         }
     }
     else
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
             LastBoundTexture = null;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         factor = 1.0f;
         if (!BlendEnabled) GL.Enable(EnableCap.Blend);
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
         if (FogEnabled)
         {
             GL.Disable(EnableCap.Fog);
         }
     }
     else if (Material.NighttimeTexture == null)
     {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.7f * blend;
     }
     else
     {
         factor = 1.0f;
     }
     if (Material.NighttimeTexture != null)
     {
         if (LightingEnabled)
         {
             GL.Disable(EnableCap.Lighting);
             LightingEnabled = false;
         }
     }
     else
     {
         if (OptionLighting & !LightingEnabled)
         {
             GL.Enable(EnableCap.Lighting);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType)
     {
         case World.MeshFace.FaceTypeTriangles:
             GL.Begin(PrimitiveType.Triangles);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             GL.Begin(PrimitiveType.TriangleStrip);
             break;
         case World.MeshFace.FaceTypeQuads:
             GL.Begin(PrimitiveType.Quads);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             GL.Begin(PrimitiveType.QuadStrip);
             break;
         default:
             GL.Begin(PrimitiveType.Polygon);
             break;
     }
     if (Material.GlowAttenuationData != 0)
     {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     }
     else
     {
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     }
     else if (EmissiveEnabled)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (Material.DaytimeTexture != null)
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     else
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     GL.End();
     // render nighttime polygon
     if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap))
     {
         if (!TexturingEnabled)
         {
             GL.Enable(EnableCap.Texture2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled)
         {
             GL.Enable(EnableCap.Blend);
         }
         GL.BindTexture(TextureTarget.Texture2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
         LastBoundTexture = null;
         GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
         GL.Enable(EnableCap.AlphaTest);
         switch (FaceType)
         {
             case World.MeshFace.FaceTypeTriangles:
                 GL.Begin(PrimitiveType.Triangles);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 GL.Begin(PrimitiveType.TriangleStrip);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 GL.Begin(PrimitiveType.Quads);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 GL.Begin(PrimitiveType.QuadStrip);
                 break;
             default:
                 GL.Begin(PrimitiveType.Polygon);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0)
         {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         }
         else
         {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         }
         else if (EmissiveEnabled)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         GL.End();
         RestoreAlphaFunc();
         if (!BlendEnabled)
         {
             GL.Disable(EnableCap.Blend);
         }
     }
     // normals
     if (OptionNormals)
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.Begin(PrimitiveType.Lines);
             GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             GL.End();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
         if (!BlendEnabled) GL.Disable(EnableCap.Blend);
         if (FogEnabled)
         {
             GL.Enable(EnableCap.Fog);
         }
     }
 }