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)); }
/// <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); } }
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(); }
// --- 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); }
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; }
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; } }