Add dynamic render quality settings and scaling

Introduce a RenderQuality enum (Low/Medium/High) and allow users to switch quality at runtime via keyboard shortcuts. The fractal renderer now adapts its internal resolution, particle counts, and computational workload based on selected quality and real-time performance, aiming to maintain a target FPS. HUD and window title display current quality and FPS. Renderer buffers and limits are dynamically resized on window or quality changes for improved performance and flexibility.
This commit is contained in:
Michal Vrba
2026-02-13 20:28:57 +01:00
parent 6fd9e52bf0
commit 2926f739ee
3 changed files with 165 additions and 17 deletions
+31 -2
View File
@@ -30,6 +30,8 @@ public class Game1 : Game
private int _fps;
private int _frameCounter;
private TimeSpan _fpsElapsed;
private const int TargetFps = 120;
private RenderQuality _renderQuality = RenderQuality.Medium;
private readonly (int Width, int Height)[] _windowedResolutions =
[
(1280, 720),
@@ -41,11 +43,14 @@ public class Game1 : Game
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
_graphics.SynchronizeWithVerticalRetrace = false;
_graphics.PreferredBackBufferWidth = 1280;
_graphics.PreferredBackBufferHeight = 720;
Content.RootDirectory = "Content";
IsMouseVisible = true;
Window.AllowUserResizing = true;
IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromSeconds(1.0 / 120.0);
_audioCapture = new AudioCapture();
_audioAnalyzer = new AudioAnalyzer(_audioCapture, fftSize: 2048, spectrumBins: 64);
@@ -65,6 +70,7 @@ public class Game1 : Game
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
_fractalRenderer = new FractalRenderer(GraphicsDevice);
_fractalRenderer.SetQuality(_renderQuality);
_pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
_pixel.SetData([Color.White]);
_hudFont = new HudBitmapFont();
@@ -107,6 +113,21 @@ public class Game1 : Game
CycleWindowResolution();
}
if (IsPressed(keyboard, Keys.D1))
{
SetRenderQuality(RenderQuality.Low);
}
if (IsPressed(keyboard, Keys.D2))
{
SetRenderQuality(RenderQuality.Medium);
}
if (IsPressed(keyboard, Keys.D3))
{
SetRenderQuality(RenderQuality.High);
}
if (IsPressed(keyboard, Keys.Space))
{
_isPaused = !_isPaused;
@@ -145,7 +166,7 @@ public class Game1 : Game
_fpsElapsed -= TimeSpan.FromSeconds(1);
}
Window.Title = $"Fractal Visualizer | {GetPresetName(_fractalPresetIndex)} | Mode: {_currentInputMode} | L:{_latestFeatures.Level:F3} B:{_latestFeatures.Bass:F2}";
Window.Title = $"Fractal Visualizer | {GetPresetName(_fractalPresetIndex)} | {_renderQuality} | Mode: {_currentInputMode} | FPS:{_fps}";
_previousKeyboardState = keyboard;
base.Update(gameTime);
}
@@ -156,6 +177,7 @@ public class Game1 : Game
if (_fractalRenderer is not null)
{
_fractalRenderer.UpdatePerformanceHint(_fps, TargetFps);
float renderTime = _isPaused ? _latestFeatures.TimeSeconds : (float)gameTime.TotalGameTime.TotalSeconds;
_fractalRenderer.Draw(_latestFeatures, renderTime, _fractalPresetIndex);
}
@@ -173,7 +195,8 @@ public class Game1 : Game
_hudFont.DrawText(_spriteBatch, _pixel, "BEAT " + _latestFeatures.Beat.ToString("0.000"), 12, 130, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "PAUSED " + (_isPaused ? "YES" : "NO"), 12, 150, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "FPS " + _fps, 12, 170, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "F OR F11 FULLSCREEN R RESIZE", 12, 190, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "QUALITY " + _renderQuality + " 1 2 3", 12, 190, 2, Color.White);
_hudFont.DrawText(_spriteBatch, _pixel, "F OR F11 FULLSCREEN R RESIZE", 12, 210, 2, Color.White);
_spriteBatch.End();
}
@@ -232,6 +255,12 @@ public class Game1 : Game
_graphics.ToggleFullScreen();
}
private void SetRenderQuality(RenderQuality quality)
{
_renderQuality = quality;
_fractalRenderer?.SetQuality(quality);
}
private void CycleWindowResolution()
{
if (_graphics.IsFullScreen)