// reset internal static void Reset() { LoadTexturesImmediately = LoadTextureImmediatelyMode.NotYet; ObjectList = new Object[256]; ObjectListCount = 0; OpaqueList = new ObjectFace[256]; OpaqueListCount = 0; TransparentColorList = new ObjectFace[256]; TransparentColorListDistance = new double[256]; TransparentColorListCount = 0; AlphaList = new ObjectFace[256]; AlphaListDistance = new double[256]; AlphaListCount = 0; OverlayList = new ObjectFace[256]; OverlayListDistance = new double[256]; OverlayListCount = 0; LibRender.Renderer.OptionLighting = true; LibRender.Renderer.OptionAmbientColor = new Color24(160, 160, 160); LibRender.Renderer.OptionDiffuseColor = new Color24(160, 160, 160); LibRender.Renderer.OptionLightPosition = new Vector3(0.215920077052065f, 0.875724044222352f, -0.431840154104129f); LibRender.Renderer.OptionLightingResultingAmount = 1.0f; GL.Disable(EnableCap.Fog); LibRender.Renderer.FogEnabled = false; }
// reset internal static void Reset() { LoadTexturesImmediately = LoadTextureImmediatelyMode.NotYet; Objects = new Object[256]; ObjectCount = 0; StaticOpaque = new ObjectGroup[] { }; StaticOpaqueForceUpdate = true; DynamicOpaque = new ObjectList(); DynamicAlpha = new ObjectList(); OverlayOpaque = new ObjectList(); OverlayAlpha = new ObjectList(); OptionLighting = true; OptionAmbientColor = new Color24(160, 160, 160); OptionDiffuseColor = new Color24(160, 160, 160); OptionLightPosition = new World.Vector3Df(0.223606797749979f, 0.86602540378444f, -0.447213595499958f); OptionLightingResultingAmount = 1.0f; OptionClock = false; OptionBrakeSystems = false; }
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; }
internal static void RenderScene(double TimeElapsed) { // initialize ResetOpenGlState(); int OpenGlTextureIndex = 0; 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.ClearColor(cr, cg, cb, 1.0f); } else { GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); } GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } else { GL.Clear(ClearBufferMask.DepthBufferBit); } GL.PushMatrix(); 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; Matrix4d lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); GL.Light(LightName.Light0, LightParameter.Position, new float[] { (float)OptionLightPosition.X, (float)OptionLightPosition.Y, (float)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.Disable(EnableCap.Fog); FogEnabled = false; } GL.Disable(EnableCap.DepthTest); UpdateBackground(TimeElapsed); RenderEvents(World.AbsoluteCameraPosition); // fog float aa = Game.CurrentFog.Start; float bb = Game.CurrentFog.End; if (aa < bb & aa < World.BackgroundImageDistance) { if (!FogEnabled) { GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); } GL.Fog(FogParameter.FogStart, aa); GL.Fog(FogParameter.FogEnd, bb); GL.Fog(FogParameter.FogColor, 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.Enable(EnableCap.Fog); FogEnabled = true; } } else if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } // world layer bool optionLighting = OptionLighting; LastBoundTexture = null; if (OptionLighting) { if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { GL.Light(LightName.Light0, LightParameter.Ambient, new float[] { inv255 *(float)OptionAmbientColor.R, inv255 * (float)OptionAmbientColor.G, inv255 * (float)OptionAmbientColor.B, 1.0f }); GL.Light(LightName.Light0, LightParameter.Diffuse, new float[] { inv255 *(float)OptionDiffuseColor.R, inv255 * (float)OptionDiffuseColor.G, inv255 * (float)OptionDiffuseColor.B, 1.0f }); } } else if (LightingEnabled) { GL.Disable(EnableCap.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.DeleteLists(StaticOpaque[i].OpenGlDisplayList, 1); StaticOpaque[i].OpenGlDisplayListAvailable = false; } if (StaticOpaque[i].List.FaceCount != 0) { StaticOpaque[i].OpenGlDisplayList = GL.GenLists(1); StaticOpaque[i].OpenGlDisplayListAvailable = true; ResetOpenGlState(); GL.NewList(StaticOpaque[i].OpenGlDisplayList, ListMode.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.EndList(); } StaticOpaque[i].WorldPosition = World.AbsoluteCameraPosition; } } } StaticOpaqueForceUpdate = false; for (int i = 0; i < StaticOpaque.Length; i++) { if (StaticOpaque[i] != null && StaticOpaque[i].OpenGlDisplayListAvailable) { ResetOpenGlState(); GL.PushMatrix(); GL.Translate(StaticOpaque[i].WorldPosition.X - World.AbsoluteCameraPosition.X, StaticOpaque[i].WorldPosition.Y - World.AbsoluteCameraPosition.Y, StaticOpaque[i].WorldPosition.Z - World.AbsoluteCameraPosition.Z); GL.CallList(StaticOpaque[i].OpenGlDisplayList); GL.PopMatrix(); } } //Update bounding box positions now we've rendered the objects int currentBox = 0; for (int i = 0; i < StaticOpaque.Length; i++) { if (StaticOpaque[i] != null) { currentBox++; } } } // 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.Enable(EnableCap.Blend); BlendEnabled = true; GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < DynamicAlpha.FaceCount; i++) { RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz); } } else { GL.Disable(EnableCap.Blend); BlendEnabled = false; SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(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.Enable(EnableCap.Blend); BlendEnabled = true; SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(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(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz); } } } // motion blur GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); if (Interface.CurrentOptions.MotionBlur != Interface.MotionBlurMode.None) { if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } RenderFullscreenMotionBlur(); } // overlay layer if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } GL.LoadIdentity(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.ChangeToCab); lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { // 3d cab ResetOpenGlState(); // TODO: inserted GL.DepthMask(true); GL.Enable(EnableCap.DepthTest); GL.Clear(ClearBufferMask.DepthBufferBit); if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } OptionLighting = true; GL.Light(LightName.Light0, LightParameter.Ambient, new float[] { 0.7f, 0.7f, 0.7f, 1.0f }); GL.Light(LightName.Light0, LightParameter.Diffuse, new float[] { 0.7f, 0.7f, 0.7f, 1.0f }); // overlay opaque SetAlphaFunc(AlphaFunction.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.Enable(EnableCap.Blend); BlendEnabled = true; GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < OverlayAlpha.FaceCount; i++) { RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz); } } else { GL.Disable(EnableCap.Blend); BlendEnabled = false; SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(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.Enable(EnableCap.Blend); BlendEnabled = true; SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(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(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz); } } } } else { /* * Render 2D Cab * This is actually an animated object generated on the fly and held in memory */ if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; // TODO: was 'true' before } OptionLighting = false; if (!BlendEnabled) { GL.Enable(EnableCap.Blend); BlendEnabled = true; } GL.DepthMask(false); GL.Disable(EnableCap.DepthTest); 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.Disable(EnableCap.Lighting); LightingEnabled = false; } if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } if (BlendEnabled) { GL.Disable(EnableCap.Blend); BlendEnabled = false; } UnsetAlphaFunc(); GL.Disable(EnableCap.DepthTest); RenderOverlays(TimeElapsed); // finalize rendering GL.PopMatrix(); LoadTexturesImmediately = LoadTextureImmediatelyMode.NoLonger; }
internal static void RenderScene() { // initialize GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.PushMatrix(); if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) { LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes; ReAddObjects(); } // setup 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; var mat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MultMatrix(ref mat); if (OptionLighting) { GL.Light(LightName.Light0, LightParameter.Position, new float[] { OptionLightPosition.X, OptionLightPosition.Y, OptionLightPosition.Z, 0.0f }); } // render polygons GL.Disable(EnableCap.DepthTest); if (OptionLighting) { if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } } else if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } GL.AlphaFunc(AlphaFunction.Greater, 0.0f); BlendEnabled = false; GL.Disable(EnableCap.Blend); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); LastBoundTexture = 0; // opaque list if (OptionCoordinateSystem) { if (LightingEnabled) { GL.Disable(EnableCap.Lighting); } GL.Color3(1.0, 0.0, 0.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(100.0, 0.01, 0.01), cx, cy, cz); GL.Color3(0.0, 1.0, 0.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 100.0, 0.01), cx, cy, cz); GL.Color3(0.0, 0.0, 1.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 0.01, 100.0), cx, cy, cz); if (LightingEnabled) { GL.Enable(EnableCap.Lighting); } } for (int i = 0; i < OpaqueListCount; i++) { RenderFace(ref OpaqueList[i], cx, cy, cz); } // transparent color list if (TransparentColorDepthSorting) { SortPolygons(TransparentColorList, TransparentColorListCount, TransparentColorListDistance, 1, 0.0); BlendEnabled = true; GL.Enable(EnableCap.Blend); for (int i = 0; i < TransparentColorListCount; i++) { GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Less, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); GL.DepthMask(true); SetAlphaFunc(AlphaFunction.Equal, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); } } else { for (int i = 0; i < TransparentColorListCount; i++) { RenderFace(ref TransparentColorList[i], cx, cy, cz); } } // alpha list SortPolygons(AlphaList, AlphaListCount, AlphaListDistance, 2, 0.0); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Smooth) { BlendEnabled = true; GL.Enable(EnableCap.Blend); bool depthMask = true; for (int i = 0; i < AlphaListCount; i++) { int r = (int)ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Faces[AlphaList[i].FaceIndex].Material; if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Additive) { if (depthMask) { GL.DepthMask(false); depthMask = false; } SetAlphaFunc(AlphaFunction.Greater, 0.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } else { if (depthMask) { GL.DepthMask(false); depthMask = false; } SetAlphaFunc(AlphaFunction.Less, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); GL.DepthMask(true); depthMask = true; SetAlphaFunc(AlphaFunction.Equal, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } } } else { BlendEnabled = true; GL.Enable(EnableCap.Blend); GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < AlphaListCount; i++) { RenderFace(ref AlphaList[i], cx, cy, cz); } } // overlay list GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } SortPolygons(OverlayList, OverlayListCount, OverlayListDistance, 3, 0.0); for (int i = 0; i < OverlayListCount; i++) { RenderFace(ref OverlayList[i], cx, cy, cz); } // render overlays BlendEnabled = false; GL.Disable(EnableCap.Blend); SetAlphaFunc(AlphaFunction.Greater, 0.9f); AlphaTestEnabled = false; GL.Disable(EnableCap.AlphaTest); GL.Disable(EnableCap.DepthTest); if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } if (OptionCoordinateSystem) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Enable(EnableCap.Blend); GL.Color4(1.0, 0.0, 0.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(100.0, 0.01, 0.01), cx, cy, cz); GL.Color4(0.0, 1.0, 0.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 100.0, 0.01), cx, cy, cz); GL.Color4(0.0, 0.0, 1.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 0.01, 100.0), cx, cy, cz); } RenderOverlays(); // finalize rendering GL.PopMatrix(); }
// reset internal static void Reset() { LoadTexturesImmediately = LoadTextureImmediatelyMode.NotYet; ObjectList = new Object[256]; ObjectListCount = 0; OpaqueList = new ObjectFace[256]; OpaqueListCount = 0; TransparentColorList = new ObjectFace[256]; TransparentColorListDistance = new double[256]; TransparentColorListCount = 0; AlphaList = new ObjectFace[256]; AlphaListDistance = new double[256]; AlphaListCount = 0; OverlayList = new ObjectFace[256]; OverlayListDistance = new double[256]; OverlayListCount = 0; OptionLighting = true; OptionAmbientColor = new World.ColorRGB(160, 160, 160); OptionDiffuseColor = new World.ColorRGB(160, 160, 160); OptionLightPosition = new World.Vector3Df(0.215920077052065f, 0.875724044222352f, -0.431840154104129f); OptionLightingResultingAmount = 1.0f; GL.Disable(EnableCap.Fog); FogEnabled = false; }
internal static void RenderScene() { // initialize Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_TRUE); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glPushMatrix(); if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) { LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes; ReAddObjects(); } // setup 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); if (OptionLighting) { Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, new float[] { OptionLightPosition.X, OptionLightPosition.Y, OptionLightPosition.Z, 0.0f }); } // render polygons Gl.glDisable(Gl.GL_DEPTH_TEST); if (OptionLighting) { if (!LightingEnabled) { Gl.glEnable(Gl.GL_LIGHTING); LightingEnabled = true; } } else if (LightingEnabled) { Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false; } Gl.glAlphaFunc(Gl.GL_GREATER, 0.0f); BlendEnabled = false; Gl.glDisable(Gl.GL_BLEND); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_TRUE); LastBoundTexture = 0; // opaque list if (OptionCoordinateSystem) { if (LightingEnabled) { Gl.glDisable(Gl.GL_LIGHTING); } Gl.glColor3d(1.0, 0.0, 0.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(100.0, 0.01, 0.01), cx, cy, cz); Gl.glColor3d(0.0, 1.0, 0.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 100.0, 0.01), cx, cy, cz); Gl.glColor3d(0.0, 0.0, 1.0); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 0.01, 100.0), cx, cy, cz); if (LightingEnabled) { Gl.glEnable(Gl.GL_LIGHTING); } } for (int i = 0; i < OpaqueListCount; i++) { RenderFace(ref OpaqueList[i], cx, cy, cz); } // transparent color list if (TransparentColorDepthSorting) { SetAlphaFunc(Gl.GL_GREATER, 0.0f); BlendEnabled = true; Gl.glEnable(Gl.GL_BLEND); SortPolygons(TransparentColorList, TransparentColorListCount, TransparentColorListDistance, 1, 0.0); } for (int i = 0; i < TransparentColorListCount; i++) { RenderFace(ref TransparentColorList[i], cx, cy, cz); } // alpha list if (!TransparentColorDepthSorting) { SetAlphaFunc(Gl.GL_GREATER, 0.0f); BlendEnabled = true; Gl.glEnable(Gl.GL_BLEND); } Gl.glDepthMask(Gl.GL_FALSE); SortPolygons(AlphaList, AlphaListCount, AlphaListDistance, 2, 0.0); for (int i = 0; i < AlphaListCount; i++) { RenderFace(ref AlphaList[i], cx, cy, cz); } // overlay list Gl.glDisable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_FALSE); if (FogEnabled) { Gl.glDisable(Gl.GL_FOG); FogEnabled = false; } SortPolygons(OverlayList, OverlayListCount, OverlayListDistance, 3, 0.0); for (int i = 0; i < OverlayListCount; i++) { RenderFace(ref OverlayList[i], cx, cy, cz); } // render overlays BlendEnabled = false; Gl.glDisable(Gl.GL_BLEND); SetAlphaFunc(Gl.GL_GREATER, 0.9f); AlphaTestEnabled = false; Gl.glDisable(Gl.GL_ALPHA_TEST); Gl.glDisable(Gl.GL_DEPTH_TEST); if (LightingEnabled) { Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false; } if (OptionCoordinateSystem) { Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); Gl.glEnable(Gl.GL_BLEND); Gl.glColor4d(1.0, 0.0, 0.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(100.0, 0.01, 0.01), cx, cy, cz); Gl.glColor4d(0.0, 1.0, 0.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 100.0, 0.01), cx, cy, cz); Gl.glColor4d(0.0, 0.0, 1.0, 0.2); RenderBox(new World.Vector3D(0.0, 0.0, 0.0), new World.Vector3D(0.0, 0.0, 1.0), new World.Vector3D(0.0, 1.0, 0.0), new World.Vector3D(1.0, 0.0, 0.0), new World.Vector3D(0.01, 0.01, 100.0), cx, cy, cz); } RenderOverlays(); // finalize rendering Gl.glPopMatrix(); }
internal static void RenderScene(double TimeElapsed) { // initialize ResetOpenGlState(); int OpenGlTextureIndex = 0; 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.ClearColor(cr, cg, cb, 1.0f); } else { GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); } GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } else { GL.Clear(ClearBufferMask.DepthBufferBit); } GL.PushMatrix(); 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; Matrix4d lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); GL.Light(LightName.Light0, LightParameter.Position, new float[] { (float) OptionLightPosition.X, (float) OptionLightPosition.Y, (float) 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.Disable(EnableCap.Fog); FogEnabled = false; } GL.Disable(EnableCap.DepthTest); UpdateBackground(TimeElapsed); // fog float aa = Game.CurrentFog.Start; float bb = Game.CurrentFog.End; if (aa < bb & aa < World.BackgroundImageDistance) { if (!FogEnabled) { GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); } GL.Fog(FogParameter.FogStart, aa); GL.Fog(FogParameter.FogEnd, bb); GL.Fog(FogParameter.FogColor, 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.Enable(EnableCap.Fog); FogEnabled = true; } } else if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } // world layer bool optionLighting = OptionLighting; LastBoundTexture = null; if (OptionLighting) { if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) { GL.Light(LightName.Light0, LightParameter.Ambient, new float[] { inv255 * (float)OptionAmbientColor.R, inv255 * (float)OptionAmbientColor.G, inv255 * (float)OptionAmbientColor.B, 1.0f }); GL.Light(LightName.Light0, LightParameter.Diffuse, new float[] { inv255 * (float)OptionDiffuseColor.R, inv255 * (float)OptionDiffuseColor.G, inv255 * (float)OptionDiffuseColor.B, 1.0f }); } } else if (LightingEnabled) { GL.Disable(EnableCap.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.DeleteLists(StaticOpaque[i].OpenGlDisplayList, 1); StaticOpaque[i].OpenGlDisplayListAvailable = false; } if (StaticOpaque[i].List.FaceCount != 0) { StaticOpaque[i].OpenGlDisplayList = GL.GenLists(1); StaticOpaque[i].OpenGlDisplayListAvailable = true; ResetOpenGlState(); GL.NewList(StaticOpaque[i].OpenGlDisplayList, ListMode.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.EndList(); } StaticOpaque[i].WorldPosition = World.AbsoluteCameraPosition; } } } StaticOpaqueForceUpdate = false; for (int i = 0; i < StaticOpaque.Length; i++) { if (StaticOpaque[i] != null && StaticOpaque[i].OpenGlDisplayListAvailable) { ResetOpenGlState(); GL.PushMatrix(); GL.Translate(StaticOpaque[i].WorldPosition.X - World.AbsoluteCameraPosition.X, StaticOpaque[i].WorldPosition.Y - World.AbsoluteCameraPosition.Y, StaticOpaque[i].WorldPosition.Z - World.AbsoluteCameraPosition.Z); GL.CallList(StaticOpaque[i].OpenGlDisplayList); GL.PopMatrix(); } } //Update bounding box positions now we've rendered the objects int currentBox = 0; for (int i = 0; i < StaticOpaque.Length; i++) { if (StaticOpaque[i] != null) { currentBox++; } } } // 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.Enable(EnableCap.Blend); BlendEnabled = true; GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < DynamicAlpha.FaceCount; i++) { RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz); } } else { GL.Disable(EnableCap.Blend); BlendEnabled = false; SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(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.Enable(EnableCap.Blend); BlendEnabled = true; SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(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(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref DynamicAlpha.Faces[i], cx, cy, cz); } } } // motion blur GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); if (Interface.CurrentOptions.MotionBlur != Interface.MotionBlurMode.None) { if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } RenderFullscreenMotionBlur(); } // overlay layer if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } GL.LoadIdentity(); MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.ChangeToCab); lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) { // 3d cab ResetOpenGlState(); // TODO: inserted GL.DepthMask(true); GL.Enable(EnableCap.DepthTest); GL.Clear(ClearBufferMask.DepthBufferBit); if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } OptionLighting = true; GL.Light(LightName.Light0, LightParameter.Ambient, new float[] { 0.7f, 0.7f, 0.7f, 1.0f }); GL.Light(LightName.Light0, LightParameter.Diffuse, new float[] { 0.7f, 0.7f, 0.7f, 1.0f }); // overlay opaque SetAlphaFunc(AlphaFunction.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.Enable(EnableCap.Blend); BlendEnabled = true; GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < OverlayAlpha.FaceCount; i++) { RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz); } } else { GL.Disable(EnableCap.Blend); BlendEnabled = false; SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(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.Enable(EnableCap.Blend); BlendEnabled = true; SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(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(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref OverlayAlpha.Faces[i], cx, cy, cz); } } } } else { /* * Render 2D Cab * This is actually an animated object generated on the fly and held in memory */ if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; // TODO: was 'true' before } OptionLighting = false; if (!BlendEnabled) { GL.Enable(EnableCap.Blend); BlendEnabled = true; } GL.DepthMask(false); GL.Disable(EnableCap.DepthTest); 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.Disable(EnableCap.Lighting); LightingEnabled = false; } if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } if (BlendEnabled) { GL.Disable(EnableCap.Blend); BlendEnabled = false; } UnsetAlphaFunc(); GL.Disable(EnableCap.DepthTest); RenderOverlays(TimeElapsed); // finalize rendering GL.PopMatrix(); LoadTexturesImmediately = LoadTextureImmediatelyMode.NoLonger; }
internal static void RenderScene() { // initialize GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.PushMatrix(); if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) { LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes; ReAddObjects(); } // setup camera var mat = Matrix4d.LookAt(0.0, 0.0, 0.0, Camera.AbsoluteDirection.X, Camera.AbsoluteDirection.Y, Camera.AbsoluteDirection.Z, Camera.AbsoluteUp.X, Camera.AbsoluteUp.Y, Camera.AbsoluteUp.Z); GL.MultMatrix(ref mat); if (LibRender.Renderer.OptionLighting) { GL.Light(LightName.Light0, LightParameter.Position, new float[] { (float)LibRender.Renderer.OptionLightPosition.X, (float)LibRender.Renderer.OptionLightPosition.Y, (float)LibRender.Renderer.OptionLightPosition.Z, 0.0f }); } // render polygons GL.Disable(EnableCap.DepthTest); if (LibRender.Renderer.OptionLighting) { if (!LibRender.Renderer.LightingEnabled) { GL.Enable(EnableCap.Lighting); LibRender.Renderer.LightingEnabled = true; } } else if (LibRender.Renderer.LightingEnabled) { GL.Disable(EnableCap.Lighting); LibRender.Renderer.LightingEnabled = false; } GL.AlphaFunc(AlphaFunction.Greater, 0.0f); LibRender.Renderer.BlendEnabled = false; GL.Disable(EnableCap.Blend); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); //LastBoundTexture = 0; // opaque list if (OptionCoordinateSystem) { if (LibRender.Renderer.LightingEnabled) { GL.Disable(EnableCap.Lighting); } GL.Color3(1.0, 0.0, 0.0); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(100.0, 0.01, 0.01), Camera.AbsolutePosition, null); GL.Color3(0.0, 1.0, 0.0); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 100.0, 0.01), Camera.AbsolutePosition, null); GL.Color3(0.0, 0.0, 1.0); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 0.01, 100.0), Camera.AbsolutePosition, null); if (LibRender.Renderer.LightingEnabled) { GL.Enable(EnableCap.Lighting); } } LibRender.Renderer.ResetOpenGlState(); for (int i = 0; i < OpaqueListCount; i++) { RenderFace(ref OpaqueList[i], Camera.AbsolutePosition); } LibRender.Renderer.ResetOpenGlState(); // transparent color list SortPolygons(TransparentColorList, TransparentColorListCount, TransparentColorListDistance, 1, 0.0); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality) { GL.Disable(EnableCap.Blend); LibRender.Renderer.BlendEnabled = false; LibRender.Renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(true); for (int i = 0; i < TransparentColorListCount; i++) { int r = (int)ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Faces[TransparentColorList[i].FaceIndex].Material; if (ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Materials[r].BlendMode == MeshMaterialBlendMode.Normal & ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) { if (ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Materials[r].Color.A == 255) { RenderFace(ref TransparentColorList[i], Camera.AbsolutePosition); } } } GL.Enable(EnableCap.Blend); LibRender.Renderer.BlendEnabled = true; LibRender.Renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(false); bool additive = false; for (int i = 0; i < TransparentColorListCount; i++) { int r = (int)ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Faces[TransparentColorList[i].FaceIndex].Material; if (ObjectManager.Objects[TransparentColorList[i].ObjectIndex].Mesh.Materials[r].BlendMode == MeshMaterialBlendMode.Additive) { if (!additive) { LibRender.Renderer.AlphaTestEnabled = false; GL.Disable(EnableCap.AlphaTest); additive = true; } RenderFace(ref TransparentColorList[i], Camera.AbsolutePosition); } else { if (additive) { LibRender.Renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref TransparentColorList[i], Camera.AbsolutePosition); } } } else { for (int i = 0; i < TransparentColorListCount; i++) { RenderFace(ref TransparentColorList[i], Camera.AbsolutePosition); } } LibRender.Renderer.ResetOpenGlState(); SortPolygons(AlphaList, AlphaListCount, AlphaListDistance, 2, 0.0); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance) { GL.Enable(EnableCap.Blend); LibRender.Renderer.BlendEnabled = true; GL.DepthMask(false); LibRender.Renderer.SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < AlphaListCount; i++) { RenderFace(ref AlphaList[i], Camera.AbsolutePosition); } } else { GL.Disable(EnableCap.Blend); LibRender.Renderer.BlendEnabled = false; LibRender.Renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(true); for (int i = 0; i < AlphaListCount; i++) { int r = (int)ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Faces[AlphaList[i].FaceIndex].Material; if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].BlendMode == MeshMaterialBlendMode.Normal & ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].GlowAttenuationData == 0) { if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].Color.A == 255) { RenderFace(ref AlphaList[i], Camera.AbsolutePosition); } } } GL.Enable(EnableCap.Blend); LibRender.Renderer.BlendEnabled = true; LibRender.Renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(false); bool additive = false; for (int i = 0; i < AlphaListCount; i++) { int r = (int)ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Faces[AlphaList[i].FaceIndex].Material; if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].BlendMode == MeshMaterialBlendMode.Additive) { if (!additive) { LibRender.Renderer.AlphaTestEnabled = false; GL.Disable(EnableCap.AlphaTest); additive = true; } RenderFace(ref AlphaList[i], Camera.AbsolutePosition); } else { if (additive) { LibRender.Renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); additive = false; } RenderFace(ref AlphaList[i], Camera.AbsolutePosition); } } } // overlay list GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); if (LibRender.Renderer.FogEnabled) { GL.Disable(EnableCap.Fog); LibRender.Renderer.FogEnabled = false; } SortPolygons(OverlayList, OverlayListCount, OverlayListDistance, 3, 0.0); for (int i = 0; i < OverlayListCount; i++) { RenderFace(ref OverlayList[i], Camera.AbsolutePosition); } // render overlays LibRender.Renderer.BlendEnabled = false; GL.Disable(EnableCap.Blend); LibRender.Renderer.SetAlphaFunc(AlphaFunction.Greater, 0.9f); LibRender.Renderer.AlphaTestEnabled = false; GL.Disable(EnableCap.AlphaTest); GL.Disable(EnableCap.DepthTest); if (LibRender.Renderer.LightingEnabled) { GL.Disable(EnableCap.Lighting); LibRender.Renderer.LightingEnabled = false; } if (OptionCoordinateSystem) { GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Enable(EnableCap.Blend); GL.Color4(1.0, 0.0, 0.0, 0.2); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(100.0, 0.01, 0.01), Camera.AbsolutePosition, null); GL.Color4(0.0, 1.0, 0.0, 0.2); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 100.0, 0.01), Camera.AbsolutePosition, null); GL.Color4(0.0, 0.0, 1.0, 0.2); LibRender.Renderer.DrawCube(Vector3.Zero, Vector3.Forward, Vector3.Down, Vector3.Right, new Vector3(0.01, 0.01, 100.0), Camera.AbsolutePosition, null); } RenderOverlays(); LibRender.Renderer.LastBoundTexture = null; //We bind the character texture, so must reset it at the end of the render sequence // finalize rendering GL.PopMatrix(); }
internal static void RenderScene(double TimeElapsed) { // initialize Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_TRUE); if (OptionWireframe | World.CurrentBackground.Texture == -1) { Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); } else { int OpenGlTextureIndex = TextureManager.UseTexture(World.CurrentBackground.Texture, TextureManager.UseMode.Normal); if (OpenGlTextureIndex > 0) { Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT); } else { Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); } } Gl.glPushMatrix(); if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) { LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes; ReAddObjects(); } // setup 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); if (OptionLighting) { 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 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; } Gl.glClearColor(inv255 * (float)Game.CurrentFog.Color.R, inv255 * (float)Game.CurrentFog.Color.G, inv255 * (float)Game.CurrentFog.Color.B, 1.0f); } else if (FogEnabled) { Gl.glDisable(Gl.GL_FOG); FogEnabled = false; } // render background Gl.glDisable(Gl.GL_DEPTH_TEST); RenderBackground(dx, dy, dz, TimeElapsed); // render polygons if (OptionLighting) { if (!LightingEnabled) { Gl.glEnable(Gl.GL_LIGHTING); LightingEnabled = true; } } else if (LightingEnabled) { Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false; } SetAlphaFunc(Gl.GL_GREATER, 0.9f); BlendEnabled = false; Gl.glDisable(Gl.GL_BLEND); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_TRUE); LastBoundTexture = 0; // opaque list for (int i = 0; i < OpaqueListCount; i++) { RenderFace(ref OpaqueList[i], cx, cy, cz); } // events if (OptionEvents) RenderEvents(cx, cy, cz); // transparent color list if (TransparentColorDepthSorting) { SortPolygons(TransparentColorList, TransparentColorListCount, TransparentColorListDistance, 1, TimeElapsed); BlendEnabled = true; Gl.glEnable(Gl.GL_BLEND); for (int i = 0; i < TransparentColorListCount; i++) { Gl.glDepthMask(Gl.GL_FALSE); SetAlphaFunc(Gl.GL_LESS, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); Gl.glDepthMask(Gl.GL_TRUE); SetAlphaFunc(Gl.GL_EQUAL, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); } } else { for (int i = 0; i < TransparentColorListCount; i++) { RenderFace(ref TransparentColorList[i], cx, cy, cz); } } // alpha list SortPolygons(AlphaList, AlphaListCount, AlphaListDistance, 2, TimeElapsed); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Smooth) { BlendEnabled = true; Gl.glEnable(Gl.GL_BLEND); bool depthMask = true; for (int i = 0; i < AlphaListCount; i++) { int r = (int)ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Faces[AlphaList[i].FaceIndex].Material; if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Additive) { if (depthMask) { Gl.glDepthMask(Gl.GL_FALSE); depthMask = false; } SetAlphaFunc(Gl.GL_GREATER, 0.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } else { if (depthMask) { Gl.glDepthMask(Gl.GL_FALSE); depthMask = false; } SetAlphaFunc(Gl.GL_LESS, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); Gl.glDepthMask(Gl.GL_TRUE); depthMask = true; SetAlphaFunc(Gl.GL_EQUAL, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } } } else { BlendEnabled = true; Gl.glEnable(Gl.GL_BLEND); Gl.glDepthMask(Gl.GL_FALSE); SetAlphaFunc(Gl.GL_GREATER, 0.0f); for (int i = 0; i < AlphaListCount; i++) { RenderFace(ref AlphaList[i], cx, cy, cz); } } // overlay list Gl.glDisable(Gl.GL_DEPTH_TEST); Gl.glDepthMask(Gl.GL_FALSE); if (FogEnabled) { Gl.glDisable(Gl.GL_FOG); FogEnabled = false; } SortPolygons(OverlayList, OverlayListCount, OverlayListDistance, 3, TimeElapsed); for (int i = 0; i < OverlayListCount; i++) { RenderFace(ref OverlayList[i], cx, cy, cz); } // render overlays BlendEnabled = false; Gl.glDisable(Gl.GL_BLEND); SetAlphaFunc(Gl.GL_GREATER, 0.9f); AlphaTestEnabled = false; Gl.glDisable(Gl.GL_ALPHA_TEST); Gl.glDisable(Gl.GL_DEPTH_TEST); if (LightingEnabled) { Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false; } RenderOverlays(TimeElapsed); // finalize rendering Gl.glPopMatrix(); }
internal static void RenderScene(double TimeElapsed) { // initialize GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); if (OptionWireframe | World.CurrentBackground.Texture == -1) { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } else { int OpenGlTextureIndex = TextureManager.UseTexture(World.CurrentBackground.Texture, TextureManager.UseMode.Normal); if (OpenGlTextureIndex > 0) { GL.Clear(ClearBufferMask.DepthBufferBit); } else { GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); } } GL.PushMatrix(); if (LoadTexturesImmediately == LoadTextureImmediatelyMode.NotYet) { LoadTexturesImmediately = LoadTextureImmediatelyMode.Yes; ReAddObjects(); } // setup 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; Matrix4d lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); //TODO: May be required GL.LoadMatrix(ref lookat); //Glu.gluLookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); if (OptionLighting) { GL.Light(LightName.Light0, LightParameter.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.Disable(EnableCap.Fog); FogEnabled = false; } GL.Disable(EnableCap.DepthTest); RenderBackground(dx, dy, dz, TimeElapsed); // fog if (Game.CurrentFog.Start < Game.CurrentFog.End & Game.CurrentFog.Start < World.BackgroundImageDistance) { if (!FogEnabled) { GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); } GL.Fog(FogParameter.FogStart, Game.CurrentFog.Start); GL.Fog(FogParameter.FogEnd, Game.CurrentFog.End); GL.Fog(FogParameter.FogColor, 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.Enable(EnableCap.Fog); FogEnabled = true; } GL.ClearColor(inv255 * (float)Game.CurrentFog.Color.R, inv255 * (float)Game.CurrentFog.Color.G, inv255 * (float)Game.CurrentFog.Color.B, 1.0f); } else if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } // render background GL.Disable(EnableCap.DepthTest); RenderBackground(dx, dy, dz, TimeElapsed); // render polygons if (OptionLighting) { if (!LightingEnabled) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } } else if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } SetAlphaFunc(AlphaFunction.Greater, 0.9f); BlendEnabled = false; GL.Disable(EnableCap.Blend); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); LastBoundTexture = 0; // opaque list for (int i = 0; i < OpaqueListCount; i++) { RenderFace(ref OpaqueList[i], cx, cy, cz); } // events if (OptionEvents) RenderEvents(cx, cy, cz); // transparent color list if (TransparentColorDepthSorting) { SortPolygons(TransparentColorList, TransparentColorListCount, TransparentColorListDistance, 1, TimeElapsed); BlendEnabled = true; GL.Enable(EnableCap.Blend); for (int i = 0; i < TransparentColorListCount; i++) { GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Less, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); GL.DepthMask(true); SetAlphaFunc(AlphaFunction.Equal, 1.0f); RenderFace(ref TransparentColorList[i], cx, cy, cz); } } else { for (int i = 0; i < TransparentColorListCount; i++) { RenderFace(ref TransparentColorList[i], cx, cy, cz); } } // alpha list SortPolygons(AlphaList, AlphaListCount, AlphaListDistance, 2, TimeElapsed); if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Smooth) { BlendEnabled = true; GL.Enable(EnableCap.Blend); bool depthMask = true; for (int i = 0; i < AlphaListCount; i++) { int r = (int)ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Faces[AlphaList[i].FaceIndex].Material; if (ObjectManager.Objects[AlphaList[i].ObjectIndex].Mesh.Materials[r].BlendMode == World.MeshMaterialBlendMode.Additive) { if (depthMask) { GL.DepthMask(false); depthMask = false; } SetAlphaFunc(AlphaFunction.Greater, 0.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } else { if (depthMask) { GL.DepthMask(false); depthMask = false; } SetAlphaFunc(AlphaFunction.Less, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); GL.DepthMask(true); depthMask = true; SetAlphaFunc(AlphaFunction.Equal, 1.0f); RenderFace(ref AlphaList[i], cx, cy, cz); } } } else { BlendEnabled = true; GL.Enable(EnableCap.Blend); GL.DepthMask(false); SetAlphaFunc(AlphaFunction.Greater, 0.0f); for (int i = 0; i < AlphaListCount; i++) { RenderFace(ref AlphaList[i], cx, cy, cz); } } // overlay list GL.Disable(EnableCap.DepthTest); GL.DepthMask(false); if (FogEnabled) { GL.Disable(EnableCap.Fog); FogEnabled = false; } SortPolygons(OverlayList, OverlayListCount, OverlayListDistance, 3, TimeElapsed); for (int i = 0; i < OverlayListCount; i++) { RenderFace(ref OverlayList[i], cx, cy, cz); } // render overlays BlendEnabled = false; GL.Disable(EnableCap.Blend); SetAlphaFunc(AlphaFunction.Greater, 0.9f); AlphaTestEnabled = false; GL.Disable(EnableCap.AlphaTest); GL.Disable(EnableCap.DepthTest); if (LightingEnabled) { GL.Disable(EnableCap.Lighting); LightingEnabled = false; } RenderOverlays(TimeElapsed); // finalize rendering GL.PopMatrix(); }