/// <summary>Resizes the OpenGL viewport if the window is resized</summary> internal static void WindowResize(int newWidth, int newHeight) { Program.Renderer.Screen.Width = newWidth; Program.Renderer.Screen.Height = newHeight; if (Loading.Complete) { Program.Renderer.UpdateViewport(ViewportChangeMode.NoChange); World.InitializeCameraRestriction(); if (Program.Renderer.OptionBackFaceCulling) { GL.Enable(EnableCap.CullFace); } else { GL.Disable(EnableCap.CullFace); } } else { GL.Viewport(0, 0, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height); Program.Renderer.PopMatrix(MatrixMode.Modelview); Matrix4D.CreateOrthographicOffCenter(0.0f, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out Program.Renderer.CurrentProjectionMatrix); Program.Renderer.PushMatrix(MatrixMode.Modelview); Program.Renderer.CurrentViewMatrix = Matrix4D.Identity; Program.Renderer.ResetOpenGlState(); } }
public static Matrix4D ComputeViewportOrthographicMatrix(Rectangle viewport) { // // Bottom and top swapped: MS -> OpenGL // return(Matrix4D.CreateOrthographicOffCenter( viewport.Left, viewport.Right, viewport.Top, viewport.Bottom, 0.0, 1.0)); }
public static void LoadingScreenLoop() { currentlyLoading = true; Program.Renderer.PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out Program.Renderer.CurrentProjectionMatrix); Program.Renderer.PushMatrix(MatrixMode.Modelview); Program.Renderer.CurrentViewMatrix = Matrix4D.Identity; while (!Loading.Complete && !Loading.Cancel) { CPreciseTimer.GetElapsedTime(); Program.currentGameWindow.ProcessEvents(); if (Program.currentGameWindow.IsExiting) { Loading.Cancel = true; } Program.Renderer.Loading.DrawLoadingScreen(Fonts.SmallFont, Loading.RouteProgress, 1.0); Program.currentGameWindow.SwapBuffers(); if (Loading.JobAvailable) { while (jobs.Count > 0) { lock (jobLock) { var currentJob = jobs.Dequeue(); var locker = locks.Dequeue(); currentJob(); lock (locker) { Monitor.Pulse(locker); } } } Loading.JobAvailable = false; } double time = CPreciseTimer.GetElapsedTime(); double wait = 1000.0 / 60.0 - time * 1000 - 50; if (wait > 0) { Thread.Sleep((int)(wait)); } } if (!Loading.Cancel) { Program.Renderer.PopMatrix(MatrixMode.Modelview); Program.Renderer.PopMatrix(MatrixMode.Projection); } else { Program.currentGameWindow.Exit(); } }
private void RenderOverlays() { //Initialize openGL SetBlendFunc(); PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Screen.Width, Screen.Height, 0.0f, -1.0f, 1.0f, out CurrentProjectionMatrix); PushMatrix(MatrixMode.Modelview); CurrentViewMatrix = Matrix4D.Identity; CultureInfo culture = CultureInfo.InvariantCulture; if (OptionInterface) { string[][] keys; if (VisibleObjects.Objects.Count == 0 && ObjectManager.AnimatedWorldObjectsUsed == 0) { keys = new[] { new[] { "F7" }, new[] { "F8" }, new[] { "F10" } }; Keys.Render(4, 4, 20, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Open one or more objects", new Vector2(32, 4), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Vector2(32, 24), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the train settings window", new Vector2(32, 44), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"v{Application.ProductVersion}", new Vector2(Screen.Width - 8, Screen.Height - 20), TextAlignment.TopLeft, TextColor); if (Interface.LogMessages.Count == 1) { Keys.Render(4, 64, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); if (Interface.LogMessages[0].Type != MessageType.Information) { OpenGlString.Draw(Fonts.SmallFont, "Display the 1 error message recently generated.", new Vector2(32, 64), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { //If all of our messages are information, then print the message text in grey OpenGlString.Draw(Fonts.SmallFont, "Display the 1 message recently generated.", new Vector2(32, 64), TextAlignment.TopLeft, TextColor); } } else if (Interface.LogMessages.Count > 1) { Keys.Render(4, 64, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); bool error = Interface.LogMessages.Any(x => x.Type != MessageType.Information); if (error) { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count.ToString(culture)} error messages recently generated.", new Vector2(32, 64), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count.ToString(culture)} messages recently generated.", new Vector2(32, 64), TextAlignment.TopLeft, TextColor); } } } else { OpenGlString.Draw(Fonts.SmallFont, $"Position: {Camera.AbsolutePosition.X.ToString("0.00", culture)}, {Camera.AbsolutePosition.Y.ToString("0.00", culture)}, {Camera.AbsolutePosition.Z.ToString("0.00", culture)}", new Vector2((int)(0.5 * Screen.Width - 88), 4), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Renderer: {(AvailableNewRenderer ? "New (GL 3.0)" : "Old (GL 1.2)")}", new Vector2((int)(0.5 * Screen.Width - 88), 24), TextAlignment.TopLeft, TextColor); keys = new[] { new[] { "F5" }, new[] { "F7" }, new[] { "del" }, new[] { "F8" }, new[] { "F10" } }; Keys.Render(4, 4, 24, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Reload the currently open objects", new Vector2(32, 4), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Open additional objects", new Vector2(32, 24), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Clear currently open objects", new Vector2(32, 44), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Vector2(32, 64), TextAlignment.TopLeft, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Display the train settings window", new Vector2(32, 84), TextAlignment.TopLeft, TextColor); keys = new[] { new[] { "F" }, new[] { "N" }, new[] { "L" }, new[] { "G" }, new[] { "B" }, new[] { "I" }, new[] { "R" } }; Keys.Render(Screen.Width - 20, 4, 16, Fonts.SmallFont, keys); keys = new[] { new[] { "F11" } }; Keys.Render(Screen.Width - 36, 124, 32, Fonts.SmallFont, keys); keys = new[] { new[] { "R" } }; Keys.Render(Screen.Width - 20, 144, 16, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, $"WireFrame: {(OptionWireFrame ? "on" : "off")}", new Vector2(Screen.Width - 28, 4), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Normals: {(OptionNormals ? "on" : "off")}", new Vector2(Screen.Width - 28, 24), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Lighting: {(Program.LightingTarget == 0 ? "night" : "day")}", new Vector2(Screen.Width - 28, 44), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Grid: {(OptionCoordinateSystem ? "on" : "off")}", new Vector2(Screen.Width - 28, 64), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"Background: {GetBackgroundColorName()}", new Vector2(Screen.Width - 28, 84), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Hide interface:", new Vector2(Screen.Width - 28, 104), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, $"{(RenderStatsOverlay ? "Hide" : "Show")} renderer statistics", new Vector2(Screen.Width - 44, 124), TextAlignment.TopRight, TextColor); OpenGlString.Draw(Fonts.SmallFont, "Switch renderer type:", new Vector2(Screen.Width - 28, 144), TextAlignment.TopRight, TextColor); keys = new[] { new[] { null, "W", null }, new[] { "A", "S", "D" } }; Keys.Render(4, Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "↑", null }, new[] { "←", "↓", "→" } }; Keys.Render((int)(0.5 * Screen.Width - 28), Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "8", "9" }, new[] { "4", "5", "6" }, new[] { null, "2", "3" } }; Keys.Render(Screen.Width - 60, Screen.Height - 60, 16, Fonts.SmallFont, keys); if (Interface.LogMessages.Count == 1) { Keys.Render(4, 112, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); if (Interface.LogMessages[0].Type != MessageType.Information) { OpenGlString.Draw(Fonts.SmallFont, "Display the 1 error message recently generated.", new Vector2(32, 112), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { //If all of our messages are information, then print the message text in grey OpenGlString.Draw(Fonts.SmallFont, "Display the 1 message recently generated.", new Vector2(32, 112), TextAlignment.TopLeft, TextColor); } } else if (Interface.LogMessages.Count > 1) { Keys.Render(4, 112, 20, Fonts.SmallFont, new[] { new[] { "F9" } }); bool error = Interface.LogMessages.Any(x => x.Type != MessageType.Information); if (error) { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count.ToString(culture)} error messages recently generated.", new Vector2(32, 112), TextAlignment.TopLeft, new Color128(1.0f, 0.5f, 0.5f)); } else { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count.ToString(culture)} messages recently generated.", new Vector2(32, 112), TextAlignment.TopLeft, TextColor); } } if (RenderStatsOverlay) { Keys.Render(4, Screen.Height - 126, 116, Fonts.SmallFont, new[] { new[] { "Renderer Statistics" } }); OpenGlString.Draw(Fonts.SmallFont, $"Total static objects: {VisibleObjects.Objects.Count}", new Vector2(4, Screen.Height - 112), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total animated objects: {ObjectManager.AnimatedWorldObjectsUsed}", new Vector2(4, Screen.Height - 100), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Current frame rate: {FrameRate.ToString("0.0", culture)}fps", new Vector2(4, Screen.Height - 88), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total opaque faces: {VisibleObjects.OpaqueFaces.Count}", new Vector2(4, Screen.Height - 76), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total alpha faces: {VisibleObjects.AlphaFaces.Count}", new Vector2(4, Screen.Height - 64), TextAlignment.TopLeft, Color128.White, true); } } } // finalize PopMatrix(MatrixMode.Projection); PopMatrix(MatrixMode.Modelview); }
private void RenderOverlays() { //Initialize openGL SetBlendFunc(); PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Screen.Width, Screen.Height, 0.0f, -1.0f, 1.0f, out CurrentProjectionMatrix); PushMatrix(MatrixMode.Modelview); CurrentViewMatrix = Matrix4D.Identity; CultureInfo culture = CultureInfo.InvariantCulture; // marker if (OptionInterface) { int y = 150; foreach (Texture t in Marker.MarkerTextures) { if (Program.CurrentHost.LoadTexture(t, OpenGlTextureWrapMode.ClampClamp)) { int w = t.Width; int h = t.Height; GL.Color4(1.0, 1.0, 1.0, 1.0); Rectangle.Draw(t, new Vector2(Screen.Width - w - 8, y), new Vector2(w, h)); y += h + 8; } } } if (!Program.CurrentlyLoading) { string[][] keys; if (VisibleObjects.Objects.Count == 0 && ObjectManager.AnimatedWorldObjectsUsed == 0) { keys = new[] { new[] { "F7" }, new[] { "F8" } }; Keys.Render(4, 4, 20, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Open route", new Point(32, 4), TextAlignment.TopLeft, Color128.White); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Point(32, 24), TextAlignment.TopLeft, Color128.White); OpenGlString.Draw(Fonts.SmallFont, $"v{Application.ProductVersion}", new Point(Screen.Width - 8, Screen.Height - 20), TextAlignment.TopLeft, Color128.White); } else if (OptionInterface) { // keys keys = new[] { new[] { "F5" }, new[] { "F7" }, new[] { "F8" } }; Keys.Render(4, 4, 24, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "Reload route", new Point(32, 4), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Open route", new Point(32, 24), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Display the options window", new Point(32, 44), TextAlignment.TopLeft, Color128.White, true); keys = new[] { new[] { "F" }, new[] { "N" }, new[] { "E" }, new[] { "C" }, new[] { "M" }, new[] { "I" } }; Keys.Render(Screen.Width - 20, 4, 16, Fonts.SmallFont, keys); OpenGlString.Draw(Fonts.SmallFont, "WireFrame:", new Point(Screen.Width - 32, 4), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Normals:", new Point(Screen.Width - 32, 24), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Events:", new Point(Screen.Width - 32, 44), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "CPU:", new Point(Screen.Width - 32, 64), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Mute:", new Point(Screen.Width - 32, 84), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, "Hide interface:", new Point(Screen.Width - 32, 104), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"{(RenderStatsOverlay ? "Hide" : "Show")} renderer statistics", new Point(Screen.Width - 32, 124), TextAlignment.TopRight, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Switch renderer type:", new Point(Screen.Width - 32, 144), TextAlignment.TopRight, Color128.White, true); keys = new[] { new[] { "F10" } }; Keys.Render(Screen.Width - 32, 124, 30, Fonts.SmallFont, keys); keys = new[] { new[] { "R" } }; Keys.Render(Screen.Width - 20, 144, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "W", null }, new[] { "A", "S", "D" } }; Keys.Render(4, Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { null, "↑", null }, new[] { "←", "↓", "→" } }; Keys.Render(0 * Screen.Width - 48, Screen.Height - 40, 16, Fonts.SmallFont, keys); keys = new[] { new[] { "P↑" }, new[] { "P↓" } }; Keys.Render((int)(0.5 * Screen.Width + 32), Screen.Height - 40, 24, Fonts.SmallFont, keys); keys = new[] { new[] { null, "/", "*" }, new[] { "7", "8", "9" }, new[] { "4", "5", "6" }, new[] { "1", "2", "3" }, new[] { null, "0", "." } }; Keys.Render(Screen.Width - 60, Screen.Height - 100, 16, Fonts.SmallFont, keys); if (Program.JumpToPositionEnabled) { OpenGlString.Draw(Fonts.SmallFont, "Jump to track position:", new Point(4, 80), TextAlignment.TopLeft, Color128.White, true); double distance; if (double.TryParse(Program.JumpToPositionValue, out distance)) { if (distance < Program.MinimumJumpToPositionValue - 100) { OpenGlString.Draw(Fonts.SmallFont, (Environment.TickCount % 1000 <= 500 ? $"{Program.JumpToPositionValue}_" : Program.JumpToPositionValue), new Point(4, 100), TextAlignment.TopLeft, Color128.Red, true); } else { OpenGlString.Draw(Fonts.SmallFont, (Environment.TickCount % 1000 <= 500 ? $"{Program.JumpToPositionValue}_" : Program.JumpToPositionValue), new Point(4, 100), TextAlignment.TopLeft, distance > Program.CurrentRoute.Tracks[0].Elements[Program.CurrentRoute.Tracks[0].Elements.Length - 1].StartingTrackPosition + 100 ? Color128.Red : Color128.Yellow, true); } } } // info double x = 0.5 * Screen.Width - 256.0; OpenGlString.Draw(Fonts.SmallFont, $"Position: {GetLengthString(Camera.Alignment.TrackPosition)} (X={GetLengthString(Camera.Alignment.Position.X)}, Y={GetLengthString(Camera.Alignment.Position.Y)}), Orientation: (Yaw={(Camera.Alignment.Yaw * 57.2957795130824).ToString("0.00", culture)}°, Pitch={(Camera.Alignment.Pitch * 57.2957795130824).ToString("0.00", culture)}°, Roll={(Camera.Alignment.Roll * 57.2957795130824).ToString("0.00", culture)}°)", new Point((int)x, 4), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Radius: {GetLengthString(CameraTrackFollower.CurveRadius)}, Cant: {(1000.0 * CameraTrackFollower.CurveCant).ToString("0", culture)} mm, Adhesion={(100.0 * CameraTrackFollower.AdhesionMultiplier).ToString("0", culture)}" + " , Rain intensity= " + CameraTrackFollower.RainIntensity + "%", new Point((int)x, 20), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Renderer: {(AvailableNewRenderer ? "New (GL 3.0)" : "Old (GL 1.2)")}", new Point((int)x, 40), TextAlignment.TopLeft, Color128.White, true); if (Program.CurrentStation >= 0) { StringBuilder t = new StringBuilder(); t.Append(Program.CurrentRoute.Stations[Program.CurrentStation].Name); if (Program.CurrentRoute.Stations[Program.CurrentStation].ArrivalTime >= 0.0) { t.Append($", Arrival: {GetTime(Program.CurrentRoute.Stations[Program.CurrentStation].ArrivalTime)}"); } if (Program.CurrentRoute.Stations[Program.CurrentStation].DepartureTime >= 0.0) { t.Append($", Departure: {GetTime(Program.CurrentRoute.Stations[Program.CurrentStation].DepartureTime)}"); } if (Program.CurrentRoute.Stations[Program.CurrentStation].OpenLeftDoors & Program.CurrentRoute.Stations[Program.CurrentStation].OpenRightDoors) { t.Append(", [L][R]"); } else if (Program.CurrentRoute.Stations[Program.CurrentStation].OpenLeftDoors) { t.Append(", [L][-]"); } else if (Program.CurrentRoute.Stations[Program.CurrentStation].OpenRightDoors) { t.Append(", [-][R]"); } else { t.Append(", [-][-]"); } switch (Program.CurrentRoute.Stations[Program.CurrentStation].StopMode) { case StationStopMode.AllStop: t.Append(", Stop"); break; case StationStopMode.AllPass: t.Append(", Pass"); break; case StationStopMode.PlayerStop: t.Append(", Player stops - others pass"); break; case StationStopMode.PlayerPass: t.Append(", Player passes - others stop"); break; } switch (Program.CurrentRoute.Stations[Program.CurrentStation].Type) { case StationType.ChangeEnds: t.Append(", Change ends"); break; case StationType.Jump: t.Append(", then Jumps to " + Program.CurrentRoute.Stations[Program.CurrentRoute.Stations[Program.CurrentStation].JumpIndex].Name); break; } t.Append(", Ratio=").Append((100.0 * Program.CurrentRoute.Stations[Program.CurrentStation].PassengerRatio).ToString("0", culture)).Append("%"); OpenGlString.Draw(Fonts.SmallFont, t.ToString(), new Point((int)x, 60), TextAlignment.TopLeft, Color128.White, true); } if (Interface.LogMessages.Count == 1) { keys = new[] { new[] { "F9" } }; Keys.Render(4, 72, 24, Fonts.SmallFont, keys); if (Interface.LogMessages[0].Type != MessageType.Information) { OpenGlString.Draw(Fonts.SmallFont, "Display the 1 error message recently generated.", new Point(32, 72), TextAlignment.TopLeft, Color128.Red, true); } else { //If all of our messages are information, then print the message text in grey OpenGlString.Draw(Fonts.SmallFont, "Display the 1 message recently generated.", new Point(32, 72), TextAlignment.TopLeft, Color128.White, true); } } else if (Interface.LogMessages.Count > 1) { Keys.Render(4, 72, 24, Fonts.SmallFont, new[] { new[] { "F9" } }); bool error = Interface.LogMessages.Any(m => m.Type != MessageType.Information); if (error) { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count} error messages recently generated.", new Point(32, 72), TextAlignment.TopLeft, Color128.Red, true); } else { OpenGlString.Draw(Fonts.SmallFont, $"Display the {Interface.LogMessages.Count} messages recently generated.", new Point(32, 72), TextAlignment.TopLeft, Color128.White, true); } } if (RenderStatsOverlay) { Keys.Render(4, Screen.Height - 126, 116, Fonts.SmallFont, new[] { new[] { "Renderer Statistics" } }); OpenGlString.Draw(Fonts.SmallFont, $"Total static objects: {VisibleObjects.Objects.Count}", new Point(4, Screen.Height - 112), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total animated objects: {ObjectManager.AnimatedWorldObjectsUsed}", new Point(4, Screen.Height - 100), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Current frame rate: {FrameRate.ToString("0.0", culture)}fps", new Point(4, Screen.Height - 88), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total opaque faces: {VisibleObjects.OpaqueFaces.Count}", new Point(4, Screen.Height - 76), TextAlignment.TopLeft, Color128.White, true); OpenGlString.Draw(Fonts.SmallFont, $"Total alpha faces: {VisibleObjects.AlphaFaces.Count}", new Point(4, Screen.Height - 64), TextAlignment.TopLeft, Color128.White, true); } } } // finalize PopMatrix(MatrixMode.Projection); PopMatrix(MatrixMode.Modelview); }
/// <summary>Is called once by the main renderer loop, in order to render all overlays shown on the screen</summary> /// <param name="TimeElapsed">The time elapsed since the last call to this function</param> internal void Render(double TimeElapsed) { //Initialize openGL renderer.SetBlendFunc(); GL.Enable(EnableCap.Blend); renderer.PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, renderer.Screen.Width, renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out renderer.CurrentProjectionMatrix); renderer.PushMatrix(MatrixMode.Modelview); renderer.CurrentViewMatrix = Matrix4D.Identity; //Check which overlays to show switch (renderer.CurrentOutputMode) { case OutputMode.Default: //Route info overlay (if selected) Game.routeInfoOverlay.Show(); //HUD foreach (HUD.Element element in HUD.CurrentHudElements) { switch (element.Subject.ToLowerInvariant()) { case "messages": RenderGameMessages(element, TimeElapsed); break; case "scoremessages": RenderScoreMessages(element, TimeElapsed); break; case "ats": RenderATSLamps(element, TimeElapsed); break; default: RenderHUDElement(element, TimeElapsed); break; } } //Marker textures if (Interface.CurrentOptions.GameMode != GameMode.Expert) { double y = 8.0; foreach (Texture t in renderer.Marker.MarkerTextures) { if (Program.CurrentHost.LoadTexture(t, OpenGlTextureWrapMode.ClampClamp)) { double w = t.Width; double h = t.Height; renderer.Rectangle.Draw(t, new OpenBveApi.Math.Vector2(renderer.Screen.Width - w - 8.0, y), new Vector2(w, h), Color128.White); y += h + 8.0; } } } //Timetable overlay //NOTE: Only affects auto-generated timetable, possibly change this inconsistant behaviour if (Program.Renderer.CurrentTimetable == DisplayedTimetable.Default) { // default if (Program.CurrentHost.LoadTexture(Timetable.DefaultTimetableTexture, OpenGlTextureWrapMode.ClampClamp)) { int w = Timetable.DefaultTimetableTexture.Width; int h = Timetable.DefaultTimetableTexture.Height; renderer.Rectangle.Draw(Timetable.DefaultTimetableTexture, new OpenBveApi.Math.Vector2(renderer.Screen.Width - w, Timetable.DefaultTimetablePosition), new Vector2(w, h), Color128.White); } } else if (Program.Renderer.CurrentTimetable == DisplayedTimetable.Custom & Timetable.CustomObjectsUsed == 0) { // custom if (Program.CurrentHost.LoadTexture(Timetable.CurrentCustomTimetableDaytimeTexture, OpenGlTextureWrapMode.ClampClamp)) { int w = Timetable.CurrentCustomTimetableDaytimeTexture.Width; int h = Timetable.CurrentCustomTimetableDaytimeTexture.Height; renderer.Rectangle.Draw(Timetable.CurrentCustomTimetableDaytimeTexture, new OpenBveApi.Math.Vector2(renderer.Screen.Width - w, Timetable.CustomTimetablePosition), new Vector2(w, h), Color128.White); } if (Program.CurrentHost.LoadTexture(Timetable.CurrentCustomTimetableDaytimeTexture, OpenGlTextureWrapMode.ClampClamp)) { int w = Timetable.CurrentCustomTimetableDaytimeTexture.Width; int h = Timetable.CurrentCustomTimetableDaytimeTexture.Height; float alpha; if (Timetable.CurrentCustomTimetableDaytimeTexture != null) { double t = (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].TrackPosition - TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousTrackPosition) / (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.NextTrackPosition - TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousTrackPosition); alpha = (float)((1.0 - t) * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousBrightness + t * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.NextBrightness); } else { alpha = 1.0f; } renderer.Rectangle.Draw(Timetable.CurrentCustomTimetableDaytimeTexture, new OpenBveApi.Math.Vector2(renderer.Screen.Width - w, Timetable.CustomTimetablePosition), new Vector2(w, h), new Color128(1.0f, 1.0f, 1.0f, alpha)); } } break; case OutputMode.Debug: RenderDebugOverlays(); break; case OutputMode.DebugATS: RenderATSDebugOverlay(); break; } // air brake debug output if (Interface.CurrentOptions.GameMode != GameMode.Expert & renderer.OptionBrakeSystems) { RenderBrakeSystemDebug(); } switch (Program.Renderer.CurrentInterface) { case InterfaceType.Pause: { //If paused, fade out the screen & write PAUSE renderer.Rectangle.Draw(null, Vector2.Null, new Vector2(renderer.Screen.Width, renderer.Screen.Height), new Color128(0.0f, 0.0f, 0.0f, 0.5f)); renderer.OpenGlString.Draw(renderer.Fonts.VeryLargeFont, Translations.GetInterfaceString("menu_pause_title"), new Vector2(renderer.Screen.Width / 2.0, renderer.Screen.Height / 2.0), TextAlignment.CenterMiddle, Color128.White, true); if (!PauseAnnounced) { if (!Tolk.Output(Translations.GetInterfaceString("menu_pause_title"))) { Interface.CurrentOptions.ScreenReaderAvailable = false; } PauseAnnounced = true; } break; } case InterfaceType.Menu: Game.Menu.Draw(TimeElapsed); PauseAnnounced = false; break; default: PauseAnnounced = false; break; } //Fade to black on change ends if (TrainManager.PlayerTrain != null) { if (TrainManager.PlayerTrain.Station >= 0 && Program.CurrentRoute.Stations[TrainManager.PlayerTrain.Station].Type == StationType.ChangeEnds && TrainManager.PlayerTrain.StationState == TrainStopState.Boarding) { double time = TrainManager.PlayerTrain.StationDepartureTime - Program.CurrentRoute.SecondsSinceMidnight; if (time < 1.0) { FadeToBlackDueToChangeEnds = Math.Max(0.0, 1.0 - time); } else if (FadeToBlackDueToChangeEnds > 0.0) { FadeToBlackDueToChangeEnds -= TimeElapsed; if (FadeToBlackDueToChangeEnds < 0.0) { FadeToBlackDueToChangeEnds = 0.0; } } } else if (FadeToBlackDueToChangeEnds > 0.0) { FadeToBlackDueToChangeEnds -= TimeElapsed; if (FadeToBlackDueToChangeEnds < 0.0) { FadeToBlackDueToChangeEnds = 0.0; } } if (FadeToBlackDueToChangeEnds > 0.0 & (renderer.Camera.CurrentMode == CameraViewMode.Interior | renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead)) { renderer.Rectangle.Draw(null, Vector2.Null, new Vector2(renderer.Screen.Width, renderer.Screen.Height), new Color128(0.0f, 0.0f, 0.0f, (float)FadeToBlackDueToChangeEnds)); } } // finalize renderer.PopMatrix(MatrixMode.Projection); renderer.PopMatrix(MatrixMode.Modelview); }
private void LoadingScreenLoop() { Program.Renderer.PushMatrix(MatrixMode.Projection); Matrix4D.CreateOrthographicOffCenter(0.0f, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out Program.Renderer.CurrentProjectionMatrix); Program.Renderer.PushMatrix(MatrixMode.Modelview); Program.Renderer.CurrentViewMatrix = Matrix4D.Identity; while (!Loading.Complete && !Loading.Cancel) { CPreciseTimer.GetElapsedTime(); this.ProcessEvents(); if (this.IsExiting) { Loading.Cancel = true; } double routeProgress = 1.0; for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++) { if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.IsLoading) { routeProgress = Program.CurrentHost.Plugins[i].Route.CurrentProgress; break; } } Program.Renderer.Loading.SetLoadingBkg(Program.CurrentRoute.Information.LoadingScreenBackground); Program.Renderer.Loading.DrawLoadingScreen(Fonts.SmallFont, routeProgress, Loading.TrainProgress); Program.currentGameWindow.SwapBuffers(); if (Loading.JobAvailable) { while (jobs.Count > 0) { lock (jobLock) { var currentJob = jobs.Dequeue(); var locker = locks.Dequeue(); currentJob(); lock (locker) { Monitor.Pulse(locker); } } } Loading.JobAvailable = false; } double time = CPreciseTimer.GetElapsedTime(); double wait = 1000.0 / 60.0 - time * 1000 - 50; if (wait > 0) { Thread.Sleep((int)(wait)); } } if (!Loading.Cancel) { Program.Renderer.PopMatrix(MatrixMode.Modelview); Program.Renderer.PopMatrix(MatrixMode.Projection); SetupSimulation(); } else { this.Exit(); } }