This class implements a high-precision, multi-platform timer
Beispiel #1
0
 public override bool LoadTexture(ref Texture Texture, OpenGlTextureWrapMode wrapMode)
 {
     return(Program.Renderer.TextureManager.LoadTexture(ref Texture, wrapMode, CPreciseTimer.GetClockTicks(), Interface.CurrentOptions.Interpolation, Interface.CurrentOptions.AnisotropicFilteringLevel));
 }
Beispiel #2
0
 /// <summary>Loads all registered textures.</summary>
 internal static void LoadAllTextures()
 {
     for (int i = 0; i < LibRender.TextureManager.RegisteredTexturesCount; i++)
     {
         LibRender.TextureManager.LoadTexture(LibRender.TextureManager.RegisteredTextures[i], OpenGlTextureWrapMode.ClampClamp, CPreciseTimer.GetClockTicks(), Interface.CurrentOptions.Interpolation, Interface.CurrentOptions.AnisotropicFilteringLevel);
     }
 }
Beispiel #3
0
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            Program.MouseMovement();
            double   timeElapsed = CPreciseTimer.GetElapsedTime();
            DateTime time        = DateTime.Now;

            Game.SecondsSinceMidnight = (double)(3600 * time.Hour + 60 * time.Minute + time.Second) + 0.001 * (double)time.Millisecond;
            lock (Program.LockObj)
            {
                ObjectManager.UpdateAnimatedWorldObjects(timeElapsed, false);
            }
            if (Program.ReducedMode)
            {
                System.Threading.Thread.Sleep(125);
            }
            else
            {
                System.Threading.Thread.Sleep(1);
            }
            bool updatelight = false;
            bool keep        = false;

            // rotate x
            if (Program.RotateX == 0)
            {
                double d = (1.0 + Math.Abs(RotateXSpeed)) * timeElapsed;
                if (RotateXSpeed >= -d & RotateXSpeed <= d)
                {
                    RotateXSpeed = 0.0;
                }
                else
                {
                    RotateXSpeed -= (double)Math.Sign(RotateXSpeed) * d;
                }
            }
            else
            {
                double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateXSpeed * RotateXSpeed)) * timeElapsed;
                double m = 1.0;
                RotateXSpeed += (double)Program.RotateX * d;
                if (RotateXSpeed < -m)
                {
                    RotateXSpeed = -m;
                }
                else if (RotateXSpeed > m)
                {
                    RotateXSpeed = m;
                }
            }
            if (RotateXSpeed != 0.0)
            {
                double cosa = Math.Cos(RotateXSpeed * timeElapsed);
                double sina = Math.Sin(RotateXSpeed * timeElapsed);
                Program.Renderer.Camera.AbsoluteDirection.Rotate(Vector3.Down, cosa, sina);
                Program.Renderer.Camera.AbsoluteUp.Rotate(Vector3.Down, cosa, sina);
                Program.Renderer.Camera.AbsoluteSide.Rotate(Vector3.Down, cosa, sina);
                keep = true;
            }
            // rotate y
            if (Program.RotateY == 0)
            {
                double d = (1.0 + Math.Abs(RotateYSpeed)) * timeElapsed;
                if (RotateYSpeed >= -d & RotateYSpeed <= d)
                {
                    RotateYSpeed = 0.0;
                }
                else
                {
                    RotateYSpeed -= (double)Math.Sign(RotateYSpeed) * d;
                }
            }
            else
            {
                double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateYSpeed * RotateYSpeed)) * timeElapsed;
                double m = 1.0;
                RotateYSpeed += (double)Program.RotateY * d;
                if (RotateYSpeed < -m)
                {
                    RotateYSpeed = -m;
                }
                else if (RotateYSpeed > m)
                {
                    RotateYSpeed = m;
                }
            }
            if (RotateYSpeed != 0.0)
            {
                double cosa = Math.Cos(RotateYSpeed * timeElapsed);
                double sina = Math.Sin(RotateYSpeed * timeElapsed);
                Program.Renderer.Camera.AbsoluteDirection.Rotate(Program.Renderer.Camera.AbsoluteSide, cosa, sina);
                Program.Renderer.Camera.AbsoluteUp.Rotate(Program.Renderer.Camera.AbsoluteSide, cosa, sina);
                keep = true;
            }
            // move x
            if (Program.MoveX == 0)
            {
                double d = (2.5 + Math.Abs(MoveXSpeed)) * timeElapsed;
                if (MoveXSpeed >= -d & MoveXSpeed <= d)
                {
                    MoveXSpeed = 0.0;
                }
                else
                {
                    MoveXSpeed -= (double)Math.Sign(MoveXSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveXSpeed * MoveXSpeed)) * timeElapsed;
                double m = 25.0;
                MoveXSpeed += (double)Program.MoveX * d;
                if (MoveXSpeed < -m)
                {
                    MoveXSpeed = -m;
                }
                else if (MoveXSpeed > m)
                {
                    MoveXSpeed = m;
                }
            }
            if (MoveXSpeed != 0.0)
            {
                Program.Renderer.Camera.AbsolutePosition += MoveXSpeed * timeElapsed * Program.Renderer.Camera.AbsoluteSide;
                keep = true;
            }
            // move y
            if (Program.MoveY == 0)
            {
                double d = (2.5 + Math.Abs(MoveYSpeed)) * timeElapsed;
                if (MoveYSpeed >= -d & MoveYSpeed <= d)
                {
                    MoveYSpeed = 0.0;
                }
                else
                {
                    MoveYSpeed -= (double)Math.Sign(MoveYSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveYSpeed * MoveYSpeed)) * timeElapsed;
                double m = 25.0;
                MoveYSpeed += (double)Program.MoveY * d;
                if (MoveYSpeed < -m)
                {
                    MoveYSpeed = -m;
                }
                else if (MoveYSpeed > m)
                {
                    MoveYSpeed = m;
                }
            }
            if (MoveYSpeed != 0.0)
            {
                Program.Renderer.Camera.AbsolutePosition += MoveYSpeed * timeElapsed * Program.Renderer.Camera.AbsoluteUp;
                keep = true;
            }
            // move z
            if (Program.MoveZ == 0)
            {
                double d = (2.5 + Math.Abs(MoveZSpeed)) * timeElapsed;
                if (MoveZSpeed >= -d & MoveZSpeed <= d)
                {
                    MoveZSpeed = 0.0;
                }
                else
                {
                    MoveZSpeed -= (double)Math.Sign(MoveZSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveZSpeed * MoveZSpeed)) * timeElapsed;
                double m = 25.0;
                MoveZSpeed += (double)Program.MoveZ * d;
                if (MoveZSpeed < -m)
                {
                    MoveZSpeed = -m;
                }
                else if (MoveZSpeed > m)
                {
                    MoveZSpeed = m;
                }
            }
            if (MoveZSpeed != 0.0)
            {
                Program.Renderer.Camera.AbsolutePosition += MoveZSpeed * timeElapsed * Program.Renderer.Camera.AbsoluteDirection;

                keep = true;
            }
            // lighting
            if (Program.LightingRelative == -1)
            {
                Program.LightingRelative = (double)Program.LightingTarget;
                updatelight = true;
            }
            if (Program.LightingTarget == 0)
            {
                if (Program.LightingRelative != 0.0)
                {
                    Program.LightingRelative -= 0.5 * timeElapsed;
                    if (Program.LightingRelative < 0.0)
                    {
                        Program.LightingRelative = 0.0;
                    }
                    updatelight = true;
                    keep        = true;
                }
            }
            else
            {
                if (Program.LightingRelative != 1.0)
                {
                    Program.LightingRelative += 0.5 * timeElapsed;
                    if (Program.LightingRelative > 1.0)
                    {
                        Program.LightingRelative = 1.0;
                    }
                    updatelight = true;
                    keep        = true;
                }
            }
            // continue
            if (Program.ReducedMode)
            {
                ReducedModeEnteringTime = 3.0;
            }
            else
            {
                if (keep)
                {
                    ReducedModeEnteringTime = 3.0;
                }
                else if (ReducedModeEnteringTime <= 0)
                {
                    Program.ReducedMode = true;
                    Program.Renderer.Camera.AbsoluteSide.Y = 0.0;
                    Program.Renderer.Camera.AbsoluteSide.Normalize();
                    Program.Renderer.Camera.AbsoluteDirection.Normalize();
                    Program.Renderer.Camera.AbsoluteUp = Vector3.Cross(Program.Renderer.Camera.AbsoluteDirection, Program.Renderer.Camera.AbsoluteSide);
                }
                else
                {
                    ReducedModeEnteringTime -= timeElapsed;
                }
            }
            if (updatelight)
            {
                Program.Renderer.Lighting.OptionAmbientColor.R = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative * (2.0 - Program.LightingRelative));
                Program.Renderer.Lighting.OptionAmbientColor.G = (byte)Math.Round(32.0 + 128.0 * 0.5 * (Program.LightingRelative + Program.LightingRelative * (2.0 - Program.LightingRelative)));
                Program.Renderer.Lighting.OptionAmbientColor.B = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Program.Renderer.Lighting.OptionDiffuseColor.R = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Program.Renderer.Lighting.OptionDiffuseColor.G = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Program.Renderer.Lighting.OptionDiffuseColor.B = (byte)Math.Round(32.0 + 128.0 * Math.Sqrt(Program.LightingRelative));
                Program.Renderer.Lighting.Initialize();
            }
            Program.Renderer.RenderScene();
            SwapBuffers();
        }
Beispiel #4
0
        // --- load texture ---

        /// <summary>Loads the specified texture into OpenGL if not already loaded.</summary>
        /// <param name="handle">The handle to the registered texture.</param>
        /// <param name="wrap">The texture type indicating the clamp mode.</param>
        /// <returns>Whether loading the texture was successful.</returns>
        internal static bool LoadTexture(Texture handle, OpenGlTextureWrapMode wrap)
        {
            //Don't try to load a texture to a null handle, this is a seriously bad idea....
            if (handle == null)
            {
                return(false);
            }
            //Set last access time
            handle.LastAccess = CPreciseTimer.GetClockTicks();
            if (handle.OpenGlTextures[(int)wrap].Valid)
            {
                return(true);
            }
            if (handle.Ignore)
            {
                return(false);
            }
            Texture texture;

            if (handle.Origin.GetTexture(out texture))
            {
                if (texture.BitsPerPixel == 32)
                {
                    int[] names = new int[1];
                    GL.GenTextures(1, names);
                    GL.BindTexture(TextureTarget.Texture2D, names[0]);
                    handle.OpenGlTextures[(int)wrap].Name = names[0];
                    handle.Width        = texture.Width;
                    handle.Height       = texture.Height;
                    handle.Transparency = texture.GetTransparencyType();
                    //texture = ResizeToPowerOfTwo(texture);

                    switch (Interface.CurrentOptions.Interpolation)
                    {
                    case InterpolationMode.NearestNeighbor:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
                        break;

                    case InterpolationMode.Bilinear:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    case InterpolationMode.NearestNeighborMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapNearest);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
                        break;

                    case InterpolationMode.BilinearMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.NearestMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    case InterpolationMode.TrilinearMipmapped:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;

                    default:
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
                        break;
                    }
                    if ((wrap & OpenGlTextureWrapMode.RepeatClamp) != 0)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.Repeat);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
                    }
                    if ((wrap & OpenGlTextureWrapMode.ClampRepeat) != 0)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.Repeat);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);
                    }
                    if (Interface.CurrentOptions.Interpolation == InterpolationMode.NearestNeighbor || Interface.CurrentOptions.Interpolation == InterpolationMode.Bilinear)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 0);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1);
                    }
                    if (Interface.CurrentOptions.Interpolation == InterpolationMode.AnisotropicFiltering)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, Interface.CurrentOptions.AnisotropicFilteringLevel);
                    }
                    if (handle.Transparency == TextureTransparencyType.Opaque)
                    {
                        /*
                         * If the texture is fully opaque, the alpha channel is not used.
                         * If the graphics driver and card support 24-bits per channel,
                         * it is best to convert the bitmap data to that format in order
                         * to save memory on the card. If the card does not support the
                         * format, it will likely be upconverted to 32-bits per channel
                         * again, and this is wasted effort.
                         * */
                        int    width = texture.Width;
                        int    height = texture.Height;
                        int    stride = (3 * (width + 1) >> 2) << 2;
                        byte[] oldBytes = texture.Bytes;
                        byte[] newBytes = new byte[stride * texture.Height];
                        int    i = 0, j = 0;
                        for (int y = 0; y < height; y++)
                        {
                            for (int x = 0; x < width; x++)
                            {
                                newBytes[j + 0] = oldBytes[i + 0];
                                newBytes[j + 1] = oldBytes[i + 1];
                                newBytes[j + 2] = oldBytes[i + 2];
                                i += 4;
                                j += 3;
                            }
                            j += stride - 3 * width;
                        }
                        GL.TexImage2D(TextureTarget.Texture2D, 0,
                                      PixelInternalFormat.Rgb8,
                                      texture.Width, texture.Height, 0,
                                      OpenTK.Graphics.OpenGL.PixelFormat.Rgb,
                                      PixelType.UnsignedByte, newBytes);
                    }
                    else
                    {
                        /*
                         * The texture uses its alpha channel, so send the bitmap data
                         * in 32-bits per channel as-is.
                         * */
                        GL.TexImage2D(TextureTarget.Texture2D, 0,
                                      PixelInternalFormat.Rgba8,
                                      texture.Width, texture.Height, 0,
                                      OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
                                      PixelType.UnsignedByte, texture.Bytes);
                    }
                    handle.OpenGlTextures[(int)wrap].Valid = true;
                    return(true);
                }
            }
            handle.Ignore = true;
            return(false);
        }
Beispiel #5
0
        protected override void OnUpdateFrame(FrameEventArgs e)
        {
            TimeFactor = MainLoop.TimeFactor;
            // timer
            double RealTimeElapsed;
            double TimeElapsed;

            if (Game.SecondsSinceMidnight >= Game.StartupTime)
            {
                RealTimeElapsed = CPreciseTimer.GetElapsedTime();
                TimeElapsed     = RealTimeElapsed * (double)TimeFactor;
                if (loadComplete && !firstFrame)
                {
                    //Our current in-game time is equal to or greater than the startup time, but the first frame has not yet been processed
                    //Therefore, reset the timer to zero as time consuming texture loads may cause us to be late at the first station
                    RealTimeElapsed = 0.0;
                    TimeElapsed     = 0.0;
                    firstFrame      = true;
                }
            }
            else
            {
                RealTimeElapsed = 0.0;
                TimeElapsed     = Game.StartupTime - Game.SecondsSinceMidnight;
            }

            //We only want to update the simulation if we aren't in a menu
            if (Game.CurrentInterface == Game.InterfaceType.Normal)
            {
#if DEBUG
                //If we're in debug mode and a frame takes greater than a second to render, we can safely assume that VS has hit a breakpoint
                //Check this and the sim no longer barfs because the update time was too great
                if (RealTimeElapsed > 1)
                {
                    RealTimeElapsed = 0.0;
                    TimeElapsed     = 0.0;
                }
#endif
                TotalTimeElapsedForInfo          += RealTimeElapsed;
                TotalTimeElapsedForSectionUpdate += TimeElapsed;


                if (TotalTimeElapsedForSectionUpdate >= 1.0)
                {
                    if (Game.Sections.Length != 0)
                    {
                        Game.UpdateSection(Game.Sections.Length - 1);
                    }
                    TotalTimeElapsedForSectionUpdate = 0.0;
                }

                // events

                // update simulation in chunks
                {
                    const double chunkTime = 1.0 / 2.0;
                    if (TimeElapsed <= chunkTime)
                    {
                        Game.SecondsSinceMidnight += TimeElapsed;
                        TrainManager.UpdateTrains(TimeElapsed);
                    }
                    else
                    {
                        const int maxChunks = 2;
                        int       chunks    = Math.Min((int)Math.Round(TimeElapsed / chunkTime), maxChunks);
                        double    time      = TimeElapsed / (double)chunks;
                        for (int i = 0; i < chunks; i++)
                        {
                            Game.SecondsSinceMidnight += time;
                            TrainManager.UpdateTrains(time);
                        }
                    }
                }
                Game.CurrentScore.Update(TimeElapsed);
                Game.UpdateMessages();
                Game.UpdateScoreMessages(TimeElapsed);

                for (int i = 0; i < InputDevicePlugin.AvailablePluginInfos.Count; i++)
                {
                    if (InputDevicePlugin.AvailablePluginInfos[i].Status == InputDevicePlugin.PluginInfo.PluginStatus.Enable)
                    {
                        InputDevicePlugin.AvailablePlugins[i].OnUpdateFrame();
                    }
                }
            }
            RenderTimeElapsed     += TimeElapsed;
            RenderRealTimeElapsed += RealTimeElapsed;
        }
Beispiel #6
0
        public static void LoadingScreenLoop()
        {
            currentlyLoading = true;

            Program.Renderer.PushMatrix(MatrixMode.Projection);
            Matrix4D.CreateOrthographicOffCenter(0.0f, Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 0.0f, -1.0f, 1.0f, out Program.Renderer.CurrentProjectionMatrix);
            Program.Renderer.PushMatrix(MatrixMode.Modelview);
            Program.Renderer.CurrentViewMatrix = Matrix4D.Identity;

            while (!Loading.Complete && !Loading.Cancel)
            {
                CPreciseTimer.GetElapsedTime();
                Program.currentGameWindow.ProcessEvents();
                if (Program.currentGameWindow.IsExiting)
                {
                    Loading.Cancel = true;
                }
                double routeProgress = 1.0;
                for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++)
                {
                    if (Program.CurrentHost.Plugins[i].Route != null && Program.CurrentHost.Plugins[i].Route.IsLoading)
                    {
                        routeProgress = Program.CurrentHost.Plugins[i].Route.CurrentProgress;
                    }
                }
                Program.Renderer.Loading.DrawLoadingScreen(Program.Renderer.Fonts.SmallFont, routeProgress);
                Program.currentGameWindow.SwapBuffers();

                if (Loading.JobAvailable)
                {
                    while (jobs.Count > 0)
                    {
                        lock (jobLock)
                        {
                            var currentJob = jobs.Dequeue();
                            var locker     = locks.Dequeue();
                            currentJob();
                            lock (locker)
                            {
                                Monitor.Pulse(locker);
                            }
                        }
                    }
                    Loading.JobAvailable = false;
                }
                double time = CPreciseTimer.GetElapsedTime();
                double wait = 1000.0 / 60.0 - time * 1000 - 50;
                if (wait > 0)
                {
                    Thread.Sleep((int)(wait));
                }
            }
            if (!Loading.Cancel)
            {
                Program.Renderer.PopMatrix(MatrixMode.Modelview);
                Program.Renderer.PopMatrix(MatrixMode.Projection);
            }
            else
            {
                Game.Reset();
                currentlyLoading         = false;
                Program.CurrentRouteFile = null;
            }
        }