LoadTexture() static private method

Loads the specified texture into OpenGL if not already loaded.
static private LoadTexture ( Texture handle, OpenGlTextureWrapMode wrap ) : bool
handle Texture The handle to the registered texture.
wrap OpenGlTextureWrapMode The texture type indicating the clamp mode.
return bool
Example #1
0
        /* --------------------------------------------------------------
         * This file contains the drawing routines for the loading screen
         * -------------------------------------------------------------- */

        internal static void DrawLoadingScreen()
        {
            // begin HACK //
            Gl.glEnable(Gl.GL_BLEND); BlendEnabled        = true;
            Gl.glDisable(Gl.GL_LIGHTING); LightingEnabled = false;
            int size = Math.Min(Screen.Width, Screen.Height);

            DrawRectangle(null, new Point(0, 0), new Size(Screen.Width, Screen.Height), Color128.Black);
            if (Textures.LoadTexture(TextureLogo, Textures.OpenGlTextureWrapMode.ClampClamp))
            {
                DrawRectangle(TextureLogo, new Point((Screen.Width - size) / 2, (Screen.Height - size) / 2), new Size(size, size), Color128.White);
            }
            DrawRectangle(null, new Point((Screen.Width - size) / 2, Screen.Height - (int)Fonts.NormalFont.FontSize - 10), new Size(Screen.Width, (int)Fonts.NormalFont.FontSize + 10), new Color128(0.0f, 0.0f, 0.0f, 0.5f));
//			double routeProgress = Math.Max(0.0, Math.Min(1.0, Loading.RouteProgress));
//			double trainProgress = Math.Max(0.0, Math.Min(1.0, Loading.TrainProgress));
            string text;

//			if (routeProgress < 1.0) {
//				text = "Loading route... " + (100.0 * routeProgress).ToString("0") + "%";
//			} else if (trainProgress < 1.0) {
//				text = "Loading train... " + (100.0 * trainProgress).ToString("0") + "%";
//			} else {
//				text = "Loading textures and sounds...";
//			}
            text = Interface.GetInterfaceString("message_loading");
            DrawString(Fonts.SmallFont, text, new Point((Screen.Width - size) / 2 + 5, Screen.Height - (int)(Fonts.NormalFont.FontSize / 2) - 5), TextAlignment.CenterLeft, Color128.White);
            // end HACK //
        }
Example #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, 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.Disable(EnableCap.Texture2D);
                if (color.HasValue)
                {
                    GL.Color4(color.Value.R, color.Value.G, color.Value.B, color.Value.A);
                }

                /*
                 * // test triangles instead of quads
                 * // future todo: indexed vbo
                 * GL.Begin(PrimitiveType.Triangles);
                 * 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 + size.Width, point.Y + size.Height);
                 * GL.Vertex2(point.X, point.Y + size.Height);
                 * GL.Vertex2(point.X, point.Y);
                 * GL.End();
                 */
                GL.Begin(PrimitiveType.Quads);                 // FIXME immediate rendering! 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);                // FIXME immediate rendering! 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();
            }
        }
Example #3
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, 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();
     }
 }
 /// <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(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, 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)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();
     }
 }
Example #5
0
        /// <summary>Renders a static frustrum based background</summary>
        /// <param name="Data">The background to render</param>
        /// <param name="Alpha">The alpha level</param>
        /// <param name="scale">The scale</param>
        internal static void RenderBackground(BackgroundManager.StaticBackground Data, float Alpha, float scale)
        {
            if (Data.Texture != null && Textures.LoadTexture(Data.Texture, OpenGlTextureWrapMode.RepeatClamp))
            {
                if (LightingEnabled)
                {
                    GL.Disable(EnableCap.Lighting);
                    LightingEnabled = false;
                }
                if (!TexturingEnabled)
                {
                    GL.Enable(EnableCap.Texture2D);
                    TexturingEnabled = true;
                }
                if (Alpha == 1.0f)
                {
                    if (BlendEnabled)
                    {
                        GL.Disable(EnableCap.Blend);
                        BlendEnabled = false;
                    }
                }
                else if (!BlendEnabled)
                {
                    GL.Enable(EnableCap.Blend);
                    BlendEnabled = true;
                }
                GL.BindTexture(TextureTarget.Texture2D, Data.Texture.OpenGlTextures[(int)OpenGlTextureWrapMode.RepeatClamp].Name);
                GL.Color4(1.0f, 1.0f, 1.0f, Alpha);

                if (!BackgroundDisplayListAvailable)
                {
                    BackgroundDisplayList = GL.GenLists(1);
                    GL.NewList(BackgroundDisplayList, ListMode.Compile);
                    float y0, y1;
                    if (Data.KeepAspectRatio)
                    {
                        int    tw = Data.Texture.Width;
                        int    th = Data.Texture.Height;
                        double hh = Math.PI * World.BackgroundImageDistance * (double)th /
                                    ((double)tw * (double)Data.Repetition);
                        y0 = (float)(-0.5 * hh);
                        y1 = (float)(1.5 * hh);
                    }
                    else
                    {
                        y0 = (float)(-0.125 * World.BackgroundImageDistance);
                        y1 = (float)(0.375 * World.BackgroundImageDistance);
                    }
                    const int    n              = 32;
                    Vector3[]    bottom         = new Vector3[n];
                    Vector3[]    top            = new Vector3[n];
                    double       angleValue     = 2.61799387799149 - 3.14159265358979 / (double)n;
                    const double angleIncrement = 6.28318530717958 / (double)n;

                    /*
                     * To ensure that the whole background cylinder is rendered inside the viewing frustum,
                     * the background is rendered before the scene with z-buffer writes disabled. Then,
                     * the actual distance from the camera is irrelevant as long as it is inside the frustum.
                     * */
                    for (int i = 0; i < n; i++)
                    {
                        float x = (float)(World.BackgroundImageDistance * Math.Cos(angleValue));
                        float z = (float)(World.BackgroundImageDistance * Math.Sin(angleValue));
                        bottom[i]   = new Vector3(scale * x, scale * y0, scale * z);
                        top[i]      = new Vector3(scale * x, scale * y1, scale * z);
                        angleValue += angleIncrement;
                    }
                    float  textureStart     = 0.5f * (float)Data.Repetition / (float)n;
                    float  textureIncrement = -(float)Data.Repetition / (float)n;
                    double textureX         = textureStart;
                    for (int i = 0; i < n; i++)
                    {
                        int j = (i + 1) % n;
                        // side wall
                        GL.Begin(PrimitiveType.Quads);
                        GL.TexCoord2(textureX, 0.005f);
                        GL.Vertex3(top[i].X, top[i].Y, top[i].Z);
                        GL.TexCoord2(textureX, 0.995f);
                        GL.Vertex3(bottom[i].X, bottom[i].Y, bottom[i].Z);
                        GL.TexCoord2(textureX + textureIncrement, 0.995f);
                        GL.Vertex3(bottom[j].X, bottom[j].Y, bottom[j].Z);
                        GL.TexCoord2(textureX + textureIncrement, 0.005f);
                        GL.Vertex3(top[j].X, top[j].Y, top[j].Z);
                        GL.End();
                        // top cap
                        GL.Begin(PrimitiveType.Triangles);
                        GL.TexCoord2(textureX, 0.005f);
                        GL.Vertex3(top[i].X, top[i].Y, top[i].Z);
                        GL.TexCoord2(textureX + textureIncrement, 0.005f);
                        GL.Vertex3(top[j].X, top[j].Y, top[j].Z);
                        GL.TexCoord2(textureX + 0.5 * textureIncrement, 0.1f);
                        GL.Vertex3(0.0f, top[i].Y, 0.0f);
                        // bottom cap
                        GL.TexCoord2(textureX + 0.5 * textureIncrement, 0.9f);
                        GL.Vertex3(0.0f, bottom[i].Y, 0.0f);
                        GL.TexCoord2(textureX + textureIncrement, 0.995f);
                        GL.Vertex3(bottom[j].X, bottom[j].Y, bottom[j].Z);
                        GL.TexCoord2(textureX, 0.995f);
                        GL.Vertex3(bottom[i].X, bottom[i].Y, bottom[i].Z);
                        GL.End();
                        // finish
                        textureX += textureIncrement;
                    }
                    GL.EndList();
                    GL.CallList(BackgroundDisplayList);
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    if (!BlendEnabled)
                    {
                        GL.Enable(EnableCap.Blend);
                        BlendEnabled = true;
                    }

                    BackgroundDisplayListAvailable = true;
                }
                else
                {
                    GL.CallList(BackgroundDisplayList);
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    if (!BlendEnabled)
                    {
                        GL.Enable(EnableCap.Blend);
                        BlendEnabled = true;
                    }
                }
            }
        }
Example #6
0
        internal static void RenderBackground(BackgroundManager.BackgroundObject Object)
        {
            if (!TexturingEnabled)
            {
                GL.Enable(EnableCap.Texture2D);
                TexturingEnabled = true;
            }
            int Mat = -1;

            for (int i = 0; i < Object.ObjectBackground.Mesh.Faces.Length; i++)
            {
                int m = Object.ObjectBackground.Mesh.Faces[i].Material;
                if (m != Mat)
                {
                    OpenGlTextureWrapMode wrap = OpenGlTextureWrapMode.ClampClamp;
                    for (int v = 0; v < Object.ObjectBackground.Mesh.Vertices.Length; v++)
                    {
                        if (Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.X <0.0f | Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                        {
                            wrap |= OpenGlTextureWrapMode.RepeatClamp;
                        }
                        if (Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.Y <0.0f | Object.ObjectBackground.Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                        {
                            wrap |= OpenGlTextureWrapMode.ClampRepeat;
                        }
                    }

                    if (Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture != null)
                    {
                        Textures.LoadTexture(Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture, wrap);
                        GL.BindTexture(TextureTarget.Texture2D, Object.ObjectBackground.Mesh.Materials[m].DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                    }
                }
                int FaceType = Object.ObjectBackground.Mesh.Faces[i].Flags & MeshFace.FaceTypeMask;
                switch (FaceType)
                {
                case MeshFace.FaceTypeTriangles:
                    GL.Begin(PrimitiveType.Triangles);
                    break;

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

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

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

                default:
                    GL.Begin(PrimitiveType.Polygon);
                    break;
                }

                for (int j = 0; j < Object.ObjectBackground.Mesh.Faces[i].Vertices.Length; j++)
                {
                    GL.Color4(inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.R * 1.0f, inv255 * Object.ObjectBackground.Mesh.Materials[m].Color.G * 1.0f, inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.B * 1.0f, inv255 * (float)Object.ObjectBackground.Mesh.Materials[m].Color.A);
                    VertexTemplate v = Object.ObjectBackground.Mesh.Vertices[Object.ObjectBackground.Mesh.Faces[i].Vertices[j].Index];
                    if (v is ColoredVertex)
                    {
                        ColoredVertex vv = v as ColoredVertex;
                        GL.Color3(vv.Color.R, vv.Color.G, vv.Color.B);
                    }
                    GL.TexCoord2(v.TextureCoordinates.X, v.TextureCoordinates.Y);
                    GL.Vertex3(v.Coordinates.X, v.Coordinates.Y, v.Coordinates.Z);
                }
                GL.End();
            }
        }
        /// <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++)
                {
                    Textures.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++)
                {
                    Textures.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++)
            {
                Textures.Texture     texture;
                Fonts.OpenGlFontChar data;
                i += font.GetCharacterData(text, i, out texture, out data) - 1;
                if (Textures.LoadTexture(texture, Textures.OpenGlTextureWrapMode.ClampClamp))
                {
                    GL.BindTexture(TextureTarget.Texture2D, texture.OpenGlTextures[(int)Textures.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 //
            GL.Disable(EnableCap.Texture2D);
        }
Example #8
0
        /// <summary>Renders the list of game (textual) messages</summary>
        /// <param name="Element">The HUD element these are to be rendered onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderGameMessages(HUD.Element Element, double TimeElapsed)
        {
            //Calculate the size of the viewing plane
            int n = MessageManager.TextualMessages.Count;
            //Minimum initial width is 16px
            double totalwidth = 16.0f;

            for (int j = 0; j < n; j++)
            {
                //Update font size for the renderer
                System.Drawing.Size size = Renderer.MeasureString(Element.Font, (string)MessageManager.TextualMessages[j].MessageToDisplay);
                MessageManager.TextualMessages[j].Width  = size.Width;
                MessageManager.TextualMessages[j].Height = size.Height;
                //Run through the list of current messages
                double a = MessageManager.TextualMessages[j].Width - j * (double)Element.Value1;
                //If our width is wider than the old, use this as the NEW viewing plane width
                if (a > totalwidth)
                {
                    totalwidth = a;
                }
            }
            //Calculate the X-width of the viewing plane
            Game.MessagesRendererSize.X += 16.0 * TimeElapsed * ((double)totalwidth - Game.MessagesRendererSize.X);
            totalwidth = (float)Game.MessagesRendererSize.X;
            double lcrh, lw, rw;

            //Calculate final viewing plane size to pass to openGL
            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);

            // start
            double w = 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++)
            {
                var   mm = MessageManager.TextualMessages[j];
                float br, bg, bb, ba;
                CreateBackColor(Element.BackgroundColor, mm.Color, out br, out bg, out bb, out ba);
                float tr, tg, tb, ta;
                CreateTextColor(Element.TextColor, mm.Color, out tr, out tg, out tb, out ta);
                float or, og, ob, oa;
                CreateBackColor(Element.OverlayColor, mm.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 < mm.Timeout)
                    {
                        if (mm.RendererAlpha == 0.0)
                        {
                            mm.RendererPosition.X = x + Element.TransitionVector.X;
                            mm.RendererPosition.Y = y + Element.TransitionVector.Y;
                            mm.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 - mm.RendererPosition.X) + 0.1) * TimeElapsed;
                    double       dy    = (speed * Math.Abs(ty - mm.RendererPosition.Y) + 0.1) * TimeElapsed;
                    if (Math.Abs(tx - mm.RendererPosition.X) < dx)
                    {
                        mm.RendererPosition.X = tx;
                    }
                    else
                    {
                        mm.RendererPosition.X += Math.Sign(tx - mm.RendererPosition.X) * dx;
                    }
                    if (Math.Abs(ty - mm.RendererPosition.Y) < dy)
                    {
                        mm.RendererPosition.Y = ty;
                    }
                    else
                    {
                        mm.RendererPosition.Y += Math.Sign(ty - mm.RendererPosition.Y) * dy;
                    }
                }
                else
                {
                    tx = x;
                    ty = y + m * Element.Value2;
                    mm.RendererPosition.X = 0.0;
                    const double speed = 12.0;
                    double       dy    = (speed * Math.Abs(ty - mm.RendererPosition.Y) + 0.1) * TimeElapsed;
                    mm.RendererPosition.X = x;
                    if (Math.Abs(ty - mm.RendererPosition.Y) < dy)
                    {
                        mm.RendererPosition.Y = ty;
                    }
                    else
                    {
                        mm.RendererPosition.Y += Math.Sign(ty - mm.RendererPosition.Y) * dy;
                    }
                }
                if ((Element.Transition & HUD.Transition.Fade) != 0)
                {
                    if (Game.SecondsSinceMidnight >= mm.Timeout)
                    {
                        mm.RendererAlpha -= TimeElapsed;
                        if (mm.RendererAlpha < 0.0)
                        {
                            mm.RendererAlpha = 0.0;
                        }
                    }
                    else
                    {
                        mm.RendererAlpha += TimeElapsed;
                        if (mm.RendererAlpha > 1.0)
                        {
                            mm.RendererAlpha = 1.0;
                        }
                        preserve = true;
                    }
                }
                else if (Game.SecondsSinceMidnight > mm.Timeout)
                {
                    if (Math.Abs(mm.RendererPosition.X - tx) < 0.1 & Math.Abs(mm.RendererPosition.Y - ty) < 0.1)
                    {
                        mm.RendererAlpha = 0.0;
                    }
                }
                if (preserve)
                {
                    m++;
                }
                double px    = mm.RendererPosition.X + (double)j * (double)Element.Value1;
                double py    = mm.RendererPosition.Y;
                float  alpha = (float)(mm.RendererAlpha * mm.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, Textures.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, Textures.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, Textures.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 = (string)mm.MessageToDisplay;
                    double u = mm.Width;
                    double v = mm.Height;
                    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, Textures.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, Textures.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, Textures.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);
                    }
                }
            }
        }
Example #9
0
 /// <summary>Calculates the viewing plane size for the given HUD element</summary>
 /// <param name="Element">The element</param>
 /// <param name="LeftWidth">The left width of the viewing plane</param>
 /// <param name="RightWidth">The right width of the viewing plane</param>
 /// <param name="LCrH">The center point of the viewing plane</param>
 private static void CalculateViewingPlaneSize(HUD.Element Element, out double LeftWidth, out double RightWidth, out double LCrH)
 {
     LCrH = 0.0;
     // left width/height
     LeftWidth = 0.0;
     if (Element.TopLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.TopLeft.BackgroundTexture.Width;
             double v = (double)Element.TopLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.CenterLeft.BackgroundTexture.Width;
             double v = (double)Element.CenterLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.BottomLeft.BackgroundTexture.Width;
             double v = (double)Element.BottomLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     // center height
     if (Element.TopMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.TopMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.CenterMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.BottomMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     // right width/height
     RightWidth = 0.0;
     if (Element.TopRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.TopRight.BackgroundTexture.Width;
             double v = (double)Element.TopRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.CenterRight.BackgroundTexture.Width;
             double v = (double)Element.CenterRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.BottomRight.BackgroundTexture.Width;
             double v = (double)Element.BottomRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
 }
Example #10
0
        private static void RenderFace(ref World.MeshMaterial Material, VertexTemplate[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
        {
            // texture
            if (Material.DaytimeTexture != null)
            {
                if (Textures.LoadTexture(Material.DaytimeTexture, wrap))
                {
                    if (!TexturingEnabled)
                    {
                        GL.Enable(EnableCap.Texture2D);
                        TexturingEnabled = true;
                    }
                    if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture)
                    {
                        GL.BindTexture(TextureTarget.Texture2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                        LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
                    }
                }
                else
                {
                    if (TexturingEnabled)
                    {
                        GL.Disable(EnableCap.Texture2D);
                        TexturingEnabled = false;
                        LastBoundTexture = null;
                    }
                }
            }
            else
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                    LastBoundTexture = null;
                }
            }
            // blend mode
            float factor;

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

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

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

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

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

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

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

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

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

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

                if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 *(float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
                }
                else
                {
                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                    if (Vertices[Face.Vertices[j].Index] is ColoredVertex)
                    {
                        ColoredVertex v = (ColoredVertex)Vertices[Face.Vertices[j].Index];
                        GL.Color3(v.Color.R, v.Color.G, v.Color.B);
                    }
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                }
                GL.End();
                RestoreAlphaFunc();
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
            }
            // normals
            if (OptionNormals)
            {
                if (TexturingEnabled)
                {
                    GL.Disable(EnableCap.Texture2D);
                    TexturingEnabled = false;
                }
                for (int j = 0; j < Face.Vertices.Length; j++)
                {
                    GL.Begin(PrimitiveType.Lines);
                    GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
                    GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
                    GL.End();
                }
            }
            // finalize
            if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
            {
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                if (!BlendEnabled)
                {
                    GL.Disable(EnableCap.Blend);
                }
                if (FogEnabled)
                {
                    GL.Enable(EnableCap.Fog);
                }
            }
        }
Example #11
0
        /* --------------------------------------------------------------
         * This file contains the base drawing routines for screen overlays
         * -------------------------------------------------------------- */

        /// <summary>Is called once by the main renderer loop, in order to render all overlays shown on the screen</summary>
        /// <param name="TimeElapsed">The time elapsed since the last call to this function</param>
        private static void RenderOverlays(double TimeElapsed)
        {
            //Initialize openGL
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
            GL.Enable(EnableCap.Blend); BlendEnabled = true;
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix();
            GL.LoadIdentity();
            GL.Ortho(0.0, (double)Screen.Width, (double)Screen.Height, 0.0, -1.0, 1.0);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.PushMatrix();
            GL.LoadIdentity();
            //Check which overlays to show
            switch (CurrentOutputMode)
            {
            case OutputMode.Default:

                //Route info overlay (if selected)
                Game.routeInfoOverlay.Show();
                //HUD
                for (int i = 0; i < Interface.CurrentHudElements.Length; i++)
                {
                    string Command = Interface.CurrentHudElements[i].Subject.ToLowerInvariant();
                    switch (Command)
                    {
                    case "messages":
                    {
                        RenderGameMessages(Interface.CurrentHudElements[i], TimeElapsed);
                    }
                    break;

                    case "scoremessages":
                    {
                        RenderScoreMessages(Interface.CurrentHudElements[i], TimeElapsed);
                    }
                    break;

                    case "ats":
                    {
                        RenderATSLamps(Interface.CurrentHudElements[i], TimeElapsed);
                    }
                    break;

                    default:
                    {
                        RenderHUDElement(Interface.CurrentHudElements[i], TimeElapsed);
                    }
                    break;
                    }
                }
                //Marker textures
                if (Interface.CurrentOptions.GameMode != Interface.GameMode.Expert)
                {
                    double y = 8.0;
                    for (int i = 0; i < Game.MarkerTextures.Length; i++)
                    {
                        if (Textures.LoadTexture(Game.MarkerTextures[i], Textures.OpenGlTextureWrapMode.ClampClamp))
                        {
                            double w = (double)Game.MarkerTextures[i].Width;
                            double h = (double)Game.MarkerTextures[i].Height;
                            GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
                            RenderOverlayTexture(Game.MarkerTextures[i], (double)Screen.Width - w - 8.0, y, (double)Screen.Width - 8.0, y + h);
                            y += h + 8.0;
                        }
                    }
                }
                //Timetable overlay
                //NOTE: Only affects auto-generated timetable, possibly change this inconsistant behaviour
                if (Timetable.CurrentTimetable == Timetable.TimetableState.Default)
                {
                    // default
                    if (Textures.LoadTexture(Timetable.DefaultTimetableTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        int w = Timetable.DefaultTimetableTexture.Width;
                        int h = Timetable.DefaultTimetableTexture.Height;
                        GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
                        RenderOverlayTexture(Timetable.DefaultTimetableTexture, (double)(Screen.Width - w), Timetable.DefaultTimetablePosition, (double)Screen.Width, (double)h + Timetable.DefaultTimetablePosition);
                    }
                }
                else if (Timetable.CurrentTimetable == Timetable.TimetableState.Custom & Timetable.CustomObjectsUsed == 0)
                {
                    // custom
                    if (Textures.LoadTexture(Timetable.CurrentCustomTimetableDaytimeTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        int w = Timetable.CurrentCustomTimetableDaytimeTexture.Width;
                        int h = Timetable.CurrentCustomTimetableDaytimeTexture.Height;
                        GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
                        RenderOverlayTexture(Timetable.CurrentCustomTimetableDaytimeTexture, (double)(Screen.Width - w), Timetable.CustomTimetablePosition, (double)Screen.Width, (double)h + Timetable.CustomTimetablePosition);
                    }

                    if (Textures.LoadTexture(Timetable.CurrentCustomTimetableDaytimeTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        int   w = Timetable.CurrentCustomTimetableDaytimeTexture.Width;
                        int   h = Timetable.CurrentCustomTimetableDaytimeTexture.Height;
                        float alpha;
                        if (Timetable.CurrentCustomTimetableDaytimeTexture != null)
                        {
                            double t = (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].FrontAxle.Follower.TrackPosition - TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousTrackPosition) / (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.NextTrackPosition - TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousTrackPosition);
                            alpha = (float)((1.0 - t) * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.PreviousBrightness + t * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Brightness.NextBrightness);
                        }
                        else
                        {
                            alpha = 1.0f;
                        }

                        GL.Color4(1.0f, 1.0f, 1.0f, alpha);
                        RenderOverlayTexture(Timetable.CurrentCustomTimetableDaytimeTexture, (double)(Screen.Width - w), Timetable.CustomTimetablePosition, (double)Screen.Width, (double)h + Timetable.CustomTimetablePosition);
                    }
                }
                break;

            case OutputMode.Debug:
                RenderDebugOverlays();
                break;

            case OutputMode.DebugATS:
                RenderATSDebugOverlay();
                break;
            }
            // air brake debug output
            if (Interface.CurrentOptions.GameMode != Interface.GameMode.Expert & OptionBrakeSystems)
            {
                RenderBrakeSystemDebug();
            }
            //If paused, fade out the screen & write PAUSE
            if (Game.CurrentInterface == Game.InterfaceType.Pause)
            {
                // pause
                GL.Color4(0.0f, 0.0f, 0.0f, 0.5f);
                RenderOverlaySolid(0.0, 0.0, (double)Screen.Width, (double)Screen.Height);
                GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
                DrawString(Fonts.VeryLargeFont, "PAUSE", new System.Drawing.Point(Screen.Width / 2, Screen.Height / 2), TextAlignment.CenterMiddle, Color128.White, true);
            }
            else if (Game.CurrentInterface == Game.InterfaceType.Menu)
            {
                Game.Menu.Draw();
            }
            //Fade to black on change ends
            if (TrainManager.PlayerTrain.Station >= 0 && Game.Stations[TrainManager.PlayerTrain.Station].Type == StationType.ChangeEnds && TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Boarding)
            {
                double time = TrainManager.PlayerTrain.StationDepartureTime - Game.SecondsSinceMidnight;
                if (time < 1.0)
                {
                    FadeToBlackDueToChangeEnds = Math.Max(0.0, 1.0 - time);
                }
                else if (FadeToBlackDueToChangeEnds > 0.0)
                {
                    FadeToBlackDueToChangeEnds -= TimeElapsed;
                    if (FadeToBlackDueToChangeEnds < 0.0)
                    {
                        FadeToBlackDueToChangeEnds = 0.0;
                    }
                }
            }
            else if (FadeToBlackDueToChangeEnds > 0.0)
            {
                FadeToBlackDueToChangeEnds -= TimeElapsed;
                if (FadeToBlackDueToChangeEnds < 0.0)
                {
                    FadeToBlackDueToChangeEnds = 0.0;
                }
            }
            if (FadeToBlackDueToChangeEnds > 0.0 & (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead))
            {
                GL.Color4(0.0, 0.0, 0.0, FadeToBlackDueToChangeEnds);
                RenderOverlaySolid(0.0, 0.0, (double)Screen.Width, (double)Screen.Height);
            }
            // finalize
            GL.PopMatrix();
            GL.MatrixMode(MatrixMode.Projection);
            GL.PopMatrix();
            GL.MatrixMode(MatrixMode.Modelview);
            GL.Disable(EnableCap.Blend);
        }
Example #12
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();
     }
 }
Example #13
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, 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 = Translations.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 = Translations.QuickReferences.HandleForward;
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[1];
                    }
                    else
                    {
                        t = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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 = Translations.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" ? Translations.QuickReferences.DoorsLeft : Translations.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.Stations[s].GetStopIndex(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 "dist_next_station":
                int i;
                if (TrainManager.PlayerTrain.Station >= 0 && TrainManager.PlayerTrain.StationState != TrainManager.TrainStopState.Completed)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                else
                {
                    i = TrainManager.PlayerTrain.LastStation + 1;
                }
                if (i > Game.Stations.Length - 1)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                int    n  = Game.Stations[i].GetStopIndex(TrainManager.PlayerTrain.Cars.Length);
                double p0 = TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition - TrainManager.PlayerTrain.Cars[0].FrontAxle.Position + 0.5 * TrainManager.PlayerTrain.Cars[0].Length;
                double p1;
                if (Game.Stations[i].Stops.Length > 0)
                {
                    p1 = Game.Stations[i].Stops[n].TrackPosition;
                }
                else
                {
                    p1 = Game.Stations[i].DefaultTrackPosition;
                }
                double m = p1 - p0;
                if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Km)
                {
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                        if (Math.Abs(m) <= 10.0)
                        {
                            t += m.ToString("0.00", Culture) + " m";
                        }
                        else
                        {
                            m /= 1000.0;
                            t += m.ToString("0.000", Culture) + " km";
                        }
                    }
                    else
                    {
                        m /= 1000.0;
                        t  = "Pass: "******"0.000", Culture) + " km";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Mile)
                {
                    m /= 1609.34;
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    m /= 1609.34;
                    if (Game.PlayerStopsAtStation(i))
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    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, 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, 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);
                    }
                }
            }
        }
Example #14
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;
                    OpenGlTextureWrapMode wrap = 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)
                        {
                            // If the object does not have a stored wrapping mode, determine it now
                            for (int v = 0; v < ObjectManager.Objects[ObjectIndex].Mesh.Vertices.Length; v++)
                            {
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.X> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.RepeatClamp;
                                }
                                if (ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y <0.0f |
                                                                                                              ObjectManager.Objects[ObjectIndex].Mesh.Vertices[v].TextureCoordinates.Y> 1.0f)
                                {
                                    wrap |= OpenGlTextureWrapMode.ClampRepeat;
                                }
                            }
                        }
                        else
                        {
                            //Yuck cast, but we need the null, as otherwise requires rewriting the texture indexer
                            wrap = (OpenGlTextureWrapMode)ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].WrapMode;
                        }
                        if (ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture != null)
                        {
                            if (Textures.LoadTexture(ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture, wrap))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].DaytimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == 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))
                            {
                                TextureTransparencyType type =
                                    ObjectManager.Objects[ObjectIndex].Mesh.Materials[k].NighttimeTexture.Transparency;
                                if (type == TextureTransparencyType.Alpha)
                                {
                                    alpha = true;
                                }
                                else if (type == TextureTransparencyType.Partial &
                                         Interface.CurrentOptions.TransparencyMode == TransparencyMode.Quality)
                                {
                                    alpha = true;
                                }
                            }
                        }
                    }
                    if (Type == ObjectType.Overlay & World.CameraRestriction != Camera.RestrictionMode.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 == 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++;
            }
        }
Example #15
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="orientation">The orientation.</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)
            {
                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++)
                {
                    Textures.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++)
                {
                    Textures.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.glEnable(Gl.GL_TEXTURE_2D);
            for (int i = 0; i < text.Length; i++)
            {
                Textures.Texture     texture;
                Fonts.OpenGlFontChar data;
                i += font.GetCharacterData(text, i, out texture, out data) - 1;
                if (Textures.LoadTexture(texture, Textures.OpenGlTextureWrapMode.ClampClamp))
                {
                    Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.OpenGlTextures[(int)Textures.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.glBlendFunc(Gl.GL_ZERO, Gl.GL_ONE_MINUS_SRC_COLOR);
                    Gl.glBegin(Gl.GL_POLYGON);
                    Gl.glColor4f(color.A, color.A, color.A, 1.0f);
                    Gl.glTexCoord2f(data.TextureCoordinates.Left, data.TextureCoordinates.Top);
                    Gl.glVertex2f(x, y);
                    Gl.glColor4f(color.A, color.A, color.A, 1.0f);
                    Gl.glTexCoord2f(data.TextureCoordinates.Right, data.TextureCoordinates.Top);
                    Gl.glVertex2f(x + data.PhysicalSize.Width, y);
                    Gl.glColor4f(color.A, color.A, color.A, 1.0f);
                    Gl.glTexCoord2f(data.TextureCoordinates.Right, data.TextureCoordinates.Bottom);
                    Gl.glVertex2f(x + data.PhysicalSize.Width, y + data.PhysicalSize.Height);
                    Gl.glColor4f(color.A, color.A, color.A, 1.0f);
                    Gl.glTexCoord2f(data.TextureCoordinates.Left, data.TextureCoordinates.Bottom);
                    Gl.glVertex2f(x, y + data.PhysicalSize.Height);
                    Gl.glEnd();

                    /*
                     * In the second pass, add the character onto the background.
                     * */
                    Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE);
                    Gl.glBegin(Gl.GL_POLYGON);
                    Gl.glColor4f(color.R, color.G, color.B, color.A);
                    Gl.glTexCoord2f(data.TextureCoordinates.Left, data.TextureCoordinates.Top);
                    Gl.glVertex2f(x, y);
                    Gl.glColor4f(color.R, color.G, color.B, color.A);
                    Gl.glTexCoord2f(data.TextureCoordinates.Right, data.TextureCoordinates.Top);
                    Gl.glVertex2f(x + data.PhysicalSize.Width, y);
                    Gl.glColor4f(color.R, color.G, color.B, color.A);
                    Gl.glTexCoord2f(data.TextureCoordinates.Right, data.TextureCoordinates.Bottom);
                    Gl.glVertex2f(x + data.PhysicalSize.Width, y + data.PhysicalSize.Height);
                    Gl.glColor4f(color.R, color.G, color.B, color.A);
                    Gl.glTexCoord2f(data.TextureCoordinates.Left, data.TextureCoordinates.Bottom);
                    Gl.glVertex2f(x, y + data.PhysicalSize.Height);
                    Gl.glEnd();
                }
                left += data.TypographicSize.Width;
            }
            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);             // HACK //
        }
Example #16
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;
            }
        }
Example #17
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();
        }
        /// <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);
                    }
                }
            }
        }