/// <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> private void RenderStaticBackgroundRetained(StaticBackground data, float alpha, float scale) { Texture t = data.Texture; if (data.Texture != null && renderer.currentHost.LoadTexture(ref t, OpenGlTextureWrapMode.RepeatClamp)) { renderer.LastBoundTexture = t.OpenGlTextures[(int)OpenGlTextureWrapMode.RepeatClamp]; if (alpha == 1.0f) { GL.Disable(EnableCap.Blend); } else { GL.Enable(EnableCap.Blend); } if (data.VAO == null) { data.CreateVAO(renderer.DefaultShader.VertexLayout, renderer); } renderer.DefaultShader.Activate(); renderer.ResetShader(renderer.DefaultShader); // matrix renderer.DefaultShader.SetCurrentProjectionMatrix(renderer.CurrentProjectionMatrix); renderer.DefaultShader.SetCurrentModelViewMatrix(Matrix4D.Scale(scale) * renderer.CurrentViewMatrix); // fog if (renderer.OptionFog) { renderer.DefaultShader.SetIsFog(true); renderer.DefaultShader.SetFog(renderer.Fog); } // texture GL.BindTexture(TextureTarget.Texture2D, t.OpenGlTextures[(int)OpenGlTextureWrapMode.RepeatClamp].Name); renderer.LastBoundTexture = null; // alpha test renderer.SetAlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode renderer.DefaultShader.SetOpacity(alpha); // render polygon VertexArrayObject VAO = (VertexArrayObject)data.VAO; VAO.Bind(); renderer.lastVAO = VAO.handle; for (int i = 0; i + 11 < 32 * 12; i += 12) { VAO.Draw(PrimitiveType.Triangles, i, 12); } renderer.RestoreBlendFunc(); } }
/// <summary>Draws a simple 2D rectangle using two-pass alpha blending.</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> /// <param name="textureCoordinates">The texture coordinates to be applied</param> public void DrawAlpha(Texture texture, Vector2 point, Vector2 size, Color128?color = null, Vector2?textureCoordinates = null) { renderer.UnsetBlendFunc(); renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(true); Draw(texture, point, size, color, textureCoordinates); renderer.SetBlendFunc(); renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(false); Draw(texture, point, size, color, textureCoordinates); renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); }
/// <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> private void RenderStaticBackground(StaticBackground data, float alpha, float scale) { if (data.Texture != null && renderer.currentHost.LoadTexture(data.Texture, OpenGlTextureWrapMode.RepeatClamp)) { GL.Enable(EnableCap.Texture2D); if (alpha == 1.0f) { GL.Disable(EnableCap.Blend); } else { GL.Enable(EnableCap.Blend); } if (data.VAO == null) { data.CreateVAO(); } renderer.DefaultShader.Activate(); renderer.ResetShader(renderer.DefaultShader); // matrix renderer.DefaultShader.SetCurrentProjectionMatrix(renderer.CurrentProjectionMatrix); renderer.DefaultShader.SetCurrentModelViewMatrix(Matrix4D.Scale(scale) * renderer.CurrentViewMatrix); // fog if (renderer.OptionFog) { renderer.DefaultShader.SetIsFog(true); renderer.DefaultShader.SetFogStart(renderer.Fog.Start); renderer.DefaultShader.SetFogEnd(renderer.Fog.End); renderer.DefaultShader.SetFogColor(new Color4(renderer.Fog.Color.R, renderer.Fog.Color.G, renderer.Fog.Color.B, 255)); } // texture renderer.DefaultShader.SetIsTexture(true); renderer.DefaultShader.SetTexture(0); GL.BindTexture(TextureTarget.Texture2D, data.Texture.OpenGlTextures[(int)OpenGlTextureWrapMode.RepeatClamp].Name); // alpha test renderer.SetAlphaFunc(AlphaFunction.Greater, 0.0f); // blend mode renderer.DefaultShader.SetOpacity(alpha); // render polygon VertexArrayObject VAO = (VertexArrayObject)data.VAO; VAO.Bind(); for (int i = 0; i + 9 < 32 * 10; i += 10) { VAO.Draw(renderer.DefaultShader.VertexLayout, PrimitiveType.Quads, i, 4); VAO.Draw(renderer.DefaultShader.VertexLayout, PrimitiveType.Triangles, i + 4, 3); VAO.Draw(renderer.DefaultShader.VertexLayout, PrimitiveType.Triangles, i + 7, 3); } VAO.UnBind(); GL.BindTexture(TextureTarget.Texture2D, 0); renderer.DefaultShader.Deactivate(); GL.Disable(EnableCap.Texture2D); renderer.RestoreBlendFunc(); } }
/// <summary>Draws on OpenGL canvas the route/train loading screen</summary> public void DrawLoadingScreen(OpenGlFont Font, double RouteProgress, double TrainProgress) { renderer.SetBlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); //FIXME: Remove when text switches between two renderer types GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); renderer.Rectangle.Draw(null, Vector2.Null, new Vector2(renderer.Screen.Width, renderer.Screen.Height), bkg); // BACKGROUND IMAGE int fontHeight = (int)Font.FontSize; int logoBottom; //int versionTop; int halfWidth = renderer.Screen.Width / 2; if (TextureLoadingBkg != null && renderer.currentHost.LoadTexture(TextureLoadingBkg, OpenGlTextureWrapMode.ClampClamp)) { int bkgHeight, bkgWidth; // stretch the background image to fit at least one screen dimension double ratio = TextureLoadingBkg.Width / (double)TextureLoadingBkg.Height; if (renderer.Screen.Width / ratio > renderer.Screen.Height) // if screen ratio is shorter than bkg... { bkgHeight = renderer.Screen.Height; // set height to screen height bkgWidth = (int)(renderer.Screen.Height * ratio); // and scale width proprtionally } else // if screen ratio is wider than bkg... { bkgWidth = renderer.Screen.Width; // set width to screen width bkgHeight = (int)(renderer.Screen.Width / ratio); // and scale height accordingly } // draw the background image down from the top screen edge renderer.Rectangle.Draw(TextureLoadingBkg, new Vector2((renderer.Screen.Width - bkgWidth) / 2.0, 0), new Vector2(bkgWidth, bkgHeight), Color128.White); } // if the route has no custom loading image, add the openBVE logo // (the route custom image is loaded in OldParsers/CsvRwRouteParser.cs) if (!customLoadScreen) { if (TextureLogo != null && renderer.currentHost.LoadTexture(TextureLogo, OpenGlTextureWrapMode.ClampClamp)) { // place the centre of the logo at from the screen top int logoTop = (int)(renderer.Screen.Height * logoCentreYFactor - TextureLogo.Height / 2.0); renderer.UnsetBlendFunc(); renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); GL.DepthMask(true); renderer.Rectangle.Draw(TextureLogo, new Vector2((renderer.Screen.Width - TextureLogo.Width) / 2.0, logoTop), new Vector2(TextureLogo.Width, TextureLogo.Height), Color128.White); renderer.SetBlendFunc(); renderer.SetAlphaFunc(AlphaFunction.Less, 1.0f); GL.DepthMask(false); renderer.Rectangle.Draw(TextureLogo, new Vector2((renderer.Screen.Width - TextureLogo.Width) / 2.0, logoTop), new Vector2(TextureLogo.Width, TextureLogo.Height), Color128.White); renderer.SetAlphaFunc(AlphaFunction.Equal, 1.0f); } } // ReSharper disable once RedundantIfElseBlock else { // if custom route image, no logo and leave a conventional black area below the potential logo } logoBottom = renderer.Screen.Height / 2; // take the height remaining below the logo and divide in 3 horiz. parts int blankHeight = (renderer.Screen.Height - logoBottom) / 3; // VERSION NUMBER // place the version above the first division int versionTop = logoBottom + blankHeight - fontHeight; renderer.OpenGlString.Draw(Font, "Version " + ProgramVersion, 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://openbve-project.net", // new Point(halfWidth, versionTop + fontHeight+2), // TextAlignment.TopMiddle, Color128.White); // PROGRESS MESSAGE AND BAR // place progress bar right below the second division int progressTop = renderer.Screen.Height - blankHeight; int progressWidth = renderer.Screen.Width - progrMargin * 2; double routeProgress = Math.Max(0.0, Math.Min(1.0, RouteProgress)); double trainProgress = Math.Max(0.0, Math.Min(1.0, TrainProgress)); // draw progress message right above the second division string text = Translations.GetInterfaceString(routeProgress < 1.0 ? "loading_loading_route" : trainProgress < 1.0 ? "loading_loading_train" : "message_loading"); renderer.OpenGlString.Draw(Font, text, new Point(halfWidth, progressTop - fontHeight - 6), TextAlignment.TopMiddle, Color128.White); // sum of route progress and train progress arrives up to 2.0: // => times 50.0 to convert to % double percent = 50.0 * (routeProgress + trainProgress); string percStr = percent.ToString("0") + "%"; // progress frame renderer.Rectangle.Draw(null, new Vector2(progrMargin - progrBorder, progressTop - progrBorder), new Vector2(progressWidth + progrBorder * 2, fontHeight + 6), Color128.White); // progress bar renderer.Rectangle.Draw(null, new Vector2(progrMargin, progressTop), new Vector2(progressWidth * (int)percent / 100.0, fontHeight + 4), ColourProgressBar); // progress percent renderer.OpenGlString.Draw(Font, percStr, new Point(halfWidth, progressTop), TextAlignment.TopMiddle, Color128.Black); }