Beispiel #1
1
 /// <summary>Draws a rectangle.</summary>
 /// <param name="texture">The texture, or a null reference.</param>
 /// <param name="point">The top-left coordinates in pixels.</param>
 /// <param name="size">The size in pixels.</param>
 /// <param name="color">The color, or a null reference.</param>
 internal static void DrawRectangle(Textures.Texture texture, Point point, Size size, Nullable<Color128> color)
 {
     // TODO: Remove Nullable<T> from color once RenderOverlayTexture and RenderOverlaySolid are fully replaced.
     if (texture == null || !Textures.LoadTexture(texture, Textures.OpenGlTextureWrapMode.ClampClamp)) {
         Gl.glDisable(Gl.GL_TEXTURE_2D);
         if (color.HasValue) {
             Gl.glColor4d(color.Value.R, color.Value.G, color.Value.B, color.Value.A);
         }
         Gl.glBegin(Gl.GL_QUADS);
         Gl.glVertex2d(point.X, point.Y);
         Gl.glVertex2d(point.X + size.Width, point.Y);
         Gl.glVertex2d(point.X + size.Width, point.Y + size.Height);
         Gl.glVertex2d(point.X, point.Y + size.Height);
         Gl.glEnd();
     } else {
         Gl.glEnable(Gl.GL_TEXTURE_2D);
         Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.OpenGlTextures[(int)Textures.OpenGlTextureWrapMode.ClampClamp].Name);
         if (color.HasValue) {
             Gl.glColor4d(color.Value.R, color.Value.G, color.Value.B, color.Value.A);
         }
         Gl.glBegin(Gl.GL_QUADS);
         Gl.glTexCoord2f(0.0f, 0.0f);
         Gl.glVertex2d(point.X, point.Y);
         Gl.glTexCoord2f(1.0f, 0.0f);
         Gl.glVertex2d(point.X + size.Width, point.Y);
         Gl.glTexCoord2f(1.0f, 1.0f);
         Gl.glVertex2d(point.X + size.Width, point.Y + size.Height);
         Gl.glTexCoord2f(0.0f, 1.0f);
         Gl.glVertex2d(point.X, point.Y + size.Height);
         Gl.glEnd();
     }
 }
Beispiel #2
0
		/// <summary>Draws a rectangle.</summary>
		/// <param name="texture">The texture, or a null reference.</param>
		/// <param name="point">The top-left coordinates in pixels.</param>
		/// <param name="size">The size in pixels.</param>
		/// <param name="color">The color, or a null reference.</param>
		internal static void DrawRectangle(Textures.Texture texture, Point point, Size size, Color128? color) {
			// TODO: Remove Nullable<T> from color once RenderOverlayTexture and RenderOverlaySolid are fully replaced.
			if (texture == null || !Textures.LoadTexture(texture, Textures.OpenGlTextureWrapMode.ClampClamp)) {
				GL.Disable(EnableCap.Texture2D);
				if (color.HasValue) {
					GL.Color4(color.Value.R, color.Value.G, color.Value.B, color.Value.A);
				}
				GL.Begin(PrimitiveType.Quads);
				GL.Vertex2(point.X, point.Y);
				GL.Vertex2(point.X + size.Width, point.Y);
				GL.Vertex2(point.X + size.Width, point.Y + size.Height);
				GL.Vertex2(point.X, point.Y + size.Height);
				GL.End();
			} else {
                GL.Enable(EnableCap.Texture2D);
				GL.BindTexture(TextureTarget.Texture2D, texture.OpenGlTextures[(int)Textures.OpenGlTextureWrapMode.ClampClamp].Name);
				if (color.HasValue) {
					GL.Color4(color.Value.R, color.Value.G, color.Value.B, color.Value.A);
				}
				GL.Begin(PrimitiveType.Quads);
				GL.TexCoord2(0.0f, 0.0f);
				GL.Vertex2(point.X, point.Y);
				GL.TexCoord2(1.0f, 0.0f);
				GL.Vertex2(point.X + size.Width, point.Y);
				GL.TexCoord2(1.0f, 1.0f);
				GL.Vertex2(point.X + size.Width, point.Y + size.Height);
				GL.TexCoord2(0.0f, 1.0f);
				GL.Vertex2(point.X, point.Y + size.Height);
				GL.End();
			}
		}
Beispiel #3
0
			/// <summary>Creates a new static background, using the default 0.8s fade-in time</summary>
			/// <param name="Texture">The texture to apply</param>
			/// <param name="Repetition">The number of times the texture should be repeated around the viewing frustrum</param>
			/// <param name="KeepAspectRatio">Whether the aspect ratio of the texture should be preseved</param>
			internal StaticBackground(Textures.Texture Texture, double Repetition, bool KeepAspectRatio)
			{
				this.Texture = Texture;
				this.Repetition = Repetition;
				this.KeepAspectRatio = KeepAspectRatio;
				this.TransitionTime = 0.8;
				this.Time = -1;
			}
Beispiel #4
0
			/// <summary>Creates a new static background</summary>
			/// <param name="Texture">The texture to apply</param>
			/// <param name="Repetition">The number of times the texture should be repeated around the viewing frustrum</param>
			/// <param name="KeepAspectRatio">Whether the aspect ratio of the texture should be preseved</param>
			/// <param name="transitionTime">The time taken in seconds for the fade-in transition to occur</param>
			/// <param name="Mode">The transition mode</param>
			/// <param name="Time">The time at which this background is to be displayed, expressed as the number of seconds since midnight</param>
			internal StaticBackground(Textures.Texture Texture, double Repetition, bool KeepAspectRatio, double transitionTime, BackgroundTransitionMode Mode, double Time)
			{
				this.Texture = Texture;
				this.Repetition = Repetition;
				this.KeepAspectRatio = KeepAspectRatio;
				this.TransitionTime = transitionTime;
				this.Mode = Mode;
				this.Time = Time;
			}
Beispiel #5
0
			// --- functions ---
			/// <summary>Gets data associated with the specified codepoint.</summary>
			/// <param name="text">The string containing the codepoint.</param>
			/// <param name="offset">The offset at which to read the codepoint. For surrogate pairs, two characters are read, and one otherwise.</param>
			/// <param name="texture">Receives the texture that contains the codepoint.</param>
			/// <param name="data">Receives the data that describes the codepoint.</param>
			/// <returns>The number of characters read.</returns>
			internal int GetCharacterData(string text, int offset, out Textures.Texture texture, out OpenGlFontChar data) {
				int value = char.ConvertToUtf32(text, offset);
				int hi = value >> 8;
				int lo = value & 0xFF;
				this.Tables[hi] = this.Tables[hi] ?? new OpenGlFontTable(this.Font, hi << 8);
				texture = this.Tables[hi].Texture;
				data = this.Tables[hi].Characters[lo];
				return value >= 0x10000 ? 2 : 1;
			}
Beispiel #6
0
 internal static void RemoveMarker(Textures.Texture Texture)
 {
     int n = MarkerTextures.Length;
     for (int i = 0; i < n; i++) {
         if (MarkerTextures[i] == Texture) {
             for (int j = i; j < n - 1; j++) {
                 MarkerTextures[j] = MarkerTextures[j + 1];
             }
             n--;
             Array.Resize<Textures.Texture>(ref MarkerTextures, n);
             break;
         }
     }
 }
Beispiel #7
0
 /// <summary>Registers a texture and returns a handle to the texture.</summary>
 /// <param name="texture">The texture data.</param>
 /// <param name="parameters">The parameters that specify how to process the texture.</param>
 /// <param name="handle">Receives the handle to the texture.</param>
 /// <returns>Whether loading the texture was successful.</returns>
 public override bool RegisterTexture(Texture texture, TextureParameters parameters, out Texture handle)
 {
     texture = texture.ApplyParameters(parameters);
     handle  = Textures.RegisterTexture(texture);
     return(true);
 }
Beispiel #8
0
 private static void RenderOverlayTexture(Textures.Texture texture, double left, double top, double right, double bottom)
 {
     DrawRectangle(texture, new System.Drawing.Point((int)left, (int)top), new System.Drawing.Size((int)(right - left), (int)(bottom - top)), null);
 }
Beispiel #9
0
        //
        // DRAW LOADING SCREEN
        //
        /// <summary>Draws on OpenGL canvas the route/train loading screen</summary>
        internal static void DrawLoadingScreen()
        {
            // begin HACK //
            if (!BlendEnabled)
            {
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                BlendEnabled = true;
            }
            if (LightingEnabled)
            {
                GL.Disable(EnableCap.Lighting);
                LightingEnabled = false;
            }
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.PushMatrix();

            // fill the screen with background colour
            GL.Color4(bkgR, bkgG, bkgB, bkgA);
            DrawRectangle(null, new System.Drawing.Point((int)0, (int)0), new System.Drawing.Size((int)Renderer.ScreenWidth, (int)Renderer.ScreenHeight), null);
            GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
            // BACKGROUND IMAGE
            int bkgHeight = Renderer.ScreenHeight, bkgWidth = Renderer.ScreenWidth;
            int fontHeight = (int)Fonts.SmallFont.FontSize;
            int logoBottom;
            //			int		versionTop;
            int  halfWidth = Renderer.ScreenWidth / 2;
            bool bkgLoaded = TextureLoadingBkg != null;

            if (TextureLoadingBkg != null && Textures.LoadTexture(TextureLoadingBkg, OpenGlTextureWrapMode.ClampClamp))
            {
                if (TextureLoadingBkg.Width != Renderer.ScreenWidth && TextureLoadingBkg.Height != Renderer.ScreenHeight)
                {
                    // stretch the background image to fit at least one screen dimension
                    double ratio = (double)TextureLoadingBkg.Width / (double)TextureLoadingBkg.Height;
                    if ((double)Renderer.ScreenWidth / ratio > Renderer.ScreenHeight) // if screen ratio is shorter than bkg...
                    {
                        bkgHeight = Renderer.ScreenHeight;                            // set height to screen height
                        bkgWidth  = (int)(Renderer.ScreenWidth * ratio);              // and scale width proprtionally
                    }
                    else                                                              // if screen ratio is wider than bkg...
                    {
                        bkgWidth  = Renderer.ScreenWidth;                             // set width to screen width
                        bkgHeight = (int)(Renderer.ScreenHeight / ratio);             // and scale height accordingly
                    }
                }


                // draw the background image down from the top screen edge
                try
                {
                    DrawRectangle(TextureLoadingBkg, new Point((Renderer.ScreenWidth - bkgWidth) / 2, 0), new Size(bkgWidth, bkgHeight), Color128.White);
                }
                catch
                {
                    TextureLoadingBkg = null;
                }
            }
            // if the route has no custom loading image, add the openBVE logo
            // (the route custom image is loaded in OldParsers/CsvRwRouteParser.cs)
            if (!customLoadScreen && Interface.CurrentOptions.LoadingLogo && TextureLogo != null)
            {
                // place the centre of the logo at from the screen top
                int logoTop = (int)(Renderer.ScreenHeight * logoCentreYFactor - TextureLogo.Height / 2.0);
                DrawRectangle(TextureLogo, new Point((Renderer.ScreenWidth - TextureLogo.Width) / 2, logoTop), new Size(TextureLogo.Width, TextureLogo.Height), Color128.White);
            }
            else
            {
                // if custom route image, no logo and leave a conventional black area below the potential logo
            }
            logoBottom = Renderer.ScreenHeight / 2;
            if (!bkgLoaded)                         // if the background texture not yet loaded, do nothing else
            {
                return;
            }
            // take the height remaining below the logo and divide in 3 horiz. parts
            int blankHeight = (Renderer.ScreenHeight - logoBottom) / 3;

            // VERSION NUMBER
            // place the version above the first division
            // int versionTop = logoBottom + blankHeight - fontHeight;
            //RenderString(Fonts.SmallFontSize, "Version " + typeof(Renderer).Assembly.GetName().Version,new Point(halfWidth, versionTop), TextAlignment.TopMiddle, Color128.White);
            // for the moment, do not show any URL; would go right below the first division
            //			DrawString(Fonts.SmallFont, "https://sites.google.com/site/openbvesim/home",
            //				new Point(halfWidth, versionTop + fontHeight+2),
            //				TextAlignment.TopMiddle, Color128.White);

            // place progress bar right below the second division
            int    progressTop   = Renderer.ScreenHeight - blankHeight;
            int    progressWidth = Renderer.ScreenWidth - progrMargin * 2;
            double routeProgress = Math.Max(0.0, Math.Min(1.0, Loading.RouteProgress));

            if (Interface.CurrentOptions.LoadingProgressBar)
            {
                // PROGRESS MESSAGE AND BAR
                double percent = 100.0 * routeProgress;
                string percStr = percent.ToString("0") + "%";
                // progress frame
                DrawRectangle(null, new Point(progrMargin - progrBorder, progressTop - progrBorder), new Size(progressWidth + progrBorder * 2, fontHeight + 6), Color128.White);
                // progress bar
                DrawRectangle(null, new Point(progrMargin, progressTop), new Size(progressWidth * (int)percent / 100, fontHeight + 4), ColourProgressBar);

                DrawString(Fonts.SmallFont, percStr, new Point(halfWidth, progressTop + 2), TextAlignment.TopMiddle, Color128.Black);
            }

            string text = "Loading route, please wait.....";

            DrawString(Fonts.SmallFont, text, new Point(halfWidth, progressTop - fontHeight - 6), TextAlignment.TopMiddle, Color128.White);
            GL.PopMatrix();
        }
Beispiel #10
0
        /// <summary>Renders all default HUD elements</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderHUDElement(HUD.Element Element, double TimeElapsed)
        {
            TrainManager.TrainDoorState      LeftDoors  = TrainManager.GetDoorsState(TrainManager.PlayerTrain, true, false);
            TrainManager.TrainDoorState      RightDoors = TrainManager.GetDoorsState(TrainManager.PlayerTrain, false, true);
            System.Globalization.CultureInfo Culture    = System.Globalization.CultureInfo.InvariantCulture;
            string Command = Element.Subject.ToLowerInvariant();
            // default
            double w, h;

            if (Element.CenterMiddle.BackgroundTexture != null)
            {
                if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                {
                    w = (double)Element.CenterMiddle.BackgroundTexture.Width;
                    h = (double)Element.CenterMiddle.BackgroundTexture.Height;
                }
                else
                {
                    w = 0.0; h = 0.0;
                }
            }
            else
            {
                w = 0.0; h = 0.0;
            }
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X == 0 ? 0.5 * (Screen.Width - w) : Screen.Width - w;
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y == 0 ? 0.5 * (Screen.Height - h) : Screen.Height - h;

            x += Element.Position.X;
            y += Element.Position.Y;
            // command
            const double speed = 1.0;
            MessageColor sc    = MessageColor.None;
            string       t;

            switch (Command)
            {
            case "reverser":
                if (TrainManager.PlayerTrain.Handles.Reverser.Driver < 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 2)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[2];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleBackward;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Reverser.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[0];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleForward;
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[1];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleNeutral;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "power":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Power.Driver == 0)
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandlePowerNull;
                    }
                }
                else
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "brake":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                    {
                        sc = MessageColor.Green;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleHoldBrake;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && ((TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 2 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length) || (!TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 1 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)))
                        {
                            t = TrainManager.PlayerTrain.Handles.HasHoldBrake ? TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 2] : TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 1];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "locobrake":
                if (!TrainManager.PlayerTrain.Handles.HasLocoBrake)
                {
                    return;
                }

                if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.LocoBrake.Driver < TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.LocoBrake.Driver];
                        }
                        else
                        {
                            t = Interface.QuickReferences.HandleLocoBrake + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "single":
                if (!TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                {
                    sc = MessageColor.Red;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleEmergency;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                {
                    sc = MessageColor.Green;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleHoldBrake;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Brake.Driver > 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Brake.Driver + 3 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 3];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Power.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Interface.QuickReferences.HandlePowerNull;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "doorsleft":
            case "doorsright":
            {
                if ((LeftDoors & TrainManager.TrainDoorState.AllClosed) == 0 | (RightDoors & TrainManager.TrainDoorState.AllClosed) == 0)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                TrainManager.TrainDoorState Doors = Command == "doorsleft" ? LeftDoors : RightDoors;
                if ((Doors & TrainManager.TrainDoorState.Mixed) != 0)
                {
                    sc = MessageColor.Orange;
                }
                else if ((Doors & TrainManager.TrainDoorState.AllClosed) != 0)
                {
                    sc = MessageColor.Gray;
                }
                else if (TrainManager.PlayerTrain.Specs.DoorCloseMode == TrainManager.DoorMode.Manual)
                {
                    sc = MessageColor.Green;
                }
                else
                {
                    sc = MessageColor.Blue;
                }
                t = Command == "doorsleft" ? Interface.QuickReferences.DoorsLeft : Interface.QuickReferences.DoorsRight;
            } break;

            case "stopleft":
            case "stopright":
            case "stopnone":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && Game.PlayerStopsAtStation(s) && Interface.CurrentOptions.GameMode != Interface.GameMode.Expert)
                {
                    bool cond;
                    if (Command == "stopleft")
                    {
                        cond = Game.Stations[s].OpenLeftDoors;
                    }
                    else if (Command == "stopright")
                    {
                        cond = Game.Stations[s].OpenRightDoors;
                    }
                    else
                    {
                        cond = !Game.Stations[s].OpenLeftDoors & !Game.Stations[s].OpenRightDoors;
                    }
                    if (TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending & cond)
                    {
                        Element.TransitionState -= speed * TimeElapsed;
                        if (Element.TransitionState < 0.0)
                        {
                            Element.TransitionState = 0.0;
                        }
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            } break;

            case "stoplefttick":
            case "stoprighttick":
            case "stopnonetick":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && Game.PlayerStopsAtStation(s) && Interface.CurrentOptions.GameMode != Interface.GameMode.Expert)
                {
                    int c = Game.GetStopIndex(s, TrainManager.PlayerTrain.Cars.Length);
                    if (c >= 0)
                    {
                        bool cond;
                        if (Command == "stoplefttick")
                        {
                            cond = Game.Stations[s].OpenLeftDoors;
                        }
                        else if (Command == "stoprighttick")
                        {
                            cond = Game.Stations[s].OpenRightDoors;
                        }
                        else
                        {
                            cond = !Game.Stations[s].OpenLeftDoors & !Game.Stations[s].OpenRightDoors;
                        }
                        if (TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending & cond)
                        {
                            Element.TransitionState -= speed * TimeElapsed;
                            if (Element.TransitionState < 0.0)
                            {
                                Element.TransitionState = 0.0;
                            }
                        }
                        else
                        {
                            Element.TransitionState += speed * TimeElapsed;
                            if (Element.TransitionState > 1.0)
                            {
                                Element.TransitionState = 1.0;
                            }
                        }
                        double d = TrainManager.PlayerTrain.StationDistanceToStopPoint;
                        double r;
                        if (d > 0.0)
                        {
                            r = d / Game.Stations[s].Stops[c].BackwardTolerance;
                        }
                        else
                        {
                            r = d / Game.Stations[s].Stops[c].ForwardTolerance;
                        }
                        if (r < -1.0)
                        {
                            r = -1.0;
                        }
                        if (r > 1.0)
                        {
                            r = 1.0;
                        }
                        y -= r * (double)Element.Value1;
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            } break;

            case "clock":
            {
                int hours   = (int)Math.Floor(Game.SecondsSinceMidnight);
                int seconds = hours % 60; hours /= 60;
                int minutes = hours % 60; hours /= 60;
                hours %= 24;
                t      = hours.ToString(Culture).PadLeft(2, '0') + ":" + minutes.ToString(Culture).PadLeft(2, '0') + ":" + seconds.ToString(Culture).PadLeft(2, '0');
                if (OptionClock)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
            } break;

            case "gradient":
                if (OptionGradient == GradientDisplayMode.Percentage)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pc = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pc).ToString("0.00", Culture) + "%" + (Math.Abs(pc) == pc ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.UnitOfChange)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.Permil)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pm = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pm).ToString("0.00", Culture) + "‰" + (Math.Abs(pm) == pm ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "speed":
                if (OptionSpeed == SpeedDisplayMode.Kmph)
                {
                    double kmph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 3.6;
                    t = kmph.ToString("0.00", Culture) + " km/h";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionSpeed == SpeedDisplayMode.Mph)
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "fps":
                int fps = (int)Math.Round(Game.InfoFrameRate);
                t = fps.ToString(Culture) + " fps";
                if (OptionFrameRates)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "ai":
                t = "A.I.";
                if (TrainManager.PlayerTrain.AI != null)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "score":
                if (Interface.CurrentOptions.GameMode == Interface.GameMode.Arcade)
                {
                    t = Game.CurrentScore.CurrentValue.ToString(Culture) + " / " + Game.CurrentScore.Maximum.ToString(Culture);
                    if (Game.CurrentScore.CurrentValue < 0)
                    {
                        sc = MessageColor.Red;
                    }
                    else if (Game.CurrentScore.CurrentValue > 0)
                    {
                        sc = MessageColor.Green;
                    }
                    else
                    {
                        sc = MessageColor.Gray;
                    }
                    Element.TransitionState = 0.0;
                }
                else
                {
                    Element.TransitionState = 1.0;
                    t = "";
                } break;

            default:
                t = Element.Text;
                break;
            }
            // transitions
            float alpha = 1.0f;

            if ((Element.Transition & HUD.Transition.Move) != 0)
            {
                double s = Element.TransitionState;
                x += Element.TransitionVector.X * s * s;
                y += Element.TransitionVector.Y * s * s;
            }
            if ((Element.Transition & HUD.Transition.Fade) != 0)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            else if (Element.Transition == HUD.Transition.None)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            // render
            if (alpha != 0.0f)
            {
                // background
                if (Element.Subject == "reverser")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxReverserWidth);
                    //X-Pos doesn't need to be changed
                }
                if (Element.Subject == "power")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.Subject == "brake")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                    if (TrainManager.PlayerTrain.MaxPowerNotchWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxPowerNotchWidth - 48);
                    }
                }
                if (Element.Subject == "single")
                {
                    w = Math.Max(Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth), TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.CenterMiddle.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        float r, g, b, a;
                        CreateBackColor(Element.BackgroundColor, sc, out r, out g, out b, out a);
                        GL.Color4(r, g, b, a * alpha);
                        RenderOverlayTexture(Element.CenterMiddle.BackgroundTexture, x, y, x + w, y + h);
                    }
                }
                {                 // text
                    System.Drawing.Size size = MeasureString(Element.Font, t);
                    float  u = size.Width;
                    float  v = size.Height;
                    double p = Math.Round(Element.TextAlignment.X < 0 ? x : Element.TextAlignment.X == 0 ? x + 0.5 * (w - u) : x + w - u);
                    double q = Math.Round(Element.TextAlignment.Y < 0 ? y : Element.TextAlignment.Y == 0 ? y + 0.5 * (h - v) : y + h - v);
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    float r, g, b, a;
                    CreateTextColor(Element.TextColor, sc, out r, out g, out b, out a);
                    DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(r, g, b, a * alpha), Element.TextShadow);
                }
                // overlay
                if (Element.CenterMiddle.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Element.CenterMiddle.OverlayTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        float r, g, b, a;
                        CreateBackColor(Element.OverlayColor, sc, out r, out g, out b, out a);
                        GL.Color4(r, g, b, a * alpha);
                        RenderOverlayTexture(Element.CenterMiddle.OverlayTexture, x, y, x + w, y + h);
                    }
                }
            }
        }
        /// <summary>Renders the list of score messages</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderScoreMessages(HUD.Element Element, double TimeElapsed)
        {
            // score messages
            int   n          = Game.ScoreMessages.Length;
            float totalwidth = 16.0f;

            float[] widths  = new float[n];
            float[] heights = new float[n];
            for (int j = 0; j < n; j++)
            {
                System.Drawing.Size size = MeasureString(Element.Font, Game.ScoreMessages[j].Text);
                widths[j]  = size.Width;
                heights[j] = size.Height;
                float a = widths[j] - j * Element.Value1;
                if (a > totalwidth)
                {
                    totalwidth = a;
                }
            }
            Game.ScoreMessagesRendererSize.X += 16.0 * TimeElapsed * ((double)totalwidth - Game.ScoreMessagesRendererSize.X);
            totalwidth = (float)Game.ScoreMessagesRendererSize.X;
            double lcrh, lw, rw;

            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);
            // start
            double w = Element.Alignment.X == 0 ? lw + rw + 128 : totalwidth + lw + rw;
            double h = Element.Value2 * n;
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X > 0 ? Screen.Width - w : 0.5 * (Screen.Width - w);
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y > 0 ? Screen.Height - h : 0.5 * (Screen.Height - h);

            x += Element.Position.X;
            y += Element.Position.Y;
            int m = 0;

            for (int j = 0; j < n; j++)
            {
                float br, bg, bb, ba;
                CreateBackColor(Element.BackgroundColor, Game.ScoreMessages[j].Color, out br, out bg, out bb, out ba);
                float tr, tg, tb, ta;
                CreateTextColor(Element.TextColor, Game.ScoreMessages[j].Color, out tr, out tg, out tb, out ta);
                float or, og, ob, oa;
                CreateBackColor(Element.OverlayColor, Game.ScoreMessages[j].Color, out or, out og, out ob, out oa);
                double tx, ty;
                bool   preserve = false;
                if ((Element.Transition & HUD.Transition.Move) != 0)
                {
                    if (Game.SecondsSinceMidnight < Game.ScoreMessages[j].Timeout)
                    {
                        if (Game.ScoreMessages[j].RendererAlpha == 0.0)
                        {
                            Game.ScoreMessages[j].RendererPosition.X = x + Element.TransitionVector.X;
                            Game.ScoreMessages[j].RendererPosition.Y = y + Element.TransitionVector.Y;
                            Game.ScoreMessages[j].RendererAlpha      = 1.0;
                        }
                        tx       = x;
                        ty       = y + m * Element.Value2;
                        preserve = true;
                    }
                    else if (Element.Transition == HUD.Transition.MoveAndFade)
                    {
                        tx = x;
                        ty = y + m * Element.Value2;
                    }
                    else
                    {
                        tx = x + Element.TransitionVector.X;
                        ty = y + (j + 1) * Element.TransitionVector.Y;
                    }
                    const double speed = 2.0;
                    double       dx    = (speed * Math.Abs(tx - Game.ScoreMessages[j].RendererPosition.X) + 0.1) * TimeElapsed;
                    double       dy    = (speed * Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) + 0.1) * TimeElapsed;
                    if (Math.Abs(tx - Game.ScoreMessages[j].RendererPosition.X) < dx)
                    {
                        Game.ScoreMessages[j].RendererPosition.X = tx;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.X += Math.Sign(tx - Game.ScoreMessages[j].RendererPosition.X) * dx;
                    }
                    if (Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) < dy)
                    {
                        Game.ScoreMessages[j].RendererPosition.Y = ty;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.Y += Math.Sign(ty - Game.ScoreMessages[j].RendererPosition.Y) * dy;
                    }
                }
                else
                {
                    tx = x;
                    ty = y + m * Element.Value2;
                    Game.ScoreMessages[j].RendererPosition.X = 0.0;
                    const double speed = 12.0;
                    double       dy    = (speed * Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) + 0.1) * TimeElapsed;
                    Game.ScoreMessages[j].RendererPosition.X = x;
                    if (Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) < dy)
                    {
                        Game.ScoreMessages[j].RendererPosition.Y = ty;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.Y += Math.Sign(ty - Game.ScoreMessages[j].RendererPosition.Y) * dy;
                    }
                }
                if ((Element.Transition & HUD.Transition.Fade) != 0)
                {
                    if (Game.SecondsSinceMidnight >= Game.ScoreMessages[j].Timeout)
                    {
                        Game.ScoreMessages[j].RendererAlpha -= TimeElapsed;
                        if (Game.ScoreMessages[j].RendererAlpha < 0.0)
                        {
                            Game.ScoreMessages[j].RendererAlpha = 0.0;
                        }
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererAlpha += TimeElapsed;
                        if (Game.ScoreMessages[j].RendererAlpha > 1.0)
                        {
                            Game.ScoreMessages[j].RendererAlpha = 1.0;
                        }
                        preserve = true;
                    }
                }
                else if (Game.SecondsSinceMidnight > Game.ScoreMessages[j].Timeout)
                {
                    if (Math.Abs(Game.ScoreMessages[j].RendererPosition.X - tx) < 0.1 & Math.Abs(Game.ScoreMessages[j].RendererPosition.Y - ty) < 0.1)
                    {
                        Game.ScoreMessages[j].RendererAlpha = 0.0;
                    }
                }
                if (preserve)
                {
                    m++;
                }
                double px    = Game.ScoreMessages[j].RendererPosition.X + (double)j * (double)Element.Value1;
                double py    = Game.ScoreMessages[j].RendererPosition.Y;
                float  alpha = (float)(Game.ScoreMessages[j].RendererAlpha * Game.ScoreMessages[j].RendererAlpha);
                // graphics
                HUD.Image Left   = j == 0 ? Element.TopLeft : j < n - 1 ? Element.CenterLeft : Element.BottomLeft;
                HUD.Image Middle = j == 0 ? Element.TopMiddle : j < n - 1 ? Element.CenterMiddle : Element.BottomMiddle;
                HUD.Image Right  = j == 0 ? Element.TopRight : j < n - 1 ? Element.CenterRight : Element.BottomRight;
                // left background
                if (Left.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Left.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.BackgroundTexture.Width;
                        double v = (double)Left.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Left.BackgroundTexture, px, py, px + u, py + v);
                    }
                }
                // right background
                if (Right.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Right.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.BackgroundTexture.Width;
                        double v = (double)Right.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Right.BackgroundTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle background
                if (Middle.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Middle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Middle.BackgroundTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
                {                 // text
                    string t = Game.ScoreMessages[j].Text;
                    double u = widths[j];
                    double v = heights[j];
                    double p = Math.Round((Element.TextAlignment.X < 0 ? px : Element.TextAlignment.X > 0 ? px + w - u : px + 0.5 * (w - u)) - j * Element.Value1);
                    double q = Math.Round(Element.TextAlignment.Y < 0 ? py : Element.TextAlignment.Y > 0 ? py + lcrh - v : py + 0.5 * (lcrh - v));
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(tr, tg, tb, ta * alpha), Element.TextShadow);
                }
                // left overlay
                if (Left.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Left.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.OverlayTexture.Width;
                        double v = (double)Left.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Left.OverlayTexture, px, py, px + u, py + v);
                    }
                }
                // right overlay
                if (Right.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Right.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.OverlayTexture.Width;
                        double v = (double)Right.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Right.OverlayTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle overlay
                if (Middle.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Middle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Middle.OverlayTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
            }
        }
Beispiel #12
0
        /// <summary>This function renderers full-screen motion blur if selected</summary>
        private static void RenderFullscreenMotionBlur()
        {
            if (Screen.Minimized)
            {
                /*
                 * HACK:
                 * This breaks if minimized, even if we don't reset the W / H values
                 */
                return;
            }
            int w = Interface.CurrentOptions.NoTextureResize ? Screen.Width : Textures.RoundUpToPowerOfTwo(Screen.Width);
            int h = Interface.CurrentOptions.NoTextureResize ? Screen.Height : Textures.RoundUpToPowerOfTwo(Screen.Height);

            // render
            if (PixelBufferOpenGlTextureIndex >= 0)
            {
                double strength;
                switch (Interface.CurrentOptions.MotionBlur)
                {
                case Interface.MotionBlurMode.Low: strength = 0.0025; break;

                case Interface.MotionBlurMode.Medium: strength = 0.0040; break;

                case Interface.MotionBlurMode.High: strength = 0.0064; break;

                default: strength = 0.0040; break;
                }
                double speed       = Math.Abs(World.CameraSpeed);
                double denominator = strength * Game.InfoFrameRate * Math.Sqrt(speed);
                float  factor;
                if (denominator > 0.001)
                {
                    factor = (float)Math.Exp(-1.0 / denominator);
                }
                else
                {
                    factor = 0.0f;
                }
                // initialize
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                    BlendEnabled = true;
                }
                if (LightingEnabled)
                {
                    GL.Disable(EnableCap.Lighting);
                    LightingEnabled = false;
                }
                GL.MatrixMode(MatrixMode.Projection);
                GL.PushMatrix();
                GL.LoadIdentity();
                GL.Ortho(0.0, (double)Screen.Width, 0.0, (double)Screen.Height, -1.0, 1.0);
                GL.MatrixMode(MatrixMode.Modelview);
                GL.PushMatrix();
                GL.LoadIdentity();
                if (!TexturingEnabled)
                {
                    GL.Enable(EnableCap.Texture2D);
                    TexturingEnabled = true;
                }
                // render
                GL.BindTexture(TextureTarget.Texture2D, PixelBufferOpenGlTextureIndex);
                GL.Color4(1.0f, 1.0f, 1.0f, factor);
                GL.Begin(PrimitiveType.Polygon);
                GL.TexCoord2(0.0, 0.0);
                GL.Vertex2(0.0, 0.0);
                GL.TexCoord2(0.0, 1.0);
                GL.Vertex2(0.0, (double)h);
                GL.TexCoord2(1.0, 1.0);
                GL.Vertex2((double)w, (double)h);
                GL.TexCoord2(1.0, 0.0);
                GL.Vertex2((double)w, 0.0);
                GL.End();
                // finalize
                GL.PopMatrix();
                GL.MatrixMode(MatrixMode.Projection);
                GL.PopMatrix();
                GL.MatrixMode(MatrixMode.Modelview);
            }
            // retrieve buffer
            {
                GL.BindTexture(TextureTarget.Texture2D, PixelBufferOpenGlTextureIndex);
                GL.CopyTexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgb8, 0, 0, w, h, 0);
            }
        }
Beispiel #13
0
        /// <summary>Loads the current HUD</summary>
        internal static void LoadHUD()
        {
            CultureInfo Culture = CultureInfo.InvariantCulture;
            string      Folder  = Program.FileSystem.GetDataFolder("In-game", Interface.CurrentOptions.UserInterfaceFolder);
            string      File    = OpenBveApi.Path.CombineFile(Folder, "interface.cfg");

            CurrentHudElements = new Element[16];
            int Length = 0;

            if (System.IO.File.Exists(File))
            {
                string[] Lines = System.IO.File.ReadAllLines(File, new System.Text.UTF8Encoding());
                for (int i = 0; i < Lines.Length; i++)
                {
                    int j = Lines[i].IndexOf(';');
                    if (j >= 0)
                    {
                        Lines[i] = Lines[i].Substring(0, j).Trim();
                    }
                    else
                    {
                        Lines[i] = Lines[i].Trim();
                    }
                    if (Lines[i].Length != 0)
                    {
                        if (!Lines[i].StartsWith(";", StringComparison.Ordinal))
                        {
                            if (Lines[i].Equals("[element]", StringComparison.OrdinalIgnoreCase))
                            {
                                Length++;
                                if (Length > CurrentHudElements.Length)
                                {
                                    Array.Resize <Element>(ref CurrentHudElements, CurrentHudElements.Length << 1);
                                }

                                CurrentHudElements[Length - 1] = new Element();
                            }
                            else if (Length == 0)
                            {
                                MessageBox.Show("Line outside of [element] structure encountered at line " + (i + 1).ToString(Culture) + " in " + File);
                            }
                            else
                            {
                                j = Lines[i].IndexOf("=", StringComparison.Ordinal);
                                if (j >= 0)
                                {
                                    string   Command   = Lines[i].Substring(0, j).TrimEnd();
                                    string[] Arguments = Lines[i].Substring(j + 1).TrimStart().Split(new char[] { ',' }, StringSplitOptions.None);
                                    for (j = 0; j < Arguments.Length; j++)
                                    {
                                        Arguments[j] = Arguments[j].Trim();
                                    }
                                    switch (Command.ToLowerInvariant())
                                    {
                                    case "subject":
                                        if (Arguments.Length == 1)
                                        {
                                            CurrentHudElements[Length - 1].Subject = Arguments[0];
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "position":
                                        if (Arguments.Length == 2)
                                        {
                                            float x, y;
                                            if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x))
                                            {
                                                MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y))
                                            {
                                                MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].Position.X = x;
                                                CurrentHudElements[Length - 1].Position.Y = y;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "alignment":
                                        if (Arguments.Length == 2)
                                        {
                                            int x, y;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x))
                                            {
                                                MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y))
                                            {
                                                MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].Alignment.X = Math.Sign(x);
                                                CurrentHudElements[Length - 1].Alignment.Y = Math.Sign(y);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "topleft":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopLeft.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopLeft.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "topmiddle":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopMiddle.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopMiddle.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "topright":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopRight.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopRight.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "centerleft":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterLeft.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterLeft.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "centermiddle":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterMiddle.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterMiddle.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "centerright":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterRight.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterRight.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "bottomleft":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomLeft.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomLeft.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "bottommiddle":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomMiddle.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomMiddle.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "bottomright":
                                        if (Arguments.Length == 2)
                                        {
                                            if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomRight.BackgroundTexture);
                                            }

                                            if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase))
                                            {
                                                Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomRight.OverlayTexture);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "backcolor":
                                        if (Arguments.Length == 4)
                                        {
                                            int r, g, b, a;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r))
                                            {
                                                MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g))
                                            {
                                                MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b))
                                            {
                                                MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a))
                                            {
                                                MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                r = r < 0 ? 0 : r > 255 ? 255 : r;
                                                g = g < 0 ? 0 : g > 255 ? 255 : g;
                                                b = b < 0 ? 0 : b > 255 ? 255 : b;
                                                a = a < 0 ? 0 : a > 255 ? 255 : a;
                                                CurrentHudElements[Length - 1].BackgroundColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a);
                                            }

                                            break;
                                        }
                                        MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        break;

                                    case "overlaycolor":
                                        if (Arguments.Length == 4)
                                        {
                                            int r, g, b, a;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r))
                                            {
                                                MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g))
                                            {
                                                MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b))
                                            {
                                                MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a))
                                            {
                                                MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                r = r < 0 ? 0 : r > 255 ? 255 : r;
                                                g = g < 0 ? 0 : g > 255 ? 255 : g;
                                                b = b < 0 ? 0 : b > 255 ? 255 : b;
                                                a = a < 0 ? 0 : a > 255 ? 255 : a;
                                                CurrentHudElements[Length - 1].OverlayColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a);
                                            }

                                            break;
                                        }
                                        MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        break;

                                    case "textcolor":
                                        if (Arguments.Length == 4)
                                        {
                                            int r, g, b, a;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r))
                                            {
                                                MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g))
                                            {
                                                MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b))
                                            {
                                                MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a))
                                            {
                                                MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                r = r < 0 ? 0 : r > 255 ? 255 : r;
                                                g = g < 0 ? 0 : g > 255 ? 255 : g;
                                                b = b < 0 ? 0 : b > 255 ? 255 : b;
                                                a = a < 0 ? 0 : a > 255 ? 255 : a;
                                                CurrentHudElements[Length - 1].TextColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a);
                                            }

                                            break;
                                        }
                                        MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        break;

                                    case "textposition":
                                        if (Arguments.Length == 2)
                                        {
                                            float x, y;
                                            if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x))
                                            {
                                                MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y))
                                            {
                                                MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].TextPosition.X = x;
                                                CurrentHudElements[Length - 1].TextPosition.Y = y;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "textalignment":
                                        if (Arguments.Length == 2)
                                        {
                                            int x, y;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x))
                                            {
                                                MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y))
                                            {
                                                MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].TextAlignment.X = Math.Sign(x);
                                                CurrentHudElements[Length - 1].TextAlignment.Y = Math.Sign(y);
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "textsize":
                                        if (Arguments.Length == 1)
                                        {
                                            int s;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s))
                                            {
                                                MessageBox.Show("SIZE is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                switch (s)
                                                {
                                                case 0:
                                                    CurrentHudElements[Length - 1].Font = Fonts.VerySmallFont;
                                                    break;

                                                case 1:
                                                    CurrentHudElements[Length - 1].Font = Fonts.SmallFont;
                                                    break;

                                                case 2:
                                                    CurrentHudElements[Length - 1].Font = Fonts.NormalFont;
                                                    break;

                                                case 3:
                                                    CurrentHudElements[Length - 1].Font = Fonts.LargeFont;
                                                    break;

                                                case 4:
                                                    CurrentHudElements[Length - 1].Font = Fonts.VeryLargeFont;
                                                    break;

                                                default:
                                                    CurrentHudElements[Length - 1].Font = Fonts.NormalFont;
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "textshadow":
                                        if (Arguments.Length == 1)
                                        {
                                            int s;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s))
                                            {
                                                MessageBox.Show("SHADOW is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].TextShadow = s != 0;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "text":
                                        if (Arguments.Length == 1)
                                        {
                                            CurrentHudElements[Length - 1].Text = Arguments[0];
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "value":
                                        if (Arguments.Length == 1)
                                        {
                                            int n;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n))
                                            {
                                                MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].Value1 = n;
                                            }
                                        }
                                        else if (Arguments.Length == 2)
                                        {
                                            float a, b;
                                            if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out a))
                                            {
                                                MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out b))
                                            {
                                                MessageBox.Show("VALUE2 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].Value1 = a;
                                                CurrentHudElements[Length - 1].Value2 = b;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "transition":
                                        if (Arguments.Length == 1)
                                        {
                                            int n;
                                            if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n))
                                            {
                                                MessageBox.Show("TRANSITION is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].Transition = (HUD.Transition)n;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }
                                        break;

                                    case "transitionvector":
                                        if (Arguments.Length == 2)
                                        {
                                            float x, y;
                                            if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x))
                                            {
                                                MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y))
                                            {
                                                MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                            }
                                            else
                                            {
                                                CurrentHudElements[Length - 1].TransitionVector.X = x;
                                                CurrentHudElements[Length - 1].TransitionVector.Y = y;
                                            }
                                        }
                                        else
                                        {
                                            MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File);
                                        }

                                        break;

                                    default:
                                        MessageBox.Show("Invalid command encountered at line " + (i + 1).ToString(Culture) + " in " + File);
                                        break;
                                    }
                                }
                                else
                                {
                                    MessageBox.Show("Invalid statement encountered at line " + (i + 1).ToString(Culture) + " in " + File);
                                }
                            }
                        }
                    }
                }
            }

            Array.Resize <Element>(ref CurrentHudElements, Length);
        }
Beispiel #14
0
        internal void Apply(ref ObjectManager.StaticObject Object)
        {
            if (TransformMatrix != Matrix4D.NoTransformation)
            {
                for (int i = 0; i < Vertices.Length; i++)
                {
                    Vertices[i].Coordinates.Transform(TransformMatrix);
                }
            }
            if (Faces.Length != 0)
            {
                int mf = Object.Mesh.Faces.Length;
                int mm = Object.Mesh.Materials.Length;
                int mv = Object.Mesh.Vertices.Length;
                Array.Resize <MeshFace>(ref Object.Mesh.Faces, mf + Faces.Length);
                Array.Resize <MeshMaterial>(ref Object.Mesh.Materials, mm + Materials.Length);
                Array.Resize <VertexTemplate>(ref Object.Mesh.Vertices, mv + Vertices.Length);
                for (int i = 0; i < Vertices.Length; i++)
                {
                    Object.Mesh.Vertices[mv + i] = Vertices[i];
                }

                for (int i = 0; i < Faces.Length; i++)
                {
                    Object.Mesh.Faces[mf + i] = Faces[i];
                    for (int j = 0; j < Object.Mesh.Faces[mf + i].Vertices.Length; j++)
                    {
                        Object.Mesh.Faces[mf + i].Vertices[j].Index += (ushort)mv;
                    }

                    Object.Mesh.Faces[mf + i].Material += (ushort)mm;
                }

                for (int i = 0; i < Materials.Length; i++)
                {
                    Object.Mesh.Materials[mm + i].Flags            = (byte)((Materials[i].EmissiveColorUsed ? MeshMaterial.EmissiveColorMask : 0) | (Materials[i].TransparentColorUsed ? MeshMaterial.TransparentColorMask : 0));
                    Object.Mesh.Materials[mm + i].Color            = Materials[i].Color;
                    Object.Mesh.Materials[mm + i].TransparentColor = Materials[i].TransparentColor;
                    if (Materials[i].DaytimeTexture != null || Materials[i].Text != null)
                    {
                        Texture tday;
                        if (Materials[i].Text != null)
                        {
                            Bitmap bitmap = null;
                            if (Materials[i].DaytimeTexture != null)
                            {
                                bitmap = new Bitmap(Materials[i].DaytimeTexture);
                            }

                            Bitmap texture = TextOverlay.AddTextToBitmap(bitmap, Materials[i].Text, Materials[i].Font, 12, Materials[i].BackgroundColor, Materials[i].TextColor, Materials[i].TextPadding);
                            tday = Textures.RegisterTexture(texture, new TextureParameters(null, new Color24(Materials[i].TransparentColor.R, Materials[i].TransparentColor.G, Materials[i].TransparentColor.B)));
                        }
                        else
                        {
                            if (Materials[i].TransparentColorUsed)
                            {
                                Textures.RegisterTexture(Materials[i].DaytimeTexture,
                                                         new TextureParameters(null,
                                                                               new Color24(Materials[i].TransparentColor.R, Materials[i].TransparentColor.G,
                                                                                           Materials[i].TransparentColor.B)), out tday);
                            }
                            else
                            {
                                Textures.RegisterTexture(Materials[i].DaytimeTexture, out tday);
                            }
                        }

                        Object.Mesh.Materials[mm + i].DaytimeTexture = tday;
                    }
                    else
                    {
                        Object.Mesh.Materials[mm + i].DaytimeTexture = null;
                    }

                    Object.Mesh.Materials[mm + i].EmissiveColor = Materials[i].EmissiveColor;
                    if (Materials[i].NighttimeTexture != null)
                    {
                        Texture tnight;
                        if (Materials[i].TransparentColorUsed)
                        {
                            Textures.RegisterTexture(Materials[i].NighttimeTexture, new TextureParameters(null, new Color24(Materials[i].TransparentColor.R, Materials[i].TransparentColor.G, Materials[i].TransparentColor.B)), out tnight);
                        }
                        else
                        {
                            Textures.RegisterTexture(Materials[i].NighttimeTexture, out tnight);
                        }

                        Object.Mesh.Materials[mm + i].NighttimeTexture = tnight;
                    }
                    else
                    {
                        Object.Mesh.Materials[mm + i].NighttimeTexture = null;
                    }

                    Object.Mesh.Materials[mm + i].DaytimeNighttimeBlend = 0;
                    Object.Mesh.Materials[mm + i].BlendMode             = Materials[i].BlendMode;
                    Object.Mesh.Materials[mm + i].GlowAttenuationData   = Materials[i].GlowAttenuationData;
                    Object.Mesh.Materials[mm + i].WrapMode = Materials[i].WrapMode;
                }
            }
        }
Beispiel #15
0
            internal void Apply(out ObjectManager.StaticObject Object)
            {
                Object = new ObjectManager.StaticObject
                {
                    Mesh =
                    {
                        Faces     = new MeshFace[]       { },
                        Materials = new MeshMaterial[]   { },
                        Vertices  = new VertexTemplate[] { }
                    }
                };
                if (faces.Count != 0)
                {
                    int mf = Object.Mesh.Faces.Length;
                    int mm = Object.Mesh.Materials.Length;
                    int mv = Object.Mesh.Vertices.Length;
                    Array.Resize(ref Object.Mesh.Faces, mf + faces.Count);
                    Array.Resize(ref Object.Mesh.Materials, mm + materials.Count);
                    Array.Resize(ref Object.Mesh.Vertices, mv + verticies.Count);
                    for (int i = 0; i < verticies.Count; i++)
                    {
                        Object.Mesh.Vertices[mv + i] = new OpenBveApi.Objects.Vertex(verticies[i].Coordinates, verticies[i].TextureCoordinates);
                    }

                    for (int i = 0; i < faces.Count; i++)
                    {
                        Object.Mesh.Faces[i]          = new MeshFace(faces[i].Vertices);
                        Object.Mesh.Faces[i].Material = (ushort)faces[i].Material;
                        for (int k = 0; k < faces[i].Vertices.Length; k++)
                        {
                            Object.Mesh.Faces[i].Vertices[k].Normal = verticies[faces[i].Vertices[k]].Normal;
                        }

                        for (int j = 0; j < Object.Mesh.Faces[mf + i].Vertices.Length; j++)
                        {
                            Object.Mesh.Faces[mf + i].Vertices[j].Index += (ushort)mv;
                        }

                        Object.Mesh.Faces[mf + i].Material += (ushort)mm;
                    }

                    for (int i = 0; i < materials.Count; i++)
                    {
                        Object.Mesh.Materials[mm + i].Flags            = 0;
                        Object.Mesh.Materials[mm + i].Color            = materials[i].Color;
                        Object.Mesh.Materials[mm + i].TransparentColor = Color24.Black;
                        Object.Mesh.Materials[mm + i].BlendMode        = MeshMaterialBlendMode.Normal;
                        if (materials[i].DaytimeTexture != null)
                        {
                            OpenBveApi.Textures.Texture tday;
                            Textures.RegisterTexture(materials[i].DaytimeTexture, out tday);
                            Object.Mesh.Materials[mm + i].DaytimeTexture = tday;
                        }
                        else
                        {
                            Object.Mesh.Materials[mm + i].DaytimeTexture = null;
                        }

                        Object.Mesh.Materials[mm + i].EmissiveColor         = materials[i].EmissiveColor;
                        Object.Mesh.Materials[mm + i].NighttimeTexture      = null;
                        Object.Mesh.Materials[mm + i].DaytimeNighttimeBlend = 0;
                        Object.Mesh.Materials[mm + i].GlowAttenuationData   = materials[i].GlowAttenuationData;
                        Object.Mesh.Materials[mm + i].WrapMode = materials[i].WrapMode;
                    }
                }
            }
        private static void RenderFace(ref World.MeshMaterial Material, VertexTemplate[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
        {
            // texture
            if (Material.DaytimeTexture != null)
            {
                if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
                {
                    if (!TexturingEnabled)
                    {
                        GL.Enable(EnableCap.Texture2D);
                        TexturingEnabled = true;
                    }
                    if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
                    {
                        GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                        LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
                    }
                }
                else
                {
                    if (TexturingEnabled)
                    {
                        GL.Disable(EnableCap.Texture2D);
                        TexturingEnabled = false;
                        LastBoundTexture = null;
                    }
                }
            }
            else
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    LastBoundTexture = null;
                }
            }
            // blend mode
            float factor;

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

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

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

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

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

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

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

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

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

                default:
                    GL.Begin(PrimitiveType.Polygon);
                    break;
                }
                float alphafactor;
                if (Material.GlowAttenuationData != 0)
                {
                    alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
                    float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }
                    alphafactor *= blend;
                }
                else
                {
                    alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
                    if (alphafactor > 1.0f)
                    {
                        alphafactor = 1.0f;
                    }
                }
                GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
                if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
                }
                else
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                    if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                    {
                        ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                        GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                    }
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                }
                GL.End();
                RestoreAlphaFunc();
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
            }
            // normals
            if (OptionNormals)
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.Begin(PrimitiveType.Lines);
                    GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
                    GL.End();
                }
            }
            // finalize
            if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
            {
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
                if (FogEnabled)
                {
                    GL.Enable(EnableCap.Fog);
                }
            }
        }
Beispiel #17
0
 /// <summary>Registers a texture and returns a handle to the texture.</summary>
 /// <param name="texture">The texture data.</param>
 /// <param name="parameters">The parameters that specify how to process the texture.</param>
 /// <param name="handle">Receives the handle to the texture.</param>
 /// <returns>Whether loading the texture was successful.</returns>
 public override bool RegisterTexture(OpenBveApi.Textures.Texture texture, OpenBveApi.Textures.TextureParameters parameters, out OpenBveApi.Textures.TextureHandle handle)
 {
     texture = texture.ApplyParameters(parameters);
     handle  = Textures.RegisterTexture(texture);
     return(true);
 }
Beispiel #18
0
		// create element
		private static int CreateElement(TrainManager.Train Train, double Left, double Top, double Width, double Height, double FullWidth, double FullHeight, double WorldLeft, double WorldTop, double WorldWidth, double WorldHeight, double WorldZ, double DriverX, double DriverY, double DriverZ, Textures.Texture Texture, Color32 Color, bool AddStateToLastElement) {
			// create object
			ObjectManager.StaticObject Object = new ObjectManager.StaticObject();
			Vector3[] v = new Vector3[4];
			double sx = 0.5 * WorldWidth * Width / FullWidth;
			double sy = 0.5 * WorldHeight * Height / FullHeight;
			v[0] = new Vector3(-sx, -sy, 0);
			v[1] = new Vector3(-sx, sy, 0);
			v[2] = new Vector3(sx, sy, 0);
			v[3] = new Vector3(sx, -sy, 0);
			World.Vertex t0 = new World.Vertex(v[0], new Vector2(0.0f, 1.0f));
			World.Vertex t1 = new World.Vertex(v[1], new Vector2(0.0f, 0.0f));
			World.Vertex t2 = new World.Vertex(v[2], new Vector2(1.0f, 0.0f));
			World.Vertex t3 = new World.Vertex(v[3], new Vector2(1.0f, 1.0f));
			Object.Mesh.Vertices = new World.Vertex[] { t0, t1, t2, t3 };
			Object.Mesh.Faces = new World.MeshFace[] { new World.MeshFace(new int[] { 0, 1, 2, 3 }) };
			Object.Mesh.Materials = new World.MeshMaterial[1];
			Object.Mesh.Materials[0].Flags = Texture != null ? (byte)World.MeshMaterial.TransparentColorMask : (byte)0;
			Object.Mesh.Materials[0].Color = Color;
			Object.Mesh.Materials[0].TransparentColor = new Color24(0, 0, 255);
			Object.Mesh.Materials[0].DaytimeTexture = Texture;
			Object.Mesh.Materials[0].NighttimeTexture = null;
			Object.Dynamic = true;
			// calculate offset
			Vector3 o;
			o.X = WorldLeft + sx + WorldWidth * Left / FullWidth;
			o.Y = WorldTop - sy - WorldHeight * Top / FullHeight;
			o.Z = WorldZ;
			// add object
			if (AddStateToLastElement) {
				int n = Train.Cars[Train.DriverCar].CarSections[0].Elements.Length - 1;
				int j = Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States.Length;
				Array.Resize<ObjectManager.AnimatedObjectState>(ref Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States, j + 1);
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[j].Position = o;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[j].Object = Object;
				return n;
			} else {
				int n = Train.Cars[Train.DriverCar].CarSections[0].Elements.Length;
				Array.Resize<ObjectManager.AnimatedObject>(ref Train.Cars[Train.DriverCar].CarSections[0].Elements, n + 1);
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n] = new ObjectManager.AnimatedObject();
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States = new ObjectManager.AnimatedObjectState[1];
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[0].Position = o;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[0].Object = Object;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].CurrentState = 0;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].ObjectIndex = ObjectManager.CreateDynamicObject();
				ObjectManager.Objects[Train.Cars[Train.DriverCar].CarSections[0].Elements[n].ObjectIndex] = ObjectManager.CloneObject(Object);
				return n;
			}
		}
Beispiel #19
0
        /// <summary>This method is called once the route and train data have been preprocessed, in order to physically setup the simulation</summary>
        private void SetupSimulation()
        {
            if (Loading.Cancel)
            {
                Close();
            }

            lock (BaseRenderer.GdiPlusLock)
            {
                Timetable.CreateTimetable();
            }
            //Check if any critical errors have occured during the route or train loading
            for (int i = 0; i < Interface.MessageCount; i++)
            {
                if (Interface.LogMessages[i].Type == MessageType.Critical)
                {
                    MessageBox.Show("A critical error has occured:\n\n" + Interface.LogMessages[i].Text + "\n\nPlease inspect the error log file for further information.", "Load", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    Close();
                }
            }
            Program.Renderer.Lighting.Initialize();
            Game.LogRouteName = System.IO.Path.GetFileName(MainLoop.currentResult.RouteFile);
            Game.LogTrainName = System.IO.Path.GetFileName(MainLoop.currentResult.TrainFolder);
            Game.LogDateTime  = DateTime.Now;

            if (Interface.CurrentOptions.LoadInAdvance)
            {
                Textures.LoadAllTextures();
            }
            else
            {
                Program.Renderer.TextureManager.UnloadAllTextures();
            }
            // camera
            Program.Renderer.InitializeVisibility();
            TrainManager.PlayerTrain.DriverBody = new DriverBody(TrainManager.PlayerTrain);
            Program.Renderer.CameraTrackFollower.UpdateAbsolute(0.0, true, false);
            Program.Renderer.CameraTrackFollower.UpdateAbsolute(-0.1, true, false);
            Program.Renderer.CameraTrackFollower.UpdateAbsolute(0.1, true, false);
            Program.Renderer.CameraTrackFollower.TriggerType = EventTriggerType.Camera;
            // starting time and track position
            Program.CurrentRoute.SecondsSinceMidnight = 0.0;
            Game.StartupTime = 0.0;
            int    PlayerFirstStationIndex = -1;
            double PlayerFirstStationPosition;
            int    os = -1;
            bool   f  = false;

            for (int i = 0; i < Program.CurrentRoute.Stations.Length; i++)
            {
                if (!String.IsNullOrEmpty(Game.InitialStationName))
                {
                    if (Game.InitialStationName.ToLowerInvariant() == Program.CurrentRoute.Stations[i].Name.ToLowerInvariant())
                    {
                        PlayerFirstStationIndex = i;
                    }
                }
                if (Program.CurrentRoute.Stations[i].StopMode == StationStopMode.AllStop | Program.CurrentRoute.Stations[i].StopMode == StationStopMode.PlayerStop & Program.CurrentRoute.Stations[i].Stops.Length != 0)
                {
                    if (f == false)
                    {
                        os = i;
                        f  = true;
                    }
                }
            }
            if (PlayerFirstStationIndex == -1)
            {
                if (os == -1)
                {
                    PlayerFirstStationIndex = 0;
                }
                else
                {
                    PlayerFirstStationIndex = os;
                }
            }
            {
                int s = Program.CurrentRoute.Stations[PlayerFirstStationIndex].GetStopIndex(TrainManager.PlayerTrain.NumberOfCars);
                if (s >= 0)
                {
                    PlayerFirstStationPosition = Program.CurrentRoute.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition;

                    double TrainLength = 0.0;
                    for (int c = 0; c < TrainManager.PlayerTrain.Cars.Length; c++)
                    {
                        TrainLength += TrainManager.PlayerTrain.Cars[c].Length;
                    }

                    for (int j = 0; j < Program.CurrentRoute.BufferTrackPositions.Length; j++)
                    {
                        if (PlayerFirstStationPosition > Program.CurrentRoute.BufferTrackPositions[j] && PlayerFirstStationPosition - TrainLength < Program.CurrentRoute.BufferTrackPositions[j])
                        {
                            /*
                             * HACK: The initial start position for the player train is stuck on a set of buffers
                             * This means we have to make some one the fly adjustments to the first station stop position
                             */

                            //Set the start position to be the buffer position plus the train length plus 1m
                            PlayerFirstStationPosition = Program.CurrentRoute.BufferTrackPositions[j] + TrainLength + 1;
                            //Update the station stop location
                            if (s >= 0)
                            {
                                Program.CurrentRoute.Stations[PlayerFirstStationIndex].Stops[s].TrackPosition = PlayerFirstStationPosition;
                            }
                            else
                            {
                                Program.CurrentRoute.Stations[PlayerFirstStationIndex].DefaultTrackPosition = PlayerFirstStationPosition;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    PlayerFirstStationPosition = Program.CurrentRoute.Stations[PlayerFirstStationIndex].DefaultTrackPosition;
                }
                if (Game.InitialStationTime != -1)
                {
                    Program.CurrentRoute.SecondsSinceMidnight = Game.InitialStationTime;
                    Game.StartupTime = Game.InitialStationTime;
                }
                else
                {
                    if (Program.CurrentRoute.Stations[PlayerFirstStationIndex].ArrivalTime < 0.0)
                    {
                        if (Program.CurrentRoute.Stations[PlayerFirstStationIndex].DepartureTime < 0.0)
                        {
                            Program.CurrentRoute.SecondsSinceMidnight = 0.0;
                            Game.StartupTime = 0.0;
                        }
                        else
                        {
                            Program.CurrentRoute.SecondsSinceMidnight = Program.CurrentRoute.Stations[PlayerFirstStationIndex].DepartureTime -
                                                                        Program.CurrentRoute.Stations[PlayerFirstStationIndex].StopTime;
                            Game.StartupTime = Program.CurrentRoute.Stations[PlayerFirstStationIndex].DepartureTime -
                                               Program.CurrentRoute.Stations[PlayerFirstStationIndex].StopTime;
                        }
                    }
                    else
                    {
                        Program.CurrentRoute.SecondsSinceMidnight = Program.CurrentRoute.Stations[PlayerFirstStationIndex].ArrivalTime;
                        Game.StartupTime = Program.CurrentRoute.Stations[PlayerFirstStationIndex].ArrivalTime;
                    }
                }
            }
            int    OtherFirstStationIndex    = -1;
            double OtherFirstStationPosition = 0.0;
            double OtherFirstStationTime     = 0.0;

            for (int i = 0; i < Program.CurrentRoute.Stations.Length; i++)
            {
                if (Program.CurrentRoute.Stations[i].StopMode == StationStopMode.AllStop | Program.CurrentRoute.Stations[i].StopMode == StationStopMode.PlayerPass & Program.CurrentRoute.Stations[i].Stops.Length != 0)
                {
                    OtherFirstStationIndex = i;
                    int s = Program.CurrentRoute.Stations[i].GetStopIndex(TrainManager.PlayerTrain.Cars.Length);
                    if (s >= 0)
                    {
                        OtherFirstStationPosition = Program.CurrentRoute.Stations[i].Stops[s].TrackPosition;
                    }
                    else
                    {
                        OtherFirstStationPosition = Program.CurrentRoute.Stations[i].DefaultTrackPosition;
                    }
                    if (Program.CurrentRoute.Stations[i].ArrivalTime < 0.0)
                    {
                        if (Program.CurrentRoute.Stations[i].DepartureTime < 0.0)
                        {
                            OtherFirstStationTime = 0.0;
                        }
                        else
                        {
                            OtherFirstStationTime = Program.CurrentRoute.Stations[i].DepartureTime - Program.CurrentRoute.Stations[i].StopTime;
                        }
                    }
                    else
                    {
                        OtherFirstStationTime = Program.CurrentRoute.Stations[i].ArrivalTime;
                    }
                    break;
                }
            }
            if (Game.PrecedingTrainTimeDeltas.Length != 0)
            {
                OtherFirstStationTime -= Game.PrecedingTrainTimeDeltas[Game.PrecedingTrainTimeDeltas.Length - 1];
                if (OtherFirstStationTime < Program.CurrentRoute.SecondsSinceMidnight)
                {
                    Program.CurrentRoute.SecondsSinceMidnight = OtherFirstStationTime;
                }
            }
            // initialize trains
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                TrainManager.Trains[i].Initialize();
                int s = TrainManager.Trains[i].IsPlayerTrain ? PlayerFirstStationIndex : OtherFirstStationIndex;
                if (s >= 0)
                {
                    if (Program.CurrentRoute.Stations[s].OpenLeftDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Doors[0].AnticipatedOpen = true;
                        }
                    }
                    if (Program.CurrentRoute.Stations[s].OpenRightDoors)
                    {
                        for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                        {
                            TrainManager.Trains[i].Cars[j].Doors[1].AnticipatedOpen = true;
                        }
                    }
                }
                if (Program.CurrentRoute.Sections.Length != 0)
                {
                    Program.CurrentRoute.Sections[0].Enter(TrainManager.Trains[i]);
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    double length = TrainManager.Trains[i].Cars[0].Length;
                    TrainManager.Trains[i].Cars[j].Move(-length);
                    TrainManager.Trains[i].Cars[j].Move(length);
                }
            }

            foreach (var Train in TrainManager.TFOs)
            {
                Train.Initialize();

                foreach (var Car in Train.Cars)
                {
                    double length = Train.Cars[0].Length;
                    Car.Move(-length);
                    Car.Move(length);
                }
            }

            // score
            Game.CurrentScore.ArrivalStation   = PlayerFirstStationIndex + 1;
            Game.CurrentScore.DepartureStation = PlayerFirstStationIndex;
            Game.CurrentScore.Maximum          = 0;
            for (int i = 0; i < Program.CurrentRoute.Stations.Length; i++)
            {
                if (i != PlayerFirstStationIndex & Program.CurrentRoute.Stations[i].PlayerStops())
                {
                    if (i == 0 || Program.CurrentRoute.Stations[i - 1].Type != StationType.ChangeEnds && Program.CurrentRoute.Stations[i - 1].Type != StationType.Jump)
                    {
                        Game.CurrentScore.Maximum += Game.ScoreValueStationArrival;
                    }
                }
            }
            if (Game.CurrentScore.Maximum <= 0)
            {
                Game.CurrentScore.Maximum = Game.ScoreValueStationArrival;
            }
            // signals
            if (Program.CurrentRoute.Sections.Length > 0)
            {
                Program.CurrentRoute.UpdateAllSections();
            }
            // move train in position
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                double p;
                if (TrainManager.Trains[i].IsPlayerTrain)
                {
                    p = PlayerFirstStationPosition;
                }
                else if (TrainManager.Trains[i].State == TrainState.Bogus)
                {
                    p = Program.CurrentRoute.BogusPreTrainInstructions[0].TrackPosition;
                    TrainManager.Trains[i].AI = new Game.BogusPretrainAI(TrainManager.Trains[i]);
                }
                else
                {
                    p = OtherFirstStationPosition;
                }
                for (int j = 0; j < TrainManager.Trains[i].Cars.Length; j++)
                {
                    TrainManager.Trains[i].Cars[j].Move(p);
                }
            }
            // timetable
            if (Timetable.DefaultTimetableDescription.Length == 0)
            {
                Timetable.DefaultTimetableDescription = Game.LogTrainName;
            }

            // initialize camera
            if (Program.Renderer.Camera.CurrentRestriction == CameraRestrictionMode.NotAvailable || Program.Renderer.Camera.CurrentRestriction == CameraRestrictionMode.Restricted3D)
            {
                Program.Renderer.Camera.CurrentMode = CameraViewMode.InteriorLookAhead;
            }
            //Place the initial camera in the driver car
            TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].UpdateCamera();
            Program.Renderer.CameraTrackFollower.UpdateAbsolute(-1.0, true, false);
            Program.Renderer.UpdateVisibility(Program.Renderer.CameraTrackFollower.TrackPosition + Program.Renderer.Camera.Alignment.Position.Z);
            Program.Renderer.Camera.SavedExterior = new CameraAlignment(new OpenBveApi.Math.Vector3(-2.5, 1.5, -15.0), 0.3, -0.2, 0.0, PlayerFirstStationPosition, 1.0);
            Program.Renderer.Camera.SavedTrack    = new CameraAlignment(new OpenBveApi.Math.Vector3(-3.0, 2.5, 0.0), 0.3, 0.0, 0.0, TrainManager.PlayerTrain.Cars[0].TrackPosition - 10.0, 1.0);
            // signalling sections
            for (int i = 0; i < TrainManager.Trains.Length; i++)
            {
                int s = TrainManager.Trains[i].CurrentSectionIndex;
                Program.CurrentRoute.Sections[s].Enter(TrainManager.Trains[i]);
            }
            if (Program.CurrentRoute.Sections.Length > 0)
            {
                Program.CurrentRoute.UpdateAllSections();
            }
            // fast-forward until start time
            {
                Game.MinimalisticSimulation = true;
                const double w = 0.25;
                double       u = Game.StartupTime - Program.CurrentRoute.SecondsSinceMidnight;
                if (u > 0)
                {
                    while (true)
                    {
                        double v = u < w ? u : w; u -= v;
                        Program.CurrentRoute.SecondsSinceMidnight += v;
                        TrainManager.UpdateTrains(v);
                        if (u <= 0.0)
                        {
                            break;
                        }
                        TotalTimeElapsedForSectionUpdate += v;
                        if (TotalTimeElapsedForSectionUpdate >= 1.0)
                        {
                            if (Program.CurrentRoute.Sections.Length > 0)
                            {
                                Program.CurrentRoute.UpdateAllSections();
                            }
                            TotalTimeElapsedForSectionUpdate = 0.0;
                        }
                    }
                }
                Game.MinimalisticSimulation = false;
            }
            // animated objects
            ObjectManager.UpdateAnimatedWorldObjects(0.0, true);
            TrainManager.UpdateTrainObjects(0.0, true);
            //HACK: This function calls a single update on all objects attached to the player's train
            //      but ignores any specified damping so that all needles etc. are in the correct place
            //      for the first frame, rather than spinning wildly to get to the starting point.
            TrainManager.PlayerTrain.UpdateCabObjects();
            // timetable
            if (TrainManager.PlayerTrain.Station >= 0)
            {
                Timetable.UpdateCustomTimetable(Program.CurrentRoute.Stations[TrainManager.PlayerTrain.Station].TimetableDaytimeTexture, Program.CurrentRoute.Stations[TrainManager.PlayerTrain.Station].TimetableNighttimeTexture);
                if (Timetable.CustomObjectsUsed != 0 & Timetable.CustomTimetableAvailable && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.AutoGenerated && Interface.CurrentOptions.TimeTableStyle != Interface.TimeTableMode.None)
                {
                    Timetable.CurrentTimetable = Timetable.TimetableState.Custom;
                }
            }
            //Create AI driver for the player train if specified via the commmand line
            if (Game.InitialAIDriver == true)
            {
                TrainManager.PlayerTrain.AI = new Game.SimpleHumanDriverAI(TrainManager.PlayerTrain, Double.PositiveInfinity);
                if (TrainManager.PlayerTrain.Plugin != null && !TrainManager.PlayerTrain.Plugin.SupportsAI)
                {
                    MessageManager.AddMessage(Translations.GetInterfaceString("notification_aiunable"), MessageDependency.None, GameMode.Expert,
                                              OpenBveApi.Colors.MessageColor.White, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                }
            }

            // warnings / errors
            if (Interface.MessageCount != 0)
            {
                int filesNotFound = 0;
                int errors        = 0;
                int warnings      = 0;
                for (int i = 0; i < Interface.MessageCount; i++)
                {
                    if (Interface.LogMessages[i].FileNotFound)
                    {
                        filesNotFound++;
                    }
                    else if (Interface.LogMessages[i].Type == MessageType.Error)
                    {
                        errors++;
                    }
                    else if (Interface.LogMessages[i].Type == MessageType.Warning)
                    {
                        warnings++;
                    }
                }
                string NotFound = null;
                string Messages;
                if (filesNotFound != 0)
                {
                    NotFound = filesNotFound.ToString() + " file(s) not found";
                    MessageManager.AddMessage(NotFound, MessageDependency.None, GameMode.Expert, MessageColor.Magenta, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                }
                if (errors != 0 & warnings != 0)
                {
                    Messages = errors.ToString() + " error(s), " + warnings.ToString() + " warning(s)";
                    MessageManager.AddMessage(Messages, MessageDependency.None, GameMode.Expert, MessageColor.Magenta, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                }
                else if (errors != 0)
                {
                    Messages = errors.ToString() + " error(s)";
                    MessageManager.AddMessage(Messages, MessageDependency.None, GameMode.Expert, MessageColor.Magenta, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                }
                else
                {
                    Messages = warnings.ToString() + " warning(s)";
                    MessageManager.AddMessage(Messages, MessageDependency.None, GameMode.Expert, MessageColor.Magenta, Program.CurrentRoute.SecondsSinceMidnight + 10.0, null);
                }
                Game.RouteInformation.FilesNotFound     = NotFound;
                Game.RouteInformation.ErrorsAndWarnings = Messages;
                //Print the plugin error encountered (If any) for 10s
                //This must be done after the simulation has init, as otherwise the timeout doesn't work
                if (Loading.PluginError != null)
                {
                    MessageManager.AddMessage(Loading.PluginError, MessageDependency.None, GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Program.CurrentRoute.SecondsSinceMidnight + 5.0, null);
                    MessageManager.AddMessage(Translations.GetInterfaceString("errors_plugin_failure2"), MessageDependency.None, GameMode.Expert, OpenBveApi.Colors.MessageColor.Red, Program.CurrentRoute.SecondsSinceMidnight + 5.0, null);
                }
            }
            loadComplete          = true;
            RenderRealTimeElapsed = 0.0;
            RenderTimeElapsed     = 0.0;
            World.InitializeCameraRestriction();
            Loading.SimulationSetup = true;
            switch (Game.InitialViewpoint)
            {
            case 0:
                if (Game.InitialReversedConsist)
                {
                    /*
                     * HACK: The cab view has been created using the position of the initial driver car.
                     * Trigger a forced change to ensure that it is now correctly positioned in the consist
                     */
                    TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].ChangeCarSection(TrainManager.CarSectionType.Interior);
                }
                break;

            case 1:
                //Switch camera to exterior
                MainLoop.SaveCameraSettings();
                Program.Renderer.Camera.CurrentMode = CameraViewMode.Exterior;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                    //Make bogies visible
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].Coupler.ChangeSection(0);
                }
                Program.Renderer.Camera.AlignmentDirection = new CameraAlignment();
                Program.Renderer.Camera.AlignmentSpeed     = new CameraAlignment();
                Program.Renderer.UpdateViewport(ViewportChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                Program.Renderer.UpdateViewingDistances(Program.CurrentRoute.CurrentBackground.BackgroundImageDistance);
                break;

            case 2:
                //Switch camera to track
                MainLoop.SaveCameraSettings();
                Program.Renderer.Camera.CurrentMode = CameraViewMode.Track;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].Coupler.ChangeSection(0);
                }

                Program.Renderer.Camera.AlignmentDirection = new CameraAlignment();
                Program.Renderer.Camera.AlignmentSpeed     = new CameraAlignment();
                Program.Renderer.UpdateViewport(ViewportChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                Program.Renderer.UpdateViewingDistances(Program.CurrentRoute.CurrentBackground.BackgroundImageDistance);
                break;

            case 3:
                //Switch camera to flyby
                MainLoop.SaveCameraSettings();
                Program.Renderer.Camera.CurrentMode = CameraViewMode.FlyBy;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].Coupler.ChangeSection(0);
                }

                Program.Renderer.Camera.AlignmentDirection = new CameraAlignment();
                Program.Renderer.Camera.AlignmentSpeed     = new CameraAlignment();
                Program.Renderer.UpdateViewport(ViewportChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                Program.Renderer.UpdateViewingDistances(Program.CurrentRoute.CurrentBackground.BackgroundImageDistance);
                break;

            case 4:
                //Switch camera to flyby
                MainLoop.SaveCameraSettings();
                Program.Renderer.Camera.CurrentMode = CameraViewMode.FlyByZooming;
                MainLoop.RestoreCameraSettings();
                for (int j = 0; j < TrainManager.PlayerTrain.Cars.Length; j++)
                {
                    TrainManager.PlayerTrain.Cars[j].ChangeCarSection(TrainManager.CarSectionType.Exterior);
                    TrainManager.PlayerTrain.Cars[j].FrontBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].RearBogie.ChangeSection(0);
                    TrainManager.PlayerTrain.Cars[j].Coupler.ChangeSection(0);
                }

                Program.Renderer.Camera.AlignmentDirection = new CameraAlignment();
                Program.Renderer.Camera.AlignmentSpeed     = new CameraAlignment();
                Program.Renderer.UpdateViewport(ViewportChangeMode.NoChange);
                World.UpdateAbsoluteCamera(0.0);
                Program.Renderer.UpdateViewingDistances(Program.CurrentRoute.CurrentBackground.BackgroundImageDistance);
                break;
            }
        }
Beispiel #20
0
        internal static void Main(string[] args)
        {
            // platform and mono
            int p = (int)Environment.OSVersion.Platform;

            if (p == 4 | p == 128)
            {
                // general Unix
                CurrentPlatform = Platform.Linux;
            }
            else if (p == 6)
            {
                // Mac
                CurrentPlatform = Platform.Mac;
            }
            else
            {
                // non-Unix
                CurrentPlatform = Platform.Windows;
            }
            CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null;
            CurrentHost        = new Host();

            // file system
            FileSystem = FileSystem.FromCommandLineArgs(args);
            FileSystem.CreateFileSystem();
            Plugins.LoadPlugins();
            // command line arguments
            SkipArgs = new bool[args.Length];
            if (args.Length != 0)
            {
                string File = System.IO.Path.Combine(Application.StartupPath, "RouteViewer.exe");
                if (System.IO.File.Exists(File))
                {
                    int Skips = 0;
                    System.Text.StringBuilder NewArgs = new System.Text.StringBuilder();
                    for (int i = 0; i < args.Length; i++)
                    {
                        if (args[i] != null && System.IO.File.Exists(args[i]))
                        {
                            if (System.IO.Path.GetExtension(args[i]).Equals(".csv", StringComparison.OrdinalIgnoreCase))
                            {
                                string Text = System.IO.File.ReadAllText(args[i], System.Text.Encoding.UTF8);
                                if (Text.Length != -1 &&
                                    Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) == -1)
                                {
                                    if (NewArgs.Length != 0)
                                    {
                                        NewArgs.Append(" ");
                                    }
                                    NewArgs.Append("\"" + args[i] + "\"");
                                    SkipArgs[i] = true;
                                    Skips++;
                                }
                            }
                        }
                        else
                        {
                            SkipArgs[i] = true;
                            Skips++;
                        }
                    }
                    if (NewArgs.Length != 0)
                    {
                        System.Diagnostics.Process.Start(File, NewArgs.ToString());
                    }
                    if (Skips == args.Length)
                    {
                        return;
                    }
                }
            }
            Options.LoadOptions();
            Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000;
            Interface.CurrentOptions.ObjectOptimizationFullThreshold  = 250;
            Interface.CurrentOptions.AntialiasingLevel         = 16;
            Interface.CurrentOptions.AnisotropicFilteringLevel = 16;
            // initialize camera

            currentGraphicsMode       = new GraphicsMode(new ColorFormat(8, 8, 8, 8), 24, 8, Interface.CurrentOptions.AntialiasingLevel);
            currentGameWindow         = new ObjectViewer(Renderer.ScreenWidth, Renderer.ScreenHeight, currentGraphicsMode, "Object Viewer", GameWindowFlags.Default);
            currentGameWindow.Visible = true;
            currentGameWindow.TargetUpdateFrequency = 0;
            currentGameWindow.TargetRenderFrequency = 0;
            currentGameWindow.Title = "Object Viewer";
            currentGameWindow.Run();
            // quit
            Textures.UnloadAllTextures();
        }
Beispiel #21
0
        /// <summary>Changes to or from fullscreen mode.</summary>
        internal static void ToggleFullscreen()
        {
            Fullscreen = !Fullscreen;
            // begin HACK //
            Renderer.ClearDisplayLists();

            GL.Disable(EnableCap.Fog);
            GL.Disable(EnableCap.Lighting);
            Renderer.LightingEnabled = false;
            Textures.UnloadAllTextures();
            if (Fullscreen)
            {
                IList <DisplayResolution> resolutions = OpenTK.DisplayDevice.Default.AvailableResolutions;

                for (int i = 0; i < resolutions.Count; i++)
                {
                    //Test each resolution
                    if (resolutions[i].Width == Interface.CurrentOptions.FullscreenWidth &&
                        resolutions[i].Height == Interface.CurrentOptions.FullscreenHeight &&
                        resolutions[i].BitsPerPixel == Interface.CurrentOptions.FullscreenBits)
                    {
                        OpenTK.DisplayDevice.Default.ChangeResolution(resolutions[i]);
                        Program.currentGameWindow.Width  = resolutions[i].Width;
                        Program.currentGameWindow.Height = resolutions[i].Height;
                        Screen.Width  = Interface.CurrentOptions.FullscreenWidth;
                        Screen.Height = Interface.CurrentOptions.FullscreenHeight;
                        Program.currentGameWindow.WindowState = WindowState.Fullscreen;
                        break;
                    }
                }
                if (Program.currentGameWindow.WindowState != WindowState.Fullscreen)
                {
                    MessageBox.Show(Interface.GetInterfaceString("errors_fullscreen_switch1") + System.Environment.NewLine +
                                    Interface.GetInterfaceString("errors_fullscreen_switch2"), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    Fullscreen = false;
                }
            }
            else
            {
                OpenTK.DisplayDevice.Default.RestoreResolution();
                Program.currentGameWindow.WindowState = WindowState.Normal;
                Program.currentGameWindow.Width       = Interface.CurrentOptions.WindowWidth;
                Program.currentGameWindow.Height      = Interface.CurrentOptions.WindowHeight;

                Screen.Width  = Interface.CurrentOptions.WindowWidth;
                Screen.Height = Interface.CurrentOptions.WindowHeight;
            }
            Renderer.InitializeLighting();
            MainLoop.UpdateViewport(MainLoop.ViewPortChangeMode.NoChange);
            MainLoop.InitializeMotionBlur();
            Timetable.CreateTimetable();
            Timetable.UpdateCustomTimetable(null, null);

            World.InitializeCameraRestriction();
            if (Renderer.OptionBackfaceCulling)
            {
                GL.Enable(EnableCap.CullFace);
            }
            else
            {
                GL.Disable(EnableCap.CullFace);
            }
            Renderer.ReAddObjects();
            // end HACK //

            //Reset the camera when switching between fullscreen and windowed mode
            //Otherwise, if the aspect ratio changes distortion will occur until the view is changed or the camera reset
            if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead)
            {
                World.CameraCurrentAlignment.Position = new OpenBveApi.Math.Vector3(0.0, 0.0,
                                                                                    0.0);
            }
            World.CameraCurrentAlignment.Yaw   = 0.0;
            World.CameraCurrentAlignment.Pitch = 0.0;
            World.CameraCurrentAlignment.Roll  = 0.0;
            if (World.CameraMode == World.CameraViewMode.Track)
            {
                TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition, true, false);
            }
        }
Beispiel #22
0
 //
 // SET CUSTOM LOADING SCREEN BACKGROUND
 //
 /// <summary>Sets the loading screen background to a custom image</summary>
 /// <summary>Sets the loading screen background to a custom image</summary>
 internal static void SetLoadingBkg(string fileName)
 {
     Textures.RegisterTexture(fileName, out TextureLoadingBkg);
     customLoadScreen = true;
 }
Beispiel #23
0
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     if (Material.DaytimeTexture != null)
     {
         if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
         {
             if (!TexturingEnabled)
             {
                 GL.Enable(EnableCap.Texture2D);
                 TexturingEnabled = true;
             }
             if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
             {
                 GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                 LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
             }
         }
         else
         {
             if (TexturingEnabled)
             {
                 GL.Disable(EnableCap.Texture2D);
                 TexturingEnabled = false;
                 LastBoundTexture = null;
             }
         }
     }
     else
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
             LastBoundTexture = null;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         factor = 1.0f;
         if (!BlendEnabled) GL.Enable(EnableCap.Blend);
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
         if (FogEnabled)
         {
             GL.Disable(EnableCap.Fog);
         }
     }
     else if (Material.NighttimeTexture == null)
     {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.7f * blend;
     }
     else
     {
         factor = 1.0f;
     }
     if (Material.NighttimeTexture != null)
     {
         if (LightingEnabled)
         {
             GL.Disable(EnableCap.Lighting);
             LightingEnabled = false;
         }
     }
     else
     {
         if (OptionLighting & !LightingEnabled)
         {
             GL.Enable(EnableCap.Lighting);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType)
     {
         case World.MeshFace.FaceTypeTriangles:
             GL.Begin(PrimitiveType.Triangles);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             GL.Begin(PrimitiveType.TriangleStrip);
             break;
         case World.MeshFace.FaceTypeQuads:
             GL.Begin(PrimitiveType.Quads);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             GL.Begin(PrimitiveType.QuadStrip);
             break;
         default:
             GL.Begin(PrimitiveType.Polygon);
             break;
     }
     if (Material.GlowAttenuationData != 0)
     {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     }
     else
     {
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     }
     else if (EmissiveEnabled)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (Material.DaytimeTexture != null)
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     else
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     GL.End();
     // render nighttime polygon
     if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap))
     {
         if (!TexturingEnabled)
         {
             GL.Enable(EnableCap.Texture2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled)
         {
             GL.Enable(EnableCap.Blend);
         }
         GL.BindTexture(TextureTarget.Texture2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
         LastBoundTexture = null;
         GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
         GL.Enable(EnableCap.AlphaTest);
         switch (FaceType)
         {
             case World.MeshFace.FaceTypeTriangles:
                 GL.Begin(PrimitiveType.Triangles);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 GL.Begin(PrimitiveType.TriangleStrip);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 GL.Begin(PrimitiveType.Quads);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 GL.Begin(PrimitiveType.QuadStrip);
                 break;
             default:
                 GL.Begin(PrimitiveType.Polygon);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0)
         {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         }
         else
         {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         }
         else if (EmissiveEnabled)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         GL.End();
         RestoreAlphaFunc();
         if (!BlendEnabled)
         {
             GL.Disable(EnableCap.Blend);
         }
     }
     // normals
     if (OptionNormals)
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.Begin(PrimitiveType.Lines);
             GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             GL.End();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
         if (!BlendEnabled) GL.Disable(EnableCap.Blend);
         if (FogEnabled)
         {
             GL.Enable(EnableCap.Fog);
         }
     }
 }
Beispiel #24
0
 private static void ApplyMeshBuilder(ref ObjectManager.StaticObject Object, MeshBuilder Builder)
 {
     if (Builder.Faces.Count != 0)
     {
         int mf = Object.Mesh.Faces.Length;
         int mm = Object.Mesh.Materials.Length;
         int mv = Object.Mesh.Vertices.Length;
         Array.Resize <World.MeshFace>(ref Object.Mesh.Faces, mf + Builder.Faces.Count);
         if (mm == 0)
         {
             if (Object.Mesh.Materials.Length == 0)
             {
                 /*
                  * If the object has no materials defined at all, we need to add one
                  */
                 Array.Resize(ref Object.Mesh.Materials, 1);
                 Object.Mesh.Materials[0]                  = new World.MeshMaterial();
                 Object.Mesh.Materials[0].Color            = new Color32(255, 255, 255);
                 Object.Mesh.Materials[0].Flags            = (byte)(0 | 0);
                 Object.Mesh.Materials[0].DaytimeTexture   = null;
                 Object.Mesh.Materials[0].NighttimeTexture = null;
                 mm++;
             }
         }
         if (Builder.Materials.Length > 0)
         {
             Array.Resize <World.MeshMaterial>(ref Object.Mesh.Materials, mm + Builder.Materials.Length);
         }
         else
         {
             /*
              * If no materials have been defined for this face group, use the last material
              */
             mm -= 1;
         }
         Array.Resize <VertexTemplate>(ref Object.Mesh.Vertices, mv + Builder.Vertices.Count);
         for (int i = 0; i < Builder.Vertices.Count; i++)
         {
             Object.Mesh.Vertices[mv + i] = Builder.Vertices[i];
         }
         for (int i = 0; i < Builder.Faces.Count; i++)
         {
             Object.Mesh.Faces[mf + i] = Builder.Faces[i];
             for (int j = 0; j < Object.Mesh.Faces[mf + i].Vertices.Length; j++)
             {
                 Object.Mesh.Faces[mf + i].Vertices[j].Index += (ushort)mv;
             }
             Object.Mesh.Faces[mf + i].Material += (ushort)mm;
         }
         for (int i = 0; i < Builder.Materials.Length; i++)
         {
             Object.Mesh.Materials[mm + i].Flags            = (byte)((Builder.Materials[i].EmissiveColorUsed ? World.MeshMaterial.EmissiveColorMask : 0) | (Builder.Materials[i].TransparentColorUsed ? World.MeshMaterial.TransparentColorMask : 0));
             Object.Mesh.Materials[mm + i].Color            = Builder.Materials[i].Color;
             Object.Mesh.Materials[mm + i].TransparentColor = Builder.Materials[i].TransparentColor;
             if (Builder.Materials[i].DaytimeTexture != null)
             {
                 Textures.Texture tday;
                 if (Builder.Materials[i].TransparentColorUsed)
                 {
                     Textures.RegisterTexture(Builder.Materials[i].DaytimeTexture, new OpenBveApi.Textures.TextureParameters(null, new Color24(Builder.Materials[i].TransparentColor.R, Builder.Materials[i].TransparentColor.G, Builder.Materials[i].TransparentColor.B)), out tday);
                 }
                 else
                 {
                     Textures.RegisterTexture(Builder.Materials[i].DaytimeTexture, out tday);
                 }
                 Object.Mesh.Materials[mm + i].DaytimeTexture = tday;
             }
             else
             {
                 Object.Mesh.Materials[mm + i].DaytimeTexture = null;
             }
             Object.Mesh.Materials[mm + i].EmissiveColor = Builder.Materials[i].EmissiveColor;
             if (Builder.Materials[i].NighttimeTexture != null)
             {
                 Textures.Texture tnight;
                 if (Builder.Materials[i].TransparentColorUsed)
                 {
                     Textures.RegisterTexture(Builder.Materials[i].NighttimeTexture, new OpenBveApi.Textures.TextureParameters(null, new Color24(Builder.Materials[i].TransparentColor.R, Builder.Materials[i].TransparentColor.G, Builder.Materials[i].TransparentColor.B)), out tnight);
                 }
                 else
                 {
                     Textures.RegisterTexture(Builder.Materials[i].NighttimeTexture, out tnight);
                 }
                 Object.Mesh.Materials[mm + i].NighttimeTexture = tnight;
             }
             else
             {
                 Object.Mesh.Materials[mm + i].NighttimeTexture = null;
             }
             Object.Mesh.Materials[mm + i].DaytimeNighttimeBlend = 0;
             Object.Mesh.Materials[mm + i].BlendMode             = Builder.Materials[i].BlendMode;
             Object.Mesh.Materials[mm + i].GlowAttenuationData   = Builder.Materials[i].GlowAttenuationData;
             Object.Mesh.Materials[mm + i].WrapMode = Textures.OpenGlTextureWrapMode.RepeatRepeat;
         }
     }
 }
Beispiel #25
0
        public static bool ReadMarkerXML(string fileName, ref CsvRwRouteParser.Marker marker)
        {
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the marker's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            if (currentXML.DocumentElement != null)
            {
                bool        iM            = false;
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/TextMarker");

                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/ImageMarker");
                    iM            = true;
                }
                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    Interface.AddMessage(Interface.MessageType.Error, false, "No marker nodes defined in XML file " + fileName);
                    return(false);
                }
                marker = new CsvRwRouteParser.Marker();
                foreach (XmlNode n in DocumentNodes)
                {
                    if (n.HasChildNodes)
                    {
                        bool             EarlyDefined = false, LateDefined = false;
                        string           EarlyText = null, Text = null, LateText = null;
                        string[]         Trains = null;
                        Textures.Texture EarlyTexture = null, Texture = null, LateTexture = null;
                        double           EarlyTime = 0.0, LateTime = 0.0, TimeOut = Double.PositiveInfinity, EndingPosition = Double.PositiveInfinity;
                        OpenBveApi.Colors.MessageColor EarlyColor = MessageColor.White, OnTimeColor = MessageColor.White, LateColor = MessageColor.White;
                        foreach (XmlNode c in n.ChildNodes)
                        {
                            switch (c.Name.ToLowerInvariant())
                            {
                            case "early":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the early message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        EarlyText = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out EarlyTexture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageEarlyTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageEarlyTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out EarlyTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        EarlyDefined = true;
                                        break;

                                    case "color":
                                        EarlyColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "ontime":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the on-time message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        Text = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out Texture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "color":
                                        OnTimeColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "late":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the late message in " + fileName);
                                }

                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        LateText = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out LateTexture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageLateTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageLateTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out LateTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        LateDefined = true;
                                        break;

                                    case "color":
                                        LateColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "timeout":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out TimeOut))
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false, "Marker timeout invalid in " + fileName);
                                }
                                break;

                            case "distance":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out EndingPosition))
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false, "Marker distance invalid in " + fileName);
                                }
                                break;

                            case "trains":
                                Trains = c.InnerText.Split(';');
                                break;
                            }
                        }
                        //Check this marker is valid
                        if (TimeOut == Double.PositiveInfinity && EndingPosition == Double.PositiveInfinity)
                        {
                            Interface.AddMessage(Interface.MessageType.Error, false, "No marker timeout or distance defined in marker XML " + fileName);
                            return(false);
                        }
                        if (EndingPosition != Double.PositiveInfinity)
                        {
                            marker.EndingPosition = EndingPosition;
                        }
                        MessageManager.TextureMessage t = new MessageManager.TextureMessage();
                        MessageManager.GeneralMessage m = new MessageManager.GeneralMessage();
                        //Add variants

                        if (EarlyDefined)
                        {
                            if (iM)
                            {
                                if (EarlyTexture != null)
                                {
                                    t.MessageEarlyTime    = EarlyTime;
                                    t.MessageEarlyTexture = EarlyTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (EarlyText != null)
                                {
                                    m.MessageEarlyTime = EarlyTime;
                                    m.MessageEarlyText = EarlyText;
                                    m.MessageColor     = EarlyColor;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        if (LateDefined)
                        {
                            if (iM)
                            {
                                if (LateTexture != null)
                                {
                                    t.MessageLateTime    = LateTime;
                                    t.MessageLateTexture = LateTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "A late time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (LateText != null)
                                {
                                    m.MessageLateTime  = LateTime;
                                    m.MessageLateText  = LateText;
                                    m.MessageLateColor = LateColor;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        //Final on-time message
                        if (iM)
                        {
                            t.Trains = Trains;
                            if (Texture != null)
                            {
                                t.MessageOnTimeTexture = Texture;
                            }
                        }
                        else
                        {
                            m.Trains = Trains;
                            if (Text != null)
                            {
                                m.MessageOnTimeText = Text;
                                m.Color             = OnTimeColor;
                            }
                        }
                        if (iM)
                        {
                            marker.Message = t;
                        }
                        else
                        {
                            marker.Message = m;
                        }
                    }
                }
            }
            return(true);
        }
Beispiel #26
0
        //This renders the frame
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            if (!firstFrame)
            {
                //If the load is not complete, then we shouldn't be running the mainloop
                return;
            }
            double TimeElapsed     = RenderTimeElapsed;
            double RealTimeElapsed = RenderRealTimeElapsed;

            //Next, check if we're in paused/ in a menu
            if (Program.Renderer.CurrentInterface != InterfaceType.Normal)
            {
                MainLoop.UpdateControlRepeats(0.0);
                MainLoop.ProcessKeyboard();
                MainLoop.ProcessControls(0.0);
                if (Program.Renderer.CurrentInterface == InterfaceType.Pause)
                {
                    System.Threading.Thread.Sleep(10);
                }
                //Renderer.UpdateLighting();
                Program.Renderer.RenderScene(TimeElapsed);
                Program.currentGameWindow.SwapBuffers();
                if (MainLoop.Quit != MainLoop.QuitMode.ContinueGame)
                {
                    Close();
                    if (Program.CurrentlyRunningOnMono && MainLoop.Quit == MainLoop.QuitMode.QuitProgram)
                    {
                        Environment.Exit(0);
                    }
                }
                //If the menu state has not changed, don't update the rendered simulation
                return;
            }

            //Use the OpenTK framerate as this is much more accurate
            //Also avoids running a calculation
            if (TotalTimeElapsedForInfo >= 0.2)
            {
                Program.Renderer.FrameRate = RenderFrequency;
                TotalTimeElapsedForInfo    = 0.0;
            }


            if (Program.Renderer.PreviousInterface != InterfaceType.Normal)
            {
                // Update animated objects with zero elapsed time (NOT time elapsed in menu)
                // and set again to avoid glitching
                ObjectManager.UpdateAnimatedWorldObjects(0.0, false);
                Program.Renderer.CurrentInterface = InterfaceType.Normal;
            }
            else
            {
                ObjectManager.UpdateAnimatedWorldObjects(TimeElapsed, false);
            }

            //We need to update the camera position in the render sequence
            //Not doing this means that the camera doesn't move
            // update in one piece
            if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead)
            {
                //Update the in-car camera based upon the current driver car (Cabview or passenger view)
                TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.CameraCar].UpdateCamera();
            }
            else if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Exterior)
            {
                //Update the camera position based upon the relative car position
                TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.CameraCar].UpdateCamera();
            }
            if (Program.Renderer.Camera.CurrentRestriction == CameraRestrictionMode.NotAvailable || Program.Renderer.Camera.CurrentRestriction == CameraRestrictionMode.Restricted3D)
            {
                TrainManager.PlayerTrain.DriverBody.Update(TimeElapsed);
            }
            //Check if we are running at an accelerated time factor-
            //Camera motion speed should be the same whatever the game speed is
            if (TimeFactor != 1)
            {
                World.UpdateAbsoluteCamera(TimeElapsed / TimeFactor);
            }
            else
            {
                World.UpdateAbsoluteCamera(TimeElapsed);
            }
            TrainManager.UpdateTrainObjects(TimeElapsed, false);
            if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead | Program.Renderer.Camera.CurrentMode == CameraViewMode.Exterior)
            {
                Program.Renderer.UpdateVisibility(Program.Renderer.CameraTrackFollower.TrackPosition + Program.Renderer.Camera.Alignment.Position.Z);
                int d = TrainManager.PlayerTrain.DriverCar;
                Program.Renderer.Camera.CurrentSpeed = TrainManager.PlayerTrain.Cars[d].CurrentSpeed;
            }
            else
            {
                Program.Renderer.Camera.CurrentSpeed = 0.0;
            }

            Program.Renderer.Camera.AlignmentDirection = new CameraAlignment();
            if (MainLoop.Quit != MainLoop.QuitMode.ContinueGame)
            {
                Program.currentGameWindow.Exit();
                if (Program.CurrentlyRunningOnMono && MainLoop.Quit == MainLoop.QuitMode.QuitProgram)
                {
                    Environment.Exit(0);
                }
            }
            Program.Renderer.Lighting.UpdateLighting(Program.CurrentRoute.SecondsSinceMidnight);
            Program.Renderer.RenderScene(TimeElapsed);
            Program.Sounds.Update(TimeElapsed, Interface.CurrentOptions.SoundModel);
            Program.currentGameWindow.SwapBuffers();
            Game.UpdateBlackBox();
            // pause/menu

            // limit framerate
            if (MainLoop.LimitFramerate)
            {
                System.Threading.Thread.Sleep(10);
            }
            MainLoop.UpdateControlRepeats(RealTimeElapsed);
            MainLoop.ProcessKeyboard();
            MainLoop.UpdateMouse(RealTimeElapsed);
            MainLoop.ProcessControls(TimeElapsed);
            for (int i = 0; i < JoystickManager.AttachedJoysticks.Length; i++)
            {
                var railDriver = JoystickManager.AttachedJoysticks[i] as JoystickManager.Raildriver;
                if (railDriver != null)
                {
                    if (Interface.CurrentOptions.RailDriverMPH)
                    {
                        railDriver.SetDisplay((int)(TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs
                                                    .CurrentPerceivedSpeed * 2.23694));
                    }
                    else
                    {
                        railDriver.SetDisplay((int)(TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs
                                                    .CurrentPerceivedSpeed * 3.6));
                    }
                }
            }
            RenderRealTimeElapsed = 0.0;
            RenderTimeElapsed     = 0.0;



#if DEBUG
            MainLoop.CheckForOpenGlError("MainLoop");
#endif
            if (Interface.CurrentOptions.UnloadUnusedTextures)
            {
                Textures.UnloadUnusedTextures(TimeElapsed);
            }
            // finish
            try
            {
                Interface.SaveLogs();
            }
            catch { }
        }
        //Parses an XML background definition
        public static BackgroundManager.BackgroundHandle ReadBackgroundXML(string fileName)
        {
            List <BackgroundManager.StaticBackground> Backgrounds = new List <BackgroundManager.StaticBackground>();
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the object's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            double[] UnitOfLength = { 1.0 };
            //Check for null
            if (currentXML.DocumentElement != null)
            {
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Background");
                //Check this file actually contains OpenBVE light definition nodes
                if (DocumentNodes != null)
                {
                    foreach (XmlNode n in DocumentNodes)
                    {
                        if (n.ChildNodes.OfType <XmlElement>().Any())
                        {
                            double DisplayTime = -1;
                            //The time to transition between backgrounds in seconds
                            double TransitionTime = 0.8;
                            //The texture to use (if static)
                            Texture t = null;
                            //The object to use (if object based)
                            ObjectManager.StaticObject o = null;
                            //The transition mode between backgrounds
                            BackgroundManager.BackgroundTransitionMode mode = BackgroundManager.BackgroundTransitionMode.FadeIn;
                            //The number of times the texture is repeated around the viewing frustrum (if appropriate)
                            double repetitions = 6;
                            foreach (XmlNode c in n.ChildNodes)
                            {
                                string[] Arguments = c.InnerText.Split(',');
                                switch (c.Name.ToLowerInvariant())
                                {
                                case "mode":
                                    switch (c.InnerText.ToLowerInvariant())
                                    {
                                    case "fadein":
                                        mode = BackgroundManager.BackgroundTransitionMode.FadeIn;
                                        break;

                                    case "fadeout":
                                        mode = BackgroundManager.BackgroundTransitionMode.FadeOut;
                                        break;

                                    case "none":
                                        mode = BackgroundManager.BackgroundTransitionMode.None;
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, true, c.InnerText + "is not a valid background fade mode in file " + fileName);
                                        break;
                                    }
                                    break;

                                case "object":
                                    string f;
                                    try
                                    {
                                        f = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(fileName), c.InnerText);
                                    }
                                    catch
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "BackgroundObject FileName is malformed in file " + fileName);
                                        break;
                                    }
                                    if (!System.IO.File.Exists(f))
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "FileName " + f + " not found in file " + fileName);
                                    }
                                    else
                                    {
                                        UnifiedObject b = ObjectManager.LoadObject(f, System.Text.Encoding.Default, false, false, false);
                                        o = (ObjectManager.StaticObject)b;
                                    }
                                    break;

                                case "repetitions":
                                    if (!NumberFormats.TryParseDoubleVb6(Arguments[0], UnitOfLength, out repetitions))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid number of repetitions in " + fileName);
                                    }
                                    break;

                                case "texture":
                                    string file;
                                    try
                                    {
                                        file = OpenBveApi.Path.CombineFile(Path, c.InnerText);
                                    }
                                    catch
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "BackgroundTexture FileName is malformed in file " + fileName);
                                        break;
                                    }
                                    if (!System.IO.File.Exists(file))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The background texture file " + c.InnerText + " does not exist in " + fileName);
                                    }
                                    else
                                    {
                                        Textures.RegisterTexture(file, out t);
                                    }
                                    break;

                                case "time":
                                    if (!Interface.TryParseTime(Arguments[0].Trim(), out DisplayTime))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid time in file " + fileName);
                                    }
                                    break;

                                case "transitiontime":
                                    if (!NumberFormats.TryParseDoubleVb6(Arguments[0], UnitOfLength, out TransitionTime))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " is not a valid background transition time in " + fileName);
                                    }
                                    break;
                                }
                            }
                            //Create background if texture is not null
                            if (t != null && o == null)
                            {
                                Backgrounds.Add(new BackgroundManager.StaticBackground(t, repetitions, false, TransitionTime, mode, DisplayTime));
                            }
                            if (t == null && o != null)
                            {
                                //All other parameters are ignored if an object has been defined
                                //TODO: Error message stating they have been ignored
                                return(new BackgroundManager.BackgroundObject(o));
                            }
                        }
                    }
                    if (Backgrounds.Count == 1)
                    {
                        return(Backgrounds[0]);
                    }
                    if (Backgrounds.Count > 1)
                    {
                        //Sort list- Not worried about when they start or end, so use simple LINQ
                        Backgrounds = Backgrounds.OrderBy(o => o.Time).ToList();
                        //If more than 2 backgrounds, convert to array and return a new dynamic background
                        return(new BackgroundManager.DynamicBackground(Backgrounds.ToArray()));
                    }
                }
            }
            //We couldn't find any valid XML, so return false
            throw new InvalidDataException();
        }
 internal MarkerStartEvent(double trackPositionDelta, Textures.Texture texture)
 {
     this.TrackPositionDelta = trackPositionDelta;
     this.DontTriggerAnymore = false;
     this.Texture = texture;
 }
Beispiel #29
0
 private static void RenderCube(Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, double Size, double CameraX, double CameraY, double CameraZ, Texture TextureIndex)
 {
     Vector3[] v = new Vector3[8];
     v[0] = new Vector3(Size, Size, -Size);
     v[1] = new Vector3(Size, -Size, -Size);
     v[2] = new Vector3(-Size, -Size, -Size);
     v[3] = new Vector3(-Size, Size, -Size);
     v[4] = new Vector3(Size, Size, Size);
     v[5] = new Vector3(Size, -Size, Size);
     v[6] = new Vector3(-Size, -Size, Size);
     v[7] = new Vector3(-Size, Size, Size);
     for (int i = 0; i < 8; i++)
     {
         v[i].Rotate(Direction, Up, Side);
         v[i].X += Position.X - CameraX;
         v[i].Y += Position.Y - CameraY;
         v[i].Z += Position.Z - CameraZ;
     }
     int[][] Faces = new int[6][];
     Faces[0] = new int[] { 0, 1, 2, 3 };
     Faces[1] = new int[] { 0, 4, 5, 1 };
     Faces[2] = new int[] { 0, 3, 7, 4 };
     Faces[3] = new int[] { 6, 5, 4, 7 };
     Faces[4] = new int[] { 6, 7, 3, 2 };
     Faces[5] = new int[] { 6, 2, 1, 5 };
     if (TextureIndex == null || !Textures.LoadTexture(TextureIndex, OpenGlTextureWrapMode.ClampClamp))
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
         }
         for (int i = 0; i < 6; i++)
         {
             GL.Begin(PrimitiveType.Quads);
             GL.Color3(1.0, 1.0, 1.0);
             for (int j = 0; j < 4; j++)
             {
                 GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z);
             }
             GL.End();
         }
         return;
     }
     else
     {
         TexturingEnabled = true;
         GL.Enable(EnableCap.Texture2D);
     }
     GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)OpenGlTextureWrapMode.ClampClamp].Name);
     Vector2[][] t = new Vector2[6][];
     t[0] = new Vector2[] { new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0) };
     t[1] = new Vector2[] { new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0) };
     t[2] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) };
     t[3] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) };
     t[4] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) };
     t[5] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) };
     for (int i = 0; i < 6; i++)
     {
         GL.Begin(PrimitiveType.Quads);
         GL.Color3(1.0, 1.0, 1.0);
         for (int j = 0; j < 4; j++)
         {
             GL.TexCoord2(t[i][j].X, t[i][j].Y);
             GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z);
         }
         GL.End();
     }
 }
Beispiel #30
0
		private static int CreateElement(TrainManager.Train Train, double Left, double Top, double Width, double Height, double RelativeRotationCenterX, double RelativeRotationCenterY, double Distance, double PanelResolution, double PanelLeft, double PanelRight, double PanelTop, double PanelBottom, double PanelBitmapWidth, double PanelBitmapHeight, double PanelCenterX, double PanelCenterY, double PanelOriginX, double PanelOriginY, double DriverX, double DriverY, double DriverZ, Textures.Texture DaytimeTexture, Textures.Texture NighttimeTexture, Color32 Color, bool AddStateToLastElement) {
			double WorldWidth, WorldHeight;
			if (Screen.Width >= Screen.Height) {
				WorldWidth = 2.0 * Math.Tan(0.5 * World.HorizontalViewingAngle) * EyeDistance;
				WorldHeight = WorldWidth / World.AspectRatio;
			} else {
				WorldHeight = 2.0 * Math.Tan(0.5 * World.VerticalViewingAngle) * EyeDistance / World.AspectRatio;
				WorldWidth = WorldHeight * World.AspectRatio;
			}
			double x0 = Left / PanelResolution;
			double x1 = (Left + Width) / PanelResolution;
			double y0 = (PanelBottom - Top) / PanelResolution * World.AspectRatio;
			double y1 = (PanelBottom - (Top + Height)) / PanelResolution * World.AspectRatio;
			double xd = 0.5 - PanelCenterX / PanelResolution;
			x0 += xd; x1 += xd;
			double yt = PanelBottom - PanelResolution / World.AspectRatio;
			double yd = (PanelCenterY - yt) / (PanelBottom - yt) - 0.5;
			y0 += yd; y1 += yd;
			x0 = (x0 - 0.5) * WorldWidth;
			x1 = (x1 - 0.5) * WorldWidth;
			y0 = (y0 - 0.5) * WorldHeight;
			y1 = (y1 - 0.5) * WorldHeight;
			double xm = x0 * (1.0 - RelativeRotationCenterX) + x1 * RelativeRotationCenterX;
			double ym = y0 * (1.0 - RelativeRotationCenterY) + y1 * RelativeRotationCenterY;
			Vector3[] v = new Vector3[4];
			v[0] = new Vector3(x0 - xm, y1 - ym, 0);
			v[1] = new Vector3(x0 - xm, y0 - ym, 0);
			v[2] = new Vector3(x1 - xm, y0 - ym, 0);
			v[3] = new Vector3(x1 - xm, y1 - ym, 0);
			World.Vertex t0 = new World.Vertex(v[0], new Vector2(0.0f, 1.0f));
			World.Vertex t1 = new World.Vertex(v[1], new Vector2(0.0f, 0.0f));
			World.Vertex t2 = new World.Vertex(v[2], new Vector2(1.0f, 0.0f));
			World.Vertex t3 = new World.Vertex(v[3], new Vector2(1.0f, 1.0f));
			ObjectManager.StaticObject Object = new ObjectManager.StaticObject();
			Object.Mesh.Vertices = new World.Vertex[] { t0, t1, t2, t3 };
			Object.Mesh.Faces = new World.MeshFace[] { new World.MeshFace(new int[] { 0, 1, 2, 3 }) };
			Object.Mesh.Materials = new World.MeshMaterial[1];
			Object.Mesh.Materials[0].Flags = (byte)(DaytimeTexture != null ? World.MeshMaterial.TransparentColorMask : 0);
			Object.Mesh.Materials[0].Color = Color;
			Object.Mesh.Materials[0].TransparentColor = new Color24(0, 0, 255);
			Object.Mesh.Materials[0].DaytimeTexture = DaytimeTexture;
			Object.Mesh.Materials[0].NighttimeTexture = NighttimeTexture;
			Object.Dynamic = true;
			// calculate offset
			Vector3 o;
			o.X = xm + DriverX;
			o.Y = ym + DriverY;
			o.Z = EyeDistance - Distance + DriverZ;
			// add object
			if (AddStateToLastElement) {
				int n = Train.Cars[Train.DriverCar].CarSections[0].Elements.Length - 1;
				int j = Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States.Length;
				Array.Resize<ObjectManager.AnimatedObjectState>(ref Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States, j + 1);
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[j].Position = o;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[j].Object = Object;
				return n;
			} else {
				int n = Train.Cars[Train.DriverCar].CarSections[0].Elements.Length;
				Array.Resize<ObjectManager.AnimatedObject>(ref Train.Cars[Train.DriverCar].CarSections[0].Elements, n + 1);
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n] = new ObjectManager.AnimatedObject();
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States = new ObjectManager.AnimatedObjectState[1];
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[0].Position = o;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].States[0].Object = Object;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].CurrentState = 0;
				Train.Cars[Train.DriverCar].CarSections[0].Elements[n].ObjectIndex = ObjectManager.CreateDynamicObject();
				ObjectManager.Objects[Train.Cars[Train.DriverCar].CarSections[0].Elements[n].ObjectIndex] = ObjectManager.CloneObject(Object);
				return n;
			}
		}
Beispiel #31
0
        /// <summary>Renders the ATS lamp overlay</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderATSLamps(HUD.Element Element, double TimeElapsed)
        {
            // ats lamps
            if (CurrentLampCollection.Lamps == null)
            {
                InitializeLamps();
            }
            double lcrh, lw, rw;

            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);
            // start

            // ReSharper disable once PossibleNullReferenceException
            int    n = CurrentLampCollection.Lamps.Length;
            double w = (double)CurrentLampCollection.Width + lw + rw;
            double h = Element.Value2 * n;
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X > 0 ? Screen.Width - w : 0.5 * (Screen.Width - w);
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y > 0 ? Screen.Height - h : 0.5 * (Screen.Height - h);

            x += Element.Position.X;
            y += Element.Position.Y;
            for (int j = 0; j < n; j++)
            {
                if (CurrentLampCollection.Lamps[j].Type != LampType.None)
                {
                    int o;
                    if (j == 0)
                    {
                        o = -1;
                    }
                    else if (CurrentLampCollection.Lamps[j - 1].Type == LampType.None)
                    {
                        o = -1;
                    }
                    else if (j < n - 1 && CurrentLampCollection.Lamps[j + 1].Type == LampType.None)
                    {
                        o = 1;
                    }
                    else if (j == n - 1)
                    {
                        o = 1;
                    }
                    else
                    {
                        o = 0;
                    }
                    HUD.Image    Left   = o < 0 ? Element.TopLeft : o == 0 ? Element.CenterLeft : Element.BottomLeft;
                    HUD.Image    Middle = o < 0 ? Element.TopMiddle : o == 0 ? Element.CenterMiddle : Element.BottomMiddle;
                    HUD.Image    Right  = o < 0 ? Element.TopRight : o == 0 ? Element.CenterRight : Element.BottomRight;
                    MessageColor sc     = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.Plugin.Panel.Length >= 272)
                    {
                        switch (CurrentLampCollection.Lamps[j].Type)
                        {
                        case LampType.Ats:
                            if (TrainManager.PlayerTrain.Plugin.Panel[256] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsOperation:
                            if (TrainManager.PlayerTrain.Plugin.Panel[258] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.AtsPPower:
                            if (TrainManager.PlayerTrain.Plugin.Panel[259] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.AtsPPattern:
                            if (TrainManager.PlayerTrain.Plugin.Panel[260] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsPBrakeOverride:
                            if (TrainManager.PlayerTrain.Plugin.Panel[261] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsPBrakeOperation:
                            if (TrainManager.PlayerTrain.Plugin.Panel[262] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsP:
                            if (TrainManager.PlayerTrain.Plugin.Panel[263] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.AtsPFailure:
                            if (TrainManager.PlayerTrain.Plugin.Panel[264] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.Atc:
                            if (TrainManager.PlayerTrain.Plugin.Panel[265] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcPower:
                            if (TrainManager.PlayerTrain.Plugin.Panel[266] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcUse:
                            if (TrainManager.PlayerTrain.Plugin.Panel[267] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcEmergency:
                            if (TrainManager.PlayerTrain.Plugin.Panel[268] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.Eb:
                            if (TrainManager.PlayerTrain.Plugin.Panel[270] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.ConstSpeed:
                            if (TrainManager.PlayerTrain.Plugin.Panel[269] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;
                        }
                    }
                    // colors
                    float br, bg, bb, ba;
                    CreateBackColor(Element.BackgroundColor, sc, out br, out bg, out bb, out ba);
                    float tr, tg, tb, ta;
                    CreateTextColor(Element.TextColor, sc, out tr, out tg, out tb, out ta);
                    float or, og, ob, oa;
                    CreateBackColor(Element.OverlayColor, sc, out or, out og, out ob, out oa);
                    // left background
                    if (Left.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Left.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Left.BackgroundTexture.Width;
                            double v = (double)Left.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Left.BackgroundTexture, x, y, x + u, y + v);
                        }
                    }
                    // right background
                    if (Right.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Right.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Right.BackgroundTexture.Width;
                            double v = (double)Right.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Right.BackgroundTexture, x + w - u, y, x + w, y + v);
                        }
                    }
                    // middle background
                    if (Middle.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Middle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double v = (double)Middle.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Middle.BackgroundTexture, x + lw, y, x + w - rw, y + v);
                        }
                    }
                    {                     // text
                        string t = CurrentLampCollection.Lamps[j].Text;
                        double u = CurrentLampCollection.Lamps[j].Width;
                        double v = CurrentLampCollection.Lamps[j].Height;
                        double p = Math.Round(Element.TextAlignment.X < 0 ? x : Element.TextAlignment.X > 0 ? x + w - u : x + 0.5 * (w - u));
                        double q = Math.Round(Element.TextAlignment.Y < 0 ? y : Element.TextAlignment.Y > 0 ? y + lcrh - v : y + 0.5 * (lcrh - v));
                        p += Element.TextPosition.X;
                        q += Element.TextPosition.Y;
                        DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(tr, tg, tb, ta), Element.TextShadow);
                    }
                    // left overlay
                    if (Left.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Left.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Left.OverlayTexture.Width;
                            double v = (double)Left.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Left.OverlayTexture, x, y, x + u, y + v);
                        }
                    }
                    // right overlay
                    if (Right.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Right.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Right.OverlayTexture.Width;
                            double v = (double)Right.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Right.OverlayTexture, x + w - u, y, x + w, y + v);
                        }
                    }
                    // middle overlay
                    if (Middle.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Middle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double v = (double)Middle.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Middle.OverlayTexture, x + lw, y, x + w - rw, y + v);
                        }
                    }
                }
                y += (double)Element.Value2;
            }
        }
Beispiel #32
0
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     if (Material.DaytimeTexture != null) {
         if (Textures.LoadTexture(Material.DaytimeTexture, wrap)) {
             if (!TexturingEnabled) {
                 Gl.glEnable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = true;
             }
             if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture) {
                 Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                 LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
             }
         } else {
             if (TexturingEnabled) {
                 Gl.glDisable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = false;
                 LastBoundTexture = null;
             }
         }
     } else {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
             LastBoundTexture = null;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         factor = 1.0f;
         if (!BlendEnabled) Gl.glEnable(Gl.GL_BLEND);
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE);
         if (FogEnabled) {
             Gl.glDisable(Gl.GL_FOG);
         }
     } else if (Material.NighttimeTexture == null) {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.7f * blend;
     } else {
         factor = 1.0f;
     }
     if (Material.NighttimeTexture != null) {
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING);
             LightingEnabled = false;
         }
     } else {
         if (OptionLighting & !LightingEnabled) {
             Gl.glEnable(Gl.GL_LIGHTING);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType) {
         case World.MeshFace.FaceTypeTriangles:
             Gl.glBegin(Gl.GL_TRIANGLES);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
             break;
         case World.MeshFace.FaceTypeQuads:
             Gl.glBegin(Gl.GL_QUADS);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             Gl.glBegin(Gl.GL_QUAD_STRIP);
             break;
         default:
             Gl.glBegin(Gl.GL_POLYGON);
             break;
     }
     if (Material.GlowAttenuationData != 0) {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     } else {
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     } else if (EmissiveEnabled) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (Material.DaytimeTexture != null) {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     } else {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     Gl.glEnd();
     // render nighttime polygon
     if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap)) {
         if (!TexturingEnabled) {
             Gl.glEnable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND);
         }
         Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
         LastBoundTexture = null;
         Gl.glAlphaFunc(Gl.GL_GREATER, 0.0f);
         Gl.glEnable(Gl.GL_ALPHA_TEST);
         switch (FaceType) {
             case World.MeshFace.FaceTypeTriangles:
                 Gl.glBegin(Gl.GL_TRIANGLES);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 Gl.glBegin(Gl.GL_QUADS);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 Gl.glBegin(Gl.GL_QUAD_STRIP);
                 break;
             default:
                 Gl.glBegin(Gl.GL_POLYGON);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0) {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         } else {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         } else if (EmissiveEnabled) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         Gl.glEnd();
         RestoreAlphaFunc();
         if (!BlendEnabled) {
             Gl.glDisable(Gl.GL_BLEND);
         }
     }
     // normals
     if (OptionNormals) {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glBegin(Gl.GL_LINES);
             Gl.glColor4f(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             Gl.glEnd();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
         if (!BlendEnabled) Gl.glDisable(Gl.GL_BLEND);
         if (FogEnabled) {
             Gl.glEnable(Gl.GL_FOG);
         }
     }
 }
Beispiel #33
0
            // --- constructors ---
            /// <summary>Creates a new table of characters.</summary>
            /// <param name="font">The font.</param>
            /// <param name="offset">The offset from codepoint U+0000.</param>
            internal OpenGlFontTable(Font font, int offset)
            {
                /*
                 * Measure characters.
                 * */
                Size[]   physicalSizes    = new Size[256];
                Size[]   typographicSizes = new Size[256];
                Bitmap   bitmap           = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
                Graphics graphics         = Graphics.FromImage(bitmap);

                graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                for (int i = 0; i < 256; i++)
                {
                    SizeF physicalSize    = graphics.MeasureString(char.ConvertFromUtf32(offset + i), font, int.MaxValue, StringFormat.GenericDefault);
                    SizeF typographicSize = graphics.MeasureString(char.ConvertFromUtf32(offset + i), font, int.MaxValue, StringFormat.GenericTypographic);
                    physicalSizes[i]    = new Size((int)Math.Ceiling(physicalSize.Width), (int)Math.Ceiling(physicalSize.Height));
                    typographicSizes[i] = new Size((int)Math.Ceiling(typographicSize.Width == 0.0f ? physicalSize.Width : typographicSize.Width), (int)Math.Ceiling(typographicSize.Height == 0.0f ? physicalSize.Height : typographicSize.Height));
                }

                /*
                 * Find suitable bitmap dimensions.
                 * */
                const int width      = 256;
                const int border     = 1;
                int       x          = border;
                int       y          = border;
                int       lineHeight = 0;

                for (int i = 0; i < 256; i++)
                {
                    if (x + physicalSizes[i].Width + border > width)
                    {
                        x          = border;
                        y         += lineHeight;
                        lineHeight = 0;
                    }
                    else
                    {
                        x += physicalSizes[i].Width + 2 * border;
                    }
                    if (physicalSizes[i].Height + border > lineHeight)
                    {
                        lineHeight = physicalSizes[i].Height + 2 * border;
                    }
                }
                y += lineHeight;
                int height = (int)RoundToPowerOfTwo((uint)y);

                graphics.Dispose();
                bitmap.Dispose();

                /*
                 * Draw character to bitmap.
                 * */
                bitmap   = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                graphics = Graphics.FromImage(bitmap);
                graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                graphics.Clear(Color.Black);
                x               = border;
                y               = border;
                lineHeight      = 0;
                this.Characters = new OpenGlFontChar[256];
                for (int i = 0; i < 256; i++)
                {
                    if (x + physicalSizes[i].Width + border > width)
                    {
                        x          = border;
                        y         += lineHeight;
                        lineHeight = 0;
                    }
                    graphics.DrawString(char.ConvertFromUtf32(offset + i), font, Brushes.White, new PointF(x, y));
                    float x0 = (float)(x - border) / (float)width;
                    float x1 = (float)(x + physicalSizes[i].Width + border) / (float)width;
                    float y0 = (float)(y - border) / (float)height;
                    float y1 = (float)(y + physicalSizes[i].Height + border) / (float)height;
                    this.Characters[i] = new OpenGlFontChar(new RectangleF(x0, y0, x1 - x0, y1 - y0), new Size(physicalSizes[i].Width + 2 * border, physicalSizes[i].Height + 2 * border), typographicSizes[i]);
                    x += physicalSizes[i].Width + 2 * border;
                    if (physicalSizes[i].Height + border > lineHeight)
                    {
                        lineHeight = physicalSizes[i].Height + 2 * border;
                    }
                }
                graphics.Dispose();
                this.Texture = Textures.RegisterTexture(bitmap);
            }
Beispiel #34
0
			internal Background(Textures.Texture Texture, int Repetition, bool KeepAspectRatio) {
				this.Texture = Texture;
				this.Repetition = Repetition;
				this.KeepAspectRatio = KeepAspectRatio;
			}
Beispiel #35
0
        // render data
        private static void RenderData(ref Table Table)
        {
            // prepare timetable
            int   w = 384, h = 192;
            int   offsetx           = 0;
            int   actualheight      = h;
            float descriptionwidth  = 256;
            float descriptionheight = 16;
            float stationnamewidth  = 16;

            for (int k = 0; k < 2; k++)
            {
                Bitmap   b = new Bitmap(w, h);
                Graphics g = Graphics.FromImage(b);
                g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                g.Clear(Color.Transparent);
                g.FillRectangle(Brushes.White, new RectangleF(offsetx, 0, w, actualheight));
                Font f   = new Font(FontFamily.GenericSansSerif, 13.0f, GraphicsUnit.Pixel);
                Font fs  = new Font(FontFamily.GenericSansSerif, 11.0f, GraphicsUnit.Pixel);
                Font fss = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel);
                // draw timetable
                string t; SizeF s;
                // description
                float x0 = offsetx + 8;
                float y0 = 8;
                if (k == 1)
                {
                    t = DefaultTimetableDescription;
                    g.DrawString(t, f, Brushes.Black, new RectangleF(x0, 6, descriptionwidth, descriptionheight + 8));
                    y0 += descriptionheight + 2;
                }
                // highest speed
                t = Interface.GetInterfaceString("timetable_highestspeed");
                s = g.MeasureString(t, fs);
                g.DrawString(t, fs, Brushes.Black, x0, y0);
                float y0a = y0 + s.Height + 2;
                float x1  = x0 + s.Width + 4;
                for (int i = 0; i < Table.Tracks.Length; i++)
                {
                    float y = y0a + 18 * i;
                    t = Table.Tracks[i].Speed;
                    g.DrawString(t, f, Brushes.Black, x0, y);
                    s = g.MeasureString(t, f);
                    float x = x0 + s.Width + 4;
                    if (x > x1)
                    {
                        x1 = x;
                    }
                }
                g.DrawLine(Pens.LightGray, new PointF(x1 - 2, 4 + descriptionheight), new PointF(x1 - 2, y0a + 18 * Table.Tracks.Length - 1));
                // driving time
                t = Interface.GetInterfaceString("timetable_drivingtime");
                s = g.MeasureString(t, fs);
                g.DrawString(t, fs, Brushes.Black, x1, y0);
                float x2 = x1 + s.Width + 4;
                for (int i = 0; i < Table.Tracks.Length; i++)
                {
                    float y = y0a + 18 * i;
                    if (Table.Tracks[i].Time.Hour.Length != 0)
                    {
                        t = Table.Tracks[i].Time.Hour;
                        g.DrawString(t, fss, Brushes.Black, x1, y + 2);
                    }
                    else
                    {
                        t = "0";
                    }
                    s = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic);
                    float x = x1 + s.Width - 1;
                    if (Table.Tracks[i].Time.Minute.Length != 0)
                    {
                        t = Table.Tracks[i].Time.Minute;
                        g.DrawString(t, fs, Brushes.Black, x, y + 2);
                    }
                    else
                    {
                        t = "00:";
                    }
                    s  = g.MeasureString(t, fs, 9999, StringFormat.GenericTypographic);
                    x += s.Width + 1;
                    t  = Table.Tracks[i].Time.Second;
                    g.DrawString(t, fss, Brushes.Black, x, y + 2);
                    s  = g.MeasureString(t, fss, 9999, StringFormat.GenericTypographic);
                    x += s.Width + 8;
                    if (x > x2)
                    {
                        x2 = x;
                    }
                }
                for (int i = 0; i < Table.Tracks.Length; i++)
                {
                    float y = y0a + 18 * i;
                    g.DrawLine(Pens.LightGray, new PointF(offsetx + 4, y - 1), new PointF(x2 - 2, y - 1));
                }
                g.DrawLine(Pens.LightGray, new PointF(x2 - 2, 4 + descriptionheight), new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1));
                // station name
                float y2 = y0;
                t = Interface.GetInterfaceString("timetable_stationname");
                s = g.MeasureString(t, f);
                g.DrawString(t, f, Brushes.Black, x2, y2);
                float x3 = x2 + s.Width + 4;
                for (int i = 0; i < Table.Stations.Length; i++)
                {
                    float y = y0 + 18 * (i + 1) + 2;
                    g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1));
                    t = Table.Stations[i].Name;
                    if (Table.Stations[i].NameJapanese & Table.Stations[i].Name.Length > 1)
                    {
                        float[] sizes     = new float[t.Length];
                        float   totalsize = 0.0f;
                        for (int j = 0; j < t.Length; j++)
                        {
                            sizes[j]   = g.MeasureString(new string(t[j], 1), f, 9999, StringFormat.GenericTypographic).Width;
                            totalsize += sizes[j];
                        }
                        float space = (stationnamewidth - totalsize) / (float)(t.Length - 1);
                        float x     = 0.0f;
                        for (int j = 0; j < t.Length; j++)
                        {
                            g.DrawString(new string(t[j], 1), f, Brushes.Black, x2 + x, y);
                            x += sizes[j] + space;
                        }
                    }
                    else
                    {
                        g.DrawString(t, f, Brushes.Black, x2, y);
                    }
                    s = g.MeasureString(t, f);
                    {
                        float x = x2 + s.Width + 4;
                        if (x > x3)
                        {
                            x3 = x;
                        }
                    }
                }
                g.DrawLine(Pens.LightGray, new PointF(x3 - 2, 4 + descriptionheight), new PointF(x3 - 2, y0 + 18 * (Table.Stations.Length + 1)));
                if (k == 0)
                {
                    stationnamewidth = x3 - x2 - 6;
                }
                // arrival time
                t = Interface.GetInterfaceString("timetable_arrivaltime");
                s = g.MeasureString(t, f);
                g.DrawString(t, f, Brushes.Black, x3, y2);
                float x4 = x3 + s.Width + 4;
                for (int i = 0; i < Table.Stations.Length; i++)
                {
                    float y = y0 + 18 * (i + 1) + 2;
                    if (Table.Stations[i].Pass)
                    {
                        t = "00";
                        s = g.MeasureString(t, fs);
                        float x = x3 + s.Width;
                        t = "   ↓";
                        g.DrawString(t, f, Brushes.Black, x, y);
                        s  = g.MeasureString(t, f);
                        x += +s.Width + 4;
                        if (x > x4)
                        {
                            x4 = x;
                        }
                    }
                    else
                    {
                        if (Table.Stations[i].Arrival.Hour.Length != 0)
                        {
                            t = Table.Stations[i].Arrival.Hour;
                            g.DrawString(t, fs, Brushes.Black, x3, y);
                        }
                        else
                        {
                            t = "00";
                        }
                        s = g.MeasureString(t, fs);
                        float x = x3 + s.Width;
                        if (Table.Stations[i].Arrival.Minute.Length != 0 & Table.Stations[i].Arrival.Second.Length != 0)
                        {
                            t = Table.Stations[i].Arrival.Minute + ":" + Table.Stations[i].Arrival.Second;
                        }
                        else
                        {
                            t = "";
                        }
                        g.DrawString(t, f, Brushes.Black, x, y);
                        s  = g.MeasureString(t, f);
                        x += s.Width + 4;
                        if (x > x4)
                        {
                            x4 = x;
                        }
                    }
                }
                g.DrawLine(Pens.LightGray, new PointF(x4 - 2, 4 + descriptionheight), new PointF(x4 - 2, y0 + 18 * (Table.Stations.Length + 1)));
                // departure time
                t = Interface.GetInterfaceString("timetable_departuretime");
                s = g.MeasureString(t, f);
                g.DrawString(t, f, Brushes.Black, x4, y2);
                float x5 = x4 + s.Width + 4;
                for (int i = 0; i < Table.Stations.Length; i++)
                {
                    float y = y0 + 18 * (i + 1) + 2;
                    if (Table.Stations[i].Terminal)
                    {
                        t = "00";
                        s = g.MeasureString(t, fs);
                        float       x  = x4 + s.Width;
                        const float c0 = 4;
                        const float c1 = 32;
                        g.DrawLine(Pens.Black, new PointF(x + c0, y + 6), new PointF(x + c1, y + 6));
                        g.DrawLine(Pens.Black, new PointF(x + c0, y + 10), new PointF(x + c1, y + 10));
                        x += c1 + 4;
                        if (x > x5)
                        {
                            x5 = x;
                        }
                    }
                    else
                    {
                        if (Table.Stations[i].Departure.Hour.Length != 0)
                        {
                            t = Table.Stations[i].Departure.Hour;
                            g.DrawString(t, fs, Brushes.Black, x4, y);
                        }
                        else
                        {
                            t = "00";
                        }
                        s = g.MeasureString(t, fs);
                        float x = x4 + s.Width;
                        if (Table.Stations[i].Departure.Minute.Length != 0 & Table.Stations[i].Departure.Second.Length != 0)
                        {
                            t = Table.Stations[i].Departure.Minute + ":" + Table.Stations[i].Departure.Second;
                        }
                        else
                        {
                            t = "";
                        }
                        g.DrawString(t, f, Brushes.Black, x, y);
                        s  = g.MeasureString(t, f);
                        x += s.Width + 4;
                        if (x > x5)
                        {
                            x5 = x;
                        }
                    }
                }
                for (int i = 0; i < Table.Stations.Length; i++)
                {
                    float y = y0 + 18 * (i + 1) + 2;
                    g.DrawLine(Pens.LightGray, new PointF(x2 - 2, y - 1), new PointF(w - 4, y - 1));
                }
                // border
                if (k == 1)
                {
                    g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(offsetx + 4, y0a + 18 * Table.Tracks.Length - 1));
                    g.DrawLine(Pens.Black, new PointF(offsetx + 4, y0a + 18 * Table.Tracks.Length - 1), new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1));
                    g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4), new PointF(w - 4, 4));
                    g.DrawLine(Pens.Black, new PointF(offsetx + 4, 4 + descriptionheight), new PointF(w - 4, 4 + descriptionheight));
                    g.DrawLine(Pens.Black, new PointF(x2 - 2, y0 + 18 * (Table.Stations.Length + 1)), new PointF(w - 4, y0 + 18 * (Table.Stations.Length + 1)));
                    g.DrawLine(Pens.Black, new PointF(w - 4, 4), new PointF(w - 4, y0 + 18 * (Table.Stations.Length + 1)));
                    g.DrawLine(Pens.Black, new PointF(x2 - 2, y0a + 18 * Table.Tracks.Length - 1), new PointF(x2 - 2, y0 + 18 * (Table.Stations.Length + 1)));
                }
                // measure
                w = (int)Math.Ceiling((double)(x5 + 1));
                h = (int)Math.Ceiling((double)(y0 + 18 * (Table.Stations.Length + 1) + 4));
                // description
                if (k == 0)
                {
                    t = DefaultTimetableDescription;
                    s = g.MeasureString(t, f, w - 16);
                    descriptionwidth  = s.Width;
                    descriptionheight = s.Height + 2;
                    h += (int)Math.Ceiling((double)s.Height) + 4;
                }
                // finish
                if (k == 0)
                {
                    // measures
                    int nw = Textures.RoundUpToPowerOfTwo(w);
                    offsetx      = nw - w;
                    w            = nw;
                    actualheight = h;
                    h            = Textures.RoundUpToPowerOfTwo(h);
                }
                else
                {
                    // create texture
                    g.Dispose();
                    DefaultTimetableTexture = Textures.RegisterTexture(b);
                }
            }
        }
Beispiel #36
0
 internal static void AddMarker(Textures.Texture Texture)
 {
     int n = MarkerTextures.Length;
     Array.Resize<Textures.Texture>(ref MarkerTextures, n + 1);
     MarkerTextures[n] = Texture;
 }
Beispiel #37
0
        /// <summary>Renders a string to the screen.</summary>
        /// <param name="font">The font to use.</param>
        /// <param name="text">The string to render.</param>
        /// <param name="location">The location.</param>
        /// <param name="alignment">The alignment.</param>
        /// <param name="color">The color.</param>
        /// <remarks>This function sets the OpenGL blend function to glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA).</remarks>
        private static void DrawString(Fonts.OpenGlFont font, string text, Point location, TextAlignment alignment, Color128 color)
        {
            if (text == null || font == null)
            {
                return;
            }

            /*
             * Prepare the top-left coordinates for rendering, incorporating the
             * orientation of the string in relation to the specified location.
             * */
            int left;

            if ((alignment & TextAlignment.Left) == 0)
            {
                int width = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    Texture texture;
                    Fonts.OpenGlFontChar data;
                    i     += font.GetCharacterData(text, i, out texture, out data) - 1;
                    width += data.TypographicSize.Width;
                }
                if ((alignment & TextAlignment.Right) != 0)
                {
                    left = location.X - width;
                }
                else
                {
                    left = location.X - width / 2;
                }
            }
            else
            {
                left = location.X;
            }
            int top;

            if ((alignment & TextAlignment.Top) == 0)
            {
                int height = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    Texture texture;
                    Fonts.OpenGlFontChar data;
                    i += font.GetCharacterData(text, i, out texture, out data) - 1;
                    if (data.TypographicSize.Height > height)
                    {
                        height = data.TypographicSize.Height;
                    }
                }
                if ((alignment & TextAlignment.Bottom) != 0)
                {
                    top = location.Y - height;
                }
                else
                {
                    top = location.Y - height / 2;
                }
            }
            else
            {
                top = location.Y;
            }

            /*
             * Render the string.
             * */
            GL.Enable(EnableCap.Texture2D);
            for (int i = 0; i < text.Length; i++)
            {
                Texture texture;
                Fonts.OpenGlFontChar data;
                i += font.GetCharacterData(text, i, out texture, out data) - 1;
                if (Textures.LoadTexture(texture, OpenGlTextureWrapMode.ClampClamp))
                {
                    GL.BindTexture(TextureTarget.Texture2D, texture.OpenGlTextures[(int)OpenGlTextureWrapMode.ClampClamp].Name);

                    int x = left - (data.PhysicalSize.Width - data.TypographicSize.Width) / 2;
                    int y = top - (data.PhysicalSize.Height - data.TypographicSize.Height) / 2;

                    /*
                     * In the first pass, mask off the background with pure black.
                     * */
                    GL.BlendFunc(BlendingFactor.Zero, BlendingFactor.OneMinusSrcColor);
                    GL.Begin(PrimitiveType.Polygon);
                    GL.Color4(color.A, color.A, color.A, 1.0f);
                    GL.TexCoord2(data.TextureCoordinates.Left, data.TextureCoordinates.Top);
                    GL.Vertex2(x, y);
                    GL.Color4(color.A, color.A, color.A, 1.0f);
                    GL.TexCoord2(data.TextureCoordinates.Right, data.TextureCoordinates.Top);
                    GL.Vertex2(x + data.PhysicalSize.Width, y);
                    GL.Color4(color.A, color.A, color.A, 1.0f);
                    GL.TexCoord2(data.TextureCoordinates.Right, data.TextureCoordinates.Bottom);
                    GL.Vertex2(x + data.PhysicalSize.Width, y + data.PhysicalSize.Height);
                    GL.Color4(color.A, color.A, color.A, 1.0f);
                    GL.TexCoord2(data.TextureCoordinates.Left, data.TextureCoordinates.Bottom);
                    GL.Vertex2(x, y + data.PhysicalSize.Height);
                    GL.End();

                    /*
                     * In the second pass, add the character onto the background.
                     * */
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
                    GL.Begin(PrimitiveType.Polygon);
                    GL.Color4(color.R, color.G, color.B, color.A);
                    GL.TexCoord2(data.TextureCoordinates.Left, data.TextureCoordinates.Top);
                    GL.Vertex2(x, y);
                    GL.Color4(color.R, color.G, color.B, color.A);
                    GL.TexCoord2(data.TextureCoordinates.Right, data.TextureCoordinates.Top);
                    GL.Vertex2(x + data.PhysicalSize.Width, y);
                    GL.Color4(color.R, color.G, color.B, color.A);
                    GL.TexCoord2(data.TextureCoordinates.Right, data.TextureCoordinates.Bottom);
                    GL.Vertex2(x + data.PhysicalSize.Width, y + data.PhysicalSize.Height);
                    GL.Color4(color.R, color.G, color.B, color.A);
                    GL.TexCoord2(data.TextureCoordinates.Left, data.TextureCoordinates.Bottom);
                    GL.Vertex2(x, y + data.PhysicalSize.Height);
                    GL.End();
                }
                left += data.TypographicSize.Width;
            }
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);             // HACK //
        }
Beispiel #38
0
 /// <summary>Creates a clone of the specified object.</summary>
 /// <param name="Prototype">The prototype.</param>
 /// <param name="DaytimeTexture">The replacement daytime texture, or a null reference to keep the texture of the prototype.</param>
 /// <param name="NighttimeTexture">The replacement nighttime texture, or a null reference to keep the texture of the prototype.</param>
 /// <returns></returns>
 internal static StaticObject CloneObject(StaticObject Prototype, Textures.Texture DaytimeTexture, Textures.Texture NighttimeTexture)
 {
     if (Prototype == null) return null;
     StaticObject Result = new StaticObject();
     Result.StartingDistance = Prototype.StartingDistance;
     Result.EndingDistance = Prototype.EndingDistance;
     Result.Dynamic = Prototype.Dynamic;
     // vertices
     Result.Mesh.Vertices = new World.Vertex[Prototype.Mesh.Vertices.Length];
     for (int j = 0; j < Prototype.Mesh.Vertices.Length; j++) {
         Result.Mesh.Vertices[j] = Prototype.Mesh.Vertices[j];
     }
     // faces
     Result.Mesh.Faces = new World.MeshFace[Prototype.Mesh.Faces.Length];
     for (int j = 0; j < Prototype.Mesh.Faces.Length; j++) {
         Result.Mesh.Faces[j].Flags = Prototype.Mesh.Faces[j].Flags;
         Result.Mesh.Faces[j].Material = Prototype.Mesh.Faces[j].Material;
         Result.Mesh.Faces[j].Vertices = new World.MeshFaceVertex[Prototype.Mesh.Faces[j].Vertices.Length];
         for (int k = 0; k < Prototype.Mesh.Faces[j].Vertices.Length; k++) {
             Result.Mesh.Faces[j].Vertices[k] = Prototype.Mesh.Faces[j].Vertices[k];
         }
     }
     // materials
     Result.Mesh.Materials = new World.MeshMaterial[Prototype.Mesh.Materials.Length];
     for (int j = 0; j < Prototype.Mesh.Materials.Length; j++) {
         Result.Mesh.Materials[j] = Prototype.Mesh.Materials[j];
         if (DaytimeTexture != null) {
             Result.Mesh.Materials[j].DaytimeTexture = DaytimeTexture;
         } else {
             Result.Mesh.Materials[j].DaytimeTexture = Prototype.Mesh.Materials[j].DaytimeTexture;
         }
         if (DaytimeTexture != null) {
             Result.Mesh.Materials[j].NighttimeTexture = NighttimeTexture;
         } else {
             Result.Mesh.Materials[j].NighttimeTexture = Prototype.Mesh.Materials[j].NighttimeTexture;
         }
     }
     return Result;
 }
Beispiel #39
0
        /// <summary>Makes an object visible within the world</summary>
        /// <param name="ObjectIndex">The object's index</param>
        /// <param name="Type">Whether this is a static or dynamic object</param>
        internal static void ShowObject(int ObjectIndex, ObjectType Type)
        {
            if (ObjectManager.Objects[ObjectIndex] == null)
            {
                return;
            }
            if (ObjectManager.Objects[ObjectIndex].RendererIndex == 0)
            {
                if (ObjectCount >= Objects.Length)
                {
                    Array.Resize <Object>(ref Objects, Objects.Length << 1);
                }
                Objects[ObjectCount].ObjectIndex = ObjectIndex;
                Objects[ObjectCount].Type        = Type;
                int f = ObjectManager.Objects[ObjectIndex].Mesh.Faces.Length;
                Objects[ObjectCount].FaceListReferences = new ObjectListReference[f];
                for (int i = 0; i < f; i++)
                {
                    bool alpha = false;
                    int  k     = ObjectManager.Objects[ObjectIndex].Mesh.Faces[i].Material;
                    Textures.OpenGlTextureWrapMode wrap = Textures.OpenGlTextureWrapMode.ClampClamp;
                    if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null | ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                    {
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode == null)
                        {
                            // HACK: Objects do not (by default) store information on the texture wrapping mode.
                            //       Let's determine the best wrapping mode now and then save it
                            //       so we can quickly access it in the rendering loop.

                            for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++)
                            {
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                                {
                                    wrap |= Textures.OpenGlTextureWrapMode.RepeatClamp;
                                }
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                                {
                                    wrap |= Textures.OpenGlTextureWrapMode.ClampRepeat;
                                }
                            }

                            if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null)
                            {
                                if (Textures.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, wrap))
                                {
                                    OpenBveApi.Textures.TextureTransparencyType type =
                                        ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency;
                                    if (type == OpenBveApi.Textures.TextureTransparencyType.Alpha)
                                    {
                                        alpha = true;
                                    }
                                    else if (type == OpenBveApi.Textures.TextureTransparencyType.Partial &&
                                             Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                    {
                                        alpha = true;
                                    }
                                }
                            }
                            if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture != null)
                            {
                                if (Textures.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture, wrap))
                                {
                                    OpenBveApi.Textures.TextureTransparencyType type =
                                        ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency;
                                    if (type == OpenBveApi.Textures.TextureTransparencyType.Alpha)
                                    {
                                        alpha = true;
                                    }
                                    else if (type == OpenBveApi.Textures.TextureTransparencyType.Partial &
                                             Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                    {
                                        alpha = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer
                            wrap = (Textures.OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode;
                        }
                    }
                    if (Type == ObjectType.Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].Color.A != 255)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].BlendMode == World.MeshMaterialBlendMode.Additive)
                    {
                        alpha = true;
                    }
                    else if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].GlowAttenuationData != 0)
                    {
                        alpha = true;
                    }
                    ObjectListType listType;
                    switch (Type)
                    {
                    case ObjectType.Static:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.StaticOpaque;
                        break;

                    case ObjectType.Dynamic:
                        listType = alpha ? ObjectListType.DynamicAlpha : ObjectListType.DynamicOpaque;
                        break;

                    case ObjectType.Overlay:
                        listType = alpha ? ObjectListType.OverlayAlpha : ObjectListType.OverlayOpaque;
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (listType == ObjectListType.StaticOpaque)
                    {
                        /*
                         * For the static opaque list, insert the face into
                         * the first vacant position in the matching group's list.
                         * */
                        int groupIndex = (int)ObjectManager.Objects[ObjectIndex].GroupIndex;
                        if (groupIndex >= StaticOpaque.Length)
                        {
                            if (StaticOpaque.Length == 0)
                            {
                                StaticOpaque = new ObjectGroup[16];
                            }
                            while (groupIndex >= StaticOpaque.Length)
                            {
                                Array.Resize <ObjectGroup>(ref StaticOpaque, StaticOpaque.Length << 1);
                            }
                        }
                        if (StaticOpaque[groupIndex] == null)
                        {
                            StaticOpaque[groupIndex] = new ObjectGroup();
                        }
                        ObjectList list     = StaticOpaque[groupIndex].List;
                        int        newIndex = list.FaceCount;
                        for (int j = 0; j < list.FaceCount; j++)
                        {
                            if (list.Faces[j] == null)
                            {
                                newIndex = j;
                                break;
                            }
                        }
                        if (newIndex == list.FaceCount)
                        {
                            if (list.FaceCount == list.Faces.Length)
                            {
                                Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                            }
                            list.FaceCount++;
                        }
                        list.Faces[newIndex] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        StaticOpaque[groupIndex].Update            = true;
                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, newIndex);
                        Game.InfoStaticOpaqueFaceCount++;

                        /*
                         * Check if the given object has a bounding box, and insert it to the end of the list of bounding boxes if required
                         */
                        if (ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox != null)
                        {
                            int Index = list.BoundingBoxes.Length;
                            for (int j = 0; j < list.BoundingBoxes.Length; j++)
                            {
                                if (list.Faces[j] == null)
                                {
                                    Index = j;
                                    break;
                                }
                            }
                            if (Index == list.BoundingBoxes.Length)
                            {
                                Array.Resize <BoundingBox>(ref list.BoundingBoxes, list.BoundingBoxes.Length << 1);
                            }
                            list.BoundingBoxes[Index].Upper = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[0];
                            list.BoundingBoxes[Index].Lower = ObjectManager.Objects[ObjectIndex].Mesh.BoundingBox[1];
                        }
                    }
                    else
                    {
                        /*
                         * For all other lists, insert the face at the end of the list.
                         * */
                        ObjectList list;
                        switch (listType)
                        {
                        case ObjectListType.DynamicOpaque:
                            list = DynamicOpaque;
                            break;

                        case ObjectListType.DynamicAlpha:
                            list = DynamicAlpha;
                            break;

                        case ObjectListType.OverlayOpaque:
                            list = OverlayOpaque;
                            break;

                        case ObjectListType.OverlayAlpha:
                            list = OverlayAlpha;
                            break;

                        default:
                            throw new InvalidOperationException();
                        }
                        if (list.FaceCount == list.Faces.Length)
                        {
                            Array.Resize <ObjectFace>(ref list.Faces, list.Faces.Length << 1);
                        }
                        list.Faces[list.FaceCount] = new ObjectFace
                        {
                            ObjectListIndex = ObjectCount,
                            ObjectIndex     = ObjectIndex,
                            FaceIndex       = i,
                            Wrap            = wrap
                        };

                        // HACK: Let's store the wrapping mode.

                        Objects[ObjectCount].FaceListReferences[i] = new ObjectListReference(listType, list.FaceCount);
                        list.FaceCount++;
                    }
                }
                ObjectManager.Objects[ObjectIndex].RendererIndex = ObjectCount + 1;
                ObjectCount++;
            }
        }
Beispiel #40
0
		// update custom timetable
		internal static void UpdateCustomTimetable(Textures.Texture daytime, Textures.Texture nighttime) {
			for (int i = 0; i < CustomObjectsUsed; i++) {
				for (int j = 0; j < CustomObjects[i].States.Length; j++) {
					for (int k = 0; k < CustomObjects[i].States[j].Object.Mesh.Materials.Length; k++) {
						if (daytime != null) {
							CustomObjects[i].States[j].Object.Mesh.Materials[k].DaytimeTexture = daytime;
						}
						if (nighttime != null) {
							CustomObjects[i].States[j].Object.Mesh.Materials[k].NighttimeTexture = nighttime;
						}
					}
				}
			}
			if (daytime != null) {
				CurrentCustomTimetableDaytimeTexture = daytime;
			}
			if (nighttime != null) {
				CurrentCustomTimetableNighttimeTexture = nighttime;
			}
			if (CurrentCustomTimetableDaytimeTexture != null | CurrentCustomTimetableNighttimeTexture != null) {
				CustomTimetableAvailable = true;
			} else {
				CustomTimetableAvailable = false;
			}
		}
Beispiel #41
0
        // process events
        internal static void KeyDown(object sender, KeyboardKeyEventArgs e)
        {
            switch (e.Key)
            {
            case Key.LShift:
            case Key.RShift:
                ShiftPressed = true;
                break;

            case Key.F5:
                // reset
                ReducedMode      = false;
                LightingRelative = -1.0;
                Game.Reset();
                Textures.UnloadAllTextures();
                //Fonts.Initialize();
                Interface.ClearMessages();
                for (int i = 0; i < Files.Length; i++)
                {
#if !DEBUG
                    try {
                                                                                #endif
                    ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8,
                                                                             ObjectManager.ObjectLoadMode.Normal, false, false, false);
                    ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0),
                                               new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0,
                                               0.0, 25.0, 0.0);
#if !DEBUG
                }
                catch (Exception ex) {
                    Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + ".");
                }
                                                                        #endif
                }
                ObjectManager.InitializeVisibility();
                ObjectManager.UpdateVisibility(0.0, true);
                ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
                break;

            case Key.F7:
            {
                OpenFileDialog Dialog = new OpenFileDialog
                {
                    CheckFileExists = true,
                    Multiselect     = true,
                    Filter          = @"All supported object files|*.csv;*.b3d;*.x;*.animated;*.l3dobj;*.l3dgrp;*.obj;*.s|openBVE Objects|*.csv;*.b3d;*.x;*.animated|LokSim 3D Objects|*.l3dobj;*.l3dgrp|Wavefront Objects|*.obj|Microsoft Train Simulator Objects|*.s|All files|*"
                };
                if (Dialog.ShowDialog() == DialogResult.OK)
                {
                    Application.DoEvents();
                    string[] f = Dialog.FileNames;
                    int      n = Files.Length;
                    Array.Resize <string>(ref Files, n + f.Length);
                    for (int i = 0; i < f.Length; i++)
                    {
                        Files[n + i] = f[i];
                    }
                    // reset
                    ReducedMode      = false;
                    LightingRelative = -1.0;
                    Game.Reset();
                    Textures.UnloadAllTextures();
                    Interface.ClearMessages();
                    for (int i = 0; i < Files.Length; i++)
                    {
#if !DEBUG
                        try
                        {
#endif
                        ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8,
                                                                                 ObjectManager.ObjectLoadMode.Normal, false, false, false);
                        ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0),
                                                   new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0,
                                                   0.0);
#if !DEBUG
                    }
                    catch (Exception ex)
                    {
                        Interface.AddMessage(Interface.MessageType.Critical, false,
                                             "Unhandled error (" + ex.Message + ") encountered while processing the file " +
                                             Files[i] + ".");
                    }
#endif
                    }
                    ObjectManager.InitializeVisibility();
                    ObjectManager.FinishCreatingObjects();
                    ObjectManager.UpdateVisibility(0.0, true);
                    ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
                }
                else
                {
                    if (Program.CurrentlyRunOnMono)
                    {
                        //HACK: Dialog doesn't close properly when pressing the ESC key under Mono
                        //Avoid calling Application.DoEvents() unless absolutely necessary though!
                        Application.DoEvents();
                    }
                }
                Dialog.Dispose();
            }
            break;

            case Key.F9:
                if (Interface.MessageCount != 0)
                {
                    formMessages.ShowMessages();
                    Application.DoEvents();
                }
                break;

            case Key.Delete:
                ReducedMode      = false;
                LightingRelative = -1.0;
                Game.Reset();
                Textures.UnloadAllTextures();
                //Fonts.Initialize();
                Interface.ClearMessages();
                Files = new string[] {};
                break;

            case Key.Left:
                RotateX     = -1;
                ReducedMode = false;
                break;

            case Key.Right:
                RotateX     = 1;
                ReducedMode = false;
                break;

            case Key.Up:
                RotateY     = -1;
                ReducedMode = false;
                break;

            case Key.Down:
                RotateY     = 1;
                ReducedMode = false;
                break;

            case Key.A:
            case Key.Keypad4:
                MoveX       = -1;
                ReducedMode = false;
                break;

            case Key.D:
            case Key.Keypad6:
                MoveX       = 1;
                ReducedMode = false;
                break;

            case Key.Keypad8:
                MoveY       = 1;
                ReducedMode = false;
                break;

            case Key.Keypad2:
                MoveY       = -1;
                ReducedMode = false;
                break;

            case Key.W:
            case Key.Keypad9:
                MoveZ       = 1;
                ReducedMode = false;
                break;

            case Key.S:
            case Key.Keypad3:
                MoveZ       = -1;
                ReducedMode = false;
                break;

            case Key.Keypad5:
                ResetCamera();
                break;

            case Key.F:
            case Key.F1:
                Renderer.OptionWireframe = !Renderer.OptionWireframe;
                if (Renderer.OptionWireframe)
                {
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                }
                else
                {
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                }
                break;

            case Key.N:
            case Key.F2:
                Renderer.OptionNormals = !Renderer.OptionNormals;
                break;

            case Key.L:
            case Key.F3:
                LightingTarget = 1 - LightingTarget;
                ReducedMode    = false;
                break;

            case Key.I:
            case Key.F4:
                Renderer.OptionInterface = !Renderer.OptionInterface;
                ReducedMode = false;
                break;

            case Key.F8:
                formOptions.ShowOptions();
                Application.DoEvents();
                break;

            case Key.G:
            case Key.C:
                Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem;
                ReducedMode = false;
                break;

            case Key.B:
                if (ShiftPressed)
                {
                    ColorDialog dialog = new ColorDialog();
                    dialog.FullOpen = true;
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        Renderer.BackgroundColor = -1;
                        Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B);
                    }
                }
                else
                {
                    Renderer.BackgroundColor++;
                    if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor)
                    {
                        Renderer.BackgroundColor = 0;
                    }
                    Renderer.ApplyBackgroundColor();
                }
                ReducedMode = false;
                break;
            }
        }