mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-11-02 12:49:12 +01:00
Take the rest of feat/opengl-vulkan's settings
What the merge left out, now on this branch's own six levels: - GraphicsRules, which say what a renderer or an anti-aliasing mode rules out, and the notes that show it - the settings split into Graphics and Effects tabs - the DLSS library check beside the exe - eu07.ini import and export - one list of renderers: the backend follows from the renderer chosen The post-processing part of the levels is gone, as three switches cannot tell six levels apart. Bloom goes with the whole level. Still a transitional variant. The old renderers, their keys and their rows stay on the page, as the exe a player runs may be an old one or may have no Vulkan. That branch's five-level list and its removal of the old renderers stay out.
This commit is contained in:
@@ -26,6 +26,8 @@ public class GraphicsPresetTests
|
||||
var store = new TestInstallation().SettingsStore;
|
||||
var low = Defaults().Copy();
|
||||
var top = Defaults().Copy();
|
||||
// Ray tracing is one of them, and only Vulkan has it.
|
||||
low.RenderEngine = top.RenderEngine = SimulatorSettings.VulkanEngine;
|
||||
(GraphicsPreset.Minimal with { Extras = null }).ApplyTo(low);
|
||||
(GraphicsPreset.Ultra with { Extras = null, Top = null }).ApplyTo(top);
|
||||
|
||||
@@ -33,7 +35,7 @@ public class GraphicsPresetTests
|
||||
var topKeys = store.Render(top);
|
||||
var differing = lowKeys.Keys.Union(topKeys.Keys)
|
||||
.Where(key => lowKeys.GetValueOrDefault(key) != topKeys.GetValueOrDefault(key))
|
||||
.Where(key => !key.StartsWith("gfx.framebuffer", StringComparison.Ordinal) && key != "gfx.buffer.percent");
|
||||
.Where(key => !key.StartsWith("gfx.framebuffer", StringComparison.Ordinal));
|
||||
|
||||
Assert.Equal(GraphicsPreset.Keys.OrderBy(k => k), differing.OrderBy(k => k));
|
||||
}
|
||||
@@ -57,7 +59,7 @@ public class GraphicsPresetTests
|
||||
Climbs(p => p.Anisotropy, 1);
|
||||
|
||||
// Four steps or three for six levels.
|
||||
Climbs(p => p.Multisampling, 2);
|
||||
Climbs(p => (int)p.AntiAliasing, 2);
|
||||
Climbs(p => p.SmokeFidelity, 2);
|
||||
Climbs(p => p.SplineFidelity, 2);
|
||||
Climbs(p => p.ReflectionsFidelity, 3);
|
||||
@@ -153,13 +155,7 @@ public class GraphicsPresetTests
|
||||
[Fact]
|
||||
public void The_new_renderers_scales_never_go_down()
|
||||
{
|
||||
void WordsClimb(string name, Func<GraphicsNewRenderer, string> word)
|
||||
{
|
||||
var words = SimulatorKeys.Named(name).Words!;
|
||||
var places = GraphicsPreset.All.Select(p => Array.IndexOf(words, word(p.NewRenderer))).ToList();
|
||||
Assert.DoesNotContain(-1, places);
|
||||
Assert.Equal(places.OrderBy(place => place), places);
|
||||
}
|
||||
void NeverDown(Func<GraphicsNewRenderer, double> value) => Climbs(p => value(p.NewRenderer), 5);
|
||||
|
||||
void TurnsOn(Func<GraphicsNewRenderer, bool> on)
|
||||
{
|
||||
@@ -167,27 +163,27 @@ public class GraphicsPresetTests
|
||||
Assert.Equal(values.OrderBy(value => value), values);
|
||||
}
|
||||
|
||||
WordsClimb("gfx.lights.shadows", r => r.LampShadows);
|
||||
WordsClimb("gfx.contactshadows", r => r.ContactShadows);
|
||||
WordsClimb("gfx.postfx.ao", r => r.Occlusion);
|
||||
WordsClimb("gfx.postfx.ao.quality", r => r.OcclusionQuality);
|
||||
WordsClimb("gfx.cabprobe", r => r.CabProbe);
|
||||
WordsClimb("gfx.ssr", r => r.ScreenReflections);
|
||||
WordsClimb("gfx.fog", r => r.Fog);
|
||||
WordsClimb("gfx.fog.quality", r => r.FogQuality);
|
||||
WordsClimb("gfx.clouds", r => r.Clouds);
|
||||
NeverDown(r => r.LampShadows);
|
||||
NeverDown(r => r.ContactShadows);
|
||||
NeverDown(r => r.Occlusion);
|
||||
NeverDown(r => r.OcclusionSlices);
|
||||
NeverDown(r => r.OcclusionSteps);
|
||||
NeverDown(r => r.CabProbe);
|
||||
NeverDown(r => r.ScreenReflections);
|
||||
NeverDown(r => r.FogQuality);
|
||||
NeverDown(r => r.Clouds);
|
||||
|
||||
TurnsOn(r => r.OcclusionLighting);
|
||||
TurnsOn(r => r.CabProbeReflections);
|
||||
TurnsOn(r => r.RayTracing);
|
||||
TurnsOn(r => r.VolumetricFog);
|
||||
TurnsOn(r => r.CloudShadows);
|
||||
TurnsOn(r => r.Grass);
|
||||
TurnsOn(r => r.Bloom);
|
||||
|
||||
Climbs(p => p.NewRenderer.GrassDistance, 0);
|
||||
Climbs(p => p.NewRenderer.GrassFade, 0);
|
||||
Climbs(p => p.NewRenderer.GrassDensity, 0);
|
||||
Climbs(p => p.NewRenderer.Precipitation, 0);
|
||||
Climbs(p => p.NewRenderer.Precipitation, 1);
|
||||
// Frames between refreshes, so the dearer the fewer.
|
||||
Climbs(p => -p.NewRenderer.CabProbeInterval, 2);
|
||||
}
|
||||
@@ -196,28 +192,32 @@ public class GraphicsPresetTests
|
||||
public void Ultra_is_the_top_of_the_new_renderers_scales()
|
||||
{
|
||||
var ultra = GraphicsPreset.Ultra.NewRenderer;
|
||||
double Top(string key) => SimulatorKeys.Named(key).Maximum;
|
||||
string TopWord(string key) => SimulatorKeys.Named(key).Words!.Last();
|
||||
|
||||
Assert.Equal(TopWord("gfx.lights.shadows"), ultra.LampShadows);
|
||||
Assert.Equal(TopWord("gfx.contactshadows"), ultra.ContactShadows);
|
||||
Assert.Equal(TopWord("gfx.postfx.ao"), ultra.Occlusion);
|
||||
Assert.Equal(TopWord("gfx.postfx.ao.quality"), ultra.OcclusionQuality);
|
||||
Assert.Equal(TopWord("gfx.cabprobe"), ultra.CabProbe);
|
||||
Assert.Equal(TopWord("gfx.ssr"), ultra.ScreenReflections);
|
||||
Assert.Equal(TopWord("gfx.fog"), ultra.Fog);
|
||||
Assert.Equal(TopWord("gfx.fog.quality"), ultra.FogQuality);
|
||||
Assert.Equal(TopWord("gfx.clouds"), ultra.Clouds);
|
||||
Assert.Equal(Top("gfx.grass.distance"), ultra.GrassDistance);
|
||||
Assert.Equal(Top("gfx.grass.fadedistance"), ultra.GrassFade);
|
||||
Assert.Equal(Top("gfx.grass.density"), ultra.GrassDensity);
|
||||
Assert.Equal(Top("gfx.precipitation.particles"), ultra.Precipitation);
|
||||
Assert.Equal(3, ultra.LampShadows);
|
||||
Assert.Equal(3, ultra.ContactShadows);
|
||||
Assert.Equal(2, ultra.Occlusion);
|
||||
Assert.Equal((6, 8), (ultra.OcclusionSlices, ultra.OcclusionSteps));
|
||||
Assert.Equal(3, ultra.CabProbe);
|
||||
Assert.Equal(3, ultra.ScreenReflections);
|
||||
Assert.True(ultra.RayTracing && ultra.VolumetricFog);
|
||||
Assert.Equal(4, ultra.FogQuality);
|
||||
Assert.Equal(4, ultra.Clouds);
|
||||
Assert.Equal(300, ultra.GrassDistance);
|
||||
Assert.Equal(2.0, ultra.GrassDensity);
|
||||
Assert.Equal(262144, ultra.Precipitation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Grass_fades_out_beyond_where_it_is_drawn_in_full()
|
||||
{
|
||||
Assert.All(GraphicsPreset.All, p => Assert.True(p.NewRenderer.GrassFade > p.NewRenderer.GrassDistance, p.NameKey));
|
||||
var store = new TestInstallation().SettingsStore;
|
||||
foreach (var preset in GraphicsPreset.All)
|
||||
{
|
||||
var settings = Defaults().Copy();
|
||||
preset.ApplyTo(settings);
|
||||
|
||||
Assert.True(int.Parse(store.Render(settings)["gfx.grass.fadedistance"]) > preset.NewRenderer.GrassDistance, preset.NameKey);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -227,7 +227,7 @@ public class GraphicsPresetTests
|
||||
GraphicsPreset.Medium.ApplyTo(settings);
|
||||
Assert.Same(GraphicsPreset.Medium, GraphicsPreset.Matching(settings));
|
||||
|
||||
settings.Extra["gfx.fog.quality"] = "ultra";
|
||||
settings.FogQuality = 4;
|
||||
|
||||
Assert.Null(GraphicsPreset.Matching(settings));
|
||||
}
|
||||
@@ -236,18 +236,19 @@ public class GraphicsPresetTests
|
||||
public void What_is_left_to_the_player_stays_through_a_level()
|
||||
{
|
||||
var settings = Defaults().Copy();
|
||||
settings.Extra["gfx.antialiasing"] = "taa";
|
||||
settings.Extra["gfx.framegeneration"] = "x2";
|
||||
settings.Extra["gfx.vulkan.device"] = "RTX";
|
||||
settings.RenderEngine = SimulatorSettings.VulkanEngine;
|
||||
settings.AntiAliasing = AntiAliasingMode.Dlss;
|
||||
settings.FrameGeneration = 2;
|
||||
settings.VulkanDevice = "RTX";
|
||||
|
||||
foreach (var preset in GraphicsPreset.All)
|
||||
{
|
||||
preset.ApplyTo(settings);
|
||||
|
||||
Assert.Same(preset, GraphicsPreset.Matching(settings));
|
||||
Assert.Equal("taa", settings.Extra["gfx.antialiasing"]);
|
||||
Assert.Equal("x2", settings.Extra["gfx.framegeneration"]);
|
||||
Assert.Equal("RTX", settings.Extra["gfx.vulkan.device"]);
|
||||
Assert.Equal(AntiAliasingMode.Dlss, settings.AntiAliasing);
|
||||
Assert.Equal(2, settings.FrameGeneration);
|
||||
Assert.Equal("RTX", settings.VulkanDevice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +263,7 @@ public class GraphicsPresetTests
|
||||
Assert.Equal(8192, ultra.ShadowMap);
|
||||
Assert.Equal(600, ultra.ShadowRange);
|
||||
Assert.Equal(Steps.Anisotropy.Max(), ultra.Anisotropy);
|
||||
Assert.Equal(Steps.MultisamplingLevels.Max(), ultra.Multisampling);
|
||||
Assert.Equal(AntiAliasingMode.Msaa8, ultra.AntiAliasing);
|
||||
Assert.Equal(Steps.ReflectionUpdates.Max(), ultra.ReflectionsRate);
|
||||
Assert.Equal(4, ultra.SmokeFidelity);
|
||||
Assert.Equal(4, ultra.SplineFidelity);
|
||||
@@ -610,13 +611,12 @@ public class GraphicsPresetTests
|
||||
OnSteps(preset.SleeperDistance, GraphicsPreset.SleeperKey);
|
||||
OnSteps(preset.ReflectedInstances, GraphicsPreset.ReflectedInstancesKey);
|
||||
OnSteps(preset.ReflectedVehicles, GraphicsPreset.ReflectedVehiclesKey);
|
||||
OnSteps(preset.NewRenderer.CabProbeInterval, "gfx.cabprobe.interval");
|
||||
OnSteps(preset.NewRenderer.GrassDistance, "gfx.grass.distance");
|
||||
OnSteps(preset.NewRenderer.GrassFade, "gfx.grass.fadedistance");
|
||||
OnSteps(preset.NewRenderer.GrassDensity, "gfx.grass.density");
|
||||
OnSteps(preset.NewRenderer.Precipitation, "gfx.precipitation.particles");
|
||||
Assert.InRange(preset.NewRenderer.CabProbeInterval, 1, 120);
|
||||
Assert.InRange(preset.NewRenderer.GrassDistance, 20, 300);
|
||||
Assert.Equal(0, preset.NewRenderer.GrassDistance % 10);
|
||||
Assert.Equal(0, preset.NewRenderer.GrassDensity % 0.25);
|
||||
Assert.Contains(preset.NewRenderer.Precipitation, new[] { 16384, 32768, 65536, 131072, 262144 });
|
||||
Assert.True(Steps.IndexOf(Steps.Anisotropy, preset.Anisotropy) >= 0, preset.NameKey);
|
||||
Assert.True(Steps.IndexOf(Steps.MultisamplingLevels, preset.Multisampling) >= 0, preset.NameKey);
|
||||
Assert.True(Steps.IndexOf(Steps.ReflectionUpdates, preset.ReflectionsRate) >= 0, preset.NameKey);
|
||||
Assert.True(Steps.IndexOf(Steps.DrawRangeFactors, preset.DrawRangeFactor) >= 0, preset.NameKey);
|
||||
foreach (int size in new[] { preset.TextureSize, preset.CabTextureSize, preset.ShadowMap })
|
||||
@@ -631,13 +631,14 @@ public class GraphicsPresetTests
|
||||
private static GraphicsGroupLevels Groups() => new(new TestInstallation().SettingsStore);
|
||||
|
||||
[Fact]
|
||||
public void Every_key_a_level_sets_but_the_buffer_belongs_to_one_part()
|
||||
public void Every_key_a_level_sets_but_those_of_the_whole_belongs_to_one_part()
|
||||
{
|
||||
var inGroups = GraphicsGroup.All.SelectMany(group => group.Keys).ToList();
|
||||
|
||||
Assert.Equal(inGroups.Distinct(), inGroups);
|
||||
Assert.Empty(inGroups.Except(GraphicsPreset.Keys).Except(GraphicsExtras.Keys).Except(GraphicsTop.Keys));
|
||||
Assert.Equal(new[] { "starter.bufferscale" }, GraphicsPreset.Keys.Except(inGroups));
|
||||
Assert.Equal(new[] { "gfx.antialiasing", "gfx.buffer.percent", "gfx.extraeffects", "gfx.postfx.bloom", "multisampling", "starter.bufferscale" },
|
||||
GraphicsPreset.Keys.Except(inGroups).OrderBy(key => key, StringComparer.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -683,7 +684,7 @@ public class GraphicsPresetTests
|
||||
|
||||
var levels = Groups().LevelsOf(settings);
|
||||
|
||||
Assert.Null(levels[GraphicsGroup.Effects]);
|
||||
Assert.Null(levels[GraphicsGroup.Lights]);
|
||||
Assert.Same(GraphicsPreset.High, levels[GraphicsGroup.Shadows]);
|
||||
}
|
||||
|
||||
@@ -697,6 +698,7 @@ public class GraphicsPresetTests
|
||||
foreach (var group in GraphicsGroup.All)
|
||||
settings = groups.Apply(group, level, settings);
|
||||
settings.BufferScalePercent = level.BufferScale;
|
||||
settings.AntiAliasing = level.AntiAliasing;
|
||||
|
||||
Assert.Same(level, GraphicsPreset.Matching(settings));
|
||||
}
|
||||
@@ -732,9 +734,10 @@ public class GraphicsPresetTests
|
||||
var settings = AtHigh();
|
||||
settings.MotionBlur = false;
|
||||
|
||||
var moved = Groups().Apply(GraphicsGroup.Effects, GraphicsPreset.VeryHigh, settings);
|
||||
settings.Smoke = false;
|
||||
|
||||
Assert.False(moved.MotionBlur);
|
||||
Assert.Equal(GraphicsPreset.VeryHigh.SmokeFidelity, moved.SmokeFidelity);
|
||||
var nature = Groups().Apply(GraphicsGroup.Nature, GraphicsPreset.VeryHigh, settings);
|
||||
Assert.False(nature.Smoke);
|
||||
Assert.Equal(GraphicsPreset.VeryHigh.SmokeFidelity, nature.SmokeFidelity);
|
||||
}
|
||||
}
|
||||
|
||||
593
StarterNG.Tests/GraphicsSettingsTests.cs
Normal file
593
StarterNG.Tests/GraphicsSettingsTests.cs
Normal file
@@ -0,0 +1,593 @@
|
||||
using StarterNG.Classes;
|
||||
using StarterNG.Domain.Settings;
|
||||
using StarterNG.Infrastructure.Settings;
|
||||
using StarterNG.Tests.Fakes;
|
||||
|
||||
namespace StarterNG.Tests;
|
||||
|
||||
public class GraphicsSettingsTests
|
||||
{
|
||||
private static readonly string UserIni = Path.Combine("/home/kolejarz", ".config", "MaSzyna", "eu07.ini");
|
||||
|
||||
private static TestInstallation WithIni(string text)
|
||||
{
|
||||
var installation = new TestInstallation(new InMemoryFileSystem().WithFile(UserIni, text));
|
||||
installation.Environment.With("HOME", "/home/kolejarz");
|
||||
installation.SettingsStore.Load();
|
||||
return installation;
|
||||
}
|
||||
|
||||
private static SimulatorSettings Read(string text, bool dlssPlatform = true)
|
||||
{
|
||||
var s = new SimulatorSettings();
|
||||
new SettingsSerializer(dlssPlatform).Read(s, ConfigFile.Parse(text));
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string Write(SimulatorSettings s, string text = "", bool dlssPlatform = true)
|
||||
{
|
||||
var c = ConfigFile.Parse(text);
|
||||
new SettingsSerializer(dlssPlatform).Write(s, c);
|
||||
return c.ToText();
|
||||
}
|
||||
|
||||
private static string[] Lines(string text) =>
|
||||
text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
|
||||
|
||||
private static string? Line(string text, string key) =>
|
||||
Lines(text).FirstOrDefault(l => l == key || l.StartsWith(key + " ", StringComparison.Ordinal));
|
||||
|
||||
[Theory]
|
||||
[InlineData("full", GraphicsBackend.OpenGL)]
|
||||
[InlineData("default", GraphicsBackend.OpenGL)]
|
||||
[InlineData("gl46", GraphicsBackend.OpenGL)]
|
||||
[InlineData("legacy", GraphicsBackend.OpenGL)]
|
||||
[InlineData("experimental", GraphicsBackend.OpenGL)]
|
||||
[InlineData("vulkan", GraphicsBackend.Vulkan)]
|
||||
[InlineData("vulkan14", GraphicsBackend.Vulkan)]
|
||||
public void The_renderer_is_read_with_the_aliases_the_simulator_takes(string value, GraphicsBackend expected)
|
||||
{
|
||||
Assert.Equal(expected, Read($"gfxrenderer {value}\n").Backend);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("full", "full")]
|
||||
[InlineData("gl46", "full")]
|
||||
[InlineData("legacy", "legacy")]
|
||||
[InlineData("simpleshader", "legacy")]
|
||||
[InlineData("simple", "simple")]
|
||||
[InlineData("experimental", "experimental")]
|
||||
[InlineData("vulkan14", "vulkan")]
|
||||
public void A_renderer_is_written_by_its_name(string read, string written)
|
||||
{
|
||||
Assert.Equal($"gfxrenderer {written}", Line(Write(Read($"gfxrenderer {read}\n")), "gfxrenderer"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_older_renderer_stays_chosen_and_can_be_chosen_again()
|
||||
{
|
||||
var installation = WithIni("gfxrenderer legacy\n");
|
||||
var store = installation.SettingsStore;
|
||||
|
||||
store.Settings.Clouds = 3;
|
||||
store.Save();
|
||||
Assert.Contains("gfxrenderer legacy", installation.Files.ReadAllText(UserIni));
|
||||
|
||||
store.Settings.RenderEngine = SimulatorSettings.VulkanEngine;
|
||||
store.Save();
|
||||
Assert.Contains("gfxrenderer vulkan", installation.Files.ReadAllText(UserIni));
|
||||
Assert.Equal(GraphicsBackend.Vulkan, store.Settings.Backend);
|
||||
|
||||
store.Settings.RenderEngine = SimulatorSettings.RenderEngineOf("simple");
|
||||
store.Save();
|
||||
Assert.Contains("gfxrenderer simple", installation.Files.ReadAllText(UserIni));
|
||||
Assert.Equal(GraphicsBackend.OpenGL, store.Settings.Backend);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Keys_only_an_older_simulator_reads_stay_in_the_file()
|
||||
{
|
||||
string[] old =
|
||||
{
|
||||
"usevbo no", "gfx.angleplatform vulkan", "gfx.usegles yes",
|
||||
"gfx.framebuffer.width 1920", "gfx.framebuffer.height 1080", "gfx.shadows.cab.range 20"
|
||||
};
|
||||
var installation = WithIni(string.Join("\n", old) + "\n");
|
||||
installation.SettingsStore.Settings.Clouds = 3;
|
||||
|
||||
installation.SettingsStore.Save();
|
||||
|
||||
string saved = installation.Files.ReadAllText(UserIni);
|
||||
Assert.All(old, line => Assert.Contains(line, saved));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Levels_leave_the_switches_only_an_older_simulator_reads()
|
||||
{
|
||||
var s = new SimulatorSettings { UseVbo = false, UseGLES = true, RenderAngleVulkan = true };
|
||||
|
||||
GraphicsPreset.Ultra.ApplyTo(s);
|
||||
|
||||
Assert.Equal((false, true, true), (s.UseVbo, s.UseGLES, s.RenderAngleVulkan));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_new_graphics_keys_are_read()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\n" +
|
||||
"gfx.antialiasing dlss\ngfx.dlss.preset K\ngfx.framegeneration x3\ngfx.reflex boost\n" +
|
||||
"gfx.raytracing yes\ngfx.raytracing.range 800\ngfx.ssr high\ngfx.postfx.ao ssao\ngfx.postfx.ao.quality 4 6\n" +
|
||||
"gfx.lights.shadows low\ngfx.contactshadows 3\ngfx.fog analytic\ngfx.fog.quality ultra\n" +
|
||||
"gfx.clouds ultra\ngfx.clouds.shadows no\ngfx.grass no\ngfx.grass.distance 120\ngfx.grass.density 1.5\n" +
|
||||
"gfx.buffer.percent 0.67\ngfx.vulkan.device RTX\n");
|
||||
|
||||
Assert.Equal(GraphicsBackend.Vulkan, s.Backend);
|
||||
Assert.Equal(AntiAliasingMode.Dlss, s.AntiAliasing);
|
||||
Assert.Equal("k", s.DlssPreset);
|
||||
Assert.Equal(3, s.FrameGeneration);
|
||||
Assert.Equal(2, s.Reflex);
|
||||
Assert.True(s.RayTracing);
|
||||
Assert.Equal(800, s.RayTracingRange);
|
||||
Assert.Equal(3, s.Ssr);
|
||||
Assert.Equal(1, s.AmbientOcclusion);
|
||||
Assert.Equal((4, 6), (s.AoSlices, s.AoSteps));
|
||||
Assert.Equal(1, s.LightShadows);
|
||||
Assert.Equal(3, s.ContactShadows);
|
||||
Assert.False(s.VolumetricFog);
|
||||
Assert.Equal(4, s.FogQuality);
|
||||
Assert.Equal(4, s.Clouds);
|
||||
Assert.False(s.CloudShadows);
|
||||
Assert.False(s.Grass);
|
||||
Assert.Equal(120, s.GrassDistance);
|
||||
Assert.Equal(1.5, s.GrassDensity);
|
||||
Assert.Equal(67, s.BufferScalePercent);
|
||||
Assert.Equal("RTX", s.VulkanDevice);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Missing_keys_take_the_simulators_defaults()
|
||||
{
|
||||
var s = Read("");
|
||||
|
||||
Assert.Equal(GraphicsBackend.OpenGL, s.Backend);
|
||||
Assert.Equal(AntiAliasingMode.Msaa4, s.AntiAliasing);
|
||||
Assert.Equal(2, s.Ssr);
|
||||
Assert.Equal(2, s.AmbientOcclusion);
|
||||
Assert.Equal(2, s.LightShadows);
|
||||
Assert.Equal(0, s.ContactShadows);
|
||||
Assert.True(s.VolumetricFog);
|
||||
Assert.Equal(2, s.FogQuality);
|
||||
Assert.Equal(2, s.Clouds);
|
||||
Assert.False(s.RayTracing);
|
||||
Assert.Equal(1, s.FrameGeneration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_tokens_written_are_the_ones_the_simulator_parses()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\n");
|
||||
s.AntiAliasing = AntiAliasingMode.Dlaa;
|
||||
s.FrameGeneration = 4;
|
||||
s.Reflex = 1;
|
||||
s.LightShadows = 3;
|
||||
s.ContactShadows = 0;
|
||||
s.Clouds = 4;
|
||||
s.VolumetricFog = false;
|
||||
s.FogQuality = 1;
|
||||
s.AmbientOcclusion = 1;
|
||||
s.Ssr = 2;
|
||||
s.RayTracing = true;
|
||||
|
||||
string text = Write(s);
|
||||
|
||||
Assert.Equal("gfx.antialiasing dlaa", Line(text, "gfx.antialiasing"));
|
||||
Assert.Equal("multisampling 0", Line(text, "multisampling"));
|
||||
Assert.Equal("gfx.framegeneration x4", Line(text, "gfx.framegeneration"));
|
||||
Assert.Equal("gfx.reflex on", Line(text, "gfx.reflex"));
|
||||
Assert.Equal("gfx.lights.shadows high", Line(text, "gfx.lights.shadows"));
|
||||
Assert.Equal("gfx.contactshadows no", Line(text, "gfx.contactshadows"));
|
||||
Assert.Equal("gfx.clouds ultra", Line(text, "gfx.clouds"));
|
||||
Assert.Equal("gfx.fog analytic", Line(text, "gfx.fog"));
|
||||
Assert.Equal("gfx.fog.quality low", Line(text, "gfx.fog.quality"));
|
||||
Assert.Equal("gfx.postfx.ao ssao", Line(text, "gfx.postfx.ao"));
|
||||
Assert.Equal("gfx.ssr medium", Line(text, "gfx.ssr"));
|
||||
Assert.Equal("gfx.raytracing yes", Line(text, "gfx.raytracing"));
|
||||
Assert.Equal("gfx.buffer.percent 100", Line(text, "gfx.buffer.percent"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Msaa_is_written_to_both_keys_for_older_simulators()
|
||||
{
|
||||
var s = Read("multisampling 1\n");
|
||||
Assert.Equal(AntiAliasingMode.Msaa2, s.AntiAliasing);
|
||||
|
||||
string text = Write(s);
|
||||
|
||||
Assert.Equal("multisampling 1", Line(text, "multisampling"));
|
||||
Assert.Equal("gfx.antialiasing msaax2", Line(text, "gfx.antialiasing"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Of_the_two_anti_aliasing_keys_the_later_one_wins_as_in_the_simulator()
|
||||
{
|
||||
Assert.Equal(AntiAliasingMode.Taa, Read("multisampling 2\ngfx.antialiasing taa\n").AntiAliasing);
|
||||
Assert.Equal(AntiAliasingMode.Msaa4, Read("gfx.antialiasing taa\nmultisampling 2\n").AntiAliasing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void On_opengl_the_vulkan_only_features_are_written_off()
|
||||
{
|
||||
var s = Read("gfxrenderer full\ngfx.antialiasing dlss\ngfx.framegeneration x2\ngfx.reflex on\ngfx.raytracing yes\n");
|
||||
|
||||
Assert.Equal(AntiAliasingMode.Taa, s.AntiAliasing);
|
||||
Assert.Equal(1, s.FrameGeneration);
|
||||
Assert.Equal(0, s.Reflex);
|
||||
Assert.False(s.RayTracing);
|
||||
|
||||
string text = Write(s);
|
||||
Assert.Equal("gfx.antialiasing taa", Line(text, "gfx.antialiasing"));
|
||||
Assert.Equal("gfx.framegeneration off", Line(text, "gfx.framegeneration"));
|
||||
Assert.Equal("gfx.reflex off", Line(text, "gfx.reflex"));
|
||||
Assert.Equal("gfx.raytracing no", Line(text, "gfx.raytracing"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Frame_generation_needs_dlss_even_on_vulkan()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\ngfx.antialiasing taa\ngfx.framegeneration x2\ngfx.reflex on\n");
|
||||
|
||||
Assert.Equal(1, s.FrameGeneration);
|
||||
Assert.Equal(1, s.Reflex);
|
||||
Assert.False(GraphicsRules.ReflexForced(s, true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Frame_generation_turns_reflex_on()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\ngfx.antialiasing dlss\ngfx.framegeneration x2\n");
|
||||
|
||||
Assert.True(GraphicsRules.ReflexForced(s, true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Without_a_dlss_platform_dlss_falls_back_to_taa()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\ngfx.antialiasing dlss\n", dlssPlatform: false);
|
||||
|
||||
Assert.Equal(AntiAliasingMode.Taa, s.AntiAliasing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dlaa_ignores_the_render_scale()
|
||||
{
|
||||
var s = Read("gfxrenderer vulkan\ngfx.antialiasing dlaa\n");
|
||||
Assert.False(GraphicsRules.BufferScaleUsed(s, true));
|
||||
|
||||
s.AntiAliasing = AntiAliasingMode.Dlss;
|
||||
Assert.True(GraphicsRules.BufferScaleUsed(s, true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Sizes_are_rounded_down_to_what_the_simulator_uses()
|
||||
{
|
||||
var s = Read("maxtexturesize 16384\nmaxcabtexturesize 3000\nshadowtune 3000 0 250 0\n");
|
||||
|
||||
Assert.Equal(8192, s.MaxTextureSize);
|
||||
Assert.Equal(2048, s.MaxCabTextureSize);
|
||||
Assert.Equal(2048, s.ShadowMapResolution);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_render_scale_reads_the_old_starter_key_when_the_new_one_is_missing()
|
||||
{
|
||||
Assert.Equal(75, Read("starter.bufferscale 75\n").BufferScalePercent);
|
||||
Assert.Equal(50, Read("starter.bufferscale 75\ngfx.buffer.percent 50\n").BufferScalePercent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_level_is_recognised_after_it_is_applied_and_survives_a_save()
|
||||
{
|
||||
for (int engine = 0; engine < SimulatorSettings.RenderEngines.Length; engine++)
|
||||
{
|
||||
foreach (var level in GraphicsPreset.All)
|
||||
{
|
||||
var installation = WithIni("");
|
||||
var store = installation.SettingsStore;
|
||||
store.Settings.RenderEngine = engine;
|
||||
level.ApplyTo(store.Settings);
|
||||
Assert.Same(level, GraphicsPreset.Matching(store.Settings));
|
||||
|
||||
store.Save();
|
||||
|
||||
var again = new TestInstallation(installation.Files);
|
||||
again.Environment.With("HOME", "/home/kolejarz");
|
||||
again.SettingsStore.Load();
|
||||
Assert.Same(level, GraphicsPreset.Matching(again.SettingsStore.Settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_change_after_a_level_leaves_the_level()
|
||||
{
|
||||
var s = new SimulatorSettings();
|
||||
GraphicsPreset.High.ApplyTo(s);
|
||||
s.Clouds = 4;
|
||||
|
||||
Assert.Null(GraphicsPreset.Matching(s));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Levels_leave_alone_what_is_not_a_matter_of_quality()
|
||||
{
|
||||
var s = new SimulatorSettings { Width = 2560, Height = 1440, VSync = true, FieldOfView = 60, MotionBlur = false };
|
||||
|
||||
GraphicsPreset.Low.ApplyTo(s);
|
||||
|
||||
Assert.Equal((2560, 1440, true, 60, false), (s.Width, s.Height, s.VSync, s.FieldOfView, s.MotionBlur));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ray_tracing_comes_with_ultra_on_vulkan_only()
|
||||
{
|
||||
var vulkan = new SimulatorSettings { RenderEngine = SimulatorSettings.VulkanEngine };
|
||||
var opengl = new SimulatorSettings();
|
||||
|
||||
GraphicsPreset.Ultra.ApplyTo(vulkan);
|
||||
GraphicsPreset.Ultra.ApplyTo(opengl);
|
||||
|
||||
Assert.True(vulkan.RayTracing);
|
||||
Assert.False(opengl.RayTracing);
|
||||
Assert.Same(GraphicsPreset.Ultra, GraphicsPreset.Matching(opengl));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_level_keeps_dlss_on_vulkan()
|
||||
{
|
||||
var s = new SimulatorSettings { RenderEngine = SimulatorSettings.VulkanEngine, AntiAliasing = AntiAliasingMode.Dlss };
|
||||
|
||||
GraphicsPreset.Ultra.ApplyTo(s);
|
||||
|
||||
Assert.Equal(AntiAliasingMode.Dlss, s.AntiAliasing);
|
||||
Assert.Same(GraphicsPreset.Ultra, GraphicsPreset.Matching(s));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_level_replaces_taa_with_its_own_multisampling()
|
||||
{
|
||||
var s = new SimulatorSettings { AntiAliasing = AntiAliasingMode.Taa };
|
||||
|
||||
GraphicsPreset.Medium.ApplyTo(s);
|
||||
|
||||
Assert.Equal(AntiAliasingMode.Msaa2, s.AntiAliasing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_import_takes_the_settings_but_keeps_this_installations_simulator_and_the_unmanaged_lines()
|
||||
{
|
||||
var installation = WithIni("starter.exe.auto no\nstarter.exe.path eu07_local.exe\ncalibratein 0 0 0 0\ngfx.clouds low\n");
|
||||
installation.Files.WithFile("/backup/eu07.ini", "starter.exe.auto no\nstarter.exe.path eu07_other.exe\ngfx.clouds ultra\ngfxrenderer vulkan\n");
|
||||
|
||||
Assert.True(installation.SettingsStore.ImportFrom("/backup/eu07.ini"));
|
||||
var s = installation.SettingsStore.Settings;
|
||||
Assert.Equal(4, s.Clouds);
|
||||
Assert.Equal(GraphicsBackend.Vulkan, s.Backend);
|
||||
Assert.Equal("eu07_local.exe", s.ExecutablePath);
|
||||
|
||||
// Nothing is written until saved, and the save keeps the user's own lines.
|
||||
Assert.Contains("gfx.clouds low", installation.Files.ReadAllText(UserIni));
|
||||
installation.SettingsStore.Save();
|
||||
string saved = installation.Files.ReadAllText(UserIni);
|
||||
Assert.Contains("calibratein 0 0 0 0", saved);
|
||||
Assert.Contains("gfx.clouds ultra", saved);
|
||||
Assert.Contains("starter.exe.path eu07_local.exe", saved);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_import_of_a_missing_file_changes_nothing()
|
||||
{
|
||||
var installation = WithIni("gfx.clouds low\n");
|
||||
|
||||
Assert.False(installation.SettingsStore.ImportFrom("/nowhere/eu07.ini"));
|
||||
Assert.Equal(1, installation.SettingsStore.Settings.Clouds);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_export_writes_a_complete_file_elsewhere_and_leaves_the_users_one_alone()
|
||||
{
|
||||
var installation = WithIni("calibratein 0 0 0 0\ngfx.clouds low\n");
|
||||
installation.SettingsStore.Settings.Clouds = 3;
|
||||
|
||||
Assert.True(installation.SettingsStore.ExportTo("/export/eu07.ini"));
|
||||
|
||||
string exported = installation.Files.ReadAllText("/export/eu07.ini");
|
||||
Assert.Contains("calibratein 0 0 0 0", exported);
|
||||
Assert.Contains("gfx.clouds high", exported);
|
||||
Assert.Contains("gfx.clouds low", installation.Files.ReadAllText(UserIni));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_export_keeps_the_older_renderer_word_of_the_file()
|
||||
{
|
||||
var installation = WithIni("gfxrenderer legacy\n");
|
||||
|
||||
Assert.True(installation.SettingsStore.ExportTo("/export/eu07.ini"));
|
||||
|
||||
Assert.Contains("gfxrenderer legacy", installation.Files.ReadAllText("/export/eu07.ini"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_dlss_libraries_are_looked_for_next_to_a_windows_build()
|
||||
{
|
||||
var files = new InMemoryFileSystem()
|
||||
.WithDirectory(TestInstallation.Root)
|
||||
.WithExecutable(TestInstallation.At("eu07.exe"), "MZ binary")
|
||||
.WithFile(TestInstallation.At("nvngx_dlss.dll"), "dll");
|
||||
var installation = new TestInstallation(files);
|
||||
|
||||
Assert.Equal((true, false), installation.Executables.DlssLibraries(TestInstallation.At("eu07.exe")));
|
||||
|
||||
files.WithFile(TestInstallation.At("nvngx_dlssg.dll"), "dll");
|
||||
Assert.Equal((true, true), installation.Executables.DlssLibraries(TestInstallation.At("eu07.exe")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_dlss_libraries_of_a_linux_build_are_the_shared_objects()
|
||||
{
|
||||
var files = new InMemoryFileSystem()
|
||||
.WithDirectory(TestInstallation.Root)
|
||||
.WithExecutable(TestInstallation.At("eu07"), "\u007fELF binary")
|
||||
.WithFile(TestInstallation.At("libnvidia-ngx-dlssg.so.310.4.0"), "so");
|
||||
var installation = new TestInstallation(files);
|
||||
|
||||
Assert.Equal((false, true), installation.Executables.DlssLibraries(TestInstallation.At("eu07")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_later_line_moved_up_keeps_the_index_of_every_key()
|
||||
{
|
||||
var c = ConfigFile.Parse("a 1\nb 2\nc 3\n");
|
||||
|
||||
c.MoveAfter("a", "c");
|
||||
|
||||
Assert.Equal("b 2\nc 3\na 1\n", c.ToText().Replace("\r\n", "\n"));
|
||||
Assert.True(c.LineOf("a") > c.LineOf("c"));
|
||||
c.Set("b", "9");
|
||||
Assert.Equal("b 9\nc 3\na 1\n", c.ToText().Replace("\r\n", "\n"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_ao_lighting_and_cab_probe_keys_survive_a_round_trip_in_the_simulators_form()
|
||||
{
|
||||
var s = Read("gfx.postfx.ao.lighting no\ngfx.cabprobe high\ngfx.cabprobe.interval 12\ngfx.cabprobe.bounce 2.5\ngfx.cabprobe.reflections no\n");
|
||||
|
||||
Assert.False(s.AoLighting);
|
||||
Assert.Equal(3, s.CabProbe);
|
||||
Assert.Equal(12, s.CabProbeInterval);
|
||||
Assert.Equal(2.5, s.CabProbeBounce);
|
||||
Assert.False(s.CabProbeReflections);
|
||||
|
||||
string text = Write(s);
|
||||
Assert.Equal("gfx.postfx.ao.lighting no", Line(text, "gfx.postfx.ao.lighting"));
|
||||
Assert.Equal("gfx.cabprobe high", Line(text, "gfx.cabprobe"));
|
||||
Assert.Equal("gfx.cabprobe.interval 12", Line(text, "gfx.cabprobe.interval"));
|
||||
Assert.Equal("gfx.cabprobe.bounce 2.5", Line(text, "gfx.cabprobe.bounce"));
|
||||
Assert.Equal("gfx.cabprobe.reflections no", Line(text, "gfx.cabprobe.reflections"));
|
||||
|
||||
var again = Read(text);
|
||||
Assert.Equal((s.AoLighting, s.CabProbe, s.CabProbeInterval, s.CabProbeBounce, s.CabProbeReflections),
|
||||
(again.AoLighting, again.CabProbe, again.CabProbeInterval, again.CabProbeBounce, again.CabProbeReflections));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Missing_ao_lighting_and_cab_probe_keys_take_the_simulators_defaults_and_are_written_like_its_export()
|
||||
{
|
||||
var s = Read("");
|
||||
|
||||
Assert.Equal((true, 2, 4, 1.0, true), (s.AoLighting, s.CabProbe, s.CabProbeInterval, s.CabProbeBounce, s.CabProbeReflections));
|
||||
|
||||
string text = Write(s);
|
||||
Assert.Equal("gfx.postfx.ao.lighting yes", Line(text, "gfx.postfx.ao.lighting"));
|
||||
Assert.Equal("gfx.cabprobe medium", Line(text, "gfx.cabprobe"));
|
||||
Assert.Equal("gfx.cabprobe.interval 4", Line(text, "gfx.cabprobe.interval"));
|
||||
Assert.Equal("gfx.cabprobe.bounce 1", Line(text, "gfx.cabprobe.bounce"));
|
||||
Assert.Equal("gfx.cabprobe.reflections yes", Line(text, "gfx.cabprobe.reflections"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Unknown_ao_lighting_and_cab_probe_values_fall_back_to_the_simulators_defaults()
|
||||
{
|
||||
var s = Read("gfx.postfx.ao.lighting maybe\ngfx.cabprobe bogus\ngfx.cabprobe.interval abc\ngfx.cabprobe.bounce x\ngfx.cabprobe.reflections ?\n");
|
||||
|
||||
Assert.Equal((true, 2, 4, 1.0, true), (s.AoLighting, s.CabProbe, s.CabProbeInterval, s.CabProbeBounce, s.CabProbeReflections));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("no", 0)]
|
||||
[InlineData("0", 0)]
|
||||
[InlineData("low", 1)]
|
||||
[InlineData("1", 1)]
|
||||
[InlineData("medium", 2)]
|
||||
[InlineData("yes", 2)]
|
||||
[InlineData("2", 2)]
|
||||
[InlineData("high", 3)]
|
||||
[InlineData("3", 3)]
|
||||
public void The_cab_probe_level_is_read_with_the_aliases_the_simulator_takes(string value, int expected)
|
||||
{
|
||||
Assert.Equal(expected, Read($"gfx.cabprobe {value}\n").CabProbe);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_cab_probe_numbers_are_kept_within_the_simulators_ranges()
|
||||
{
|
||||
var s = Read("gfx.cabprobe.interval 500\ngfx.cabprobe.bounce 9\n");
|
||||
Assert.Equal((120, 4.0), (s.CabProbeInterval, s.CabProbeBounce));
|
||||
|
||||
s = Read("gfx.cabprobe.interval 0\ngfx.cabprobe.bounce -1\n");
|
||||
Assert.Equal((1, 0.0), (s.CabProbeInterval, s.CabProbeBounce));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_ao_lighting_counts_with_gtao_only()
|
||||
{
|
||||
Assert.True(GraphicsRules.AoLightingUsed(Read("gfx.postfx.ao gtao\n")));
|
||||
Assert.False(GraphicsRules.AoLightingUsed(Read("gfx.postfx.ao ssao\n")));
|
||||
Assert.False(GraphicsRules.AoLightingUsed(Read("gfx.postfx.ao no\n")));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("gfx.ssr no\ngfx.contactshadows no\n", true)]
|
||||
[InlineData("gfx.ssr low\ngfx.contactshadows no\n", false)]
|
||||
[InlineData("gfx.ssr no\ngfx.contactshadows low\n", false)]
|
||||
[InlineData("gfx.ssr no\ngfx.contactshadows no\ngfx.depthprepass.scene yes\n", false)]
|
||||
[InlineData("gfx.ssr no\ngfx.contactshadows no\ngfx.postfx.ao.lighting no\n", false)]
|
||||
[InlineData("gfx.ssr no\ngfx.contactshadows no\ngfx.postfx.ao ssao\n", false)]
|
||||
public void The_ao_lighting_adds_the_depth_pass_only_when_nothing_else_draws_it(string text, bool expected)
|
||||
{
|
||||
Assert.Equal(expected, GraphicsRules.AoLightingAddsDepthPrepass(Read(text)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("gfx.cabprobe medium\n", true, true)]
|
||||
[InlineData("gfx.cabprobe no\n", false, false)]
|
||||
[InlineData("gfx.cabprobe low\ngfx.lights.clustered no\n", true, false)]
|
||||
[InlineData("gfx.cabprobe high\ngfx.lights.cab no\n", true, false)]
|
||||
public void The_cab_probe_lights_the_cab_only_with_its_lamp_as_a_light(string text, bool used, bool lights)
|
||||
{
|
||||
var s = Read(text);
|
||||
|
||||
Assert.Equal(used, GraphicsRules.CabProbeUsed(s));
|
||||
Assert.Equal(lights, GraphicsRules.CabProbeLights(s));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, false, 0, 8, false)]
|
||||
[InlineData(1, false, 0, 8, false)]
|
||||
[InlineData(2, false, 1, 8, true)]
|
||||
[InlineData(3, true, 2, 4, true)]
|
||||
[InlineData(4, true, 3, 3, true)]
|
||||
[InlineData(5, true, 3, 2, true)]
|
||||
public void A_level_sets_the_ao_lighting_and_the_cab_probe(int place, bool aoLighting, int probe, int interval, bool reflections)
|
||||
{
|
||||
var level = GraphicsPreset.All[place];
|
||||
var s = new SimulatorSettings { CabProbeBounce = 2.5 };
|
||||
|
||||
level.ApplyTo(s);
|
||||
|
||||
Assert.Equal((aoLighting, probe, interval, reflections), (s.AoLighting, s.CabProbe, s.CabProbeInterval, s.CabProbeReflections));
|
||||
Assert.Equal(2.5, s.CabProbeBounce);
|
||||
Assert.Same(level, GraphicsPreset.Matching(s));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_import_keeps_the_lamp_switch_of_the_users_own_file()
|
||||
{
|
||||
var installation = WithIni("gfx.lights.cab no\n");
|
||||
installation.Files.WithFile("/backup/eu07.ini", "gfx.lights.cab yes\ngfx.cabprobe high\n");
|
||||
|
||||
Assert.True(installation.SettingsStore.ImportFrom("/backup/eu07.ini"));
|
||||
|
||||
Assert.False(installation.SettingsStore.Settings.CabLampLight);
|
||||
Assert.Equal(3, installation.SettingsStore.Settings.CabProbe);
|
||||
}
|
||||
}
|
||||
@@ -861,6 +861,9 @@ public class SettingsStoreTests
|
||||
[InlineData("opengl")]
|
||||
[InlineData("gl46")]
|
||||
[InlineData("vulkan14")]
|
||||
[InlineData("legacy")]
|
||||
[InlineData("simple")]
|
||||
[InlineData("experimental")]
|
||||
public void A_renderer_word_the_simulator_reads_as_another_stays_until_changed(string word)
|
||||
{
|
||||
var installation = WithHome(new InMemoryFileSystem().WithFile(UserIni, $"gfxrenderer {word}\n"));
|
||||
@@ -936,46 +939,33 @@ public class SettingsStoreTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Anti_aliasing_is_saved_below_multisampling_for_the_later_line_to_count()
|
||||
public void The_two_anti_aliasing_keys_untouched_keep_their_order()
|
||||
{
|
||||
var installation = WithHome(new InMemoryFileSystem().WithFile(UserIni, "gfx.antialiasing taa\nwidth 800\nmultisampling 2\n"));
|
||||
// Moving them would change which of the two the simulator goes by.
|
||||
const string ini = "gfx.antialiasing taa\nwidth 800\nmultisampling 2\n";
|
||||
var installation = WithHome(new InMemoryFileSystem().WithFile(UserIni, ini));
|
||||
installation.SettingsStore.Load();
|
||||
|
||||
installation.SettingsStore.Save();
|
||||
|
||||
string saved = SavedLines(installation);
|
||||
Assert.True(saved.IndexOf("multisampling ", StringComparison.Ordinal) < saved.IndexOf("gfx.antialiasing taa", StringComparison.Ordinal), saved);
|
||||
Assert.True(saved.IndexOf("gfx.antialiasing taa", StringComparison.Ordinal) < saved.IndexOf("multisampling 2", StringComparison.Ordinal), saved);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Anti_aliasing_left_to_multisampling_goes_from_the_file()
|
||||
public void A_chosen_anti_aliasing_is_saved_below_multisampling_for_the_later_line_to_count()
|
||||
{
|
||||
var installation = WithHome(new InMemoryFileSystem().WithFile(UserIni, "multisampling 2\ngfx.antialiasing taa\n"));
|
||||
var installation = WithHome(new InMemoryFileSystem().WithFile(UserIni, "gfx.antialiasing msaax4\nwidth 800\nmultisampling 2\n"));
|
||||
installation.SettingsStore.Load();
|
||||
|
||||
installation.SettingsStore.Settings.Extra["gfx.antialiasing"] = "";
|
||||
installation.SettingsStore.Settings.AntiAliasing = AntiAliasingMode.Taa;
|
||||
installation.SettingsStore.Save();
|
||||
|
||||
Assert.DoesNotContain("\ngfx.antialiasing", SavedLines(installation));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("TAA", "taa")]
|
||||
[InlineData(" dlaa ", "dlaa")]
|
||||
[InlineData("", "")]
|
||||
[InlineData("fxaa", "")]
|
||||
public void A_choice_reads_the_words_it_offers_and_else_the_default(string raw, string word)
|
||||
{
|
||||
Assert.Equal(word, SimulatorKeys.Named("gfx.antialiasing").ParseChoice(raw));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("4 6", "4 6")]
|
||||
[InlineData("4 6", "4 6")]
|
||||
[InlineData("5 5", "3 4")]
|
||||
public void A_choice_of_two_numbers_is_one_word(string raw, string word)
|
||||
{
|
||||
Assert.Equal(word, SimulatorKeys.Named("gfx.postfx.ao.quality").ParseChoice(raw));
|
||||
string saved = SavedLines(installation);
|
||||
Assert.True(saved.IndexOf("multisampling ", StringComparison.Ordinal) < saved.IndexOf("gfx.antialiasing taa", StringComparison.Ordinal), saved);
|
||||
var again = WithHome(installation.Files);
|
||||
again.SettingsStore.Load();
|
||||
Assert.Equal(AntiAliasingMode.Taa, again.SettingsStore.Settings.AntiAliasing);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -62,7 +62,7 @@ public sealed class AppServices
|
||||
SceneryFiles = new SceneryFileWatch(files, Sceneries, Library, State);
|
||||
|
||||
Executables = new ExecutableLocator(files, paths, environment, log);
|
||||
SettingsStore = new SettingsStore(files, clock, log, settingsPaths, new SettingsSerializer(), Executables);
|
||||
SettingsStore = new SettingsStore(files, clock, log, settingsPaths, new SettingsSerializer(dlssPlatform: !environment.IsMacOS), Executables);
|
||||
MissingVehicleLog = new MissingVehicleLog(SettingsStore.Settings, missingAssets, Library, log);
|
||||
Favorites = new FavoriteSceneries(files, log, settingsPaths.FavoritesPath());
|
||||
Tapes = new HaslerTapes(files, paths, log, clock, Timetables,
|
||||
|
||||
@@ -157,15 +157,7 @@ public sealed class SettingsStore
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var change in Changes(Settings))
|
||||
{
|
||||
if (change.After is null)
|
||||
_config.Remove(change.Key);
|
||||
else
|
||||
_config.Set(change.Key, change.After);
|
||||
}
|
||||
// Each sets the mode as the simulator reads it, so this one has to come later to count.
|
||||
_config.MoveAfter("gfx.antialiasing", "multisampling");
|
||||
ApplyChanges(_config, Changes(Settings));
|
||||
_synced = Render(Settings);
|
||||
|
||||
try
|
||||
@@ -184,6 +176,91 @@ public sealed class SettingsStore
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyChanges(ConfigFile config, IReadOnlyList<IniChange> changes)
|
||||
{
|
||||
foreach (var change in changes)
|
||||
{
|
||||
if (change.After is null)
|
||||
config.Remove(change.Key);
|
||||
else
|
||||
config.Set(change.Key, change.After);
|
||||
}
|
||||
|
||||
// Each sets the mode as the simulator reads it, so the new one has to come later to count.
|
||||
// Untouched, the two keep their order: moving them would change which one decides.
|
||||
if (changes.Any(change => change.Key is "gfx.antialiasing" or "multisampling"))
|
||||
config.MoveAfter("gfx.antialiasing", "multisampling");
|
||||
}
|
||||
|
||||
/// <summary>Whether the simulator can have DLSS on this platform at all.</summary>
|
||||
public bool DlssPlatform => _serializer.DlssPlatform;
|
||||
|
||||
/// <summary>
|
||||
/// Takes the settings of another eu07.ini (a backup, a file from another machine)
|
||||
/// into the current ones, keeping what belongs to this installation: the chosen
|
||||
/// simulator, its card, the last scenery and the window state. The lines of this
|
||||
/// user's file the starter does not manage stay as they are. Nothing is written until Save.
|
||||
/// </summary>
|
||||
public bool ImportFrom(string path)
|
||||
{
|
||||
ConfigFile imported;
|
||||
try
|
||||
{
|
||||
imported = ConfigFile.Parse(_files.ReadAllText(path, _encoding));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Log($"importing {path}", ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
var s = Settings;
|
||||
bool selectAutomatically = s.SelectExeAutomatically;
|
||||
string executable = s.ExecutablePath;
|
||||
var gpu = s.Gpu;
|
||||
string lastScenery = s.LastScenery;
|
||||
bool maximized = s.WindowMaximized;
|
||||
// Only read for the dependencies and never written, so they stay as this user's file has them.
|
||||
bool cabLampLight = s.CabLampLight;
|
||||
bool depthPrepassScene = s.DepthPrepassScene;
|
||||
|
||||
_serializer.Read(s, imported);
|
||||
|
||||
s.SelectExeAutomatically = selectAutomatically;
|
||||
s.ExecutablePath = executable;
|
||||
s.Gpu = gpu;
|
||||
s.LastScenery = lastScenery;
|
||||
s.WindowMaximized = maximized;
|
||||
s.CabLampLight = cabLampLight;
|
||||
s.DepthPrepassScene = depthPrepassScene;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the settings as a complete eu07.ini somewhere else - this user's file
|
||||
/// with the settings applied - leaving the file itself and its state alone.
|
||||
/// </summary>
|
||||
public bool ExportTo(string path)
|
||||
{
|
||||
var copy = ConfigFile.Parse(_config.ToText());
|
||||
ApplyChanges(copy, Changes(Settings));
|
||||
|
||||
try
|
||||
{
|
||||
string? directory = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
_files.CreateDirectory(directory);
|
||||
|
||||
_files.WriteAllBytesAtomic(path, _encoding.GetBytes(copy.ToText()));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Log($"exporting {path}", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Every key as <paramref name="settings"/> would put it, in the order they are written.</summary>
|
||||
public IReadOnlyDictionary<string, string> Render(SimulatorSettings settings)
|
||||
{
|
||||
|
||||
@@ -58,6 +58,9 @@ public sealed class ConfigFile
|
||||
|
||||
public bool Has(string key) => _index.ContainsKey(key);
|
||||
|
||||
/// <summary>The line the key is on, or -1. The simulator reads the file top down, so a later line wins.</summary>
|
||||
public int LineOf(string key) => _index.TryGetValue(key, out int i) ? i : -1;
|
||||
|
||||
/// <summary>Whether the line setting the key is one the simulator never gets to.</summary>
|
||||
public bool IsPastEnd(string key) =>
|
||||
_end >= 0 && _index.TryGetValue(key, out int line) && line > _end;
|
||||
|
||||
@@ -121,102 +121,75 @@ public sealed record GraphicsTop(
|
||||
|
||||
/// <summary>
|
||||
/// What only the simulators with the OpenGL 4.6 and Vulkan 1.4 renderers read, the others pass it
|
||||
/// over. High is what they do with nothing set. Left to the player: anti-aliasing by TAA or DLSS,
|
||||
/// frame generation, Reflex, the choice of the card, automatic exposure and the fitted cascades.
|
||||
/// over. High is what they do with nothing set. Left to the player: frame generation, Reflex, the
|
||||
/// choice of the card, automatic exposure, the fitted cascades and the bounced light of the cab.
|
||||
/// </summary>
|
||||
/// <param name="CabProbeInterval">gfx.cabprobe.interval, in frames: the lower the dearer.</param>
|
||||
/// <param name="RayTracing">gfx.raytracing: the Vulkan renderer's alone, OpenGL passes it over.</param>
|
||||
/// <param name="RayTracing">gfx.raytracing: the Vulkan renderer's alone, off on OpenGL.</param>
|
||||
public sealed record GraphicsNewRenderer(
|
||||
string LampShadows,
|
||||
string ContactShadows,
|
||||
string Occlusion,
|
||||
string OcclusionQuality,
|
||||
int LampShadows,
|
||||
int ContactShadows,
|
||||
int Occlusion,
|
||||
int OcclusionSlices,
|
||||
int OcclusionSteps,
|
||||
bool OcclusionLighting,
|
||||
string CabProbe,
|
||||
double CabProbeInterval,
|
||||
int CabProbe,
|
||||
int CabProbeInterval,
|
||||
bool CabProbeReflections,
|
||||
string ScreenReflections,
|
||||
int ScreenReflections,
|
||||
bool RayTracing,
|
||||
string Fog,
|
||||
string FogQuality,
|
||||
string Clouds,
|
||||
bool VolumetricFog,
|
||||
int FogQuality,
|
||||
int Clouds,
|
||||
bool CloudShadows,
|
||||
bool Grass,
|
||||
double GrassDistance,
|
||||
double GrassFade,
|
||||
int GrassDistance,
|
||||
double GrassDensity,
|
||||
double Precipitation,
|
||||
int Precipitation,
|
||||
bool Bloom)
|
||||
{
|
||||
private const string LampShadowsKey = "gfx.lights.shadows";
|
||||
private const string ContactShadowsKey = "gfx.contactshadows";
|
||||
private const string OcclusionKey = "gfx.postfx.ao";
|
||||
private const string OcclusionQualityKey = "gfx.postfx.ao.quality";
|
||||
private const string OcclusionLightingKey = "gfx.postfx.ao.lighting";
|
||||
private const string CabProbeKey = "gfx.cabprobe";
|
||||
private const string CabProbeIntervalKey = "gfx.cabprobe.interval";
|
||||
private const string CabProbeReflectionsKey = "gfx.cabprobe.reflections";
|
||||
private const string ScreenReflectionsKey = "gfx.ssr";
|
||||
private const string RayTracingKey = "gfx.raytracing";
|
||||
private const string FogKey = "gfx.fog";
|
||||
private const string FogQualityKey = "gfx.fog.quality";
|
||||
private const string CloudsKey = "gfx.clouds";
|
||||
private const string CloudShadowsKey = "gfx.clouds.shadows";
|
||||
private const string GrassKey = "gfx.grass";
|
||||
private const string GrassDistanceKey = "gfx.grass.distance";
|
||||
private const string GrassFadeKey = "gfx.grass.fadedistance";
|
||||
private const string GrassDensityKey = "gfx.grass.density";
|
||||
private const string PrecipitationKey = "gfx.precipitation.particles";
|
||||
private const string BloomKey = "gfx.postfx.bloom";
|
||||
|
||||
/// <summary>The eu07.ini keys these values live in, all of them rows of <see cref="SimulatorKeys"/>.</summary>
|
||||
/// <summary>The eu07.ini keys these values live in; the fade of the grass follows its distance.</summary>
|
||||
public static readonly IReadOnlyList<string> Keys = new[]
|
||||
{
|
||||
LampShadowsKey, ContactShadowsKey, OcclusionKey, OcclusionQualityKey, OcclusionLightingKey,
|
||||
CabProbeKey, CabProbeIntervalKey, CabProbeReflectionsKey, ScreenReflectionsKey, RayTracingKey,
|
||||
FogKey, FogQualityKey, CloudsKey, CloudShadowsKey,
|
||||
GrassKey, GrassDistanceKey, GrassFadeKey, GrassDensityKey, PrecipitationKey, BloomKey
|
||||
"gfx.lights.shadows", "gfx.contactshadows", "gfx.postfx.ao", "gfx.postfx.ao.quality", "gfx.postfx.ao.lighting",
|
||||
"gfx.cabprobe", "gfx.cabprobe.interval", "gfx.cabprobe.reflections", "gfx.ssr", "gfx.raytracing",
|
||||
"gfx.fog", "gfx.fog.quality", "gfx.clouds", "gfx.clouds.shadows",
|
||||
"gfx.grass", "gfx.grass.distance", "gfx.grass.fadedistance", "gfx.grass.density",
|
||||
"gfx.precipitation.particles", "gfx.postfx.bloom"
|
||||
};
|
||||
|
||||
public static GraphicsNewRenderer Of(SimulatorSettings s) =>
|
||||
new(WordOf(s, LampShadowsKey), WordOf(s, ContactShadowsKey), WordOf(s, OcclusionKey), WordOf(s, OcclusionQualityKey),
|
||||
GraphicsPreset.ToggleOf(s, OcclusionLightingKey), WordOf(s, CabProbeKey), GraphicsPreset.NumberOf(s, CabProbeIntervalKey),
|
||||
GraphicsPreset.ToggleOf(s, CabProbeReflectionsKey), WordOf(s, ScreenReflectionsKey), GraphicsPreset.ToggleOf(s, RayTracingKey),
|
||||
WordOf(s, FogKey), WordOf(s, FogQualityKey), WordOf(s, CloudsKey), GraphicsPreset.ToggleOf(s, CloudShadowsKey),
|
||||
GraphicsPreset.ToggleOf(s, GrassKey), GraphicsPreset.NumberOf(s, GrassDistanceKey), GraphicsPreset.NumberOf(s, GrassFadeKey),
|
||||
GraphicsPreset.NumberOf(s, GrassDensityKey), GraphicsPreset.NumberOf(s, PrecipitationKey), GraphicsPreset.ToggleOf(s, BloomKey));
|
||||
new(s.LightShadows, s.ContactShadows, s.AmbientOcclusion, s.AoSlices, s.AoSteps, s.AoLighting,
|
||||
s.CabProbe, s.CabProbeInterval, s.CabProbeReflections, s.Ssr, s.RayTracing,
|
||||
s.VolumetricFog, s.FogQuality, s.Clouds, s.CloudShadows,
|
||||
s.Grass, s.GrassDistance, s.GrassDensity, s.PrecipitationParticles, s.Bloom);
|
||||
|
||||
/// <summary>This level as it lands on <paramref name="s"/>: ray tracing on Vulkan only.</summary>
|
||||
public GraphicsNewRenderer For(SimulatorSettings s) =>
|
||||
GraphicsRules.RayTracingAllowed(s) ? this : this with { RayTracing = false };
|
||||
|
||||
public void ApplyTo(SimulatorSettings s)
|
||||
{
|
||||
void Number(string key, double value) => s.Extra[key] = value.ToString(CultureInfo.InvariantCulture);
|
||||
void Toggle(string key, bool value) => s.Extra[key] = SimulatorKey.FormatToggle(value);
|
||||
|
||||
s.Extra[LampShadowsKey] = LampShadows;
|
||||
s.Extra[ContactShadowsKey] = ContactShadows;
|
||||
s.Extra[OcclusionKey] = Occlusion;
|
||||
s.Extra[OcclusionQualityKey] = OcclusionQuality;
|
||||
Toggle(OcclusionLightingKey, OcclusionLighting);
|
||||
s.Extra[CabProbeKey] = CabProbe;
|
||||
Number(CabProbeIntervalKey, CabProbeInterval);
|
||||
Toggle(CabProbeReflectionsKey, CabProbeReflections);
|
||||
s.Extra[ScreenReflectionsKey] = ScreenReflections;
|
||||
Toggle(RayTracingKey, RayTracing);
|
||||
s.Extra[FogKey] = Fog;
|
||||
s.Extra[FogQualityKey] = FogQuality;
|
||||
s.Extra[CloudsKey] = Clouds;
|
||||
Toggle(CloudShadowsKey, CloudShadows);
|
||||
Toggle(GrassKey, Grass);
|
||||
Number(GrassDistanceKey, GrassDistance);
|
||||
Number(GrassFadeKey, GrassFade);
|
||||
Number(GrassDensityKey, GrassDensity);
|
||||
Number(PrecipitationKey, Precipitation);
|
||||
Toggle(BloomKey, Bloom);
|
||||
}
|
||||
|
||||
private static string WordOf(SimulatorSettings s, string name)
|
||||
{
|
||||
var key = SimulatorKeys.Named(name);
|
||||
return key.ParseChoice(key.RawIn(s));
|
||||
s.LightShadows = LampShadows;
|
||||
s.ContactShadows = ContactShadows;
|
||||
s.AmbientOcclusion = Occlusion;
|
||||
s.AoSlices = OcclusionSlices;
|
||||
s.AoSteps = OcclusionSteps;
|
||||
s.AoLighting = OcclusionLighting;
|
||||
s.CabProbe = CabProbe;
|
||||
s.CabProbeInterval = CabProbeInterval;
|
||||
s.CabProbeReflections = CabProbeReflections;
|
||||
s.Ssr = ScreenReflections;
|
||||
s.RayTracing = RayTracing && GraphicsRules.RayTracingAllowed(s);
|
||||
s.VolumetricFog = VolumetricFog;
|
||||
s.FogQuality = FogQuality;
|
||||
s.Clouds = Clouds;
|
||||
s.CloudShadows = CloudShadows;
|
||||
s.Grass = Grass;
|
||||
s.GrassDistance = GrassDistance;
|
||||
s.GrassDensity = GrassDensity;
|
||||
s.PrecipitationParticles = Precipitation;
|
||||
s.Bloom = Bloom;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +201,8 @@ public sealed record GraphicsNewRenderer(
|
||||
/// two ends of the scale, which have <see cref="Extras"/>.
|
||||
/// </summary>
|
||||
/// <param name="NameKey">Its name's translation key.</param>
|
||||
/// <param name="CabShadowsRange">gfx.shadows.cab.range, in metres, read only by the legacy renderer.</param>
|
||||
/// <param name="AntiAliasing">Multisampling, as older simulators read it too. DLSS, once on, stays: no level does better.</param>
|
||||
/// <param name="ReflectionsRate">gfx.reflections.framerate, in updates a second.</param>
|
||||
/// <param name="DrawRange">basedrawrange, in metres. Below 2000 it changes nothing on screen: the renderer
|
||||
/// keeps at least that for signals and lights (opengl33renderer.cpp).</param>
|
||||
@@ -236,13 +211,12 @@ public sealed record GraphicsNewRenderer(
|
||||
/// <param name="BufferScale">starter.bufferscale, in percent. Above the screen over High: on a 4K one
|
||||
/// Ultra is a picture of 8K, multisampled on top.</param>
|
||||
/// <param name="DrawRangeFactor">gfx.drawrange.factor.max: how far the regulator may stretch the draw range.</param>
|
||||
/// <param name="CabShadowsRange">gfx.shadows.cab.range, in metres, read only by the legacy renderer.</param>
|
||||
public sealed record GraphicsPreset(
|
||||
string NameKey,
|
||||
int TextureSize,
|
||||
int CabTextureSize,
|
||||
double Anisotropy,
|
||||
int Multisampling,
|
||||
AntiAliasingMode AntiAliasing,
|
||||
int DynamicLights,
|
||||
int SmokeFidelity,
|
||||
bool Shadows,
|
||||
@@ -276,52 +250,52 @@ public sealed record GraphicsPreset(
|
||||
public static readonly IReadOnlyList<string> RowKeys = new[]
|
||||
{
|
||||
DrawRangeKey, DistanceFactorKey, SleeperKey, ReflectedInstancesKey, ReflectedVehiclesKey
|
||||
}.Concat(GraphicsNewRenderer.Keys).ToList();
|
||||
};
|
||||
|
||||
/// <summary>The eu07.ini keys a level sets.</summary>
|
||||
public static readonly IReadOnlyList<string> Keys = new[]
|
||||
{
|
||||
"maxtexturesize", "maxcabtexturesize", "anisotropicfiltering", "multisampling", "dynamiclights",
|
||||
"maxtexturesize", "maxcabtexturesize", "anisotropicfiltering", "multisampling", "gfx.antialiasing", "dynamiclights",
|
||||
"gfx.smoke.fidelity", "shadows", "gfx.shadowmap.enabled", "shadowtune", "gfx.shadow.rank.cutoff",
|
||||
"gfx.envmap.enabled", "gfx.reflections.fidelity", "gfx.reflections.framerate", "gfx.extraeffects",
|
||||
"splinefidelity", DrawRangeKey, DistanceFactorKey, "starter.bufferscale", SleeperKey,
|
||||
"splinefidelity", DrawRangeKey, DistanceFactorKey, "starter.bufferscale", "gfx.buffer.percent", SleeperKey,
|
||||
"gfx.drawrange.factor.max", ReflectedInstancesKey, ReflectedVehiclesKey, "gfx.shadows.cab.range"
|
||||
}.Concat(GraphicsNewRenderer.Keys).ToList();
|
||||
|
||||
/// <summary>The last resort: no shadows, no reflections, no effects, no smoke, a softer picture.</summary>
|
||||
public static readonly GraphicsPreset Minimal = new(
|
||||
"PresetMinimal", TextureSize: 512, CabTextureSize: 512, Anisotropy: 1, Multisampling: 0,
|
||||
"PresetMinimal", TextureSize: 512, CabTextureSize: 512, Anisotropy: 1, AntiAliasing: AntiAliasingMode.Off,
|
||||
DynamicLights: 1, SmokeFidelity: 1, Shadows: false, ShadowMap: 512, ShadowRange: 75, ShadowRank: 1,
|
||||
EnvMap: false, ReflectionsFidelity: 0, ReflectionsRate: 1 / 300.0, ExtraEffects: false,
|
||||
SplineFidelity: 1, DrawRange: 2000, DistanceFactor: 0.6, BufferScale: 70,
|
||||
SleeperDistance: 100, DrawRangeFactor: 1, ReflectedInstances: 250, ReflectedVehicles: 50, CabShadowsRange: 0,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "no", ContactShadows: "no", Occlusion: "no", OcclusionQuality: "3 4",
|
||||
OcclusionLighting: false, CabProbe: "no", CabProbeInterval: 8, CabProbeReflections: false, ScreenReflections: "no",
|
||||
RayTracing: false, Fog: "analytic", FogQuality: "low", Clouds: "no", CloudShadows: false, Grass: false,
|
||||
GrassDistance: 30, GrassFade: 40, GrassDensity: 0.25, Precipitation: 16384, Bloom: false),
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 0, ContactShadows: 0, Occlusion: 0, OcclusionSlices: 2, OcclusionSteps: 3,
|
||||
OcclusionLighting: false, CabProbe: 0, CabProbeInterval: 8, CabProbeReflections: false, ScreenReflections: 0,
|
||||
RayTracing: false, VolumetricFog: false, FogQuality: 1, Clouds: 0, CloudShadows: false, Grass: false,
|
||||
GrassDistance: 30, GrassDensity: 0.25, Precipitation: 16384, Bloom: false),
|
||||
Extras: new GraphicsExtras(MotionBlur: false, ChromaticAberration: false, Smoke: false, PythonUpdateMs: 800));
|
||||
|
||||
public static readonly GraphicsPreset Low = new(
|
||||
"PresetLow", TextureSize: 1024, CabTextureSize: 1024, Anisotropy: 2, Multisampling: 0,
|
||||
"PresetLow", TextureSize: 1024, CabTextureSize: 1024, Anisotropy: 2, AntiAliasing: AntiAliasingMode.Off,
|
||||
DynamicLights: 3, SmokeFidelity: 1, Shadows: true, ShadowMap: 1024, ShadowRange: 125, ShadowRank: 2,
|
||||
EnvMap: true, ReflectionsFidelity: 0, ReflectionsRate: 1 / 60.0, ExtraEffects: true,
|
||||
SplineFidelity: 1, DrawRange: 2000, DistanceFactor: 0.7, BufferScale: 80,
|
||||
SleeperDistance: 150, DrawRangeFactor: 1.5, ReflectedInstances: 400, ReflectedVehicles: 100, CabShadowsRange: 0,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "low", ContactShadows: "no", Occlusion: "ssao", OcclusionQuality: "3 4",
|
||||
OcclusionLighting: false, CabProbe: "no", CabProbeInterval: 8, CabProbeReflections: false, ScreenReflections: "low",
|
||||
RayTracing: false, Fog: "volumetric", FogQuality: "low", Clouds: "low", CloudShadows: false, Grass: true,
|
||||
GrassDistance: 40, GrassFade: 50, GrassDensity: 0.5, Precipitation: 32768, Bloom: true));
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 1, ContactShadows: 0, Occlusion: 1, OcclusionSlices: 2, OcclusionSteps: 3,
|
||||
OcclusionLighting: false, CabProbe: 0, CabProbeInterval: 8, CabProbeReflections: false, ScreenReflections: 1,
|
||||
RayTracing: false, VolumetricFog: true, FogQuality: 1, Clouds: 1, CloudShadows: false, Grass: true,
|
||||
GrassDistance: 40, GrassDensity: 0.5, Precipitation: 32768, Bloom: true));
|
||||
|
||||
public static readonly GraphicsPreset Medium = new(
|
||||
"PresetMedium", TextureSize: 2048, CabTextureSize: 2048, Anisotropy: 4, Multisampling: 1,
|
||||
"PresetMedium", TextureSize: 2048, CabTextureSize: 2048, Anisotropy: 4, AntiAliasing: AntiAliasingMode.Msaa2,
|
||||
DynamicLights: 5, SmokeFidelity: 2, Shadows: true, ShadowMap: 1024, ShadowRange: 175, ShadowRank: 2,
|
||||
EnvMap: true, ReflectionsFidelity: 1, ReflectionsRate: 1 / 30.0, ExtraEffects: true,
|
||||
SplineFidelity: 2, DrawRange: 2250, DistanceFactor: 0.85, BufferScale: 90,
|
||||
SleeperDistance: 200, DrawRangeFactor: 2, ReflectedInstances: 550, ReflectedVehicles: 150, CabShadowsRange: 20,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "low", ContactShadows: "no", Occlusion: "ssao", OcclusionQuality: "3 4",
|
||||
OcclusionLighting: false, CabProbe: "low", CabProbeInterval: 8, CabProbeReflections: true, ScreenReflections: "low",
|
||||
RayTracing: false, Fog: "volumetric", FogQuality: "low", Clouds: "low", CloudShadows: true, Grass: true,
|
||||
GrassDistance: 50, GrassFade: 60, GrassDensity: 0.75, Precipitation: 49152, Bloom: true));
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 1, ContactShadows: 0, Occlusion: 1, OcclusionSlices: 3, OcclusionSteps: 4,
|
||||
OcclusionLighting: false, CabProbe: 1, CabProbeInterval: 8, CabProbeReflections: true, ScreenReflections: 1,
|
||||
RayTracing: false, VolumetricFog: true, FogQuality: 1, Clouds: 1, CloudShadows: true, Grass: true,
|
||||
GrassDistance: 50, GrassDensity: 0.75, Precipitation: 32768, Bloom: true));
|
||||
|
||||
/// <summary>
|
||||
/// Where a player with no settings of their own starts. The simulator's own values (Globals.h),
|
||||
@@ -329,27 +303,27 @@ public sealed record GraphicsPreset(
|
||||
/// with levels to go under this one.
|
||||
/// </summary>
|
||||
public static readonly GraphicsPreset High = new(
|
||||
"PresetHigh", TextureSize: 4096, CabTextureSize: 4096, Anisotropy: 8, Multisampling: 2,
|
||||
"PresetHigh", TextureSize: 4096, CabTextureSize: 4096, Anisotropy: 8, AntiAliasing: AntiAliasingMode.Msaa4,
|
||||
DynamicLights: 7, SmokeFidelity: 2, Shadows: true, ShadowMap: 2048, ShadowRange: 250, ShadowRank: 3,
|
||||
EnvMap: true, ReflectionsFidelity: 1, ReflectionsRate: 0.1, ExtraEffects: true,
|
||||
SplineFidelity: 2, DrawRange: 2500, DistanceFactor: 1, BufferScale: 100,
|
||||
SleeperDistance: 250, DrawRangeFactor: 3, ReflectedInstances: 750, ReflectedVehicles: 250, CabShadowsRange: 40,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "medium", ContactShadows: "no", Occlusion: "gtao", OcclusionQuality: "3 4",
|
||||
OcclusionLighting: true, CabProbe: "medium", CabProbeInterval: 4, CabProbeReflections: true, ScreenReflections: "medium",
|
||||
RayTracing: false, Fog: "volumetric", FogQuality: "medium", Clouds: "medium", CloudShadows: true, Grass: true,
|
||||
GrassDistance: 60, GrassFade: 70, GrassDensity: 1, Precipitation: 65536, Bloom: true));
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 2, ContactShadows: 0, Occlusion: 2, OcclusionSlices: 3, OcclusionSteps: 4,
|
||||
OcclusionLighting: true, CabProbe: 2, CabProbeInterval: 4, CabProbeReflections: true, ScreenReflections: 2,
|
||||
RayTracing: false, VolumetricFog: true, FogQuality: 2, Clouds: 2, CloudShadows: true, Grass: true,
|
||||
GrassDistance: 60, GrassDensity: 1, Precipitation: 65536, Bloom: true));
|
||||
|
||||
/// <summary>For a strong card. A map of 4096 doubles the cascades, so the range here reaches 800 m.</summary>
|
||||
public static readonly GraphicsPreset VeryHigh = new(
|
||||
"PresetVeryHigh", TextureSize: 8192, CabTextureSize: 8192, Anisotropy: 16, Multisampling: 3,
|
||||
"PresetVeryHigh", TextureSize: 8192, CabTextureSize: 8192, Anisotropy: 16, AntiAliasing: AntiAliasingMode.Msaa8,
|
||||
DynamicLights: 7, SmokeFidelity: 3, Shadows: true, ShadowMap: 4096, ShadowRange: 400, ShadowRank: 3,
|
||||
EnvMap: true, ReflectionsFidelity: 2, ReflectionsRate: 2, ExtraEffects: true,
|
||||
SplineFidelity: 3, DrawRange: 5000, DistanceFactor: 2, BufferScale: 150,
|
||||
SleeperDistance: 2000, DrawRangeFactor: 3, ReflectedInstances: 1500, ReflectedVehicles: 1000, CabShadowsRange: 70,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "high", ContactShadows: "medium", Occlusion: "gtao", OcclusionQuality: "4 6",
|
||||
OcclusionLighting: true, CabProbe: "high", CabProbeInterval: 3, CabProbeReflections: true, ScreenReflections: "high",
|
||||
RayTracing: false, Fog: "volumetric", FogQuality: "high", Clouds: "high", CloudShadows: true, Grass: true,
|
||||
GrassDistance: 120, GrassFade: 140, GrassDensity: 1.5, Precipitation: 98304, Bloom: true));
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 3, ContactShadows: 2, Occlusion: 2, OcclusionSlices: 4, OcclusionSteps: 6,
|
||||
OcclusionLighting: true, CabProbe: 3, CabProbeInterval: 3, CabProbeReflections: true, ScreenReflections: 3,
|
||||
RayTracing: false, VolumetricFog: true, FogQuality: 3, Clouds: 3, CloudShadows: true, Grass: true,
|
||||
GrassDistance: 120, GrassDensity: 1.5, Precipitation: 131072, Bloom: true));
|
||||
|
||||
/// <summary>
|
||||
/// Every value at the top of what the screen offers. Not the best picture throughout: a map
|
||||
@@ -357,15 +331,15 @@ public sealed record GraphicsPreset(
|
||||
/// than at <see cref="VeryHigh"/>.
|
||||
/// </summary>
|
||||
public static readonly GraphicsPreset Ultra = new(
|
||||
"PresetUltra", TextureSize: 8192, CabTextureSize: 8192, Anisotropy: 16, Multisampling: 3,
|
||||
"PresetUltra", TextureSize: 8192, CabTextureSize: 8192, Anisotropy: 16, AntiAliasing: AntiAliasingMode.Msaa8,
|
||||
DynamicLights: 7, SmokeFidelity: 4, Shadows: true, ShadowMap: 8192, ShadowRange: 600, ShadowRank: 3,
|
||||
EnvMap: true, ReflectionsFidelity: 2, ReflectionsRate: 60, ExtraEffects: true,
|
||||
SplineFidelity: 4, DrawRange: 10000, DistanceFactor: 3, BufferScale: 200,
|
||||
SleeperDistance: 5000, DrawRangeFactor: 3, ReflectedInstances: 3000, ReflectedVehicles: 2000, CabShadowsRange: 100,
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: "high", ContactShadows: "high", Occlusion: "gtao", OcclusionQuality: "6 8",
|
||||
OcclusionLighting: true, CabProbe: "high", CabProbeInterval: 2, CabProbeReflections: true, ScreenReflections: "high",
|
||||
RayTracing: true, Fog: "volumetric", FogQuality: "ultra", Clouds: "ultra", CloudShadows: true, Grass: true,
|
||||
GrassDistance: 300, GrassFade: 350, GrassDensity: 2, Precipitation: 131072, Bloom: true),
|
||||
NewRenderer: new GraphicsNewRenderer(LampShadows: 3, ContactShadows: 3, Occlusion: 2, OcclusionSlices: 6, OcclusionSteps: 8,
|
||||
OcclusionLighting: true, CabProbe: 3, CabProbeInterval: 2, CabProbeReflections: true, ScreenReflections: 3,
|
||||
RayTracing: true, VolumetricFog: true, FogQuality: 4, Clouds: 4, CloudShadows: true, Grass: true,
|
||||
GrassDistance: 300, GrassDensity: 2, Precipitation: 262144, Bloom: true),
|
||||
Extras: new GraphicsExtras(MotionBlur: true, ChromaticAberration: true, Smoke: true, PythonUpdateMs: 200),
|
||||
Top: new GraphicsTop(ShadowAngleLimit: 0.2, TargetFps: 0, ScreenWindowFps: 200, TextureRelease: 0,
|
||||
Screens: true, ScreenMipmaps: true, CompressTextures: false, SkipDecor: false,
|
||||
@@ -378,7 +352,9 @@ public sealed record GraphicsPreset(
|
||||
s.MaxTextureSize = TextureSize;
|
||||
s.MaxCabTextureSize = CabTextureSize;
|
||||
s.TextureFiltering = Anisotropy;
|
||||
s.Multisampling = Multisampling;
|
||||
if (!GraphicsRules.IsDlss(s.AntiAliasing))
|
||||
s.AntiAliasing = AntiAliasing;
|
||||
s.CabShadowsRange = CabShadowsRange;
|
||||
s.DynamicLights = DynamicLights;
|
||||
s.SmokeFidelity = SmokeFidelity;
|
||||
s.RenderShadows = Shadows;
|
||||
@@ -397,7 +373,6 @@ public sealed record GraphicsPreset(
|
||||
s.DrawRangeFactor = DrawRangeFactor;
|
||||
s.Extra[ReflectedInstancesKey] = ReflectedInstances.ToString(CultureInfo.InvariantCulture);
|
||||
s.Extra[ReflectedVehiclesKey] = ReflectedVehicles.ToString(CultureInfo.InvariantCulture);
|
||||
s.CabShadowsRange = CabShadowsRange;
|
||||
NewRenderer.ApplyTo(s);
|
||||
Extras?.ApplyTo(s);
|
||||
Top?.ApplyTo(s);
|
||||
@@ -406,7 +381,7 @@ public sealed record GraphicsPreset(
|
||||
/// <summary>Whether <paramref name="s"/> is at this level throughout.</summary>
|
||||
public bool Matches(SimulatorSettings s) =>
|
||||
s.MaxTextureSize == TextureSize && s.MaxCabTextureSize == CabTextureSize &&
|
||||
Near(s.TextureFiltering, Anisotropy) && s.Multisampling == Multisampling &&
|
||||
Near(s.TextureFiltering, Anisotropy) && (GraphicsRules.IsDlss(s.AntiAliasing) || s.AntiAliasing == AntiAliasing) &&
|
||||
s.DynamicLights == DynamicLights && s.SmokeFidelity == SmokeFidelity &&
|
||||
s.RenderShadows == Shadows && s.ShadowMapResolution == ShadowMap &&
|
||||
s.ShadowProjectionRange == ShadowRange && s.ShadowRankCutoff == ShadowRank &&
|
||||
@@ -419,7 +394,7 @@ public sealed record GraphicsPreset(
|
||||
Near(NumberOf(s, ReflectedInstancesKey), ReflectedInstances) &&
|
||||
Near(NumberOf(s, ReflectedVehiclesKey), ReflectedVehicles) &&
|
||||
s.CabShadowsRange == CabShadowsRange &&
|
||||
GraphicsNewRenderer.Of(s) == NewRenderer &&
|
||||
GraphicsNewRenderer.Of(s) == NewRenderer.For(s) &&
|
||||
(Extras is null || GraphicsExtras.Of(s) == Extras) &&
|
||||
(Top is null || GraphicsTop.Of(s) == Top);
|
||||
|
||||
@@ -442,7 +417,7 @@ public sealed record GraphicsPreset(
|
||||
|
||||
/// <summary>
|
||||
/// A part of the picture with a level of its own, as its section on the screen has it. The rest
|
||||
/// of a level - the buffer, the frame pacing, the sky and the cab - goes only with the whole.
|
||||
/// of a level - the buffer, the anti-aliasing, the post-processing switches, the frame pacing, the sky and the cab - goes only with the whole.
|
||||
/// </summary>
|
||||
/// <param name="Keys">The eu07.ini keys it sets.</param>
|
||||
public sealed record GraphicsGroup(IReadOnlyList<string> Keys)
|
||||
@@ -455,31 +430,42 @@ public sealed record GraphicsGroup(IReadOnlyList<string> Keys)
|
||||
|
||||
public static readonly GraphicsGroup Textures = new(new[]
|
||||
{
|
||||
"maxtexturesize", "maxcabtexturesize", "anisotropicfiltering", "multisampling",
|
||||
"maxtexturesize", "maxcabtexturesize", "anisotropicfiltering",
|
||||
"compresstex", GraphicsTop.TextureReleaseKey
|
||||
});
|
||||
|
||||
public static readonly GraphicsGroup Effects = new(new[]
|
||||
{
|
||||
"dynamiclights", "gfx.smoke.fidelity", "gfx.extraeffects", "gfx.postfx.motionblur.enabled",
|
||||
"gfx.postfx.chromaticaberration.enabled", "gfx.smoke"
|
||||
});
|
||||
|
||||
public static readonly GraphicsGroup Shadows = new(new[]
|
||||
{
|
||||
"shadows", "gfx.shadowmap.enabled", "shadowtune", "gfx.shadow.rank.cutoff",
|
||||
"gfx.shadow.angle.min", "gfx.shadows.cab.range"
|
||||
"shadows", "gfx.shadowmap.enabled", "shadowtune", "gfx.shadow.rank.cutoff", "gfx.shadow.angle.min", "gfx.shadows.cab.range"
|
||||
});
|
||||
|
||||
public static readonly GraphicsGroup Lights = new(new[]
|
||||
{
|
||||
"dynamiclights", "gfx.lights.shadows", "gfx.contactshadows", "gfx.postfx.ao", "gfx.postfx.ao.quality",
|
||||
"gfx.postfx.ao.lighting", "gfx.cabprobe", "gfx.cabprobe.interval", "gfx.cabprobe.reflections"
|
||||
});
|
||||
|
||||
public static readonly GraphicsGroup Reflections = new(new[]
|
||||
{
|
||||
"gfx.envmap.enabled", "gfx.reflections.fidelity", "gfx.reflections.framerate",
|
||||
GraphicsPreset.ReflectedInstancesKey, GraphicsPreset.ReflectedVehiclesKey
|
||||
GraphicsPreset.ReflectedInstancesKey, GraphicsPreset.ReflectedVehiclesKey, "gfx.ssr", "gfx.raytracing"
|
||||
});
|
||||
|
||||
public static readonly GraphicsGroup NewRenderer = new(GraphicsNewRenderer.Keys);
|
||||
public static readonly GraphicsGroup Atmosphere = new(new[]
|
||||
{
|
||||
"gfx.fog", "gfx.fog.quality", "gfx.clouds", "gfx.clouds.shadows"
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyList<GraphicsGroup> All = new[] { DrawRange, Textures, Effects, Shadows, Reflections, NewRenderer };
|
||||
public static readonly GraphicsGroup Nature = new(new[]
|
||||
{
|
||||
"gfx.grass", "gfx.grass.distance", "gfx.grass.fadedistance", "gfx.grass.density",
|
||||
"gfx.smoke", "gfx.smoke.fidelity", "gfx.precipitation.particles"
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyList<GraphicsGroup> All = new[]
|
||||
{
|
||||
DrawRange, Textures, Shadows, Lights, Reflections, Atmosphere, Nature
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>What applying a level touched.</summary>
|
||||
|
||||
126
StarterNG/Domain/Settings/GraphicsRules.cs
Normal file
126
StarterNG/Domain/Settings/GraphicsRules.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
namespace StarterNG.Domain.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// What the simulator does with combinations of graphics settings, mirrored here so
|
||||
/// the starter only offers what takes effect and writes eu07.ini the way the
|
||||
/// simulator will run it (utilities/Globals.cpp, rendering/vulkan14, rendering/opengl46).
|
||||
/// </summary>
|
||||
public static class GraphicsRules
|
||||
{
|
||||
public static bool IsDlss(AntiAliasingMode mode) => mode is AntiAliasingMode.Dlss or AntiAliasingMode.Dlaa;
|
||||
|
||||
public static bool IsTemporal(AntiAliasingMode mode) => mode == AntiAliasingMode.Taa || IsDlss(mode);
|
||||
|
||||
public static bool IsVulkan(SimulatorSettings s) => s.Backend == GraphicsBackend.Vulkan;
|
||||
|
||||
/// <summary>
|
||||
/// DLSS is the Vulkan renderer's only (the OpenGL one takes TAA instead), and the
|
||||
/// DLSS SDK has no macOS libraries.
|
||||
/// </summary>
|
||||
public static bool DlssAllowed(SimulatorSettings s, bool dlssPlatform) => dlssPlatform && IsVulkan(s);
|
||||
|
||||
public static bool DlssActive(SimulatorSettings s, bool dlssPlatform) =>
|
||||
DlssAllowed(s, dlssPlatform) && IsDlss(s.AntiAliasing);
|
||||
|
||||
/// <summary>The frame generation goes with gfx.antialiasing dlss or dlaa, nothing else.</summary>
|
||||
public static bool FrameGenerationAllowed(SimulatorSettings s, bool dlssPlatform) => DlssActive(s, dlssPlatform);
|
||||
|
||||
/// <summary>Reflex (VK_NV_low_latency2) is the Vulkan renderer's only.</summary>
|
||||
public static bool ReflexAllowed(SimulatorSettings s) => IsVulkan(s);
|
||||
|
||||
/// <summary>The frame generation turns Reflex on whatever gfx.reflex says.</summary>
|
||||
public static bool ReflexForced(SimulatorSettings s, bool dlssPlatform) =>
|
||||
FrameGenerationAllowed(s, dlssPlatform) && s.FrameGeneration > 1;
|
||||
|
||||
/// <summary>Ray traced reflections: the Vulkan renderer on a GPU with ray queries.</summary>
|
||||
public static bool RayTracingAllowed(SimulatorSettings s) => IsVulkan(s);
|
||||
|
||||
/// <summary>The render scale is ignored by DLAA, which always draws at the size of the window.</summary>
|
||||
public static bool BufferScaleUsed(SimulatorSettings s, bool dlssPlatform) =>
|
||||
!(DlssActive(s, dlssPlatform) && s.AntiAliasing == AntiAliasingMode.Dlaa);
|
||||
|
||||
/// <summary>TAA and DLSS run in the post-processing which gfx.skippipeline leaves out.</summary>
|
||||
public static bool TemporalWithoutPipeline(SimulatorSettings s) => s.SkipPipeline && IsTemporal(s.AntiAliasing);
|
||||
|
||||
/// <summary>With the clustered lights the headlights come from the clusters; dynamiclights only caps the old path.</summary>
|
||||
public static bool DynamicLightsUsed(SimulatorSettings s) => !s.LightsClustered;
|
||||
|
||||
/// <summary>The ambient occlusion goes into the lighting only with GTAO.</summary>
|
||||
public static bool AoLightingUsed(SimulatorSettings s) => s.AmbientOcclusion == 2;
|
||||
|
||||
/// <summary>
|
||||
/// The AO in the lighting needs the depth of the whole scene drawn before its colour. SSR, contact
|
||||
/// shadows and gfx.depthprepass.scene draw it anyway; without them it is an extra pass (CPU time on OpenGL).
|
||||
/// </summary>
|
||||
public static bool AoLightingAddsDepthPrepass(SimulatorSettings s) =>
|
||||
AoLightingUsed(s) && s.AoLighting && s.Ssr == 0 && s.ContactShadows == 0 && !s.DepthPrepassScene;
|
||||
|
||||
public static bool CabProbeUsed(SimulatorSettings s) => s.CabProbe > 0;
|
||||
|
||||
/// <summary>
|
||||
/// The light bounced around the cab comes from the cab lamp as a light, which needs the clustered lights
|
||||
/// and gfx.lights.cab; without them the probe gives the reflections only.
|
||||
/// </summary>
|
||||
public static bool CabProbeLights(SimulatorSettings s) => CabProbeUsed(s) && s.LightsClustered && s.CabLampLight;
|
||||
|
||||
/// <summary>
|
||||
/// Brings the settings to what the simulator would run with: the Vulkan-only
|
||||
/// features off on OpenGL, DLSS falling back to TAA, values within the ranges
|
||||
/// the simulator clamps them to.
|
||||
/// </summary>
|
||||
public static void Normalize(SimulatorSettings s, bool dlssPlatform)
|
||||
{
|
||||
if (IsDlss(s.AntiAliasing) && !DlssAllowed(s, dlssPlatform))
|
||||
s.AntiAliasing = AntiAliasingMode.Taa;
|
||||
|
||||
s.FrameGeneration = FrameGenerationAllowed(s, dlssPlatform) ? Clamp(s.FrameGeneration, 1, 4) : 1;
|
||||
s.Reflex = ReflexAllowed(s) ? Clamp(s.Reflex, 0, 2) : 0;
|
||||
if (!RayTracingAllowed(s))
|
||||
s.RayTracing = false;
|
||||
|
||||
if (!IsKnownDlssPreset(s.DlssPreset))
|
||||
s.DlssPreset = "default";
|
||||
|
||||
s.MaxTextureSize = PowerOfTwo(s.MaxTextureSize, 64, 8192);
|
||||
s.MaxCabTextureSize = PowerOfTwo(s.MaxCabTextureSize, 512, 8192);
|
||||
s.ShadowMapResolution = PowerOfTwo(s.ShadowMapResolution, 512, 8192);
|
||||
s.BufferScalePercent = Clamp(s.BufferScalePercent, 25, 200);
|
||||
s.LightShadows = Clamp(s.LightShadows, 0, 3);
|
||||
s.ContactShadows = Clamp(s.ContactShadows, 0, 3);
|
||||
s.AmbientOcclusion = Clamp(s.AmbientOcclusion, 0, 2);
|
||||
s.AoSlices = Clamp(s.AoSlices, 1, 8);
|
||||
s.AoSteps = Clamp(s.AoSteps, 1, 16);
|
||||
s.CabProbe = Clamp(s.CabProbe, 0, 3);
|
||||
s.CabProbeInterval = Clamp(s.CabProbeInterval, 1, 120);
|
||||
s.CabProbeBounce = s.CabProbeBounce < 0 ? 0 : (s.CabProbeBounce > 4 ? 4 : s.CabProbeBounce);
|
||||
s.Ssr = Clamp(s.Ssr, 0, 3);
|
||||
s.RayTracingRange = Clamp(s.RayTracingRange, 10, 5000);
|
||||
s.FogQuality = Clamp(s.FogQuality, 1, 4);
|
||||
s.Clouds = Clamp(s.Clouds, 0, 4);
|
||||
s.GrassDistance = Clamp(s.GrassDistance, 5, 500);
|
||||
s.GrassDensity = s.GrassDensity < 0 ? 0 : (s.GrassDensity > 4 ? 4 : s.GrassDensity);
|
||||
s.PrecipitationParticles = Clamp(s.PrecipitationParticles, 0, 1 << 20);
|
||||
}
|
||||
|
||||
public static readonly string[] DlssPresets = { "default", "j", "k", "l", "m" };
|
||||
|
||||
public static bool IsKnownDlssPreset(string? preset)
|
||||
{
|
||||
foreach (string known in DlssPresets)
|
||||
if (string.Equals(known, preset, System.StringComparison.OrdinalIgnoreCase))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int Clamp(int v, int lo, int hi) => v < lo ? lo : (v > hi ? hi : v);
|
||||
|
||||
/// <summary>The power of two nearest below, as the simulator rounds texture and shadow map sizes.</summary>
|
||||
private static int PowerOfTwo(int v, int lo, int hi)
|
||||
{
|
||||
v = Clamp(v, lo, hi);
|
||||
int p = lo;
|
||||
while (p * 2 <= v)
|
||||
p *= 2;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -128,5 +128,5 @@ public static class SettingReach
|
||||
_ => RendererKind.Legacy
|
||||
};
|
||||
|
||||
private static bool IsVulkan(string renderer) => renderer.ToLowerInvariant() is "vulkan" or "vulkan14";
|
||||
public static bool IsVulkan(string renderer) => renderer.ToLowerInvariant() is "vulkan" or "vulkan14";
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
|
||||
namespace StarterNG.Domain.Settings;
|
||||
|
||||
public enum SimulatorKeyKind { Toggle, Number, Text, Choice }
|
||||
public enum SimulatorKeyKind { Toggle, Number, Text }
|
||||
|
||||
/// <summary>
|
||||
/// An eu07.ini key the simulator reads that needs no logic of the starter's own:
|
||||
@@ -24,25 +24,13 @@ public sealed record SimulatorKey(
|
||||
double Step = 1,
|
||||
string Unit = "",
|
||||
bool ZeroIsOff = false,
|
||||
int Repeat = 1,
|
||||
string[]? Words = null)
|
||||
int Repeat = 1)
|
||||
{
|
||||
/// <summary>The label's translation key; the explanation's adds "Desc".</summary>
|
||||
public string LabelKey => "Ini." + Key;
|
||||
|
||||
public string DescriptionKey => LabelKey + ".Desc";
|
||||
|
||||
/// <summary>The translation key of a word of a choice; the empty one leaves the key out of the file.</summary>
|
||||
public static string WordKey(string word) =>
|
||||
"IniWord." + (word.Length == 0 ? "same" : word.Replace(' ', '_'));
|
||||
|
||||
/// <summary>The word of <paramref name="raw"/> among those offered, or else the default: the row then shows that and leaves the file alone.</summary>
|
||||
public string ParseChoice(string raw)
|
||||
{
|
||||
string word = string.Join(' ', raw.ToLowerInvariant().Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries));
|
||||
return Words is not null && Words.Contains(word) ? word : Default;
|
||||
}
|
||||
|
||||
public static bool ParseToggle(string raw) =>
|
||||
FirstToken(raw).ToLowerInvariant() is "yes" or "true" or "1" or "tak";
|
||||
|
||||
@@ -81,8 +69,6 @@ public static class SimulatorKeys
|
||||
public const string Physics = "physics";
|
||||
public const string Advanced = "advanced";
|
||||
|
||||
private const string NewRenderer = "GfxColNewRenderer";
|
||||
|
||||
private static SimulatorKey Toggle(string key, bool value, string category, string section) =>
|
||||
new(key, SimulatorKeyKind.Toggle, SimulatorKey.FormatToggle(value), category, section);
|
||||
|
||||
@@ -95,9 +81,6 @@ public static class SimulatorKeys
|
||||
private static SimulatorKey Text(string key, string category, string section) =>
|
||||
new(key, SimulatorKeyKind.Text, string.Empty, category, section);
|
||||
|
||||
private static SimulatorKey Choice(string key, string value, string category, string section, params string[] words) =>
|
||||
new(key, SimulatorKeyKind.Choice, value, category, section, Words: words);
|
||||
|
||||
public static SimulatorKey Named(string key) => All.First(k => k.Key == key);
|
||||
|
||||
public static IReadOnlyList<SimulatorKey> All { get; } = new[]
|
||||
@@ -131,38 +114,6 @@ public static class SimulatorKeys
|
||||
Toggle("newaircouplers", true, Graphics, "IniSectionRanges"),
|
||||
Toggle("smoothtraction", true, Graphics, "IniSectionRanges"),
|
||||
|
||||
// Read by the OpenGL 4.6 and Vulkan 1.4 simulators; the older ones pass them over.
|
||||
Choice("gfx.antialiasing", "", Graphics, NewRenderer, "", "taa", "dlss", "dlaa"),
|
||||
Choice("gfx.dlss.preset", "default", Graphics, NewRenderer, "default", "k", "j", "m", "l"),
|
||||
Choice("gfx.framegeneration", "off", Graphics, NewRenderer, "off", "x2", "x3", "x4"),
|
||||
Choice("gfx.reflex", "off", Graphics, NewRenderer, "off", "on", "boost"),
|
||||
Toggle("gfx.raytracing", false, Graphics, NewRenderer),
|
||||
Number("gfx.raytracing.range", 500, Graphics, NewRenderer, 10, 5000, 10, " m"),
|
||||
Text("gfx.vulkan.device", Graphics, NewRenderer),
|
||||
Toggle("gfx.lights.clustered", true, Graphics, NewRenderer),
|
||||
Choice("gfx.lights.shadows", "medium", Graphics, NewRenderer, "no", "low", "medium", "high"),
|
||||
Choice("gfx.contactshadows", "no", Graphics, NewRenderer, "no", "low", "medium", "high"),
|
||||
Toggle("gfx.shadow.sdsm", false, Graphics, NewRenderer),
|
||||
Choice("gfx.postfx.ao", "gtao", Graphics, NewRenderer, "no", "ssao", "gtao"),
|
||||
Choice("gfx.postfx.ao.quality", "3 4", Graphics, NewRenderer, "3 4", "4 6", "6 8"),
|
||||
Toggle("gfx.postfx.ao.lighting", true, Graphics, NewRenderer),
|
||||
Choice("gfx.ssr", "medium", Graphics, NewRenderer, "no", "low", "medium", "high"),
|
||||
Choice("gfx.cabprobe", "medium", Graphics, NewRenderer, "no", "low", "medium", "high"),
|
||||
Number("gfx.cabprobe.interval", 4, Graphics, NewRenderer, 1, 16, 1),
|
||||
Toggle("gfx.cabprobe.reflections", true, Graphics, NewRenderer),
|
||||
Number("gfx.cabprobe.bounce", 1, Graphics, NewRenderer, 0, 4, 0.25),
|
||||
Choice("gfx.fog", "volumetric", Graphics, NewRenderer, "analytic", "volumetric"),
|
||||
Choice("gfx.fog.quality", "medium", Graphics, NewRenderer, "low", "medium", "high", "ultra"),
|
||||
Choice("gfx.clouds", "medium", Graphics, NewRenderer, "no", "low", "medium", "high", "ultra"),
|
||||
Toggle("gfx.clouds.shadows", true, Graphics, NewRenderer),
|
||||
Toggle("gfx.grass", true, Graphics, NewRenderer),
|
||||
Number("gfx.grass.distance", 60, Graphics, NewRenderer, 5, 300, 5, " m"),
|
||||
Number("gfx.grass.fadedistance", 70, Graphics, NewRenderer, 10, 350, 10, " m"),
|
||||
Number("gfx.grass.density", 1, Graphics, NewRenderer, 0, 2, 0.25, "×"),
|
||||
Number("gfx.precipitation.particles", 65536, Graphics, NewRenderer, 0, 131072, 16384),
|
||||
Toggle("gfx.postfx.bloom", true, Graphics, NewRenderer),
|
||||
Toggle("gfx.postfx.autoexposure", true, Graphics, NewRenderer),
|
||||
|
||||
Number("sound.maxsources", 30, Sound, "IniSectionAudio", 8, 256, 8),
|
||||
Toggle("sound.asyncload", false, Sound, "IniSectionAudio"),
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@ public enum ConsistReadyOverride { Scenery = 0, AlwaysCold = 1, AlwaysReady = 2
|
||||
|
||||
public enum ExeProblem { None, NotFound, NotExecutable, WrongPlatform, NotAProgram }
|
||||
|
||||
// gfxrenderer: the OpenGL renderer ("full", read by every build) or the Vulkan 1.4 one.
|
||||
public enum GraphicsBackend { OpenGL = 0, Vulkan = 1 }
|
||||
|
||||
// gfx.antialiasing. Dlss and Dlaa are the Vulkan renderer's only; the simulator falls back to TAA elsewhere.
|
||||
public enum AntiAliasingMode { Off, Msaa2, Msaa4, Msaa8, Taa, Dlss, Dlaa }
|
||||
|
||||
public sealed class SimulatorSettings
|
||||
{
|
||||
public bool LanguageWasSet { get; internal set; }
|
||||
@@ -49,13 +55,18 @@ public sealed class SimulatorSettings
|
||||
public bool LogMissingVehicleFiles;
|
||||
|
||||
public int RenderEngine;
|
||||
public GraphicsBackend Backend => RenderEngine == VulkanEngine ? GraphicsBackend.Vulkan : GraphicsBackend.OpenGL;
|
||||
public string VulkanDevice = "";
|
||||
public int Width = 1280;
|
||||
public int Height = 720;
|
||||
public int BufferScalePercent = 100;
|
||||
public int MaxTextureSize = 4096;
|
||||
public int MaxCabTextureSize = 4096;
|
||||
public double TextureFiltering = 8;
|
||||
public int Multisampling = 2;
|
||||
public AntiAliasingMode AntiAliasing = AntiAliasingMode.Msaa4;
|
||||
public string DlssPreset = "default";
|
||||
public int FrameGeneration = 1;
|
||||
public int Reflex;
|
||||
public int DynamicLights = 7;
|
||||
public double DrawRangeFactor = 3.0;
|
||||
public bool VSync;
|
||||
@@ -65,14 +76,48 @@ public sealed class SimulatorSettings
|
||||
public bool MotionBlur = true;
|
||||
public bool ExtraEffects = true;
|
||||
public bool EnvMap = true;
|
||||
public bool UseVbo = true;
|
||||
public bool RenderShadows = true;
|
||||
public bool ShadowSdsm;
|
||||
public int LightShadows = 2;
|
||||
public int ContactShadows;
|
||||
public bool LightsClustered = true;
|
||||
public int AmbientOcclusion = 2;
|
||||
public int AoSlices = 3;
|
||||
public int AoSteps = 4;
|
||||
public bool AoLighting = true;
|
||||
public int CabProbe = 2;
|
||||
public int CabProbeInterval = 4;
|
||||
public double CabProbeBounce = 1.0;
|
||||
public bool CabProbeReflections = true;
|
||||
|
||||
// Read from eu07.ini only, for the dependencies shown: the starter offers no switch for them.
|
||||
public bool CabLampLight { get; internal set; } = true;
|
||||
public bool DepthPrepassScene { get; internal set; }
|
||||
public int Ssr = 2;
|
||||
public bool RayTracing;
|
||||
public int RayTracingRange = 500;
|
||||
public bool VolumetricFog = true;
|
||||
public int FogQuality = 2;
|
||||
public int Clouds = 2;
|
||||
public bool CloudShadows = true;
|
||||
public bool Grass = true;
|
||||
public int GrassDistance = 60;
|
||||
public double GrassDensity = 1.0;
|
||||
public int PrecipitationParticles = 65536;
|
||||
public bool Bloom = true;
|
||||
public bool AutoExposure = true;
|
||||
|
||||
// Only the older simulators read these.
|
||||
public bool UseVbo = true;
|
||||
public bool RenderAngleVulkan;
|
||||
public bool UseGLES;
|
||||
public int CabShadowsRange;
|
||||
|
||||
/// <summary>Updates of the reflections a second; the simulator's own is one in five minutes.</summary>
|
||||
public double ReflectionsFramerate = 1 / 300.0;
|
||||
public int ShadowMapResolution = 2048;
|
||||
/// <summary>The third number of shadowtune; the second and fourth go unread.</summary>
|
||||
public int ShadowProjectionRange = 250;
|
||||
public int CabShadowsRange;
|
||||
public int ShadowRankCutoff = 3;
|
||||
public int ReflectionsFidelity;
|
||||
public int FieldOfView = 45;
|
||||
@@ -82,7 +127,6 @@ public sealed class SimulatorSettings
|
||||
public double FpsLimit = 30;
|
||||
public double ShadowAngleLimit = 0.2;
|
||||
public bool FullscreenWindowed;
|
||||
public bool RenderAngleVulkan;
|
||||
|
||||
public int SplineFidelity = 1;
|
||||
public bool FullPhysics = true;
|
||||
@@ -110,7 +154,6 @@ public sealed class SimulatorSettings
|
||||
|
||||
public bool CompressTextures = true;
|
||||
public bool ScaleSpeculars = true;
|
||||
public bool UseGLES;
|
||||
public bool ShaderGamma;
|
||||
public bool ScreenMipmaps = true;
|
||||
public bool ExtendedModelConversion;
|
||||
@@ -163,6 +206,9 @@ public sealed class SimulatorSettings
|
||||
/// </summary>
|
||||
public static readonly string[] RenderEngines = { "full", "legacy", "simple", "experimental", "vulkan" };
|
||||
|
||||
/// <summary>Where "vulkan" stands among <see cref="RenderEngines"/>.</summary>
|
||||
public const int VulkanEngine = 4;
|
||||
|
||||
/// <summary>Where <paramref name="word"/> stands among <see cref="RenderEngines"/>, as the simulator reads it.</summary>
|
||||
public static int RenderEngineOf(string word) => word.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
|
||||
@@ -26,13 +26,6 @@ public static class Steps
|
||||
/// <summary>anisotropicfiltering: 16 is the most any card offers.</summary>
|
||||
public static readonly double[] Anisotropy = { 1, 2, 4, 8, 16 };
|
||||
|
||||
/// <summary>
|
||||
/// multisampling, as the power of two of the samples: none to x8. The simulator
|
||||
/// takes 4 (x16) too, which only some cards can do - on one that cannot, the
|
||||
/// frame buffer fails to build - so it stays in the file but off the slider.
|
||||
/// </summary>
|
||||
public static readonly double[] MultisamplingLevels = { 0, 1, 2, 3 };
|
||||
|
||||
/// <summary>
|
||||
/// <paramref name="steps"/> with <paramref name="value"/> among them: one
|
||||
/// eu07.ini has that is none of the steps stays what it is.
|
||||
|
||||
@@ -268,6 +268,33 @@ public sealed class ExecutableLocator
|
||||
}
|
||||
|
||||
/// <summary>A path as <see cref="Resolve"/> gives it, which may be relative to the installation.</summary>
|
||||
/// <summary>Whether the DLSS and frame generation libraries lie next to the simulator: without them it cannot use either.</summary>
|
||||
public (bool Dlss, bool FrameGeneration) DlssLibraries(string executable)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Resolve hands back either a path of its own search or the bare name of the pick.
|
||||
string full = _files.FileExists(executable) ? executable : FullPath(executable);
|
||||
string? directory = Path.GetDirectoryName(full);
|
||||
if (string.IsNullOrEmpty(directory) || !_files.DirectoryExists(directory))
|
||||
return (false, false);
|
||||
|
||||
bool windowsBuild = _files.FileExists(full)
|
||||
? Format(full) == BinaryFormat.PortableExecutable
|
||||
: _environment.IsWindows;
|
||||
|
||||
return windowsBuild
|
||||
? (Has(directory, "nvngx_dlss.dll"), Has(directory, "nvngx_dlssg.dll"))
|
||||
: (Has(directory, "libnvidia-ngx-dlss.so*"), Has(directory, "libnvidia-ngx-dlssg.so*"));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return (false, false);
|
||||
}
|
||||
}
|
||||
|
||||
private bool Has(string directory, string pattern) => _files.GetFiles(directory, pattern).Count > 0;
|
||||
|
||||
public string FullPath(string path) =>
|
||||
Path.IsPathRooted(path) ? path : Path.Combine(_paths.Root, path);
|
||||
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace StarterNG.Infrastructure.Settings;
|
||||
|
||||
public sealed class SettingsSerializer
|
||||
{
|
||||
private readonly bool _dlssPlatform;
|
||||
|
||||
/// <param name="dlssPlatform">Whether the simulator can have DLSS here at all (not on macOS).</param>
|
||||
public SettingsSerializer(bool dlssPlatform = true)
|
||||
{
|
||||
_dlssPlatform = dlssPlatform;
|
||||
}
|
||||
|
||||
public bool DlssPlatform => _dlssPlatform;
|
||||
|
||||
public void Read(SimulatorSettings s, ConfigFile c)
|
||||
{
|
||||
s.LanguageWasSet = c.Has("lang");
|
||||
@@ -67,13 +77,17 @@ public sealed class SettingsSerializer
|
||||
s.LogMissingVehicleFiles = c.GetBool("starter.logmissingvehicles", false);
|
||||
|
||||
s.RenderEngine = SimulatorSettings.RenderEngineOf(c.GetString("gfxrenderer", "full"));
|
||||
s.VulkanDevice = c.GetString("gfx.vulkan.device", "");
|
||||
s.Width = c.GetInt("width", 1280);
|
||||
s.Height = c.GetInt("height", 720);
|
||||
s.BufferScalePercent = ReadBufferScale(c);
|
||||
s.MaxTextureSize = c.GetInt("maxtexturesize", 4096);
|
||||
s.MaxCabTextureSize = c.GetInt("maxcabtexturesize", 4096);
|
||||
s.TextureFiltering = Math.Max(1, c.GetDouble("anisotropicfiltering", 8));
|
||||
s.Multisampling = Clamp(c.GetInt("multisampling", 2), 0, 4);
|
||||
s.AntiAliasing = ReadAntiAliasing(c);
|
||||
s.DlssPreset = c.GetString("gfx.dlss.preset", "default").ToLowerInvariant();
|
||||
s.FrameGeneration = ParseFrameGeneration(FirstToken(c, "gfx.framegeneration"));
|
||||
s.Reflex = ParseReflex(FirstToken(c, "gfx.reflex"));
|
||||
s.DynamicLights = Clamp(c.GetInt("dynamiclights", 7), 0, 7);
|
||||
s.DrawRangeFactor = c.GetDouble("gfx.drawrange.factor.max", 3.0);
|
||||
s.VSync = c.GetBool("vsync", false);
|
||||
@@ -85,6 +99,34 @@ public sealed class SettingsSerializer
|
||||
s.EnvMap = c.GetBool("gfx.envmap.enabled", true);
|
||||
s.UseVbo = c.GetBool("usevbo", true);
|
||||
s.RenderShadows = c.GetBool("shadows", true);
|
||||
s.ShadowSdsm = c.GetBool("gfx.shadow.sdsm", false);
|
||||
s.LightShadows = ParseLevel(FirstToken(c, "gfx.lights.shadows"), 2, 3);
|
||||
s.ContactShadows = ParseLevel(FirstToken(c, "gfx.contactshadows"), 0, 3);
|
||||
s.LightsClustered = c.GetBool("gfx.lights.clustered", true);
|
||||
s.AmbientOcclusion = ParseAmbientOcclusion(FirstToken(c, "gfx.postfx.ao"));
|
||||
var aoQuality = c.GetTokens("gfx.postfx.ao.quality");
|
||||
s.AoSlices = aoQuality.Length >= 1 ? ParseInt(aoQuality[0], 3) : 3;
|
||||
s.AoSteps = aoQuality.Length >= 2 ? ParseInt(aoQuality[1], 4) : 4;
|
||||
s.AoLighting = c.GetBool("gfx.postfx.ao.lighting", true);
|
||||
s.CabProbe = ParseCabProbe(FirstToken(c, "gfx.cabprobe"));
|
||||
s.CabProbeInterval = c.GetInt("gfx.cabprobe.interval", 4);
|
||||
s.CabProbeBounce = c.GetDouble("gfx.cabprobe.bounce", 1.0);
|
||||
s.CabProbeReflections = c.GetBool("gfx.cabprobe.reflections", true);
|
||||
s.CabLampLight = c.GetBool("gfx.lights.cab", true);
|
||||
s.DepthPrepassScene = c.GetBool("gfx.depthprepass.scene", false);
|
||||
s.Ssr = ParseLevel(FirstToken(c, "gfx.ssr"), 2, 3);
|
||||
s.RayTracing = c.GetBool("gfx.raytracing", false);
|
||||
s.RayTracingRange = (int)Math.Round(c.GetDouble("gfx.raytracing.range", 500));
|
||||
s.VolumetricFog = ParseVolumetricFog(FirstToken(c, "gfx.fog"));
|
||||
s.FogQuality = ParseFogQuality(FirstToken(c, "gfx.fog.quality"));
|
||||
s.Clouds = ParseLevel(FirstToken(c, "gfx.clouds"), 2, 4);
|
||||
s.CloudShadows = c.GetBool("gfx.clouds.shadows", true);
|
||||
s.Grass = c.GetBool("gfx.grass", true);
|
||||
s.GrassDistance = (int)Math.Round(c.GetDouble("gfx.grass.distance", 60));
|
||||
s.GrassDensity = c.GetDouble("gfx.grass.density", 1.0);
|
||||
s.PrecipitationParticles = c.GetInt("gfx.precipitation.particles", 65536);
|
||||
s.Bloom = c.GetBool("gfx.postfx.bloom", true);
|
||||
s.AutoExposure = c.GetBool("gfx.postfx.autoexposure", true);
|
||||
// A negative rate counts as its size; none at all, as never.
|
||||
double reflections = Math.Abs(c.GetDouble("gfx.reflections.framerate", 1 / 300.0));
|
||||
s.ReflectionsFramerate = reflections > 0 ? reflections : 1 / 300.0;
|
||||
@@ -174,6 +216,8 @@ public sealed class SettingsSerializer
|
||||
foreach (var key in SimulatorKeys.All)
|
||||
if (c.Has(key.Key))
|
||||
s.Extra[key.Key] = c.GetRaw(key.Key) ?? string.Empty;
|
||||
|
||||
GraphicsRules.Normalize(s, _dlssPlatform);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,7 +228,7 @@ public sealed class SettingsSerializer
|
||||
public static readonly string[] FixedLengthKeys = { "uart", "uarttune", "uartfeature" };
|
||||
|
||||
/// <summary>Keys written only when they say something, besides those of <see cref="SimulatorKeys"/>.</summary>
|
||||
public static readonly string[] OptionalKeys = { "fpslimit", "gfx.angleplatform" };
|
||||
public static readonly string[] OptionalKeys = { "fpslimit", "gfx.angleplatform", "gfx.vulkan.device" };
|
||||
|
||||
/// <summary>Keys no simulator reads any more, taken out of the file on a save.</summary>
|
||||
public static readonly string[] ObsoleteKeys =
|
||||
@@ -195,6 +239,8 @@ public sealed class SettingsSerializer
|
||||
|
||||
public void Write(SimulatorSettings s, ConfigFile c)
|
||||
{
|
||||
GraphicsRules.Normalize(s, _dlssPlatform);
|
||||
|
||||
c.Set("lang", string.IsNullOrWhiteSpace(s.LanguageCode)
|
||||
? "en"
|
||||
: s.LanguageCode.Trim().ToLowerInvariant());
|
||||
@@ -241,6 +287,7 @@ public sealed class SettingsSerializer
|
||||
c.SetBool("starter.logmissingvehicles", s.LogMissingVehicleFiles);
|
||||
|
||||
c.Set("gfxrenderer", SimulatorSettings.RenderEngines[Clamp(s.RenderEngine, 0, SimulatorSettings.RenderEngines.Length - 1)]);
|
||||
if (!string.IsNullOrWhiteSpace(s.VulkanDevice)) c.Set("gfx.vulkan.device", s.VulkanDevice.Trim());
|
||||
c.SetInt("width", s.Width);
|
||||
c.SetInt("height", s.Height);
|
||||
c.SetInt("starter.bufferscale", s.BufferScalePercent);
|
||||
@@ -253,7 +300,13 @@ public sealed class SettingsSerializer
|
||||
c.SetInt("maxtexturesize", s.MaxTextureSize);
|
||||
c.SetInt("maxcabtexturesize", s.MaxCabTextureSize);
|
||||
c.SetDouble("anisotropicfiltering", s.TextureFiltering);
|
||||
c.SetInt("multisampling", s.Multisampling);
|
||||
// multisampling is what older simulators read; gfx.antialiasing overrides it in the new ones, but only from
|
||||
// a later line, since each key sets the mode as it is read.
|
||||
c.SetInt("multisampling", MultisamplingLevel(s.AntiAliasing));
|
||||
c.Set("gfx.antialiasing", AntiAliasingToken(s.AntiAliasing));
|
||||
c.Set("gfx.dlss.preset", s.DlssPreset);
|
||||
c.Set("gfx.framegeneration", s.FrameGeneration > 1 ? $"x{s.FrameGeneration}" : "off");
|
||||
c.Set("gfx.reflex", s.Reflex switch { 1 => "on", 2 => "boost", _ => "off" });
|
||||
c.SetInt("dynamiclights", s.DynamicLights);
|
||||
c.SetDouble("gfx.drawrange.factor.max", s.DrawRangeFactor);
|
||||
c.SetBool("vsync", s.VSync);
|
||||
@@ -266,6 +319,32 @@ public sealed class SettingsSerializer
|
||||
c.SetBool("usevbo", s.UseVbo);
|
||||
c.SetBool("shadows", s.RenderShadows);
|
||||
c.SetBool("gfx.shadowmap.enabled", s.RenderShadows);
|
||||
c.SetBool("gfx.shadow.sdsm", s.ShadowSdsm);
|
||||
c.Set("gfx.lights.shadows", LevelToken(s.LightShadows));
|
||||
c.Set("gfx.contactshadows", LevelToken(s.ContactShadows));
|
||||
c.SetBool("gfx.lights.clustered", s.LightsClustered);
|
||||
c.Set("gfx.postfx.ao", s.AmbientOcclusion switch { 1 => "ssao", 2 => "gtao", _ => "no" });
|
||||
c.Set("gfx.postfx.ao.quality", $"{s.AoSlices} {s.AoSteps}");
|
||||
c.SetBool("gfx.postfx.ao.lighting", s.AoLighting);
|
||||
c.Set("gfx.cabprobe", LevelToken(s.CabProbe));
|
||||
c.SetInt("gfx.cabprobe.interval", s.CabProbeInterval);
|
||||
c.SetDouble("gfx.cabprobe.bounce", s.CabProbeBounce);
|
||||
c.SetBool("gfx.cabprobe.reflections", s.CabProbeReflections);
|
||||
c.Set("gfx.ssr", LevelToken(s.Ssr));
|
||||
c.SetBool("gfx.raytracing", s.RayTracing);
|
||||
c.SetInt("gfx.raytracing.range", s.RayTracingRange);
|
||||
c.Set("gfx.fog", s.VolumetricFog ? "yes" : "analytic");
|
||||
c.Set("gfx.fog.quality", LevelToken(s.FogQuality));
|
||||
c.Set("gfx.clouds", LevelToken(s.Clouds));
|
||||
c.SetBool("gfx.clouds.shadows", s.CloudShadows);
|
||||
c.SetBool("gfx.grass", s.Grass);
|
||||
c.SetInt("gfx.grass.distance", s.GrassDistance);
|
||||
// The grass thins out past its distance; the simulator's own default keeps a sixth of it for that.
|
||||
c.SetInt("gfx.grass.fadedistance", Math.Min(600, s.GrassDistance + Math.Max(10, s.GrassDistance / 6)));
|
||||
c.SetDouble("gfx.grass.density", s.GrassDensity);
|
||||
c.SetInt("gfx.precipitation.particles", s.PrecipitationParticles);
|
||||
c.SetBool("gfx.postfx.bloom", s.Bloom);
|
||||
c.SetBool("gfx.postfx.autoexposure", s.AutoExposure);
|
||||
c.Set("gfx.reflections.framerate", s.ReflectionsFramerate.ToString("0.######", CultureInfo.InvariantCulture));
|
||||
c.Set("shadowtune",
|
||||
$"{s.ShadowMapResolution} {s.ShadowTuneUnused[0]} " +
|
||||
@@ -346,6 +425,128 @@ public sealed class SettingsSerializer
|
||||
return Clamp((int)Math.Round(value > 4 ? value : value * 100), 25, 200);
|
||||
}
|
||||
|
||||
private static string FirstToken(ConfigFile c, string key)
|
||||
{
|
||||
var tokens = c.GetTokens(key);
|
||||
return tokens.Length > 0 ? tokens[0].ToLowerInvariant() : string.Empty;
|
||||
}
|
||||
|
||||
// The names the simulator takes for Vulkan; every other word is OpenGL to the screen, and stays in the file until changed.
|
||||
// Whichever of the two keys comes later in the file decides, as each sets the mode when the simulator reads it.
|
||||
private static AntiAliasingMode ReadAntiAliasing(ConfigFile c)
|
||||
{
|
||||
var fromMultisampling = c.GetInt("multisampling", 2) switch
|
||||
{
|
||||
<= 0 => AntiAliasingMode.Off,
|
||||
1 => AntiAliasingMode.Msaa2,
|
||||
2 => AntiAliasingMode.Msaa4,
|
||||
_ => AntiAliasingMode.Msaa8
|
||||
};
|
||||
|
||||
if (!c.Has("gfx.antialiasing") ||
|
||||
(c.Has("multisampling") && c.LineOf("multisampling") > c.LineOf("gfx.antialiasing")))
|
||||
return fromMultisampling;
|
||||
|
||||
return FirstToken(c, "gfx.antialiasing") switch
|
||||
{
|
||||
"off" or "no" or "none" or "0" => AntiAliasingMode.Off,
|
||||
"msaax2" => AntiAliasingMode.Msaa2,
|
||||
"msaax4" => AntiAliasingMode.Msaa4,
|
||||
"msaax8" or "msaax16" => AntiAliasingMode.Msaa8,
|
||||
"taa" => AntiAliasingMode.Taa,
|
||||
"dlss" => AntiAliasingMode.Dlss,
|
||||
"dlaa" => AntiAliasingMode.Dlaa,
|
||||
_ => fromMultisampling
|
||||
};
|
||||
}
|
||||
|
||||
private static string AntiAliasingToken(AntiAliasingMode mode) => mode switch
|
||||
{
|
||||
AntiAliasingMode.Msaa2 => "msaax2",
|
||||
AntiAliasingMode.Msaa4 => "msaax4",
|
||||
AntiAliasingMode.Msaa8 => "msaax8",
|
||||
AntiAliasingMode.Taa => "taa",
|
||||
AntiAliasingMode.Dlss => "dlss",
|
||||
AntiAliasingMode.Dlaa => "dlaa",
|
||||
_ => "off"
|
||||
};
|
||||
|
||||
private static int MultisamplingLevel(AntiAliasingMode mode) => mode switch
|
||||
{
|
||||
AntiAliasingMode.Msaa2 => 1,
|
||||
AntiAliasingMode.Msaa4 => 2,
|
||||
AntiAliasingMode.Msaa8 => 3,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
private static int ParseFrameGeneration(string value) => value switch
|
||||
{
|
||||
"x2" or "on" or "yes" or "2" => 2,
|
||||
"x3" or "3" => 3,
|
||||
"x4" or "4" => 4,
|
||||
_ => 1
|
||||
};
|
||||
|
||||
private static int ParseReflex(string value) => value switch
|
||||
{
|
||||
"on" or "yes" or "1" => 1,
|
||||
"boost" or "2" => 2,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
// no/low/medium/high(/ultra) or the number of the level; an absent key keeps the simulator's default.
|
||||
private static int ParseLevel(string value, int fallback, int max)
|
||||
{
|
||||
if (value.Length == 0)
|
||||
return fallback;
|
||||
int level = value switch
|
||||
{
|
||||
"low" or "1" => 1,
|
||||
"medium" or "yes" or "true" or "2" => 2,
|
||||
"high" or "3" => 3,
|
||||
"ultra" or "4" => 4,
|
||||
_ => 0
|
||||
};
|
||||
return Math.Min(level, max);
|
||||
}
|
||||
|
||||
private static string LevelToken(int level) => level switch
|
||||
{
|
||||
1 => "low",
|
||||
2 => "medium",
|
||||
3 => "high",
|
||||
4 => "ultra",
|
||||
_ => "no"
|
||||
};
|
||||
|
||||
// As the simulator reads it, but a value it does not know keeps its default (medium) rather than turning the probe off.
|
||||
private static int ParseCabProbe(string value) => value switch
|
||||
{
|
||||
"no" or "false" or "off" or "0" => 0,
|
||||
"low" or "1" => 1,
|
||||
"high" or "3" => 3,
|
||||
_ => 2
|
||||
};
|
||||
|
||||
private static int ParseAmbientOcclusion(string value) => value switch
|
||||
{
|
||||
"" => 2,
|
||||
"yes" or "true" or "1" or "gtao" => 2,
|
||||
"ssao" => 1,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
private static bool ParseVolumetricFog(string value) =>
|
||||
value is not ("analytic" or "old" or "no" or "false" or "0");
|
||||
|
||||
private static int ParseFogQuality(string value) => value switch
|
||||
{
|
||||
"low" or "1" => 1,
|
||||
"high" or "3" => 3,
|
||||
"ultra" or "4" => 4,
|
||||
_ => 2
|
||||
};
|
||||
|
||||
private static int Clamp(int v, int lo, int hi) => v < lo ? lo : (v > hi ? hi : v);
|
||||
|
||||
private static int SensitivityStep(double mouseScale) =>
|
||||
|
||||
@@ -253,6 +253,21 @@
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="Margin" Value="0,21,14,0" />
|
||||
</Style>
|
||||
<!-- The same for a dropdown with a note under it (what the simulator will do instead). -->
|
||||
<Style Selector="ctl|SettingRow:not(.Compact) > StackPanel > ComboBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="Width" Value="360" />
|
||||
</Style>
|
||||
<Style Selector="ctl|SettingRow:not(.Compact) > TextBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="Width" Value="360" />
|
||||
</Style>
|
||||
<!-- Notes under a setting: amber, since green is the interactive accent. -->
|
||||
<Style Selector="TextBlock.SettingNote">
|
||||
<Setter Property="Foreground" Value="#D9A43A" />
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
</Style>
|
||||
<Style Selector="ctl|SettingRow:not(.Compact) > NumericUpDown">
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="Width" Value="140" />
|
||||
|
||||
@@ -24,7 +24,25 @@ internal static class SettingTexts
|
||||
|
||||
public static string Anisotropy(double value) => "x" + value.ToString("0.#", CultureInfo.CurrentCulture);
|
||||
|
||||
public static string Multisampling(int level) => level <= 0 ? App.Loc["MsaaNone"] : "x" + (1 << level);
|
||||
public static string AntiAliasing(AntiAliasingMode mode) => mode switch
|
||||
{
|
||||
AntiAliasingMode.Msaa2 => "MSAA x2",
|
||||
AntiAliasingMode.Msaa4 => "MSAA x4",
|
||||
AntiAliasingMode.Msaa8 => "MSAA x8",
|
||||
AntiAliasingMode.Taa => App.Loc["AaTaa"],
|
||||
AntiAliasingMode.Dlss => App.Loc["AaDlss"],
|
||||
AntiAliasingMode.Dlaa => App.Loc["AaDlaa"],
|
||||
_ => App.Loc["MsaaNone"]
|
||||
};
|
||||
|
||||
private static string Level(int level) => App.Loc[level switch
|
||||
{
|
||||
1 => "LevelLow",
|
||||
2 => "LevelMedium",
|
||||
3 => "LevelHigh",
|
||||
4 => "LevelUltra",
|
||||
_ => "LevelOff"
|
||||
}];
|
||||
|
||||
public static string TwoDecimals(double value) => value.ToString("0.00", CultureInfo.CurrentCulture);
|
||||
|
||||
@@ -76,7 +94,7 @@ internal static class SettingTexts
|
||||
Add("MaxTexResolution", p.TextureSize + " px");
|
||||
Add("MaxTexCabResolution", p.CabTextureSize + " px");
|
||||
Add("TexFilteringQuality", Anisotropy(p.Anisotropy));
|
||||
Add("Multisampling", Multisampling(p.Multisampling));
|
||||
Add("AntiAliasing", AntiAliasing(p.AntiAliasing));
|
||||
Add("DynamicLights", p.DynamicLights.ToString(CultureInfo.CurrentCulture));
|
||||
Add("SmokeParticlesMultiplier", Fidelity(p.SmokeFidelity));
|
||||
Add("RenderShadows", YesNo(p.Shadows));
|
||||
@@ -101,23 +119,18 @@ internal static class SettingTexts
|
||||
Add("RenderRange", "×" + Whole(p.DrawRangeFactor));
|
||||
Add("Ini." + GraphicsPreset.ReflectedInstancesKey, Whole(p.ReflectedInstances) + " m");
|
||||
Add("Ini." + GraphicsPreset.ReflectedVehiclesKey, Whole(p.ReflectedVehicles) + " m");
|
||||
Add("CabShadowsRange", p.CabShadowsRange + " m");
|
||||
|
||||
var renderer = p.NewRenderer;
|
||||
string Word(string word) => App.Loc[SimulatorKey.WordKey(word)];
|
||||
lines.Add(App.Loc["GfxColNewRenderer"] + ":");
|
||||
Add("Ini.gfx.lights.shadows", Word(renderer.LampShadows));
|
||||
Add("Ini.gfx.contactshadows", Word(renderer.ContactShadows));
|
||||
Add("Ini.gfx.postfx.ao", Word(renderer.Occlusion));
|
||||
Add("Ini.gfx.postfx.ao.quality", Word(renderer.OcclusionQuality));
|
||||
Add("Ini.gfx.cabprobe", Word(renderer.CabProbe));
|
||||
Add("Ini.gfx.ssr", Word(renderer.ScreenReflections));
|
||||
Add("Ini.gfx.raytracing", YesNo(renderer.RayTracing));
|
||||
Add("Ini.gfx.fog", Word(renderer.Fog));
|
||||
Add("Ini.gfx.fog.quality", Word(renderer.FogQuality));
|
||||
Add("Ini.gfx.clouds", Word(renderer.Clouds));
|
||||
Add("Ini.gfx.grass", renderer.Grass ? Whole(renderer.GrassDistance) + " m" : App.Loc["No"]);
|
||||
Add("Ini.gfx.postfx.bloom", YesNo(renderer.Bloom));
|
||||
Add("LightShadows", Level(renderer.LampShadows));
|
||||
Add("ContactShadows", Level(renderer.ContactShadows));
|
||||
Add("AmbientOcclusion", renderer.Occlusion switch { 1 => "SSAO", 2 => "GTAO", _ => App.Loc["LevelOff"] });
|
||||
Add("CabProbe", Level(renderer.CabProbe));
|
||||
Add("Ssr", Level(renderer.ScreenReflections));
|
||||
Add("RayTracing", YesNo(renderer.RayTracing));
|
||||
Add("VolumetricFog", renderer.VolumetricFog ? Level(renderer.FogQuality) : App.Loc["No"]);
|
||||
Add("Clouds", Level(renderer.Clouds));
|
||||
Add("Grass", renderer.Grass ? renderer.GrassDistance + " m" : App.Loc["No"]);
|
||||
Add("Bloom", YesNo(renderer.Bloom));
|
||||
|
||||
if (p.Extras is { } extras)
|
||||
{
|
||||
|
||||
395
StarterNG/Views/Settings.Graphics.cs
Normal file
395
StarterNG/Views/Settings.Graphics.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
using StarterNG.Application;
|
||||
using StarterNG.Domain.Settings;
|
||||
|
||||
namespace StarterNG.Views;
|
||||
|
||||
// What the graphics and effects categories add to the screen: the controls of the settings the
|
||||
// new renderers read, the dependencies between them (what the simulator only does on Vulkan,
|
||||
// with DLSS, ...), and the import and export of eu07.ini.
|
||||
public partial class Settings
|
||||
{
|
||||
private static readonly CultureInfo Invariant = CultureInfo.InvariantCulture;
|
||||
|
||||
private static readonly FilePickerFileType[] IniTypes =
|
||||
{
|
||||
new("eu07.ini") { Patterns = new[] { "*.ini" } },
|
||||
new("*") { Patterns = new[] { "*" } }
|
||||
};
|
||||
|
||||
/// <summary>Set while the dependencies are brought in line, so the changes they make do not recurse.</summary>
|
||||
private bool _updatingGraphics;
|
||||
|
||||
/// <summary>
|
||||
/// What only Vulkan has, as it was when OpenGL got chosen, so that going back to
|
||||
/// Vulkan brings it back instead of leaving it switched off.
|
||||
/// </summary>
|
||||
private (AntiAliasingMode AntiAliasing, int FrameGeneration, int Reflex, bool RayTracing)? _vulkanChoices;
|
||||
|
||||
private string? _dlssProbedFor;
|
||||
private (bool Dlss, bool FrameGeneration) _dlssProbe;
|
||||
|
||||
private static bool DlssPlatform => AppServices.Current.SettingsStore.DlssPlatform;
|
||||
|
||||
private void InitGraphics()
|
||||
{
|
||||
// The notes are worked out here, not bound, so they follow a change of language by hand.
|
||||
App.Loc.LanguageChanged += UpdateGraphicsState;
|
||||
SelectExeCb.SelectionChanged += (_, _) => UpdateGraphicsState();
|
||||
}
|
||||
|
||||
private void ShowGraphics(SimulatorSettings s)
|
||||
{
|
||||
RenderEngineCb.SelectedIndex = s.RenderEngine;
|
||||
VulkanDeviceTb.Text = s.VulkanDevice;
|
||||
SelectTag(AntiAliasingCb, AntiAliasingTag(s.AntiAliasing));
|
||||
SelectTag(DlssPresetCb, s.DlssPreset);
|
||||
SelectTag(FrameGenerationCb, s.FrameGeneration.ToString(Invariant));
|
||||
SelectTag(ReflexCb, s.Reflex.ToString(Invariant));
|
||||
|
||||
ShadowSdsmCb.IsChecked = s.ShadowSdsm;
|
||||
LightsClusteredCb.IsChecked = s.LightsClustered;
|
||||
SelectTag(LightShadowsCb, s.LightShadows.ToString(Invariant));
|
||||
SelectTag(ContactShadowsCb, s.ContactShadows.ToString(Invariant));
|
||||
SelectTag(AmbientOcclusionCb, s.AmbientOcclusion.ToString(Invariant));
|
||||
SelectOrAddTag(AoQualityCb, $"{s.AoSlices} {s.AoSteps}", $"{s.AoSlices} / {s.AoSteps}");
|
||||
AoLightingCb.IsChecked = s.AoLighting;
|
||||
SelectTag(CabProbeCb, s.CabProbe.ToString(Invariant));
|
||||
CabProbeIntervalNud.Value = s.CabProbeInterval;
|
||||
CabProbeBounceSlider.Value = s.CabProbeBounce;
|
||||
CabProbeReflectionsCb.IsChecked = s.CabProbeReflections;
|
||||
|
||||
SelectTag(SsrCb, s.Ssr.ToString(Invariant));
|
||||
RayTracingCb.IsChecked = s.RayTracing;
|
||||
RayTracingRangeSlider.Value = s.RayTracingRange;
|
||||
|
||||
VolumetricFogCb.IsChecked = s.VolumetricFog;
|
||||
SelectTag(FogQualityCb, s.FogQuality.ToString(Invariant));
|
||||
SelectTag(CloudsCb, s.Clouds.ToString(Invariant));
|
||||
CloudShadowsCb.IsChecked = s.CloudShadows;
|
||||
|
||||
BloomCb.IsChecked = s.Bloom;
|
||||
AutoExposureCb.IsChecked = s.AutoExposure;
|
||||
|
||||
GrassCb.IsChecked = s.Grass;
|
||||
GrassDistanceSlider.Value = s.GrassDistance;
|
||||
GrassDensitySlider.Value = s.GrassDensity;
|
||||
string particles = s.PrecipitationParticles.ToString(Invariant);
|
||||
SelectOrAddTag(PrecipitationCb, particles, particles);
|
||||
}
|
||||
|
||||
private void CaptureGraphics(SimulatorSettings s)
|
||||
{
|
||||
s.RenderEngine = Math.Max(0, RenderEngineCb.SelectedIndex);
|
||||
s.VulkanDevice = VulkanDeviceTb.Text?.Trim() ?? "";
|
||||
s.AntiAliasing = AntiAliasingFromTag(SelectedTag(AntiAliasingCb));
|
||||
s.DlssPreset = SelectedTag(DlssPresetCb) ?? "default";
|
||||
s.FrameGeneration = TagInt(FrameGenerationCb, 1);
|
||||
s.Reflex = TagInt(ReflexCb, 0);
|
||||
|
||||
s.ShadowSdsm = IsChecked(ShadowSdsmCb);
|
||||
s.LightsClustered = IsChecked(LightsClusteredCb);
|
||||
s.LightShadows = TagInt(LightShadowsCb, 2);
|
||||
s.ContactShadows = TagInt(ContactShadowsCb, 0);
|
||||
s.AmbientOcclusion = TagInt(AmbientOcclusionCb, 2);
|
||||
var ao = (SelectedTag(AoQualityCb) ?? "3 4").Split(' ');
|
||||
s.AoSlices = ao.Length > 0 && int.TryParse(ao[0], NumberStyles.Integer, Invariant, out int slices) ? slices : 3;
|
||||
s.AoSteps = ao.Length > 1 && int.TryParse(ao[1], NumberStyles.Integer, Invariant, out int steps) ? steps : 4;
|
||||
s.AoLighting = IsChecked(AoLightingCb);
|
||||
s.CabProbe = TagInt(CabProbeCb, 2);
|
||||
s.CabProbeInterval = (int)(CabProbeIntervalNud.Value ?? 4);
|
||||
s.CabProbeBounce = CabProbeBounceSlider.Value;
|
||||
s.CabProbeReflections = IsChecked(CabProbeReflectionsCb);
|
||||
|
||||
s.Ssr = TagInt(SsrCb, 2);
|
||||
s.RayTracing = IsChecked(RayTracingCb);
|
||||
s.RayTracingRange = (int)RayTracingRangeSlider.Value;
|
||||
|
||||
s.VolumetricFog = IsChecked(VolumetricFogCb);
|
||||
s.FogQuality = TagInt(FogQualityCb, 2);
|
||||
s.Clouds = TagInt(CloudsCb, 2);
|
||||
s.CloudShadows = IsChecked(CloudShadowsCb);
|
||||
|
||||
s.Bloom = IsChecked(BloomCb);
|
||||
s.AutoExposure = IsChecked(AutoExposureCb);
|
||||
|
||||
s.Grass = IsChecked(GrassCb);
|
||||
s.GrassDistance = (int)GrassDistanceSlider.Value;
|
||||
s.GrassDensity = GrassDensitySlider.Value;
|
||||
s.PrecipitationParticles = TagInt(PrecipitationCb, 65536);
|
||||
}
|
||||
|
||||
private void OnBackendChanged()
|
||||
{
|
||||
if (_loading || _updatingGraphics)
|
||||
return;
|
||||
|
||||
_updatingGraphics = true;
|
||||
try
|
||||
{
|
||||
if (!SettingReach.IsVulkan(SelectedRenderer()))
|
||||
{
|
||||
var s = Trial();
|
||||
_vulkanChoices ??= (s.AntiAliasing, s.FrameGeneration, s.Reflex, s.RayTracing);
|
||||
if (GraphicsRules.IsDlss(s.AntiAliasing))
|
||||
SelectTag(AntiAliasingCb, "taa");
|
||||
FrameGenerationCb.SelectedIndex = 0;
|
||||
ReflexCb.SelectedIndex = 0;
|
||||
RayTracingCb.IsChecked = false;
|
||||
}
|
||||
else if (_vulkanChoices is { } kept)
|
||||
{
|
||||
if (GraphicsRules.IsDlss(kept.AntiAliasing) && DlssPlatform && SelectedTag(AntiAliasingCb) == "taa")
|
||||
SelectTag(AntiAliasingCb, AntiAliasingTag(kept.AntiAliasing));
|
||||
SelectTag(FrameGenerationCb, kept.FrameGeneration.ToString(Invariant));
|
||||
SelectTag(ReflexCb, kept.Reflex.ToString(Invariant));
|
||||
RayTracingCb.IsChecked = kept.RayTracing;
|
||||
_vulkanChoices = null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_updatingGraphics = false;
|
||||
}
|
||||
|
||||
UpdateGraphicsState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Brings the graphics controls in line with one another the way the simulator
|
||||
/// treats them, and says why something is off.
|
||||
/// </summary>
|
||||
private void UpdateGraphicsState()
|
||||
{
|
||||
if (!_built || _loading || _updatingGraphics)
|
||||
return;
|
||||
|
||||
_updatingGraphics = true;
|
||||
try
|
||||
{
|
||||
var s = Trial();
|
||||
bool vulkan = GraphicsRules.IsVulkan(s);
|
||||
bool dlssAllowed = GraphicsRules.DlssAllowed(s, DlssPlatform);
|
||||
|
||||
foreach (var item in AntiAliasingCb.Items.OfType<ComboBoxItem>())
|
||||
if (item.Tag is "dlss" or "dlaa")
|
||||
item.IsEnabled = dlssAllowed;
|
||||
if (GraphicsRules.IsDlss(s.AntiAliasing) && !dlssAllowed)
|
||||
SelectTag(AntiAliasingCb, "taa");
|
||||
|
||||
s = Trial();
|
||||
bool dlss = GraphicsRules.DlssActive(s, DlssPlatform);
|
||||
DlssPresetRow.IsEnabled = dlss;
|
||||
FrameGenerationRow.IsEnabled = dlss;
|
||||
if (!dlss && FrameGenerationCb.SelectedIndex > 0)
|
||||
FrameGenerationCb.SelectedIndex = 0;
|
||||
ReflexRow.IsEnabled = vulkan;
|
||||
if (!vulkan && ReflexCb.SelectedIndex > 0)
|
||||
ReflexCb.SelectedIndex = 0;
|
||||
VulkanDeviceRow.IsEnabled = vulkan;
|
||||
RayTracingRow.IsEnabled = vulkan;
|
||||
if (!vulkan)
|
||||
RayTracingCb.IsChecked = false;
|
||||
|
||||
s = Trial();
|
||||
BufferScaleRow.IsEnabled = GraphicsRules.BufferScaleUsed(s, DlssPlatform);
|
||||
RayTracingRangeRow.IsEnabled = vulkan && s.RayTracing;
|
||||
DynamicLightsRow.IsEnabled = GraphicsRules.DynamicLightsUsed(s);
|
||||
AoQualityRow.IsEnabled = s.AmbientOcclusion > 0;
|
||||
AoLightingRow.IsEnabled = GraphicsRules.AoLightingUsed(s);
|
||||
bool probe = GraphicsRules.CabProbeUsed(s);
|
||||
CabProbeIntervalRow.IsEnabled = probe;
|
||||
CabProbeReflectionsRow.IsEnabled = probe;
|
||||
CabProbeBounceRow.IsEnabled = GraphicsRules.CabProbeLights(s);
|
||||
FogQualityRow.IsEnabled = s.VolumetricFog;
|
||||
CloudShadowsRow.IsEnabled = s.Clouds > 0;
|
||||
GrassDistanceRow.IsEnabled = s.Grass;
|
||||
GrassDensityRow.IsEnabled = s.Grass;
|
||||
|
||||
DlssPresetInfo.Text = App.Loc[(SelectedTag(DlssPresetCb) ?? "default") switch
|
||||
{
|
||||
"k" => "DlssPresetInfoK",
|
||||
"j" => "DlssPresetInfoJ",
|
||||
"m" => "DlssPresetInfoM",
|
||||
"l" => "DlssPresetInfoL",
|
||||
_ => "DlssPresetInfoDefault"
|
||||
}];
|
||||
SetNote(RenderEngineNote, App.Loc[vulkan ? "REVulkanNote" : "REOpenGLNote"]);
|
||||
SetNote(AntiAliasingNote, AntiAliasingRemark(s, dlss));
|
||||
SetNote(FrameGenerationNote, FrameGenerationRemark(s, dlss));
|
||||
SetNote(ReflexNote, GraphicsRules.ReflexForced(s, DlssPlatform) ? App.Loc["ReflexForcedNote"] : "");
|
||||
SetNote(AoLightingNote, AoLightingRemark(s));
|
||||
SetNote(CabProbeNote, GraphicsRules.CabProbeUsed(s) && !GraphicsRules.CabProbeLights(s) ? App.Loc["CabProbeReflectionsOnlyNote"] : "");
|
||||
SetNote(SkipPipelineNote, GraphicsRules.TemporalWithoutPipeline(s) ? App.Loc["TemporalNeedsPipelineNote"] : "");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_updatingGraphics = false;
|
||||
}
|
||||
}
|
||||
|
||||
private string AntiAliasingRemark(SimulatorSettings s, bool dlss)
|
||||
{
|
||||
if (!DlssPlatform && GraphicsRules.IsVulkan(s))
|
||||
return App.Loc["DlssNoPlatformNote"];
|
||||
if (GraphicsRules.TemporalWithoutPipeline(s))
|
||||
return App.Loc["TemporalNeedsPipelineNote"];
|
||||
if (dlss && !DlssLibraries(s).Dlss)
|
||||
return string.Format(App.Loc["DlssMissingLibraryNote"], DlssLibraryName(frameGeneration: false));
|
||||
return "";
|
||||
}
|
||||
|
||||
private static string AoLightingRemark(SimulatorSettings s)
|
||||
{
|
||||
if (!GraphicsRules.AoLightingUsed(s) || !s.AoLighting)
|
||||
return "";
|
||||
if (s.SkipPipeline)
|
||||
return App.Loc["AoNeedsPipelineNote"];
|
||||
return GraphicsRules.AoLightingAddsDepthPrepass(s) ? App.Loc["AoLightingPrepassNote"] : "";
|
||||
}
|
||||
|
||||
private string FrameGenerationRemark(SimulatorSettings s, bool dlss)
|
||||
{
|
||||
if (!dlss)
|
||||
return GraphicsRules.IsVulkan(s) ? App.Loc["FrameGenerationNeedsDlssNote"] : "";
|
||||
if (s.FrameGeneration > 1 && !DlssLibraries(s).FrameGeneration)
|
||||
return string.Format(App.Loc["DlssMissingLibraryNote"], DlssLibraryName(frameGeneration: true));
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>Looked up once per simulator picked: the search for it reads the installation's directory.</summary>
|
||||
private (bool Dlss, bool FrameGeneration) DlssLibraries(SimulatorSettings s)
|
||||
{
|
||||
string key = s.SelectExeAutomatically ? "\u0001auto" : s.ExecutablePath;
|
||||
if (_dlssProbedFor != key)
|
||||
{
|
||||
var executables = AppServices.Current.Executables;
|
||||
_dlssProbe = executables.DlssLibraries(executables.Resolve(s, out _));
|
||||
_dlssProbedFor = key;
|
||||
}
|
||||
return _dlssProbe;
|
||||
}
|
||||
|
||||
private static string DlssLibraryName(bool frameGeneration) =>
|
||||
AppServices.Current.Environment.IsWindows
|
||||
? (frameGeneration ? "nvngx_dlssg.dll" : "nvngx_dlss.dll")
|
||||
: (frameGeneration ? "libnvidia-ngx-dlssg.so" : "libnvidia-ngx-dlss.so");
|
||||
|
||||
private async void ImportIniButton_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TopLevel.GetTopLevel(this) is not Window owner)
|
||||
return;
|
||||
|
||||
var picked = await owner.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = App.Loc["ImportIniTitle"],
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = IniTypes
|
||||
});
|
||||
if (picked.Count == 0 || picked[0].TryGetLocalPath() is not { } path)
|
||||
return;
|
||||
|
||||
if (!AppServices.Current.SettingsStore.ImportFrom(path))
|
||||
{
|
||||
await MessageBox.Show(owner, string.Format(App.Loc["ImportIniFailed"], path), App.Loc["ImportIni"],
|
||||
MessageBoxButtons.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
_vulkanChoices = null;
|
||||
ApplyToUi();
|
||||
// What came from the other file is a choice to save, not a value the screen could not show.
|
||||
_shownUnlikeSettings = new Dictionary<string, ShownValue>();
|
||||
MarkDirty();
|
||||
SaveStatus.Text = string.Format(App.Loc["ImportIniDone"], Path.GetFileName(path));
|
||||
}
|
||||
|
||||
private async void ExportIniButton_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (TopLevel.GetTopLevel(this) is not Window owner)
|
||||
return;
|
||||
|
||||
var file = await owner.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||
{
|
||||
Title = App.Loc["ExportIniTitle"],
|
||||
SuggestedFileName = "eu07.ini",
|
||||
DefaultExtension = "ini",
|
||||
FileTypeChoices = IniTypes,
|
||||
ShowOverwritePrompt = true
|
||||
});
|
||||
if (file?.TryGetLocalPath() is not { } path)
|
||||
return;
|
||||
|
||||
// The edits on screen go into the export as they would into a save, but the
|
||||
// user's own eu07.ini is not written.
|
||||
CaptureInto(AppServices.Current.Settings);
|
||||
if (!AppServices.Current.SettingsStore.ExportTo(path))
|
||||
{
|
||||
await MessageBox.Show(owner, string.Format(App.Loc["ExportIniFailed"], path), App.Loc["ExportIni"],
|
||||
MessageBoxButtons.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
SaveStatus.Text = string.Format(App.Loc["ExportIniDone"], Path.GetFileName(path));
|
||||
ToolTip.SetTip(SaveStatus, path);
|
||||
}
|
||||
|
||||
private static void SetNote(TextBlock note, string text)
|
||||
{
|
||||
note.Text = text;
|
||||
note.IsVisible = text.Length > 0;
|
||||
}
|
||||
|
||||
private static string? SelectedTag(ComboBox cb) => (cb.SelectedItem as ComboBoxItem)?.Tag as string;
|
||||
|
||||
private static int TagInt(ComboBox cb, int fallback) =>
|
||||
int.TryParse(SelectedTag(cb), NumberStyles.Integer, Invariant, out int n) ? n : fallback;
|
||||
|
||||
private static void SelectTag(ComboBox cb, string? tag)
|
||||
{
|
||||
int index = IndexOfTag(cb, tag);
|
||||
if (index >= 0)
|
||||
cb.SelectedIndex = index;
|
||||
}
|
||||
|
||||
/// <summary>Selects the item of the tag, adding one for a value from the file the list does not offer.</summary>
|
||||
private static void SelectOrAddTag(ComboBox cb, string tag, string label)
|
||||
{
|
||||
int index = IndexOfTag(cb, tag);
|
||||
if (index < 0)
|
||||
{
|
||||
cb.Items.Add(new ComboBoxItem { Tag = tag, Content = label });
|
||||
index = cb.Items.Count - 1;
|
||||
}
|
||||
cb.SelectedIndex = index;
|
||||
}
|
||||
|
||||
private static string AntiAliasingTag(AntiAliasingMode mode) => mode switch
|
||||
{
|
||||
AntiAliasingMode.Msaa2 => "msaax2",
|
||||
AntiAliasingMode.Msaa4 => "msaax4",
|
||||
AntiAliasingMode.Msaa8 => "msaax8",
|
||||
AntiAliasingMode.Taa => "taa",
|
||||
AntiAliasingMode.Dlss => "dlss",
|
||||
AntiAliasingMode.Dlaa => "dlaa",
|
||||
_ => "off"
|
||||
};
|
||||
|
||||
private static AntiAliasingMode AntiAliasingFromTag(string? tag) => tag switch
|
||||
{
|
||||
"msaax2" => AntiAliasingMode.Msaa2,
|
||||
"msaax4" => AntiAliasingMode.Msaa4,
|
||||
"msaax8" => AntiAliasingMode.Msaa8,
|
||||
"taa" => AntiAliasingMode.Taa,
|
||||
"dlss" => AntiAliasingMode.Dlss,
|
||||
"dlaa" => AntiAliasingMode.Dlaa,
|
||||
_ => AntiAliasingMode.Off
|
||||
};
|
||||
}
|
||||
@@ -56,6 +56,16 @@
|
||||
HorizontalContentAlignment="Center"
|
||||
Content="{Binding [ProfileSaveAs], Source={x:Static starterNg:App.Loc}}"
|
||||
Click="ProfileSaveAsButton_OnClick" />
|
||||
<TextBlock Classes="FieldLabel" Margin="0,8,0,0"
|
||||
Text="{Binding [SettingsFile], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Button x:Name="ImportIniBtn" Classes="Flat" HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center"
|
||||
Content="{Binding [ImportIni], Source={x:Static starterNg:App.Loc}}"
|
||||
Click="ImportIniButton_OnClick" />
|
||||
<Button x:Name="ExportIniBtn" Classes="Flat" HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center"
|
||||
Content="{Binding [ExportIni], Source={x:Static starterNg:App.Loc}}"
|
||||
Click="ExportIniButton_OnClick" />
|
||||
</StackPanel>
|
||||
|
||||
<ListBox x:Name="CategoryList" Classes="SettingsNav" SelectedIndex="0"
|
||||
@@ -63,6 +73,7 @@
|
||||
SelectionChanged="CategoryList_OnSelectionChanged">
|
||||
<ListBoxItem Tag="general" Content="{Binding [General], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ListBoxItem Tag="graphics" Content="{Binding [Graphic], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ListBoxItem Tag="effects" Content="{Binding [Effects], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ListBoxItem Tag="sound" Content="{Binding [Sounds], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ListBoxItem Tag="physics" Content="{Binding [Physics], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ListBoxItem Tag="devices" Content="{Binding [Communication], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -193,10 +204,11 @@
|
||||
<ComboBoxItem Content="{Binding [REExperimental], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [REVulkan], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="RenderEngineNote" Classes="SettingNote" IsVisible="False" />
|
||||
<!-- Amber like the UART warnings: this one stops the simulator. -->
|
||||
<TextBlock x:Name="RenderEngineWarning" IsVisible="False" TextWrapping="Wrap"
|
||||
Foreground="{StaticResource CarbonAccentBright}"
|
||||
Text="{Binding [REExperimentalWarning], Source={x:Static starterNg:App.Loc}}" />
|
||||
<!-- Amber like the UART warnings: this one stops the simulator. -->
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="GpuRow" ConfigKey="starter.gpu" Label="{Binding [GpuChoice], Source={x:Static starterNg:App.Loc}}">
|
||||
@@ -206,19 +218,33 @@
|
||||
<ComboBoxItem Content="{Binding [GpuSystem], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="VulkanDeviceRow" ConfigKey="gfx.vulkan.device"
|
||||
Label="{Binding [VulkanDevice], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [VulkanDeviceDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<TextBox x:Name="VulkanDeviceTb" PlaceholderText="{Binding [VulkanDeviceAuto], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.angleplatform" Description="{Binding [RenderAngleVulkanDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderAngleVulkanCb" Content="{Binding [RenderAngleVulkan], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.extraeffects">
|
||||
<CheckBox x:Name="AdditionalShadersCb" Content="{Binding [AdditionalShadersEffects], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.skippipeline" Description="{Binding [SkipPipelineDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="SkipPipelineCb" Content="{Binding [SkipPipeline], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="6">
|
||||
<CheckBox x:Name="SkipPipelineCb" Content="{Binding [SkipPipeline], Source={x:Static starterNg:App.Loc}}" />
|
||||
<TextBlock x:Name="SkipPipelineNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="usevbo" Description="{Binding [RenderVBODesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderVBOCb" Content="{Binding [RenderVBO], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="rendercab" />
|
||||
<ctl:KeySlot Key="newaircouplers" />
|
||||
<ctl:KeySlot Key="smoothtraction" />
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [GfxColResolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingsSection Header="{Binding [GfxColImage], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="width, height" Label="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ResolutionCb" />
|
||||
@@ -226,7 +252,8 @@
|
||||
<ctl:SettingRow ConfigKey="fullscreenwindowed">
|
||||
<CheckBox x:Name="FullscreenWindowedCb" Content="{Binding [FullscreenWindowed], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="starter.bufferscale" Label="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow x:Name="BufferScaleRow" ConfigKey="gfx.buffer.percent, starter.bufferscale"
|
||||
Label="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [BufforResolutionDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #bufferScale.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider Name="bufferScale" Minimum="25" Maximum="200" TickFrequency="1"
|
||||
@@ -238,6 +265,61 @@
|
||||
<Slider Name="fovSlider" Minimum="10" Maximum="75" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="45" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.antialiasing, multisampling"
|
||||
Label="{Binding [AntiAliasing], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [AntiAliasingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<ComboBox x:Name="AntiAliasingCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="off" Content="{Binding [MsaaNone], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="msaax2" Content="MSAA x2" />
|
||||
<ComboBoxItem Tag="msaax4" Content="MSAA x4" />
|
||||
<ComboBoxItem Tag="msaax8" Content="MSAA x8" />
|
||||
<ComboBoxItem Tag="taa" Content="{Binding [AaTaa], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="dlss" Content="{Binding [AaDlss], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="dlaa" Content="{Binding [AaDlaa], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="AntiAliasingNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="DlssPresetRow" ConfigKey="gfx.dlss.preset"
|
||||
Label="{Binding [DlssPreset], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [DlssPresetDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<ComboBox x:Name="DlssPresetCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="default" Content="{Binding [DlssPresetDefault], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="k" Content="{Binding [DlssPresetK], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="j" Content="{Binding [DlssPresetJ], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="m" Content="{Binding [DlssPresetM], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="l" Content="{Binding [DlssPresetL], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="DlssPresetInfo" Classes="FieldHint" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="FrameGenerationRow" ConfigKey="gfx.framegeneration"
|
||||
Label="{Binding [FrameGeneration], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [FrameGenerationDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<ComboBox x:Name="FrameGenerationCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="x2" />
|
||||
<ComboBoxItem Tag="3" Content="x3" />
|
||||
<ComboBoxItem Tag="4" Content="x4" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="FrameGenerationNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="ReflexRow" ConfigKey="gfx.reflex"
|
||||
Label="{Binding [Reflex], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [ReflexDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<ComboBox x:Name="ReflexCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [ReflexOn], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [ReflexBoost], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="ReflexNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
@@ -302,52 +384,41 @@
|
||||
<Slider x:Name="TexFilteringSlider"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="multisampling" x:Name="MultisamplingRow"
|
||||
Label="{Binding [Multisampling], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [MultisamplingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<!-- Moves through Steps.MultisamplingLevels; see SliderSteps. -->
|
||||
<Slider x:Name="MultisamplingSlider"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="gfx.textures.streaming" />
|
||||
<ctl:KeySlot Key="gfx.textures.releasedistance" />
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="EffectsSection" Header="{Binding [GfxColEffects], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingsSection Header="{Binding [GfxColScripts], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="gfx.extraeffects">
|
||||
<CheckBox x:Name="AdditionalShadersCb" Content="{Binding [AdditionalShadersEffects], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingRow ConfigKey="python.enabled" Description="{Binding [RenderScreensDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderScreensCb" Content="{Binding [RenderScreens], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.chromaticaberration.enabled">
|
||||
<CheckBox x:Name="ChromaticAberrationCb" Content="{Binding [ChromaticAberration], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.motionblur.enabled">
|
||||
<CheckBox x:Name="MotionBlurCb" Content="{Binding [MotionBlur], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="gfx.postfx.motionblur.shutter" />
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke" Margin="0,0,0,4">
|
||||
<CheckBox x:Name="SmokeDisplayCb" Content="{Binding [SmokeDisplay], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke.fidelity" x:Name="SmokeParticlesRow"
|
||||
Label="{Binding [SmokeParticlesMultiplier], Source={x:Static starterNg:App.Loc}}"
|
||||
IsEnabled="{Binding #SmokeDisplayCb.IsChecked}">
|
||||
<Slider x:Name="SmokeParticlesSlider" Minimum="1" Maximum="4" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="2"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [DynamicLightsDesc], Source={x:Static starterNg:App.Loc}}" ConfigKey="dynamiclights" Label="{Binding [DynamicLights], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #DynamicLightsSlider.Value, StringFormat='{}{0:0}'}">
|
||||
<Slider x:Name="DynamicLightsSlider" Minimum="0" Maximum="7" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="7" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="skyenabled" />
|
||||
<ctl:KeySlot Key="rendercab" />
|
||||
<ctl:KeySlot Key="newaircouplers" />
|
||||
<ctl:KeySlot Key="smoothtraction" />
|
||||
<StackPanel IsEnabled="{Binding #RenderScreensCb.IsChecked}">
|
||||
<ctl:SettingRow ConfigKey="python.threadedupload">
|
||||
<CheckBox x:Name="RenderScreensThreadCb" Content="{Binding [RenderScreensThread], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="python.updatetime" Label="{Binding [PyScreenPriority], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [PyScreenPriorityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="PyScreenPriorityCb" Classes="Localized">
|
||||
<ComboBoxItem Tag="200" Content="{Binding [PyPriorityNormal], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="400" Content="{Binding [PyPriorityLower], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="800" Content="{Binding [PyPriorityLowest], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1600" Content="{Binding [PyPriorityIdle], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="python.fpslimit" />
|
||||
<ctl:KeySlot Key="python.vsync" />
|
||||
<ctl:KeySlot Key="python.displaywindows" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============================ EFFECTS ============================ -->
|
||||
<StackPanel Tag="effects" IsVisible="False">
|
||||
<TextBlock Classes="CategoryCaption" IsVisible="False"
|
||||
Text="{Binding [Effects], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingsSection ToggleKey="shadows" x:Name="ShadowsSection" Header="{Binding [GfxColShadows], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingsSection.Toggle>
|
||||
<CheckBox x:Name="RenderShadowsCb" FontSize="12" MinHeight="0"
|
||||
@@ -382,6 +453,9 @@
|
||||
IsSnapToTickEnabled="True" Value="30"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.shadow.sdsm" Description="{Binding [ShadowSdsmDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="ShadowSdsmCb" Content="{Binding [ShadowSdsm], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.shadow.angle.min" x:Name="ShadowAngleLimitRow"
|
||||
Label="{Binding [ShadowAngleLimit], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [ShadowAngleLimitDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
@@ -400,6 +474,84 @@
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="LightsSection" Header="{Binding [GfxColLights], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="gfx.lights.clustered" Description="{Binding [LightsClusteredDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="LightsClusteredCb" Content="{Binding [LightsClustered], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="DynamicLightsRow" Description="{Binding [DynamicLightsDesc], Source={x:Static starterNg:App.Loc}}" ConfigKey="dynamiclights" Label="{Binding [DynamicLights], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #DynamicLightsSlider.Value, StringFormat='{}{0:0}'}">
|
||||
<Slider x:Name="DynamicLightsSlider" Minimum="0" Maximum="7" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="7" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.lights.shadows" Label="{Binding [LightShadows], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [LightShadowsDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="LightShadowsCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.contactshadows" Label="{Binding [ContactShadows], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [ContactShadowsDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ContactShadowsCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.ao" Label="{Binding [AmbientOcclusion], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [AmbientOcclusionDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="AmbientOcclusionCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="SSAO" />
|
||||
<ComboBoxItem Tag="2" Content="GTAO" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="AoLightingRow" ConfigKey="gfx.postfx.ao.lighting" Description="{Binding [AoLightingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<CheckBox x:Name="AoLightingCb" Content="{Binding [AoLighting], Source={x:Static starterNg:App.Loc}}" />
|
||||
<TextBlock x:Name="AoLightingNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="AoQualityRow" ConfigKey="gfx.postfx.ao.quality" Label="{Binding [AmbientOcclusionQuality], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="AoQualityCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="2 3" Content="{Binding [QualityLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3 4" Content="{Binding [QualityNormal], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="4 6" Content="{Binding [QualityHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="6 8" Content="{Binding [QualityVeryHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.cabprobe" Label="{Binding [CabProbe], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [CabProbeDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel Spacing="6">
|
||||
<ComboBox x:Name="CabProbeCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
<TextBlock x:Name="CabProbeNote" Classes="SettingNote" IsVisible="False" />
|
||||
</StackPanel>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CabProbeIntervalRow" ConfigKey="gfx.cabprobe.interval"
|
||||
Label="{Binding [CabProbeInterval], Source={x:Static starterNg:App.Loc}}">
|
||||
<NumericUpDown x:Name="CabProbeIntervalNud" Minimum="1" Maximum="120" Value="4" Increment="1" FormatString="0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CabProbeBounceRow" ConfigKey="gfx.cabprobe.bounce"
|
||||
Label="{Binding [CabProbeBounce], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [CabProbeBounceDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #CabProbeBounceSlider.Value, StringFormat='{}{0:0.0}'}">
|
||||
<Slider x:Name="CabProbeBounceSlider" Minimum="0" Maximum="4" TickFrequency="0.1" IsSnapToTickEnabled="True" Value="1" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CabProbeReflectionsRow" ConfigKey="gfx.cabprobe.reflections" Description="{Binding [CabProbeReflectionsDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="CabProbeReflectionsCb" Content="{Binding [CabProbeReflections], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="ReflectionsSection" Header="{Binding [GfxColReflections], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="gfx.envmap.enabled" Description="{Binding [ReflectionsCubeMapDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
@@ -424,66 +576,109 @@
|
||||
<ctl:KeySlot Key="gfx.reflections.range_instances" />
|
||||
<ctl:KeySlot Key="gfx.reflections.range_vehicles" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="NewRendererSection" Header="{Binding [GfxColNewRenderer], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:KeySlot Key="gfx.antialiasing" />
|
||||
<ctl:KeySlot Key="gfx.dlss.preset" />
|
||||
<ctl:KeySlot Key="gfx.framegeneration" />
|
||||
<ctl:KeySlot Key="gfx.reflex" />
|
||||
<ctl:KeySlot Key="gfx.lights.clustered" />
|
||||
<ctl:KeySlot Key="gfx.lights.shadows" />
|
||||
<ctl:KeySlot Key="gfx.contactshadows" />
|
||||
<ctl:KeySlot Key="gfx.shadow.sdsm" />
|
||||
<ctl:KeySlot Key="gfx.postfx.ao" />
|
||||
<ctl:KeySlot Key="gfx.postfx.ao.quality" />
|
||||
<ctl:KeySlot Key="gfx.postfx.ao.lighting" />
|
||||
<ctl:KeySlot Key="gfx.ssr" />
|
||||
<ctl:KeySlot Key="gfx.raytracing" />
|
||||
<ctl:KeySlot Key="gfx.raytracing.range" />
|
||||
<ctl:KeySlot Key="gfx.cabprobe" />
|
||||
<ctl:KeySlot Key="gfx.cabprobe.interval" />
|
||||
<ctl:KeySlot Key="gfx.cabprobe.reflections" />
|
||||
<ctl:KeySlot Key="gfx.cabprobe.bounce" />
|
||||
<ctl:KeySlot Key="gfx.fog" />
|
||||
<ctl:KeySlot Key="gfx.fog.quality" />
|
||||
<ctl:KeySlot Key="gfx.clouds" />
|
||||
<ctl:KeySlot Key="gfx.clouds.shadows" />
|
||||
<ctl:KeySlot Key="gfx.precipitation.particles" />
|
||||
<ctl:KeySlot Key="gfx.grass" />
|
||||
<ctl:KeySlot Key="gfx.grass.distance" />
|
||||
<ctl:KeySlot Key="gfx.grass.fadedistance" />
|
||||
<ctl:KeySlot Key="gfx.grass.density" />
|
||||
<ctl:KeySlot Key="gfx.postfx.bloom" />
|
||||
<ctl:KeySlot Key="gfx.postfx.autoexposure" />
|
||||
<ctl:KeySlot Key="gfx.vulkan.device" />
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [GfxColScripts], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="python.enabled" Description="{Binding [RenderScreensDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderScreensCb" Content="{Binding [RenderScreens], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingRow ConfigKey="gfx.ssr" Label="{Binding [Ssr], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [SsrDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="SsrCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="RayTracingRow" ConfigKey="gfx.raytracing" Description="{Binding [RayTracingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RayTracingCb" Content="{Binding [RayTracing], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="RayTracingRangeRow" ConfigKey="gfx.raytracing.range"
|
||||
Label="{Binding [RayTracingRange], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #RayTracingRangeSlider.Value, StringFormat='{}{0:0} m'}">
|
||||
<Slider x:Name="RayTracingRangeSlider" Minimum="50" Maximum="2000" TickFrequency="50" IsSnapToTickEnabled="True" Value="500" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="AtmosphereSection" Header="{Binding [GfxColAtmosphere], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:KeySlot Key="skyenabled" />
|
||||
<ctl:SettingRow ConfigKey="gfx.fog" Description="{Binding [VolumetricFogDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="VolumetricFogCb" Content="{Binding [VolumetricFog], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="FogQualityRow" ConfigKey="gfx.fog.quality" Label="{Binding [FogQuality], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="FogQualityCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="4" Content="{Binding [LevelUltra], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.clouds" Label="{Binding [Clouds], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [CloudsDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="CloudsCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [LevelOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [LevelLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [LevelMedium], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [LevelHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="4" Content="{Binding [LevelUltra], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CloudShadowsRow" ConfigKey="gfx.clouds.shadows">
|
||||
<CheckBox x:Name="CloudShadowsCb" Content="{Binding [CloudShadows], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="PostFxSection" Header="{Binding [GfxColPostFx], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.bloom">
|
||||
<CheckBox x:Name="BloomCb" Content="{Binding [Bloom], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.autoexposure" Description="{Binding [AutoExposureDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="AutoExposureCb" Content="{Binding [AutoExposure], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.motionblur.enabled">
|
||||
<CheckBox x:Name="MotionBlurCb" Content="{Binding [MotionBlur], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="gfx.postfx.motionblur.shutter" />
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.chromaticaberration.enabled">
|
||||
<CheckBox x:Name="ChromaticAberrationCb" Content="{Binding [ChromaticAberration], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
|
||||
<ctl:SettingsSection x:Name="NatureSection" Header="{Binding [GfxColNature], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow ConfigKey="gfx.grass" Margin="0,0,0,4">
|
||||
<CheckBox x:Name="GrassCb" Content="{Binding [Grass], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="GrassDistanceRow" ConfigKey="gfx.grass.distance, gfx.grass.fadedistance"
|
||||
Label="{Binding [GrassDistance], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #GrassDistanceSlider.Value, StringFormat='{}{0:0} m'}">
|
||||
<Slider x:Name="GrassDistanceSlider" Minimum="20" Maximum="300" TickFrequency="10" IsSnapToTickEnabled="True" Value="60" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="GrassDensityRow" ConfigKey="gfx.grass.density"
|
||||
Label="{Binding [GrassDensity], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #GrassDensitySlider.Value, StringFormat='{}{0:0.00}'}">
|
||||
<Slider x:Name="GrassDensitySlider" Minimum="0.25" Maximum="2.0" TickFrequency="0.25" IsSnapToTickEnabled="True" Value="1.0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke" Margin="0,0,0,4">
|
||||
<CheckBox x:Name="SmokeDisplayCb" Content="{Binding [SmokeDisplay], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke.fidelity" x:Name="SmokeParticlesRow"
|
||||
Label="{Binding [SmokeParticlesMultiplier], Source={x:Static starterNg:App.Loc}}"
|
||||
IsEnabled="{Binding #SmokeDisplayCb.IsChecked}">
|
||||
<Slider x:Name="SmokeParticlesSlider" Minimum="1" Maximum="4" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="2"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.precipitation.particles" Label="{Binding [Precipitation], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [PrecipitationDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="PrecipitationCb" Classes="Localized" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="16384" Content="{Binding [QualityVeryLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="32768" Content="{Binding [QualityLow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="65536" Content="{Binding [QualityNormal], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="131072" Content="{Binding [QualityHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="262144" Content="{Binding [QualityVeryHigh], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<StackPanel IsEnabled="{Binding #RenderScreensCb.IsChecked}">
|
||||
<ctl:SettingRow ConfigKey="python.threadedupload">
|
||||
<CheckBox x:Name="RenderScreensThreadCb" Content="{Binding [RenderScreensThread], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="python.updatetime" Label="{Binding [PyScreenPriority], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [PyScreenPriorityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="PyScreenPriorityCb" Classes="Localized">
|
||||
<ComboBoxItem Tag="200" Content="{Binding [PyPriorityNormal], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="400" Content="{Binding [PyPriorityLower], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="800" Content="{Binding [PyPriorityLowest], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1600" Content="{Binding [PyPriorityIdle], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:KeySlot Key="python.fpslimit" />
|
||||
<ctl:KeySlot Key="python.vsync" />
|
||||
<ctl:KeySlot Key="python.displaywindows" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ctl:SettingsSection>
|
||||
</StackPanel>
|
||||
|
||||
@@ -38,8 +38,6 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
|
||||
private readonly SliderSteps _anisotropy;
|
||||
|
||||
private readonly SliderSteps _multisampling;
|
||||
|
||||
private readonly SliderSteps _drawRangeFactor;
|
||||
|
||||
// False while the layout loads: the handlers it names fire as it sets their controls'
|
||||
@@ -62,7 +60,6 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
_fpsLimit = new SliderSteps(FpsLimitSlider, Steps.FrameRateLimits);
|
||||
_reflections = new SliderSteps(reflectionsFramerate, Steps.ReflectionUpdates);
|
||||
_anisotropy = new SliderSteps(TexFilteringSlider, Steps.Anisotropy);
|
||||
_multisampling = new SliderSteps(MultisamplingSlider, Steps.MultisamplingLevels);
|
||||
_drawRangeFactor = new SliderSteps(RenderRangeSlider, Steps.DrawRangeFactors);
|
||||
_built = true;
|
||||
|
||||
@@ -115,6 +112,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
if (string.Equals(key.Key, "targetfps", StringComparison.OrdinalIgnoreCase))
|
||||
UpdateIdleNotes();
|
||||
};
|
||||
InitGraphics();
|
||||
MotionBlurCb.IsCheckedChanged += (_, _) => UpdateDependentRows();
|
||||
ReflectionsCubeMapCb.IsCheckedChanged += (_, _) => UpdateDependentRows();
|
||||
|
||||
@@ -369,6 +367,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
RefreshDerivedRows();
|
||||
UpdateGpuNote();
|
||||
NoteShownValues();
|
||||
UpdateGraphicsState();
|
||||
UpdatePresetMarks();
|
||||
}
|
||||
|
||||
@@ -403,14 +402,13 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
VirtualShuntingCb.IsChecked = s.VirtualShunting;
|
||||
LogMissingVehicleFilesCb.IsChecked = s.LogMissingVehicleFiles;
|
||||
|
||||
RenderEngineCb.SelectedIndex = s.RenderEngine;
|
||||
ShowGraphics(s);
|
||||
GpuCb.SelectedIndex = s.Gpu == GpuPreference.System ? 1 : 0;
|
||||
SelectResolution(s.Width, s.Height);
|
||||
bufferScale.Value = s.BufferScalePercent;
|
||||
textureResolutionSlider.Value = Log2(s.MaxTextureSize, 12);
|
||||
cabTextureResolutionSlider.Value = Log2(s.MaxCabTextureSize, 12);
|
||||
_anisotropy.Value = s.TextureFiltering;
|
||||
_multisampling.Value = s.Multisampling;
|
||||
DynamicLightsSlider.Value = s.DynamicLights;
|
||||
_drawRangeFactor.Value = s.DrawRangeFactor;
|
||||
VSyncCb.IsChecked = s.VSync;
|
||||
@@ -493,6 +491,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
UpdateQualityCaptions();
|
||||
UpdateIdleNotes();
|
||||
UpdateDependentRows();
|
||||
UpdateGraphicsState();
|
||||
}
|
||||
|
||||
// ── Levels of detail ─────────────────────────────────────────────────────
|
||||
@@ -515,8 +514,9 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
foreach (var (section, group) in new[]
|
||||
{
|
||||
(DrawRangeSection, GraphicsGroup.DrawRange), (TexturesSection, GraphicsGroup.Textures),
|
||||
(EffectsSection, GraphicsGroup.Effects), (ShadowsSection, GraphicsGroup.Shadows),
|
||||
(ReflectionsSection, GraphicsGroup.Reflections), (NewRendererSection, GraphicsGroup.NewRenderer)
|
||||
(ShadowsSection, GraphicsGroup.Shadows), (LightsSection, GraphicsGroup.Lights),
|
||||
(ReflectionsSection, GraphicsGroup.Reflections), (AtmosphereSection, GraphicsGroup.Atmosphere),
|
||||
(NatureSection, GraphicsGroup.Nature)
|
||||
})
|
||||
{
|
||||
var levels = new ComboBox();
|
||||
@@ -806,14 +806,13 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
s.VirtualShunting = IsChecked(VirtualShuntingCb);
|
||||
s.LogMissingVehicleFiles = IsChecked(LogMissingVehicleFilesCb);
|
||||
|
||||
s.RenderEngine = Math.Max(0, RenderEngineCb.SelectedIndex);
|
||||
CaptureGraphics(s);
|
||||
s.Gpu = SelectedGpu();
|
||||
ReadResolution(s);
|
||||
s.BufferScalePercent = (int)bufferScale.Value;
|
||||
s.MaxTextureSize = 1 << (int)textureResolutionSlider.Value;
|
||||
s.MaxCabTextureSize = 1 << (int)cabTextureResolutionSlider.Value;
|
||||
s.TextureFiltering = _anisotropy.Value;
|
||||
s.Multisampling = (int)_multisampling.Value;
|
||||
s.DynamicLights = (int)DynamicLightsSlider.Value;
|
||||
s.DrawRangeFactor = _drawRangeFactor.Value;
|
||||
s.VSync = IsChecked(VSyncCb);
|
||||
@@ -1010,6 +1009,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
if (!_built)
|
||||
return;
|
||||
|
||||
OnBackendChanged();
|
||||
RefreshDerivedRows();
|
||||
}
|
||||
|
||||
@@ -1315,7 +1315,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
bool bindings = category == "controls";
|
||||
ControlsHost.IsVisible = bindings;
|
||||
SettingsScroll.IsVisible = !bindings;
|
||||
PresetBar.IsVisible = category == "graphics" && !searching;
|
||||
PresetBar.IsVisible = category is "graphics" or "effects" && !searching;
|
||||
|
||||
if (bindings)
|
||||
{
|
||||
@@ -1422,6 +1422,9 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
case NumericUpDown nud:
|
||||
nud.ValueChanged += (_, _) => OnControlChanged();
|
||||
break;
|
||||
case TextBox box when ReferenceEquals(box, VulkanDeviceTb):
|
||||
box.TextChanged += (_, _) => OnControlChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1434,6 +1437,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
{
|
||||
MarkDirty();
|
||||
QueuePresetMarks();
|
||||
UpdateGraphicsState();
|
||||
}
|
||||
|
||||
private void MarkDirty()
|
||||
@@ -1485,8 +1489,6 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
TrackCurvesRow.ValueText = SettingTexts.Fidelity((int)TrackCurvesSlider.Value);
|
||||
SmokeParticlesRow.ValueText = SettingTexts.Fidelity((int)SmokeParticlesSlider.Value);
|
||||
|
||||
MultisamplingRow.ValueText = SettingTexts.Multisampling((int)_multisampling.Value);
|
||||
|
||||
RenderRangeRow.ValueText = "×" + _drawRangeFactor.Value.ToString("0.0", CultureInfo.CurrentCulture);
|
||||
|
||||
CursorSensitivityRow.ValueText = (int)CursorSensitivitySlider.Value switch
|
||||
|
||||
@@ -77,7 +77,6 @@ internal sealed class SimulatorKeyRows
|
||||
TickFrequency = key.Step,
|
||||
IsSnapToTickEnabled = true
|
||||
},
|
||||
SimulatorKeyKind.Choice => ChoiceBox(key),
|
||||
_ => new TextBox { MinWidth = 200 }
|
||||
};
|
||||
|
||||
@@ -103,23 +102,11 @@ internal sealed class SimulatorKeyRows
|
||||
case TextBox text:
|
||||
text.TextChanged += (_, _) => OnEdited(row);
|
||||
break;
|
||||
case ComboBox box:
|
||||
box.SelectionChanged += (_, _) => OnEdited(row);
|
||||
break;
|
||||
}
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
private static ComboBox ChoiceBox(SimulatorKey key)
|
||||
{
|
||||
var box = new ComboBox();
|
||||
box.Classes.Add("Localized");
|
||||
foreach (string word in key.Words ?? Array.Empty<string>())
|
||||
box.Items.Add(new ComboBoxItem { Tag = word });
|
||||
return box;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only a value other than the one shown counts: a text box reports the text it
|
||||
/// was given after the fact, and a slider reports its own clamping.
|
||||
@@ -172,11 +159,6 @@ internal sealed class SimulatorKeyRows
|
||||
row.Setting.Label = label;
|
||||
text.PlaceholderText = App.Loc["IniDefault"];
|
||||
break;
|
||||
case ComboBox choice:
|
||||
row.Setting.Label = label;
|
||||
foreach (var item in choice.Items.OfType<ComboBoxItem>())
|
||||
item.Content = App.Loc[SimulatorKey.WordKey(item.Tag as string ?? string.Empty)];
|
||||
break;
|
||||
default:
|
||||
row.Setting.Label = label;
|
||||
UpdateValueText(row);
|
||||
@@ -242,10 +224,6 @@ internal sealed class SimulatorKeyRows
|
||||
case TextBox text:
|
||||
text.Text = raw.Trim();
|
||||
break;
|
||||
case ComboBox choice:
|
||||
string word = row.Key.ParseChoice(raw);
|
||||
choice.SelectedItem = choice.Items.OfType<ComboBoxItem>().FirstOrDefault(item => item.Tag as string == word);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +232,6 @@ internal sealed class SimulatorKeyRows
|
||||
CheckBox box => SimulatorKey.FormatToggle(box.IsChecked == true),
|
||||
Slider slider => row.Key.FormatNumber(slider.Value),
|
||||
TextBox text => (text.Text ?? string.Empty).Trim(),
|
||||
ComboBox choice => (choice.SelectedItem as ComboBoxItem)?.Tag as string ?? row.Key.Default,
|
||||
_ => string.Empty
|
||||
};
|
||||
|
||||
|
||||
@@ -406,11 +406,7 @@
|
||||
|
||||
<String key="Graphic">Grafika</String>
|
||||
<String key="RenderEngine">Vykreslovací engine</String>
|
||||
<String key="REFull">Plný</String>
|
||||
<String key="RenderEngineDesc">Plný: OpenGL se stíny a odrazy, v novém simulátoru OpenGL 4.6. Starý, Zjednodušený, Experimentální: starší verze simulátoru, nová spustí Plný. Vulkan 1.4: když ho exe nemá nebo ho karta nezvládne, nová verze spustí OpenGL a starší Starý.</String>
|
||||
<String key="REOld">Starý</String>
|
||||
<String key="RESimp">Zjednodušený</String>
|
||||
<String key="REExperimental">Experimentální</String>
|
||||
<String key="RenderEngineDesc">Plný funguje s každým exe. Starý, Zjednodušený a Experimentální jen se staršími, nový místo nich spustí Plný.</String>
|
||||
<String key="REExperimentalWarning">Upozornění: experimentální renderer je ve vývoji. Může být nestabilní, nezobrazovat části scény nebo se na některých grafických kartách nespustit. Pokud se simulátor nespustí nebo vypadá špatně, vraťte se k rendereru „Plný“.</String>
|
||||
<String key="GpuChoice">Grafická karta (Linux)</String>
|
||||
<String key="GpuDiscrete">Výkonnější (dedikovaná)</String>
|
||||
@@ -436,8 +432,6 @@
|
||||
<String key="MaxTexCabResolution">Maximální rozlišení textur kabiny</String>
|
||||
<String key="TexFilteringQuality">Kvalita filtrování textur</String>
|
||||
<String key="TexFilteringQualityDesc">Ostrost textur viděných pod úhlem, např. kolejí. I x16 stojí málo.</String>
|
||||
<String key="Multisampling">Multisampling</String>
|
||||
<String key="MultisamplingDesc">Vyhlazování hran. Každý stupeň znatelně ubírá snímky.</String>
|
||||
<String key="QualityVeryLow">Velmi nízká</String>
|
||||
<String key="QualityLow">Nízká</String>
|
||||
<String key="QualityNormal">Normální</String>
|
||||
@@ -462,7 +456,6 @@
|
||||
<String key="ShadowAngleLimit">Omezení délky stínů</String>
|
||||
<String key="ShadowLimitShort">Zkrácené</String>
|
||||
<String key="FullscreenWindowed">Automatické rozlišení (celá obrazovka bez okrajů)</String>
|
||||
<String key="RenderAngleVulkan">Použít renderer ANGLE Vulkan</String>
|
||||
<String key="VSync">VSync</String>
|
||||
<String key="SmokeDisplay">Zobrazení kouře</String>
|
||||
<String key="SmokeParticlesMultiplier">Násobitel částic kouře</String>
|
||||
@@ -472,7 +465,6 @@
|
||||
<String key="AdditionalShadersEffects">Další efekty shaderů</String>
|
||||
<String key="ReflectionsCubeMap">Odrazy jako cubemapa</String>
|
||||
<String key="SkipPipeline">SkipPipeline</String>
|
||||
<String key="RenderVBO">Vykreslování VBO</String>
|
||||
<String key="RenderShadows">Vykreslovat stíny</String>
|
||||
<String key="ReflectionsFramerate">Frekvence obnovy odrazů</String>
|
||||
<String key="ReflectionsFramerateDesc">Jak často obnovovat odrazy. Méně často znamená více snímků.</String>
|
||||
@@ -482,7 +474,6 @@
|
||||
<String key="ShadowsResolution">Rozlišení stínů</String>
|
||||
<String key="ShaderRange">Dosah stínů</String>
|
||||
<String key="ShaderRangeDesc">Jak daleko sahají stíny; čím dál, tím méně ostré. Za šipkou skutečný dosah.</String>
|
||||
<String key="CabShadowsRange">Dosah zdrojů stínů v kabině</String>
|
||||
|
||||
<String key="ShadowDisplay">Zobrazovat stíny</String>
|
||||
<String key="CSROnlyImportant">Jen důležité</String>
|
||||
@@ -527,8 +518,6 @@
|
||||
<String key="CompressTextures">Komprimovat textury TGA</String>
|
||||
<String key="ScaleSpeculars">Škálovat odlesky (kompatibilita starých modelů)</String>
|
||||
<String key="ScaleSpecularsDesc">Zeslabuje lesk modelů dělaných pro starší renderery.</String>
|
||||
<String key="UseGLES">Použít OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES místo OpenGL. Nefunguje s rendererem legacy.</String>
|
||||
<String key="ShaderGamma">Gama korekce v shaderech</String>
|
||||
<String key="ShaderGammaDesc">Gama v shaderech místo sRGB. Když ovladač dává příliš světlý nebo tmavý obraz.</String>
|
||||
<String key="ScreenMipmaps">Generovat mipmapy pro textury displejů v kabině (Python)</String>
|
||||
@@ -674,7 +663,6 @@
|
||||
<String key="GfxColResolution">Obraz</String>
|
||||
<String key="GfxColRendering">Renderer</String>
|
||||
<String key="GfxColShadows">Stíny</String>
|
||||
<String key="GfxColEffects">Efekty</String>
|
||||
<String key="GfxColTextures">Textury a vyhlazování</String>
|
||||
<String key="GfxColDrawRange">Dohlednost</String>
|
||||
<String key="GfxColSmoothness">Plynulost</String>
|
||||
@@ -867,62 +855,90 @@
|
||||
<String key="GfxGroupLevelTip">Úroveň jen pro tuto část grafiky</String>
|
||||
<String key="REVulkan">Vulkan 1.4</String>
|
||||
<String key="IdleVulkanOnly">Funguje jen s Vulkanem.</String>
|
||||
<String key="GfxColNewRenderer">Nový renderer (OpenGL 4.6, Vulkan)</String>
|
||||
<String key="Ini.gfx.antialiasing">Vyhlazování TAA / DLSS</String>
|
||||
<String key="Ini.gfx.dlss.preset">Předvolba DLSS</String>
|
||||
<String key="Ini.gfx.framegeneration">Generování snímků</String>
|
||||
<String key="Ini.gfx.reflex">NVIDIA Reflex</String>
|
||||
<String key="Ini.gfx.raytracing">Odrazy ray tracing</String>
|
||||
<String key="Ini.gfx.raytracing.range">Dosah ray tracingu</String>
|
||||
<String key="Ini.gfx.vulkan.device">Grafická karta (Vulkan)</String>
|
||||
<String key="Ini.gfx.ssr">Odrazy v prostoru obrazovky (SSR)</String>
|
||||
<String key="Ini.gfx.postfx.ao">Okolní zastínění</String>
|
||||
<String key="Ini.gfx.postfx.ao.quality">Kvalita zastínění</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting">Zastínění v okolním světle</String>
|
||||
<String key="Ini.gfx.lights.clustered">Klastrové osvětlení</String>
|
||||
<String key="Ini.gfx.lights.shadows">Stíny lamp a reflektorů</String>
|
||||
<String key="Ini.gfx.contactshadows">Kontaktní stíny</String>
|
||||
<String key="Ini.gfx.shadow.sdsm">Kaskády stínů podle scény (SDSM)</String>
|
||||
<String key="Ini.gfx.cabprobe">Sonda kabiny</String>
|
||||
<String key="Ini.gfx.cabprobe.interval">Obnovení sondy každých N snímků</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections">Kabina odráží sebe</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce">Odražené světlo lampy v kabině</String>
|
||||
<String key="Ini.gfx.fog">Mlha</String>
|
||||
<String key="Ini.gfx.fog.quality">Kvalita mlhy</String>
|
||||
<String key="Ini.gfx.clouds">Objemová oblaka</String>
|
||||
<String key="Ini.gfx.clouds.shadows">Stíny oblaků na zemi</String>
|
||||
<String key="Ini.gfx.grass">Tráva</String>
|
||||
<String key="Ini.gfx.grass.distance">Dosah trávy</String>
|
||||
<String key="Ini.gfx.grass.fadedistance">Tráva mizí do</String>
|
||||
<String key="Ini.gfx.grass.density">Hustota trávy</String>
|
||||
<String key="Ini.gfx.precipitation.particles">Srážky (částice)</String>
|
||||
<String key="Ini.gfx.postfx.bloom">Záře světlých míst (bloom)</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure">Automatická expozice</String>
|
||||
<String key="IniWord.same">Jako MSAA výše</String>
|
||||
<String key="IniWord.no">Vypnuto</String>
|
||||
<String key="IniWord.off">Vypnuto</String>
|
||||
<String key="IniWord.low">Nízká</String>
|
||||
<String key="IniWord.medium">Střední</String>
|
||||
<String key="IniWord.high">Vysoká</String>
|
||||
<String key="IniWord.ultra">Ultra</String>
|
||||
<String key="IniWord.on">Zapnuto</String>
|
||||
<String key="IniWord.boost">Zapnuto + boost</String>
|
||||
<String key="IniWord.ssao">SSAO</String>
|
||||
<String key="IniWord.gtao">GTAO</String>
|
||||
<String key="IniWord.volumetric">Objemová</String>
|
||||
<String key="IniWord.analytic">Analytická</String>
|
||||
<String key="IniWord.default">Automaticky</String>
|
||||
<String key="IniWord.k">K: nejlepší kvalita</String>
|
||||
<String key="IniWord.j">J: méně rozmazání</String>
|
||||
<String key="IniWord.m">M: pro režim Výkon</String>
|
||||
<String key="IniWord.l">L: pro Ultra výkon</String>
|
||||
<String key="IniWord.x2">x2</String>
|
||||
<String key="IniWord.x3">x3</String>
|
||||
<String key="IniWord.x4">x4</String>
|
||||
<String key="IniWord.taa">TAA</String>
|
||||
<String key="IniWord.dlss">DLSS (škálování)</String>
|
||||
<String key="IniWord.dlaa">DLAA (nativní rozlišení)</String>
|
||||
<String key="IniWord.3_4">Výchozí (3×4)</String>
|
||||
<String key="IniWord.4_6">Vysoká (4×6)</String>
|
||||
<String key="IniWord.6_8">Ultra (6×8)</String>
|
||||
<String key="DlssPreset">Předvolba DLSS</String>
|
||||
<String key="FrameGeneration">Generování snímků</String>
|
||||
<String key="Reflex">NVIDIA Reflex</String>
|
||||
<String key="RayTracing">Odrazy ray tracing</String>
|
||||
<String key="RayTracingRange">Dosah ray tracingu</String>
|
||||
<String key="VulkanDevice">Grafická karta (Vulkan)</String>
|
||||
<String key="Ssr">Odrazy v prostoru obrazovky (SSR)</String>
|
||||
<String key="AmbientOcclusion">Okolní zastínění</String>
|
||||
<String key="AmbientOcclusionQuality">Kvalita zastínění</String>
|
||||
<String key="AoLighting">Zastínění v okolním světle</String>
|
||||
<String key="LightsClustered">Klastrové osvětlení</String>
|
||||
<String key="LightShadows">Stíny lamp a reflektorů</String>
|
||||
<String key="ContactShadows">Kontaktní stíny</String>
|
||||
<String key="ShadowSdsm">Kaskády stínů podle scény (SDSM)</String>
|
||||
<String key="CabProbe">Sonda kabiny</String>
|
||||
<String key="CabProbeInterval">Obnovení sondy každých N snímků</String>
|
||||
<String key="CabProbeReflections">Kabina odráží sebe</String>
|
||||
<String key="CabProbeBounce">Odražené světlo lampy v kabině</String>
|
||||
<String key="FogQuality">Kvalita mlhy</String>
|
||||
<String key="Clouds">Objemová oblaka</String>
|
||||
<String key="CloudShadows">Stíny oblaků na zemi</String>
|
||||
<String key="Grass">Tráva</String>
|
||||
<String key="GrassDistance">Dosah trávy</String>
|
||||
<String key="GrassDensity">Hustota trávy</String>
|
||||
<String key="Precipitation">Srážky (částice)</String>
|
||||
<String key="Bloom">Záře světlých míst (bloom)</String>
|
||||
<String key="AutoExposure">Automatická expozice</String>
|
||||
<String key="LevelOff">Vypnuto</String>
|
||||
<String key="LevelLow">Nízká</String>
|
||||
<String key="LevelMedium">Střední</String>
|
||||
<String key="LevelHigh">Vysoká</String>
|
||||
<String key="LevelUltra">Ultra</String>
|
||||
<String key="ReflexOn">Zapnuto</String>
|
||||
<String key="ReflexBoost">Zapnuto + boost</String>
|
||||
<String key="AaTaa">TAA</String>
|
||||
<String key="AaDlss">DLSS (škálování)</String>
|
||||
<String key="AaDlaa">DLAA (nativní rozlišení)</String>
|
||||
<String key="DlssPresetDefault">Automaticky</String>
|
||||
<String key="DlssPresetK">K: nejlepší kvalita</String>
|
||||
<String key="DlssPresetJ">J: méně rozmazání</String>
|
||||
<String key="DlssPresetM">M: pro režim Výkon</String>
|
||||
<String key="DlssPresetL">L: pro Ultra výkon</String>
|
||||
<String key="Effects">Efekty</String>
|
||||
<String key="GfxColImage">Rozlišení a vyhlazování</String>
|
||||
<String key="GfxColLights">Osvětlení</String>
|
||||
<String key="GfxColAtmosphere">Atmosféra a počasí</String>
|
||||
<String key="GfxColPostFx">Postprocessing</String>
|
||||
<String key="GfxColNature">Vegetace a částice</String>
|
||||
<String key="AntiAliasing">Vyhlazování hran</String>
|
||||
<String key="VolumetricFog">Objemová mlha</String>
|
||||
<String key="REOpenGLNote">DLSS, generování snímků, Reflex a ray tracing jen s Vulkanem.</String>
|
||||
<String key="REVulkanNote">Vyžaduje exe s Vulkanem a kartu, která ho podporuje. Jinak simulátor spustí Plný nebo Starý.</String>
|
||||
<String key="VulkanDeviceAuto">automaticky</String>
|
||||
<String key="DlssPresetInfoDefault">K pro DLAA, Kvalitu a Vyvážený, M pro Výkon, L pro Ultra výkon. Ovladač to může při aktualizaci změnit.</String>
|
||||
<String key="DlssPresetInfoK">Model transformer s nejlepší kvalitou obrazu, ale nejnáročnější. Výchozí pro DLAA, Kvalitu a Vyvážený.</String>
|
||||
<String key="DlssPresetInfoJ">Podobný K: o něco méně šmouh za pohyblivými objekty za cenu většího blikání. NVIDIA doporučuje spíše K.</String>
|
||||
<String key="DlssPresetInfoM">Model pro režim Výkon (měřítko asi 50 %), tam výchozí. Expozici obrazu počítá sám.</String>
|
||||
<String key="DlssPresetInfoL">Model pro režim Ultra výkon (měřítko asi 33 %), tam výchozí. Expozici obrazu počítá sám.</String>
|
||||
<String key="DlssMissingLibraryNote">Vedle simulátoru chybí {0}: bez této knihovny simulátor tuto funkci DLSS nepoužije.</String>
|
||||
<String key="DlssNoPlatformNote">Na macOS není DLSS k dispozici.</String>
|
||||
<String key="FrameGenerationNeedsDlssNote">Generování snímků funguje jen s DLSS nebo DLAA.</String>
|
||||
<String key="ReflexForcedNote">Generování snímků zapíná Reflex samo, ať je zde vybráno cokoli.</String>
|
||||
<String key="AoLightingPrepassNote">Potřebuje hloubku celé scény před barvou; bez SSR a kontaktních stínů je to průchod navíc (zátěž CPU v OpenGL).</String>
|
||||
<String key="AoNeedsPipelineNote">Při přeskočeném postprocessingu AO nefunguje.</String>
|
||||
<String key="CabProbeReflectionsOnlyNote">Bez klastrového osvětlení a lampy kabiny jako světla (gfx.lights.cab) dává sonda jen odrazy.</String>
|
||||
<String key="TemporalNeedsPipelineNote">TAA a DLSS běží v postprocessingu: při jeho přeskočení se hrany nevyhladí.</String>
|
||||
<String key="SettingsFile">Soubor eu07.ini</String>
|
||||
<String key="ImportIni">Importovat…</String>
|
||||
<String key="ImportIniTitle">Importovat nastavení z eu07.ini</String>
|
||||
<String key="ImportIniFailed">Soubor se nepodařilo přečíst:
|
||||
{0}</String>
|
||||
<String key="ImportIniDone">Importováno {0}: uložením zachováte</String>
|
||||
<String key="ExportIni">Exportovat…</String>
|
||||
<String key="ExportIniTitle">Exportovat nastavení do eu07.ini</String>
|
||||
<String key="ExportIniFailed">Soubor se nepodařilo zapsat:
|
||||
{0}</String>
|
||||
<String key="ExportIniDone">Exportováno do {0}</String>
|
||||
<String key="REFull">Plný</String>
|
||||
<String key="REOld">Starý</String>
|
||||
<String key="RESimp">Zjednodušený</String>
|
||||
<String key="REExperimental">Experimentální</String>
|
||||
<String key="RenderAngleVulkan">Použít renderer ANGLE Vulkan</String>
|
||||
<String key="RenderVBO">Vykreslování VBO</String>
|
||||
<String key="CabShadowsRange">Dosah zdrojů stínů v kabině</String>
|
||||
<String key="UseGLES">Použít OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES místo OpenGL. Nefunguje s rendererem legacy.</String>
|
||||
</Language>
|
||||
|
||||
@@ -413,11 +413,7 @@
|
||||
|
||||
<String key="Graphic">Graphics</String>
|
||||
<String key="RenderEngine">Render engine</String>
|
||||
<String key="RenderEngineDesc">Full: OpenGL with shadows and reflections, OpenGL 4.6 in the new simulator. Old, Simplified, Experimental: older simulator versions, the new one starts Full. Vulkan 1.4: if the exe lacks it or the card cannot run it, the new version starts OpenGL and an older one Old.</String>
|
||||
<String key="REFull">Full</String>
|
||||
<String key="REOld">Old</String>
|
||||
<String key="RESimp">Simplified</String>
|
||||
<String key="REExperimental">Experimental</String>
|
||||
<String key="RenderEngineDesc">Full works with every exe. Old, Simplified and Experimental only with older ones; a new exe starts Full instead.</String>
|
||||
<String key="REExperimentalWarning">Note: the experimental renderer is still being developed. It may be unstable, miss parts of the scene or not start on some graphics cards. If the simulator does not start or looks wrong, go back to the “Full” renderer.</String>
|
||||
<String key="GpuChoice">Graphics card (Linux)</String>
|
||||
<String key="GpuDiscrete">Faster (discrete)</String>
|
||||
@@ -444,8 +440,6 @@
|
||||
<String key="MaxTexCabResolution">Maximum cabin texture resolution</String>
|
||||
<String key="TexFilteringQuality">Texture filtering quality</String>
|
||||
<String key="TexFilteringQualityDesc">Sharpness of textures seen at an angle, such as tracks. Even x16 costs little.</String>
|
||||
<String key="Multisampling">Multisampling</String>
|
||||
<String key="MultisamplingDesc">Smooths edges. Every step costs noticeable frames.</String>
|
||||
<String key="QualityVeryLow">Very low</String>
|
||||
<String key="QualityLow">Low</String>
|
||||
<String key="QualityNormal">Normal</String>
|
||||
@@ -472,8 +466,6 @@
|
||||
<String key="ShadowAngleLimitDesc">Shortens the long shadows cast by a low sun. Higher values cut them sooner.</String>
|
||||
<String key="ShadowLimitShort">Shortened</String>
|
||||
<String key="FullscreenWindowed">Automatic resolution (borderless fullscreen)</String>
|
||||
<String key="RenderAngleVulkan">Use ANGLE Vulkan renderer</String>
|
||||
<String key="RenderAngleVulkanDesc">Runs the ANGLE renderer on Vulkan instead of the default backend. Useful when OpenGL misbehaves.</String>
|
||||
<String key="VSync">VSync</String>
|
||||
<String key="VSyncDesc">Synchronizes frame rate with the monitor refresh rate.</String>
|
||||
<String key="SmokeDisplay">Smoke display</String>
|
||||
@@ -486,8 +478,6 @@
|
||||
<String key="ReflectionsCubeMapDesc">Renders reflections into a cube map, so surfaces mirror the surroundings from every direction.</String>
|
||||
<String key="SkipPipeline">Simplified depth read (compatibility)</String>
|
||||
<String key="SkipPipelineDesc">Alternative depth-buffer read path with MSAA; enable it if your GPU has compatibility issues.</String>
|
||||
<String key="RenderVBO">Render VBO</String>
|
||||
<String key="RenderVBODesc">Keeps geometry in GPU buffers (faster). Disable only if you have problems with an old GPU.</String>
|
||||
<String key="RenderShadows">Render shadows</String>
|
||||
<String key="ReflectionsFramerate">Reflections refresh rate</String>
|
||||
<String key="ReflectionsFramerateDesc">How often reflections refresh. Less often means more frames.</String>
|
||||
@@ -497,8 +487,6 @@
|
||||
<String key="ShadowsResolution">Shadows resolution</String>
|
||||
<String key="ShaderRange">Shadow range</String>
|
||||
<String key="ShaderRangeDesc">How far shadows reach; the further, the softer. After the arrow: the real reach.</String>
|
||||
<String key="CabShadowsRange">Cabin shadow sources range</String>
|
||||
<String key="CabShadowsRangeDesc">Distance at which light sources still cast shadows inside the cab. Zero turns cab shadows off.</String>
|
||||
|
||||
<String key="ShadowDisplay">Display shadows</String>
|
||||
<String key="ShadowDisplayDesc">Sets which objects cast shadows based on material priority. Lower value = fewer shadows, higher performance.</String>
|
||||
@@ -556,8 +544,6 @@
|
||||
<String key="CompressTextures">Compress TGA textures</String>
|
||||
<String key="ScaleSpeculars">Scale specular highlights (old-model compatibility)</String>
|
||||
<String key="ScaleSpecularsDesc">Tones down the shine of models made for older renderers.</String>
|
||||
<String key="UseGLES">Use OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES instead of OpenGL. Does not work with the legacy renderer.</String>
|
||||
<String key="ShaderGamma">Gamma correction in shaders</String>
|
||||
<String key="ShaderGammaDesc">Gamma in the shaders instead of sRGB. For when a driver gives too bright or dark a picture.</String>
|
||||
<String key="ScreenMipmaps">Generate mipmaps for in-cab (Python) screen textures</String>
|
||||
@@ -704,7 +690,6 @@
|
||||
<String key="GfxColResolution">Picture</String>
|
||||
<String key="GfxColRendering">Renderer</String>
|
||||
<String key="GfxColShadows">Shadows</String>
|
||||
<String key="GfxColEffects">Effects</String>
|
||||
<String key="GfxColTextures">Textures and anti-aliasing</String>
|
||||
<String key="GfxColDrawRange">Draw distance</String>
|
||||
<String key="GfxColSmoothness">Smoothness</String>
|
||||
@@ -1099,81 +1084,113 @@
|
||||
<String key="GfxGroupLevelTip">Level for this part of the graphics only</String>
|
||||
<String key="REVulkan">Vulkan 1.4</String>
|
||||
<String key="IdleVulkanOnly">Works with Vulkan only.</String>
|
||||
<String key="GfxColNewRenderer">New renderer (OpenGL 4.6, Vulkan)</String>
|
||||
<String key="Ini.gfx.antialiasing">TAA / DLSS anti-aliasing</String>
|
||||
<String key="Ini.gfx.antialiasing.Desc">Replaces MSAA. TAA smooths the whole image at the cost of slight blur. DLSS and DLAA need Vulkan and an NVIDIA RTX card.</String>
|
||||
<String key="Ini.gfx.dlss.preset">DLSS preset</String>
|
||||
<String key="Ini.gfx.dlss.preset.Desc">The model DLSS rebuilds the image with. The DLSS mode follows the buffer scale: about 67% Quality, 50% Performance, 33% Ultra Performance.</String>
|
||||
<String key="Ini.gfx.framegeneration">Frame generation</String>
|
||||
<String key="Ini.gfx.framegeneration.Desc">Extra frames between the drawn ones. With DLSS or DLAA only. x3 and x4 need an RTX 50 card.</String>
|
||||
<String key="Ini.gfx.reflex">NVIDIA Reflex</String>
|
||||
<String key="Ini.gfx.reflex.Desc">Less delay between the controls and the image.</String>
|
||||
<String key="Ini.gfx.raytracing">Ray traced reflections</String>
|
||||
<String key="Ini.gfx.raytracing.Desc">Fills in reflections where SSR finds nothing. The card needs ray query.</String>
|
||||
<String key="Ini.gfx.raytracing.range">Ray tracing range</String>
|
||||
<String key="Ini.gfx.vulkan.device">Graphics card (Vulkan)</String>
|
||||
<String key="Ini.gfx.vulkan.device.Desc">A card's number from the list in the log, or part of its name, like RTX. Empty: chosen automatically.</String>
|
||||
<String key="Ini.gfx.ssr">Screen space reflections (SSR)</String>
|
||||
<String key="Ini.gfx.ssr.Desc">Reflections of what is on screen, on wet and smooth surfaces.</String>
|
||||
<String key="Ini.gfx.postfx.ao">Ambient occlusion</String>
|
||||
<String key="Ini.gfx.postfx.ao.Desc">Darkens corners and places where surfaces meet. GTAO is more accurate than SSAO.</String>
|
||||
<String key="Ini.gfx.postfx.ao.quality">Occlusion quality</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting">Occlusion in ambient light</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting.Desc">GTAO only. Darkens ambient light and reflections, sun and lamps stay bright. Off: multiplies the finished image, cheaper.</String>
|
||||
<String key="Ini.gfx.lights.clustered">Clustered lighting</String>
|
||||
<String key="Ini.gfx.lights.clustered.Desc">Vehicle lights and street lamps with no limit on their number. Needed for scenery lamps and the cab lamp.</String>
|
||||
<String key="Ini.gfx.lights.shadows">Lamp and headlight shadows</String>
|
||||
<String key="Ini.gfx.lights.shadows.Desc">Shadows cast by the cab lamp, street lamps and vehicle headlights.</String>
|
||||
<String key="Ini.gfx.contactshadows">Contact shadows</String>
|
||||
<String key="Ini.gfx.contactshadows.Desc">Small shadows where objects touch, which the shadow map misses.</String>
|
||||
<String key="Ini.gfx.shadow.sdsm">Shadow cascades fitted to the scene (SDSM)</String>
|
||||
<String key="Ini.gfx.shadow.sdsm.Desc">Spreads the sun shadow resolution over what is actually in view.</String>
|
||||
<String key="Ini.gfx.cabprobe">Cab probe</String>
|
||||
<String key="Ini.gfx.cabprobe.Desc">Light bounced off the cab walls and reflections of the interior in the windows.</String>
|
||||
<String key="Ini.gfx.cabprobe.interval">Refresh the probe every N frames</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections">Cab reflects itself</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections.Desc">The windows show the cab interior instead of the sky where SSR finds nothing.</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce">Cab lamp light bounce</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce.Desc">How much of the lamp's light reflected off the walls lights the cab again. Works with the cab probe.</String>
|
||||
<String key="Ini.gfx.fog">Fog</String>
|
||||
<String key="Ini.gfx.fog.Desc">Volumetric: with sun rays, cloud shadows and lamp light. Analytic: simpler and cheaper.</String>
|
||||
<String key="Ini.gfx.fog.quality">Fog quality</String>
|
||||
<String key="Ini.gfx.clouds">Volumetric clouds</String>
|
||||
<String key="Ini.gfx.clouds.shadows">Cloud shadows on the ground</String>
|
||||
<String key="Ini.gfx.grass">Grass</String>
|
||||
<String key="Ini.gfx.grass.distance">Grass range</String>
|
||||
<String key="Ini.gfx.grass.fadedistance">Grass fades out at</String>
|
||||
<String key="Ini.gfx.grass.density">Grass density</String>
|
||||
<String key="Ini.gfx.precipitation.particles">Precipitation (particles)</String>
|
||||
<String key="Ini.gfx.precipitation.particles.Desc">Number of raindrops and snowflakes in the heaviest precipitation.</String>
|
||||
<String key="Ini.gfx.postfx.bloom">Glow of bright areas (bloom)</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure">Automatic exposure</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure.Desc">Image brightness adapts to the scene, for instance entering a tunnel.</String>
|
||||
<String key="IniWord.same">As MSAA above</String>
|
||||
<String key="IniWord.no">Off</String>
|
||||
<String key="IniWord.off">Off</String>
|
||||
<String key="IniWord.low">Low</String>
|
||||
<String key="IniWord.medium">Medium</String>
|
||||
<String key="IniWord.high">High</String>
|
||||
<String key="IniWord.ultra">Ultra</String>
|
||||
<String key="IniWord.on">On</String>
|
||||
<String key="IniWord.boost">On + boost</String>
|
||||
<String key="IniWord.ssao">SSAO</String>
|
||||
<String key="IniWord.gtao">GTAO</String>
|
||||
<String key="IniWord.volumetric">Volumetric</String>
|
||||
<String key="IniWord.analytic">Analytic</String>
|
||||
<String key="IniWord.default">Automatic</String>
|
||||
<String key="IniWord.k">K: best quality</String>
|
||||
<String key="IniWord.j">J: less smearing</String>
|
||||
<String key="IniWord.m">M: for Performance mode</String>
|
||||
<String key="IniWord.l">L: for Ultra Performance</String>
|
||||
<String key="IniWord.x2">x2</String>
|
||||
<String key="IniWord.x3">x3</String>
|
||||
<String key="IniWord.x4">x4</String>
|
||||
<String key="IniWord.taa">TAA</String>
|
||||
<String key="IniWord.dlss">DLSS (upscaling)</String>
|
||||
<String key="IniWord.dlaa">DLAA (native resolution)</String>
|
||||
<String key="IniWord.3_4">Default (3×4)</String>
|
||||
<String key="IniWord.4_6">High (4×6)</String>
|
||||
<String key="IniWord.6_8">Ultra (6×8)</String>
|
||||
<String key="DlssPreset">DLSS preset</String>
|
||||
<String key="DlssPresetDesc">The model DLSS rebuilds the image with. The DLSS mode follows the buffer scale: about 67% Quality, 50% Performance, 33% Ultra Performance.</String>
|
||||
<String key="FrameGeneration">Frame generation</String>
|
||||
<String key="FrameGenerationDesc">Extra frames between the drawn ones. With DLSS or DLAA only. x3 and x4 need an RTX 50 card.</String>
|
||||
<String key="Reflex">NVIDIA Reflex</String>
|
||||
<String key="ReflexDesc">Less delay between the controls and the image.</String>
|
||||
<String key="RayTracing">Ray traced reflections</String>
|
||||
<String key="RayTracingDesc">Fills in reflections where SSR finds nothing. The card needs ray query.</String>
|
||||
<String key="RayTracingRange">Ray tracing range</String>
|
||||
<String key="VulkanDevice">Graphics card (Vulkan)</String>
|
||||
<String key="VulkanDeviceDesc">A card's number from the list in the log, or part of its name, like RTX. Empty: chosen automatically.</String>
|
||||
<String key="Ssr">Screen space reflections (SSR)</String>
|
||||
<String key="SsrDesc">Reflections of what is on screen, on wet and smooth surfaces.</String>
|
||||
<String key="AmbientOcclusion">Ambient occlusion</String>
|
||||
<String key="AmbientOcclusionDesc">Darkens corners and places where surfaces meet. GTAO is more accurate than SSAO.</String>
|
||||
<String key="AmbientOcclusionQuality">Occlusion quality</String>
|
||||
<String key="AoLighting">Occlusion in ambient light</String>
|
||||
<String key="AoLightingDesc">GTAO only. Darkens ambient light and reflections, sun and lamps stay bright. Off: multiplies the finished image, cheaper.</String>
|
||||
<String key="LightsClustered">Clustered lighting</String>
|
||||
<String key="LightsClusteredDesc">Vehicle lights and street lamps with no limit on their number. Needed for scenery lamps and the cab lamp.</String>
|
||||
<String key="LightShadows">Lamp and headlight shadows</String>
|
||||
<String key="LightShadowsDesc">Shadows cast by the cab lamp, street lamps and vehicle headlights.</String>
|
||||
<String key="ContactShadows">Contact shadows</String>
|
||||
<String key="ContactShadowsDesc">Small shadows where objects touch, which the shadow map misses.</String>
|
||||
<String key="ShadowSdsm">Shadow cascades fitted to the scene (SDSM)</String>
|
||||
<String key="ShadowSdsmDesc">Spreads the sun shadow resolution over what is actually in view.</String>
|
||||
<String key="CabProbe">Cab probe</String>
|
||||
<String key="CabProbeDesc">Light bounced off the cab walls and reflections of the interior in the windows.</String>
|
||||
<String key="CabProbeInterval">Refresh the probe every N frames</String>
|
||||
<String key="CabProbeReflections">Cab reflects itself</String>
|
||||
<String key="CabProbeReflectionsDesc">The windows show the cab interior instead of the sky where SSR finds nothing.</String>
|
||||
<String key="CabProbeBounce">Cab lamp light bounce</String>
|
||||
<String key="CabProbeBounceDesc">How much of the lamp's light reflected off the walls lights the cab again. Works with the cab probe.</String>
|
||||
<String key="FogQuality">Fog quality</String>
|
||||
<String key="Clouds">Volumetric clouds</String>
|
||||
<String key="CloudShadows">Cloud shadows on the ground</String>
|
||||
<String key="Grass">Grass</String>
|
||||
<String key="GrassDistance">Grass range</String>
|
||||
<String key="GrassDensity">Grass density</String>
|
||||
<String key="Precipitation">Precipitation (particles)</String>
|
||||
<String key="PrecipitationDesc">Number of raindrops and snowflakes in the heaviest precipitation.</String>
|
||||
<String key="Bloom">Glow of bright areas (bloom)</String>
|
||||
<String key="AutoExposure">Automatic exposure</String>
|
||||
<String key="AutoExposureDesc">Image brightness adapts to the scene, for instance entering a tunnel.</String>
|
||||
<String key="LevelOff">Off</String>
|
||||
<String key="LevelLow">Low</String>
|
||||
<String key="LevelMedium">Medium</String>
|
||||
<String key="LevelHigh">High</String>
|
||||
<String key="LevelUltra">Ultra</String>
|
||||
<String key="ReflexOn">On</String>
|
||||
<String key="ReflexBoost">On + boost</String>
|
||||
<String key="AaTaa">TAA</String>
|
||||
<String key="AaDlss">DLSS (upscaling)</String>
|
||||
<String key="AaDlaa">DLAA (native resolution)</String>
|
||||
<String key="DlssPresetDefault">Automatic</String>
|
||||
<String key="DlssPresetK">K: best quality</String>
|
||||
<String key="DlssPresetJ">J: less smearing</String>
|
||||
<String key="DlssPresetM">M: for Performance mode</String>
|
||||
<String key="DlssPresetL">L: for Ultra Performance</String>
|
||||
<String key="Effects">Effects</String>
|
||||
<String key="GfxColImage">Resolution and anti-aliasing</String>
|
||||
<String key="GfxColLights">Lighting</String>
|
||||
<String key="GfxColAtmosphere">Atmosphere and weather</String>
|
||||
<String key="GfxColPostFx">Post-processing</String>
|
||||
<String key="GfxColNature">Vegetation and particles</String>
|
||||
<String key="AntiAliasing">Anti-aliasing</String>
|
||||
<String key="AntiAliasingDesc">MSAA smooths the edges of objects, TAA the whole image at the cost of a slight blur. DLSS and DLAA need Vulkan and an NVIDIA RTX card, otherwise the simulator uses TAA.</String>
|
||||
<String key="VolumetricFog">Volumetric fog</String>
|
||||
<String key="VolumetricFogDesc">Fog with sun shafts, cloud shadows and the light of lamps. Off: the simpler analytic fog.</String>
|
||||
<String key="CloudsDesc">The quality of the clouds drawn in the sky.</String>
|
||||
<String key="REOpenGLNote">DLSS, frame generation, Reflex and ray tracing need Vulkan.</String>
|
||||
<String key="REVulkanNote">Needs an exe with Vulkan and a card that supports it. Otherwise the simulator starts Full or Old.</String>
|
||||
<String key="VulkanDeviceAuto">automatic</String>
|
||||
<String key="DlssPresetInfoDefault">K for DLAA, Quality and Balanced, M for Performance, L for Ultra Performance. The driver may change this with an update.</String>
|
||||
<String key="DlssPresetInfoK">The transformer model with the best image quality, but the most expensive to compute. The default for DLAA, Quality and Balanced.</String>
|
||||
<String key="DlssPresetInfoJ">Similar to K: slightly less ghosting behind moving objects at the cost of more flicker. NVIDIA recommends K instead.</String>
|
||||
<String key="DlssPresetInfoM">The model tuned for Performance mode (about 50% scale), its default there. Works out the image exposure itself.</String>
|
||||
<String key="DlssPresetInfoL">The model tuned for Ultra Performance mode (about 33% scale), its default there. Works out the image exposure itself.</String>
|
||||
<String key="DlssMissingLibraryNote">{0} is not next to the simulator: without it the simulator cannot use this DLSS feature.</String>
|
||||
<String key="DlssNoPlatformNote">DLSS is not available on macOS.</String>
|
||||
<String key="FrameGenerationNeedsDlssNote">Frame generation works with DLSS or DLAA only.</String>
|
||||
<String key="ReflexForcedNote">Frame generation turns Reflex on by itself, whatever is chosen here.</String>
|
||||
<String key="AoLightingPrepassNote">Needs the depth of the whole scene before its colour; without SSR and contact shadows that is an extra pass (CPU cost on OpenGL).</String>
|
||||
<String key="AoNeedsPipelineNote">With the post-processing skipped the AO does not work.</String>
|
||||
<String key="CabProbeReflectionsOnlyNote">Without the clustered lighting and the cab lamp as a light (gfx.lights.cab) the probe gives the reflections only.</String>
|
||||
<String key="TemporalNeedsPipelineNote">TAA and DLSS run in the post-processing: with it skipped the edges will not be smoothed.</String>
|
||||
<String key="SettingsFile">eu07.ini file</String>
|
||||
<String key="ImportIni">Import…</String>
|
||||
<String key="ImportIniTitle">Import settings from eu07.ini</String>
|
||||
<String key="ImportIniFailed">The file could not be read:
|
||||
{0}</String>
|
||||
<String key="ImportIniDone">Imported {0}: save to keep it</String>
|
||||
<String key="ExportIni">Export…</String>
|
||||
<String key="ExportIniTitle">Export settings to eu07.ini</String>
|
||||
<String key="ExportIniFailed">The file could not be written:
|
||||
{0}</String>
|
||||
<String key="ExportIniDone">Exported to {0}</String>
|
||||
<String key="REFull">Full</String>
|
||||
<String key="REOld">Old</String>
|
||||
<String key="RESimp">Simplified</String>
|
||||
<String key="REExperimental">Experimental</String>
|
||||
<String key="RenderAngleVulkan">Use ANGLE Vulkan renderer</String>
|
||||
<String key="RenderAngleVulkanDesc">Runs the ANGLE renderer on Vulkan instead of the default backend. Useful when OpenGL misbehaves.</String>
|
||||
<String key="RenderVBO">Render VBO</String>
|
||||
<String key="RenderVBODesc">Keeps geometry in GPU buffers (faster). Disable only if you have problems with an old GPU.</String>
|
||||
<String key="CabShadowsRange">Cabin shadow sources range</String>
|
||||
<String key="CabShadowsRangeDesc">Distance at which light sources still cast shadows inside the cab. Zero turns cab shadows off.</String>
|
||||
<String key="UseGLES">Use OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES instead of OpenGL. Does not work with the legacy renderer.</String>
|
||||
</Language>
|
||||
|
||||
@@ -406,11 +406,7 @@
|
||||
|
||||
<String key="Graphic">Grafika</String>
|
||||
<String key="RenderEngine">Megjelenítő motor</String>
|
||||
<String key="REFull">Teljes</String>
|
||||
<String key="RenderEngineDesc">Teljes: OpenGL árnyékokkal és tükröződéssel, az új szimulátorban OpenGL 4.6. Régi, Egyszerűsített, Kísérleti: a szimulátor régebbi verziói, az új a Teljeset indítja. Vulkan 1.4: ha az exe nem tartalmazza vagy a kártya nem bírja, az új verzió OpenGL-t, a régebbi a Régit indítja.</String>
|
||||
<String key="REOld">Régi</String>
|
||||
<String key="RESimp">Egyszerűsített</String>
|
||||
<String key="REExperimental">Kísérleti</String>
|
||||
<String key="RenderEngineDesc">A Teljes minden exe-vel működik. A Régi, az Egyszerűsített és a Kísérleti csak a régebbiekkel, az új helyettük a Teljeset indítja.</String>
|
||||
<String key="REExperimentalWarning">Figyelem: a kísérleti renderelő még fejlesztés alatt áll. Instabil lehet, a jelenet egyes részei hiányozhatnak, vagy egyes videokártyákon el sem indul. Ha a szimulátor nem indul el vagy hibásan jelenik meg, válts vissza a „Teljes” renderelőre.</String>
|
||||
<String key="GpuChoice">Videokártya (Linux)</String>
|
||||
<String key="GpuDiscrete">Erősebb (dedikált)</String>
|
||||
@@ -436,8 +432,6 @@
|
||||
<String key="MaxTexCabResolution">Vezetőállás-textúrák legnagyobb felbontása</String>
|
||||
<String key="TexFilteringQuality">Textúraszűrés minősége</String>
|
||||
<String key="TexFilteringQualityDesc">A ferdén látott textúrák élessége, pl. a síneké. Még az x16 is keveset igényel.</String>
|
||||
<String key="Multisampling">Multisampling</String>
|
||||
<String key="MultisamplingDesc">Élsimítás. Minden fokozat érezhetően kevesebb képkockát jelent.</String>
|
||||
<String key="QualityVeryLow">Nagyon alacsony</String>
|
||||
<String key="QualityLow">Alacsony</String>
|
||||
<String key="QualityNormal">Normál</String>
|
||||
@@ -462,7 +456,6 @@
|
||||
<String key="ShadowAngleLimit">Árnyékhossz korlátozása</String>
|
||||
<String key="ShadowLimitShort">Rövidített</String>
|
||||
<String key="FullscreenWindowed">Automatikus felbontás (keret nélküli teljes képernyő)</String>
|
||||
<String key="RenderAngleVulkan">ANGLE Vulkan megjelenítő használata</String>
|
||||
<String key="VSync">VSync</String>
|
||||
<String key="SmokeDisplay">Füst megjelenítése</String>
|
||||
<String key="SmokeParticlesMultiplier">Füstrészecskék szorzója</String>
|
||||
@@ -472,7 +465,6 @@
|
||||
<String key="AdditionalShadersEffects">További shader-effektek</String>
|
||||
<String key="ReflectionsCubeMap">Tükröződések cubemapként</String>
|
||||
<String key="SkipPipeline">SkipPipeline</String>
|
||||
<String key="RenderVBO">VBO megjelenítés</String>
|
||||
<String key="RenderShadows">Árnyékok megjelenítése</String>
|
||||
<String key="ReflectionsFramerate">Tükröződések frissítési gyakorisága</String>
|
||||
<String key="ReflectionsFramerateDesc">Milyen gyakran frissüljenek a tükröződések. Ritkábban több képkocka.</String>
|
||||
@@ -482,7 +474,6 @@
|
||||
<String key="ShadowsResolution">Árnyékok felbontása</String>
|
||||
<String key="ShaderRange">Árnyékok hatótávolsága</String>
|
||||
<String key="ShaderRangeDesc">Meddig érnek az árnyékok; minél messzebb, annál lágyabbak. A nyíl után a valódi távolság.</String>
|
||||
<String key="CabShadowsRange">Vezetőállás árnyékforrásainak hatótávolsága</String>
|
||||
|
||||
<String key="ShadowDisplay">Árnyékok megjelenítése</String>
|
||||
<String key="CSROnlyImportant">Csak a fontosak</String>
|
||||
@@ -527,8 +518,6 @@
|
||||
<String key="CompressTextures">TGA textúrák tömörítése</String>
|
||||
<String key="ScaleSpeculars">Csillanások skálázása (régi modellek kompatibilitása)</String>
|
||||
<String key="ScaleSpecularsDesc">Csökkenti a régebbi megjelenítőkhöz készült modellek csillogását.</String>
|
||||
<String key="UseGLES">OpenGL ES használata</String>
|
||||
<String key="UseGLESDesc">OpenGL ES az OpenGL helyett. A legacy megjelenítővel nem működik.</String>
|
||||
<String key="ShaderGamma">Gammakorrekció a shaderekben</String>
|
||||
<String key="ShaderGammaDesc">Gamma a shaderekben sRGB helyett. Ha az illesztő túl világos vagy sötét képet ad.</String>
|
||||
<String key="ScreenMipmaps">Mipmapok készítése a vezetőállás (Python) kijelzőtextúráihoz</String>
|
||||
@@ -674,7 +663,6 @@
|
||||
<String key="GfxColResolution">Kép</String>
|
||||
<String key="GfxColRendering">Renderelő</String>
|
||||
<String key="GfxColShadows">Árnyékok</String>
|
||||
<String key="GfxColEffects">Effektek</String>
|
||||
<String key="GfxColTextures">Textúrák és élsimítás</String>
|
||||
<String key="GfxColDrawRange">Látótávolság</String>
|
||||
<String key="GfxColSmoothness">Folyamatosság</String>
|
||||
@@ -867,62 +855,90 @@
|
||||
<String key="GfxGroupLevelTip">Csak a grafika ezen részének szintje</String>
|
||||
<String key="REVulkan">Vulkan 1.4</String>
|
||||
<String key="IdleVulkanOnly">Csak Vulkannal működik.</String>
|
||||
<String key="GfxColNewRenderer">Új renderelő (OpenGL 4.6, Vulkan)</String>
|
||||
<String key="Ini.gfx.antialiasing">TAA / DLSS élsimítás</String>
|
||||
<String key="Ini.gfx.dlss.preset">DLSS előbeállítás</String>
|
||||
<String key="Ini.gfx.framegeneration">Képkocka-generálás</String>
|
||||
<String key="Ini.gfx.reflex">NVIDIA Reflex</String>
|
||||
<String key="Ini.gfx.raytracing">Sugárkövetéses tükröződés</String>
|
||||
<String key="Ini.gfx.raytracing.range">Sugárkövetés hatótávja</String>
|
||||
<String key="Ini.gfx.vulkan.device">Videokártya (Vulkan)</String>
|
||||
<String key="Ini.gfx.ssr">Képernyőtéri tükröződés (SSR)</String>
|
||||
<String key="Ini.gfx.postfx.ao">Környezeti kitakarás</String>
|
||||
<String key="Ini.gfx.postfx.ao.quality">Kitakarás minősége</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting">Kitakarás a környezeti fényben</String>
|
||||
<String key="Ini.gfx.lights.clustered">Klaszteres megvilágítás</String>
|
||||
<String key="Ini.gfx.lights.shadows">Lámpák és fényszórók árnyéka</String>
|
||||
<String key="Ini.gfx.contactshadows">Kontaktárnyékok</String>
|
||||
<String key="Ini.gfx.shadow.sdsm">Jelenethez igazított árnyékkaszkádok (SDSM)</String>
|
||||
<String key="Ini.gfx.cabprobe">Fülkeszonda</String>
|
||||
<String key="Ini.gfx.cabprobe.interval">Szonda frissítése N képkockánként</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections">A fülke önmagát tükrözi</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce">A fülkelámpa visszavert fénye</String>
|
||||
<String key="Ini.gfx.fog">Köd</String>
|
||||
<String key="Ini.gfx.fog.quality">Köd minősége</String>
|
||||
<String key="Ini.gfx.clouds">Térfogati felhők</String>
|
||||
<String key="Ini.gfx.clouds.shadows">Felhők árnyéka a talajon</String>
|
||||
<String key="Ini.gfx.grass">Fű</String>
|
||||
<String key="Ini.gfx.grass.distance">Fű hatótávja</String>
|
||||
<String key="Ini.gfx.grass.fadedistance">A fű eltűnik eddig</String>
|
||||
<String key="Ini.gfx.grass.density">Fű sűrűsége</String>
|
||||
<String key="Ini.gfx.precipitation.particles">Csapadék (részecskék)</String>
|
||||
<String key="Ini.gfx.postfx.bloom">Világos részek ragyogása (bloom)</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure">Automatikus expozíció</String>
|
||||
<String key="IniWord.same">Mint a fenti MSAA</String>
|
||||
<String key="IniWord.no">Ki</String>
|
||||
<String key="IniWord.off">Ki</String>
|
||||
<String key="IniWord.low">Alacsony</String>
|
||||
<String key="IniWord.medium">Közepes</String>
|
||||
<String key="IniWord.high">Magas</String>
|
||||
<String key="IniWord.ultra">Ultra</String>
|
||||
<String key="IniWord.on">Be</String>
|
||||
<String key="IniWord.boost">Be + boost</String>
|
||||
<String key="IniWord.ssao">SSAO</String>
|
||||
<String key="IniWord.gtao">GTAO</String>
|
||||
<String key="IniWord.volumetric">Térfogati</String>
|
||||
<String key="IniWord.analytic">Analitikus</String>
|
||||
<String key="IniWord.default">Automatikus</String>
|
||||
<String key="IniWord.k">K: legjobb minőség</String>
|
||||
<String key="IniWord.j">J: kevesebb elmosódás</String>
|
||||
<String key="IniWord.m">M: Teljesítmény módhoz</String>
|
||||
<String key="IniWord.l">L: Ultra teljesítményhez</String>
|
||||
<String key="IniWord.x2">x2</String>
|
||||
<String key="IniWord.x3">x3</String>
|
||||
<String key="IniWord.x4">x4</String>
|
||||
<String key="IniWord.taa">TAA</String>
|
||||
<String key="IniWord.dlss">DLSS (felskálázás)</String>
|
||||
<String key="IniWord.dlaa">DLAA (natív felbontás)</String>
|
||||
<String key="IniWord.3_4">Alapértelmezett (3×4)</String>
|
||||
<String key="IniWord.4_6">Magas (4×6)</String>
|
||||
<String key="IniWord.6_8">Ultra (6×8)</String>
|
||||
<String key="DlssPreset">DLSS előbeállítás</String>
|
||||
<String key="FrameGeneration">Képkocka-generálás</String>
|
||||
<String key="Reflex">NVIDIA Reflex</String>
|
||||
<String key="RayTracing">Sugárkövetéses tükröződés</String>
|
||||
<String key="RayTracingRange">Sugárkövetés hatótávja</String>
|
||||
<String key="VulkanDevice">Videokártya (Vulkan)</String>
|
||||
<String key="Ssr">Képernyőtéri tükröződés (SSR)</String>
|
||||
<String key="AmbientOcclusion">Környezeti kitakarás</String>
|
||||
<String key="AmbientOcclusionQuality">Kitakarás minősége</String>
|
||||
<String key="AoLighting">Kitakarás a környezeti fényben</String>
|
||||
<String key="LightsClustered">Klaszteres megvilágítás</String>
|
||||
<String key="LightShadows">Lámpák és fényszórók árnyéka</String>
|
||||
<String key="ContactShadows">Kontaktárnyékok</String>
|
||||
<String key="ShadowSdsm">Jelenethez igazított árnyékkaszkádok (SDSM)</String>
|
||||
<String key="CabProbe">Fülkeszonda</String>
|
||||
<String key="CabProbeInterval">Szonda frissítése N képkockánként</String>
|
||||
<String key="CabProbeReflections">A fülke önmagát tükrözi</String>
|
||||
<String key="CabProbeBounce">A fülkelámpa visszavert fénye</String>
|
||||
<String key="FogQuality">Köd minősége</String>
|
||||
<String key="Clouds">Térfogati felhők</String>
|
||||
<String key="CloudShadows">Felhők árnyéka a talajon</String>
|
||||
<String key="Grass">Fű</String>
|
||||
<String key="GrassDistance">Fű hatótávja</String>
|
||||
<String key="GrassDensity">Fű sűrűsége</String>
|
||||
<String key="Precipitation">Csapadék (részecskék)</String>
|
||||
<String key="Bloom">Világos részek ragyogása (bloom)</String>
|
||||
<String key="AutoExposure">Automatikus expozíció</String>
|
||||
<String key="LevelOff">Ki</String>
|
||||
<String key="LevelLow">Alacsony</String>
|
||||
<String key="LevelMedium">Közepes</String>
|
||||
<String key="LevelHigh">Magas</String>
|
||||
<String key="LevelUltra">Ultra</String>
|
||||
<String key="ReflexOn">Be</String>
|
||||
<String key="ReflexBoost">Be + boost</String>
|
||||
<String key="AaTaa">TAA</String>
|
||||
<String key="AaDlss">DLSS (felskálázás)</String>
|
||||
<String key="AaDlaa">DLAA (natív felbontás)</String>
|
||||
<String key="DlssPresetDefault">Automatikus</String>
|
||||
<String key="DlssPresetK">K: legjobb minőség</String>
|
||||
<String key="DlssPresetJ">J: kevesebb elmosódás</String>
|
||||
<String key="DlssPresetM">M: Teljesítmény módhoz</String>
|
||||
<String key="DlssPresetL">L: Ultra teljesítményhez</String>
|
||||
<String key="Effects">Effektek</String>
|
||||
<String key="GfxColImage">Felbontás és élsimítás</String>
|
||||
<String key="GfxColLights">Világítás</String>
|
||||
<String key="GfxColAtmosphere">Légkör és időjárás</String>
|
||||
<String key="GfxColPostFx">Utófeldolgozás</String>
|
||||
<String key="GfxColNature">Növényzet és részecskék</String>
|
||||
<String key="AntiAliasing">Élsimítás</String>
|
||||
<String key="VolumetricFog">Térfogati köd</String>
|
||||
<String key="REOpenGLNote">A DLSS, a képkocka-generálás, a Reflex és a ray tracing csak Vulkannal működik.</String>
|
||||
<String key="REVulkanNote">Vulkanos exe és azt támogató kártya kell hozzá. Különben a szimulátor a Teljeset vagy a Régit indítja.</String>
|
||||
<String key="VulkanDeviceAuto">automatikus</String>
|
||||
<String key="DlssPresetInfoDefault">K a DLAA, a Minőség és a Kiegyensúlyozott módhoz, M a Teljesítményhez, L az Ultra teljesítményhez. Az illesztőprogram frissítéskor módosíthatja.</String>
|
||||
<String key="DlssPresetInfoK">A legjobb képminőségű transformer modell, de a legdrágább. Alapértelmezett a DLAA, a Minőség és a Kiegyensúlyozott módhoz.</String>
|
||||
<String key="DlssPresetInfoJ">A K-hoz hasonló: kevesebb szellemkép a mozgó tárgyak mögött, több villogással. Az NVIDIA inkább a K-t ajánlja.</String>
|
||||
<String key="DlssPresetInfoM">A Teljesítmény módhoz (kb. 50%-os méretezés) való modell, ott alapértelmezett. A kép expozícióját maga számolja.</String>
|
||||
<String key="DlssPresetInfoL">Az Ultra teljesítmény módhoz (kb. 33%-os méretezés) való modell, ott alapértelmezett. A kép expozícióját maga számolja.</String>
|
||||
<String key="DlssMissingLibraryNote">A szimulátor mellett nincs {0}: e könyvtár nélkül a szimulátor nem használja ezt a DLSS-funkciót.</String>
|
||||
<String key="DlssNoPlatformNote">macOS-en a DLSS nem érhető el.</String>
|
||||
<String key="FrameGenerationNeedsDlssNote">A képkocka-generálás csak DLSS-sel vagy DLAA-val működik.</String>
|
||||
<String key="ReflexForcedNote">A képkocka-generálás magától bekapcsolja a Reflexet, bármi van itt kiválasztva.</String>
|
||||
<String key="AoLightingPrepassNote">A teljes jelenet mélysége kell a szín előtt; SSR és kontaktárnyékok nélkül ez egy külön menet (CPU-terhelés OpenGL-ben).</String>
|
||||
<String key="AoNeedsPipelineNote">Kihagyott utófeldolgozásnál az AO nem működik.</String>
|
||||
<String key="CabProbeReflectionsOnlyNote">Klaszteres megvilágítás és a fülkelámpa mint fény (gfx.lights.cab) nélkül a szonda csak tükröződést ad.</String>
|
||||
<String key="TemporalNeedsPipelineNote">A TAA és a DLSS az utófeldolgozásban fut: ha kihagyod, az élek nem simulnak ki.</String>
|
||||
<String key="SettingsFile">eu07.ini fájl</String>
|
||||
<String key="ImportIni">Importálás…</String>
|
||||
<String key="ImportIniTitle">Beállítások importálása az eu07.ini fájlból</String>
|
||||
<String key="ImportIniFailed">A fájl nem olvasható:
|
||||
{0}</String>
|
||||
<String key="ImportIniDone">{0} importálva: mentéssel megmarad</String>
|
||||
<String key="ExportIni">Exportálás…</String>
|
||||
<String key="ExportIniTitle">Beállítások exportálása az eu07.ini fájlba</String>
|
||||
<String key="ExportIniFailed">A fájl nem írható:
|
||||
{0}</String>
|
||||
<String key="ExportIniDone">Exportálva ide: {0}</String>
|
||||
<String key="REFull">Teljes</String>
|
||||
<String key="REOld">Régi</String>
|
||||
<String key="RESimp">Egyszerűsített</String>
|
||||
<String key="REExperimental">Kísérleti</String>
|
||||
<String key="RenderAngleVulkan">ANGLE Vulkan megjelenítő használata</String>
|
||||
<String key="RenderVBO">VBO megjelenítés</String>
|
||||
<String key="CabShadowsRange">Vezetőállás árnyékforrásainak hatótávolsága</String>
|
||||
<String key="UseGLES">OpenGL ES használata</String>
|
||||
<String key="UseGLESDesc">OpenGL ES az OpenGL helyett. A legacy megjelenítővel nem működik.</String>
|
||||
</Language>
|
||||
|
||||
@@ -413,11 +413,7 @@
|
||||
|
||||
<String key="Graphic">Grafika</String>
|
||||
<String key="RenderEngine">Silnik renderowania</String>
|
||||
<String key="RenderEngineDesc">Pełny: OpenGL z cieniami i odbiciami, w nowym symulatorze OpenGL 4.6. Stary, Uproszczony, Eksperymentalny: starsze wersje symulatora, nowa włączy Pełny. Vulkan 1.4: gdy exe go nie ma albo karta nie da rady, nowa wersja włączy OpenGL, a starsza Stary.</String>
|
||||
<String key="REFull">Pełny</String>
|
||||
<String key="REOld">Stary</String>
|
||||
<String key="RESimp">Uproszczony</String>
|
||||
<String key="REExperimental">Eksperymentalny</String>
|
||||
<String key="RenderEngineDesc">Pełny działa z każdym exe. Stary, Uproszczony i Eksperymentalny tylko ze starszymi exe, nowy włączy zamiast nich Pełny.</String>
|
||||
<String key="REExperimentalWarning">Uwaga: renderer eksperymentalny jest w trakcie rozwoju. Może działać niestabilnie, nie pokazywać części obiektów albo nie uruchomić się na niektórych kartach graficznych. Gdy symulator nie startuje lub wygląda źle, wróć do renderera „Pełny”.</String>
|
||||
<String key="GpuChoice">Karta graficzna (Linux)</String>
|
||||
<String key="GpuDiscrete">Wydajniejsza (dedykowana)</String>
|
||||
@@ -444,8 +440,6 @@
|
||||
<String key="MaxTexCabResolution">Maksymalna rozdzielczość tekstur kabiny</String>
|
||||
<String key="TexFilteringQuality">Jakość filtrowania tekstur</String>
|
||||
<String key="TexFilteringQualityDesc">Ostrość tekstur oglądanych pod kątem, np. torów. Nawet x16 kosztuje niewiele.</String>
|
||||
<String key="Multisampling">Multisampling</String>
|
||||
<String key="MultisamplingDesc">Wygładzanie krawędzi. Każdy stopień wyraźnie kosztuje klatki.</String>
|
||||
<String key="QualityVeryLow">Bardzo niska</String>
|
||||
<String key="QualityLow">Niska</String>
|
||||
<String key="QualityNormal">Normalna</String>
|
||||
@@ -472,8 +466,6 @@
|
||||
<String key="ShadowAngleLimitDesc">Skraca długie cienie rzucane przez nisko stojące słońce. Wyższe wartości ucinają je wcześniej.</String>
|
||||
<String key="ShadowLimitShort">Skrócone</String>
|
||||
<String key="FullscreenWindowed">Automatyczna rozdzielczość (pełny ekran bez obramowania)</String>
|
||||
<String key="RenderAngleVulkan">Użyj renderera ANGLE Vulkan</String>
|
||||
<String key="RenderAngleVulkanDesc">Uruchamia renderer ANGLE na Vulkanie zamiast domyślnego backendu. Przydatne, gdy OpenGL sprawia problemy.</String>
|
||||
<String key="VSync">VSync</String>
|
||||
<String key="VSyncDesc">Synchronizacja klatek z odświeżaniem monitora.</String>
|
||||
<String key="SmokeDisplay">Wyświetlanie dymu</String>
|
||||
@@ -486,8 +478,6 @@
|
||||
<String key="ReflectionsCubeMapDesc">Renderuje odbicia do mapy sześciennej, dzięki czemu powierzchnie odbijają otoczenie ze wszystkich stron.</String>
|
||||
<String key="SkipPipeline">Uproszczony odczyt głębi (zgodność)</String>
|
||||
<String key="SkipPipelineDesc">Alternatywna ścieżka odczytu bufora głębi przy MSAA; włącz przy problemach z kompatybilnością karty graficznej.</String>
|
||||
<String key="RenderVBO">Renderowanie VBO</String>
|
||||
<String key="RenderVBODesc">Trzyma geometrię w buforach karty graficznej. Wyłącz tylko przy problemach ze starszymi kartami.</String>
|
||||
<String key="RenderShadows">Renderowanie cieni</String>
|
||||
<String key="ReflectionsFramerate">Odświeżanie odbić</String>
|
||||
<String key="ReflectionsFramerateDesc">Jak często odświeżać odbicia. Rzadziej to więcej klatek.</String>
|
||||
@@ -497,8 +487,6 @@
|
||||
<String key="ShadowsResolution">Rozdzielczość cieni</String>
|
||||
<String key="ShaderRange">Zasięg cieni</String>
|
||||
<String key="ShaderRangeDesc">Jak daleko sięgają cienie; im dalej, tym mniej ostre. Po strzałce zasięg rzeczywisty.</String>
|
||||
<String key="CabShadowsRange">Zasięg źródeł cieni w kabinie</String>
|
||||
<String key="CabShadowsRangeDesc">Odległość, z jakiej źródła światła nadal rzucają cień w kabinie. Zero wyłącza cienie w kabinie.</String>
|
||||
|
||||
<String key="ShadowDisplay">Wyświetlanie cieni</String>
|
||||
<String key="ShadowDisplayDesc">Określa, które obiekty rzucają cień według priorytetu materiału. Niższa wartość = mniej cieni, wyższa wydajność.</String>
|
||||
@@ -556,8 +544,6 @@
|
||||
<String key="CompressTextures">Kompresuj tekstury TGA</String>
|
||||
<String key="ScaleSpeculars">Skaluj odbicia specularne (kompatybilność ze starymi modelami)</String>
|
||||
<String key="ScaleSpecularsDesc">Osłabia połysk modeli robionych pod starsze renderery.</String>
|
||||
<String key="UseGLES">Używaj OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES zamiast OpenGL. Nie działa z rendererem legacy.</String>
|
||||
<String key="ShaderGamma">Korekcja gamma w shaderach</String>
|
||||
<String key="ShaderGammaDesc">Gamma w shaderach zamiast sRGB. Gdy sterownik daje za jasny lub za ciemny obraz.</String>
|
||||
<String key="ScreenMipmaps">Generuj mipmapy dla tekstur ekranów kabinowych (Python)</String>
|
||||
@@ -704,7 +690,6 @@
|
||||
<String key="GfxColResolution">Obraz</String>
|
||||
<String key="GfxColRendering">Silnik renderowania</String>
|
||||
<String key="GfxColShadows">Cienie</String>
|
||||
<String key="GfxColEffects">Efekty</String>
|
||||
<String key="GfxColTextures">Tekstury i wygładzanie</String>
|
||||
<String key="GfxColDrawRange">Zasięg rysowania</String>
|
||||
<String key="GfxColSmoothness">Płynność</String>
|
||||
@@ -921,81 +906,113 @@
|
||||
<String key="GfxGroupLevelTip">Poziom tylko tej części grafiki</String>
|
||||
<String key="REVulkan">Vulkan 1.4</String>
|
||||
<String key="IdleVulkanOnly">Działa tylko z Vulkanem.</String>
|
||||
<String key="GfxColNewRenderer">Nowy renderer (OpenGL 4.6, Vulkan)</String>
|
||||
<String key="Ini.gfx.antialiasing">Wygładzanie TAA / DLSS</String>
|
||||
<String key="Ini.gfx.antialiasing.Desc">Zastępuje MSAA. TAA wygładza cały obraz kosztem lekkiego rozmycia. DLSS i DLAA tylko z Vulkanem na kartach NVIDIA RTX.</String>
|
||||
<String key="Ini.gfx.dlss.preset">Preset DLSS</String>
|
||||
<String key="Ini.gfx.dlss.preset.Desc">Model, którym DLSS odtwarza obraz. Tryb DLSS wynika ze skali bufora: ok. 67% Jakość, 50% Wydajność, 33% Ultra wydajność.</String>
|
||||
<String key="Ini.gfx.framegeneration">Generowanie klatek</String>
|
||||
<String key="Ini.gfx.framegeneration.Desc">Dodatkowe klatki między rysowanymi. Tylko z DLSS lub DLAA. x3 i x4 tylko na kartach RTX 50.</String>
|
||||
<String key="Ini.gfx.reflex">NVIDIA Reflex</String>
|
||||
<String key="Ini.gfx.reflex.Desc">Mniejsze opóźnienie między sterowaniem a obrazem.</String>
|
||||
<String key="Ini.gfx.raytracing">Odbicia ray tracing</String>
|
||||
<String key="Ini.gfx.raytracing.Desc">Uzupełnia odbicia tam, gdzie SSR nic nie znajduje. Karta musi mieć ray query.</String>
|
||||
<String key="Ini.gfx.raytracing.range">Zasięg ray tracingu</String>
|
||||
<String key="Ini.gfx.vulkan.device">Karta graficzna (Vulkan)</String>
|
||||
<String key="Ini.gfx.vulkan.device.Desc">Numer karty z listy w logu albo fragment nazwy, np. RTX. Puste: wybór automatyczny.</String>
|
||||
<String key="Ini.gfx.ssr">Odbicia w przestrzeni ekranu (SSR)</String>
|
||||
<String key="Ini.gfx.ssr.Desc">Odbicia tego, co widać na ekranie, na mokrych i gładkich powierzchniach.</String>
|
||||
<String key="Ini.gfx.postfx.ao">Okluzja otoczenia</String>
|
||||
<String key="Ini.gfx.postfx.ao.Desc">Przyciemnia zakamarki i styki powierzchni. GTAO jest dokładniejsze od SSAO.</String>
|
||||
<String key="Ini.gfx.postfx.ao.quality">Jakość okluzji</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting">Okluzja w świetle otoczenia</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting.Desc">Tylko z GTAO. Przyciemnia światło otoczenia i odbicia, a słońce i lampy zostają jasne. Wyłączone: mnoży gotowy obraz, taniej.</String>
|
||||
<String key="Ini.gfx.lights.clustered">Oświetlenie klastrowe</String>
|
||||
<String key="Ini.gfx.lights.clustered.Desc">Światła pojazdów i latarnie bez limitu liczby. Potrzebne dla lamp scenerii i lampy w kabinie.</String>
|
||||
<String key="Ini.gfx.lights.shadows">Cienie lamp i reflektorów</String>
|
||||
<String key="Ini.gfx.lights.shadows.Desc">Cienie rzucane przez lampę kabiny, latarnie i reflektory pojazdów.</String>
|
||||
<String key="Ini.gfx.contactshadows">Cienie kontaktowe</String>
|
||||
<String key="Ini.gfx.contactshadows.Desc">Drobne cienie w miejscach styku obiektów, których mapa cieni nie łapie.</String>
|
||||
<String key="Ini.gfx.shadow.sdsm">Kaskady cieni dopasowane do sceny (SDSM)</String>
|
||||
<String key="Ini.gfx.shadow.sdsm.Desc">Rozkłada rozdzielczość cieni słońca na to, co faktycznie widać.</String>
|
||||
<String key="Ini.gfx.cabprobe">Próbka kabiny</String>
|
||||
<String key="Ini.gfx.cabprobe.Desc">Światło odbite od ścian kabiny i odbicia wnętrza w szybach.</String>
|
||||
<String key="Ini.gfx.cabprobe.interval">Odświeżanie próbki co N klatek</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections">Kabina odbija siebie</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections.Desc">W szybach widać wnętrze kabiny zamiast nieba tam, gdzie SSR nic nie znajduje.</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce">Odbite światło lampy w kabinie</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce.Desc">Ile światła lampy odbitego od ścian oświetla kabinę ponownie. Działa z próbką kabiny.</String>
|
||||
<String key="Ini.gfx.fog">Mgła</String>
|
||||
<String key="Ini.gfx.fog.Desc">Wolumetryczna: z promieniami słońca, cieniami chmur i światłem lamp. Analityczna: prostsza i tańsza.</String>
|
||||
<String key="Ini.gfx.fog.quality">Jakość mgły</String>
|
||||
<String key="Ini.gfx.clouds">Chmury wolumetryczne</String>
|
||||
<String key="Ini.gfx.clouds.shadows">Cienie chmur na ziemi</String>
|
||||
<String key="Ini.gfx.grass">Trawa</String>
|
||||
<String key="Ini.gfx.grass.distance">Zasięg trawy</String>
|
||||
<String key="Ini.gfx.grass.fadedistance">Trawa zanika do</String>
|
||||
<String key="Ini.gfx.grass.density">Gęstość trawy</String>
|
||||
<String key="Ini.gfx.precipitation.particles">Opady (cząsteczki)</String>
|
||||
<String key="Ini.gfx.precipitation.particles.Desc">Liczba kropli deszczu i płatków śniegu przy największych opadach.</String>
|
||||
<String key="Ini.gfx.postfx.bloom">Poświata jasnych miejsc (bloom)</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure">Automatyczna ekspozycja</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure.Desc">Jasność obrazu dopasowuje się do sceny, np. przy wjeździe do tunelu.</String>
|
||||
<String key="IniWord.same">Jak MSAA wyżej</String>
|
||||
<String key="IniWord.no">Wyłączone</String>
|
||||
<String key="IniWord.off">Wyłączone</String>
|
||||
<String key="IniWord.low">Niskie</String>
|
||||
<String key="IniWord.medium">Średnie</String>
|
||||
<String key="IniWord.high">Wysokie</String>
|
||||
<String key="IniWord.ultra">Ultra</String>
|
||||
<String key="IniWord.on">Włączony</String>
|
||||
<String key="IniWord.boost">Włączony + boost</String>
|
||||
<String key="IniWord.ssao">SSAO</String>
|
||||
<String key="IniWord.gtao">GTAO</String>
|
||||
<String key="IniWord.volumetric">Wolumetryczna</String>
|
||||
<String key="IniWord.analytic">Analityczna</String>
|
||||
<String key="IniWord.default">Automatyczny</String>
|
||||
<String key="IniWord.k">K: najlepsza jakość</String>
|
||||
<String key="IniWord.j">J: mniej smużenia</String>
|
||||
<String key="IniWord.m">M: pod tryb Wydajność</String>
|
||||
<String key="IniWord.l">L: pod Ultra wydajność</String>
|
||||
<String key="IniWord.x2">x2</String>
|
||||
<String key="IniWord.x3">x3</String>
|
||||
<String key="IniWord.x4">x4</String>
|
||||
<String key="IniWord.taa">TAA</String>
|
||||
<String key="IniWord.dlss">DLSS (skalowanie)</String>
|
||||
<String key="IniWord.dlaa">DLAA (natywna rozdzielczość)</String>
|
||||
<String key="IniWord.3_4">Domyślna (3×4)</String>
|
||||
<String key="IniWord.4_6">Wysoka (4×6)</String>
|
||||
<String key="IniWord.6_8">Ultra (6×8)</String>
|
||||
<String key="DlssPreset">Preset DLSS</String>
|
||||
<String key="DlssPresetDesc">Model, którym DLSS odtwarza obraz. Tryb DLSS wynika ze skali bufora: ok. 67% Jakość, 50% Wydajność, 33% Ultra wydajność.</String>
|
||||
<String key="FrameGeneration">Generowanie klatek</String>
|
||||
<String key="FrameGenerationDesc">Dodatkowe klatki między rysowanymi. Tylko z DLSS lub DLAA. x3 i x4 tylko na kartach RTX 50.</String>
|
||||
<String key="Reflex">NVIDIA Reflex</String>
|
||||
<String key="ReflexDesc">Mniejsze opóźnienie między sterowaniem a obrazem.</String>
|
||||
<String key="RayTracing">Odbicia ray tracing</String>
|
||||
<String key="RayTracingDesc">Uzupełnia odbicia tam, gdzie SSR nic nie znajduje. Karta musi mieć ray query.</String>
|
||||
<String key="RayTracingRange">Zasięg ray tracingu</String>
|
||||
<String key="VulkanDevice">Karta graficzna (Vulkan)</String>
|
||||
<String key="VulkanDeviceDesc">Numer karty z listy w logu albo fragment nazwy, np. RTX. Puste: wybór automatyczny.</String>
|
||||
<String key="Ssr">Odbicia w przestrzeni ekranu (SSR)</String>
|
||||
<String key="SsrDesc">Odbicia tego, co widać na ekranie, na mokrych i gładkich powierzchniach.</String>
|
||||
<String key="AmbientOcclusion">Okluzja otoczenia</String>
|
||||
<String key="AmbientOcclusionDesc">Przyciemnia zakamarki i styki powierzchni. GTAO jest dokładniejsze od SSAO.</String>
|
||||
<String key="AmbientOcclusionQuality">Jakość okluzji</String>
|
||||
<String key="AoLighting">Okluzja w świetle otoczenia</String>
|
||||
<String key="AoLightingDesc">Tylko z GTAO. Przyciemnia światło otoczenia i odbicia, a słońce i lampy zostają jasne. Wyłączone: mnoży gotowy obraz, taniej.</String>
|
||||
<String key="LightsClustered">Oświetlenie klastrowe</String>
|
||||
<String key="LightsClusteredDesc">Światła pojazdów i latarnie bez limitu liczby. Potrzebne dla lamp scenerii i lampy w kabinie.</String>
|
||||
<String key="LightShadows">Cienie lamp i reflektorów</String>
|
||||
<String key="LightShadowsDesc">Cienie rzucane przez lampę kabiny, latarnie i reflektory pojazdów.</String>
|
||||
<String key="ContactShadows">Cienie kontaktowe</String>
|
||||
<String key="ContactShadowsDesc">Drobne cienie w miejscach styku obiektów, których mapa cieni nie łapie.</String>
|
||||
<String key="ShadowSdsm">Kaskady cieni dopasowane do sceny (SDSM)</String>
|
||||
<String key="ShadowSdsmDesc">Rozkłada rozdzielczość cieni słońca na to, co faktycznie widać.</String>
|
||||
<String key="CabProbe">Próbka kabiny</String>
|
||||
<String key="CabProbeDesc">Światło odbite od ścian kabiny i odbicia wnętrza w szybach.</String>
|
||||
<String key="CabProbeInterval">Odświeżanie próbki co N klatek</String>
|
||||
<String key="CabProbeReflections">Kabina odbija siebie</String>
|
||||
<String key="CabProbeReflectionsDesc">W szybach widać wnętrze kabiny zamiast nieba tam, gdzie SSR nic nie znajduje.</String>
|
||||
<String key="CabProbeBounce">Odbite światło lampy w kabinie</String>
|
||||
<String key="CabProbeBounceDesc">Ile światła lampy odbitego od ścian oświetla kabinę ponownie. Działa z próbką kabiny.</String>
|
||||
<String key="FogQuality">Jakość mgły</String>
|
||||
<String key="Clouds">Chmury wolumetryczne</String>
|
||||
<String key="CloudShadows">Cienie chmur na ziemi</String>
|
||||
<String key="Grass">Trawa</String>
|
||||
<String key="GrassDistance">Zasięg trawy</String>
|
||||
<String key="GrassDensity">Gęstość trawy</String>
|
||||
<String key="Precipitation">Opady (cząsteczki)</String>
|
||||
<String key="PrecipitationDesc">Liczba kropli deszczu i płatków śniegu przy największych opadach.</String>
|
||||
<String key="Bloom">Poświata jasnych miejsc (bloom)</String>
|
||||
<String key="AutoExposure">Automatyczna ekspozycja</String>
|
||||
<String key="AutoExposureDesc">Jasność obrazu dopasowuje się do sceny, np. przy wjeździe do tunelu.</String>
|
||||
<String key="LevelOff">Wyłączone</String>
|
||||
<String key="LevelLow">Niskie</String>
|
||||
<String key="LevelMedium">Średnie</String>
|
||||
<String key="LevelHigh">Wysokie</String>
|
||||
<String key="LevelUltra">Ultra</String>
|
||||
<String key="ReflexOn">Włączony</String>
|
||||
<String key="ReflexBoost">Włączony + boost</String>
|
||||
<String key="AaTaa">TAA</String>
|
||||
<String key="AaDlss">DLSS (skalowanie)</String>
|
||||
<String key="AaDlaa">DLAA (natywna rozdzielczość)</String>
|
||||
<String key="DlssPresetDefault">Automatyczny</String>
|
||||
<String key="DlssPresetK">K: najlepsza jakość</String>
|
||||
<String key="DlssPresetJ">J: mniej smużenia</String>
|
||||
<String key="DlssPresetM">M: pod tryb Wydajność</String>
|
||||
<String key="DlssPresetL">L: pod Ultra wydajność</String>
|
||||
<String key="Effects">Efekty</String>
|
||||
<String key="GfxColImage">Rozdzielczość i wygładzanie</String>
|
||||
<String key="GfxColLights">Oświetlenie</String>
|
||||
<String key="GfxColAtmosphere">Atmosfera i pogoda</String>
|
||||
<String key="GfxColPostFx">Postprocessing</String>
|
||||
<String key="GfxColNature">Roślinność i cząsteczki</String>
|
||||
<String key="AntiAliasing">Wygładzanie krawędzi</String>
|
||||
<String key="AntiAliasingDesc">MSAA wygładza krawędzie obiektów, TAA cały obraz kosztem lekkiego rozmycia. DLSS i DLAA tylko z Vulkanem na kartach NVIDIA RTX, inaczej symulator użyje TAA.</String>
|
||||
<String key="VolumetricFog">Mgła wolumetryczna</String>
|
||||
<String key="VolumetricFogDesc">Mgła z promieniami słońca, cieniami chmur i światłem lamp. Wyłączona: prostsza mgła analityczna.</String>
|
||||
<String key="CloudsDesc">Jakość chmur rysowanych na niebie.</String>
|
||||
<String key="REOpenGLNote">DLSS, generowanie klatek, Reflex i ray tracing tylko z Vulkanem.</String>
|
||||
<String key="REVulkanNote">Wymaga exe z Vulkanem i karty, która go obsługuje. Inaczej symulator włączy Pełny albo Stary.</String>
|
||||
<String key="VulkanDeviceAuto">automatycznie</String>
|
||||
<String key="DlssPresetInfoDefault">K dla DLAA, Jakości i Zrównoważonego, M dla Wydajności, L dla Ultra wydajności. Sterownik może to zmienić przy aktualizacji.</String>
|
||||
<String key="DlssPresetInfoK">Model transformer o najlepszej jakości obrazu, ale najdroższy w obliczeniach. Domyślny dla DLAA, Jakości i Zrównoważonego.</String>
|
||||
<String key="DlssPresetInfoJ">Podobny do K: trochę mniej smug za ruchomymi obiektami kosztem większego migotania. NVIDIA zaleca raczej K.</String>
|
||||
<String key="DlssPresetInfoM">Model dobrany do trybu Wydajność (skala ok. 50%), w nim domyślny. Sam liczy ekspozycję obrazu.</String>
|
||||
<String key="DlssPresetInfoL">Model dobrany do trybu Ultra wydajność (skala ok. 33%), w nim domyślny. Sam liczy ekspozycję obrazu.</String>
|
||||
<String key="DlssMissingLibraryNote">Obok symulatora nie ma {0}: bez tej biblioteki nie użyje tej funkcji DLSS.</String>
|
||||
<String key="DlssNoPlatformNote">Na macOS DLSS nie jest dostępny.</String>
|
||||
<String key="FrameGenerationNeedsDlssNote">Generowanie klatek działa tylko z DLSS albo DLAA.</String>
|
||||
<String key="ReflexForcedNote">Generowanie klatek włącza Reflex samo, niezależnie od tego wyboru.</String>
|
||||
<String key="AoLightingPrepassNote">Wymaga głębi całej sceny przed kolorem; bez SSR i cieni kontaktowych to dodatkowy przebieg (koszt CPU w OpenGL).</String>
|
||||
<String key="AoNeedsPipelineNote">Przy pominiętym postprocessingu AO nie działa.</String>
|
||||
<String key="CabProbeReflectionsOnlyNote">Bez oświetlenia klastrowego i lampy kabiny jako światła (gfx.lights.cab) próbka daje tylko odbicia.</String>
|
||||
<String key="TemporalNeedsPipelineNote">TAA i DLSS działają w postprocessingu: gdy go pominiesz, krawędzie nie będą wygładzane.</String>
|
||||
<String key="SettingsFile">Plik eu07.ini</String>
|
||||
<String key="ImportIni">Importuj…</String>
|
||||
<String key="ImportIniTitle">Importuj ustawienia z eu07.ini</String>
|
||||
<String key="ImportIniFailed">Nie udało się odczytać pliku:
|
||||
{0}</String>
|
||||
<String key="ImportIniDone">Zaimportowano {0}: zapisz, aby zachować</String>
|
||||
<String key="ExportIni">Eksportuj…</String>
|
||||
<String key="ExportIniTitle">Eksportuj ustawienia do eu07.ini</String>
|
||||
<String key="ExportIniFailed">Nie udało się zapisać pliku:
|
||||
{0}</String>
|
||||
<String key="ExportIniDone">Wyeksportowano do {0}</String>
|
||||
<String key="REFull">Pełny</String>
|
||||
<String key="REOld">Stary</String>
|
||||
<String key="RESimp">Uproszczony</String>
|
||||
<String key="REExperimental">Eksperymentalny</String>
|
||||
<String key="RenderAngleVulkan">Użyj renderera ANGLE Vulkan</String>
|
||||
<String key="RenderAngleVulkanDesc">Uruchamia renderer ANGLE na Vulkanie zamiast domyślnego backendu. Przydatne, gdy OpenGL sprawia problemy.</String>
|
||||
<String key="RenderVBO">Renderowanie VBO</String>
|
||||
<String key="RenderVBODesc">Trzyma geometrię w buforach karty graficznej. Wyłącz tylko przy problemach ze starszymi kartami.</String>
|
||||
<String key="CabShadowsRange">Zasięg źródeł cieni w kabinie</String>
|
||||
<String key="CabShadowsRangeDesc">Odległość, z jakiej źródła światła nadal rzucają cień w kabinie. Zero wyłącza cienie w kabinie.</String>
|
||||
<String key="UseGLES">Używaj OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES zamiast OpenGL. Nie działa z rendererem legacy.</String>
|
||||
</Language>
|
||||
|
||||
@@ -406,11 +406,7 @@
|
||||
|
||||
<String key="Graphic">Графика</String>
|
||||
<String key="RenderEngine">Движок отрисовки</String>
|
||||
<String key="REFull">Полный</String>
|
||||
<String key="RenderEngineDesc">Полный: OpenGL с тенями и отражениями, в новом симуляторе OpenGL 4.6. Старый, Упрощённый, Экспериментальный: старые версии симулятора, новая запустит Полный. Vulkan 1.4: если его нет в exe или карта не справится, новая версия запустит OpenGL, а старая Старый.</String>
|
||||
<String key="REOld">Старый</String>
|
||||
<String key="RESimp">Упрощённый</String>
|
||||
<String key="REExperimental">Экспериментальный</String>
|
||||
<String key="RenderEngineDesc">Полный работает с любым exe. Старый, Упрощённый и Экспериментальный только со старыми, новый вместо них запустит Полный.</String>
|
||||
<String key="REExperimentalWarning">Внимание: экспериментальный рендерер находится в разработке. Он может работать нестабильно, не показывать части сцены или не запускаться на некоторых видеокартах. Если симулятор не запускается или выглядит неправильно, вернитесь к рендереру «Полный».</String>
|
||||
<String key="GpuChoice">Видеокарта (Linux)</String>
|
||||
<String key="GpuDiscrete">Мощнее (дискретная)</String>
|
||||
@@ -436,8 +432,6 @@
|
||||
<String key="MaxTexCabResolution">Максимальное разрешение текстур кабины</String>
|
||||
<String key="TexFilteringQuality">Качество фильтрации текстур</String>
|
||||
<String key="TexFilteringQualityDesc">Чёткость текстур под углом, например рельсов. Даже x16 стоит немного.</String>
|
||||
<String key="Multisampling">Multisampling</String>
|
||||
<String key="MultisamplingDesc">Сглаживание краёв. Каждая ступень заметно снижает частоту кадров.</String>
|
||||
<String key="QualityVeryLow">Очень низкое</String>
|
||||
<String key="QualityLow">Низкое</String>
|
||||
<String key="QualityNormal">Нормальное</String>
|
||||
@@ -462,7 +456,6 @@
|
||||
<String key="ShadowAngleLimit">Ограничение длины теней</String>
|
||||
<String key="ShadowLimitShort">Укороченные</String>
|
||||
<String key="FullscreenWindowed">Автоматическое разрешение (полный экран без рамки)</String>
|
||||
<String key="RenderAngleVulkan">Использовать рендерер ANGLE Vulkan</String>
|
||||
<String key="VSync">VSync</String>
|
||||
<String key="SmokeDisplay">Отображение дыма</String>
|
||||
<String key="SmokeParticlesMultiplier">Множитель частиц дыма</String>
|
||||
@@ -472,7 +465,6 @@
|
||||
<String key="AdditionalShadersEffects">Дополнительные эффекты шейдеров</String>
|
||||
<String key="ReflectionsCubeMap">Отражения как кубическая карта</String>
|
||||
<String key="SkipPipeline">SkipPipeline</String>
|
||||
<String key="RenderVBO">Отрисовка VBO</String>
|
||||
<String key="RenderShadows">Отрисовывать тени</String>
|
||||
<String key="ReflectionsFramerate">Частота обновления отражений</String>
|
||||
<String key="ReflectionsFramerateDesc">Как часто обновлять отражения. Реже значит больше кадров.</String>
|
||||
@@ -482,7 +474,6 @@
|
||||
<String key="ShadowsResolution">Разрешение теней</String>
|
||||
<String key="ShaderRange">Дальность теней</String>
|
||||
<String key="ShaderRangeDesc">Как далеко видны тени; чем дальше, тем мягче. После стрелки реальная дальность.</String>
|
||||
<String key="CabShadowsRange">Дальность источников теней в кабине</String>
|
||||
|
||||
<String key="ShadowDisplay">Показывать тени</String>
|
||||
<String key="CSROnlyImportant">Только важные</String>
|
||||
@@ -527,8 +518,6 @@
|
||||
<String key="CompressTextures">Сжимать текстуры TGA</String>
|
||||
<String key="ScaleSpeculars">Масштабировать блики (совместимость со старыми моделями)</String>
|
||||
<String key="ScaleSpecularsDesc">Ослабляет блеск моделей, сделанных для старых рендереров.</String>
|
||||
<String key="UseGLES">Использовать OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES вместо OpenGL. Не работает с рендерером legacy.</String>
|
||||
<String key="ShaderGamma">Гамма-коррекция в шейдерах</String>
|
||||
<String key="ShaderGammaDesc">Гамма в шейдерах вместо sRGB. Если драйвер даёт слишком светлую или тёмную картинку.</String>
|
||||
<String key="ScreenMipmaps">Создавать мипмапы для текстур экранов кабины (Python)</String>
|
||||
@@ -674,7 +663,6 @@
|
||||
<String key="GfxColResolution">Изображение</String>
|
||||
<String key="GfxColRendering">Рендерер</String>
|
||||
<String key="GfxColShadows">Тени</String>
|
||||
<String key="GfxColEffects">Эффекты</String>
|
||||
<String key="GfxColTextures">Текстуры и сглаживание</String>
|
||||
<String key="GfxColDrawRange">Дальность отрисовки</String>
|
||||
<String key="GfxColSmoothness">Плавность</String>
|
||||
@@ -867,62 +855,90 @@
|
||||
<String key="GfxGroupLevelTip">Уровень только для этой части графики</String>
|
||||
<String key="REVulkan">Vulkan 1.4</String>
|
||||
<String key="IdleVulkanOnly">Работает только с Vulkan.</String>
|
||||
<String key="GfxColNewRenderer">Новый рендерер (OpenGL 4.6, Vulkan)</String>
|
||||
<String key="Ini.gfx.antialiasing">Сглаживание TAA / DLSS</String>
|
||||
<String key="Ini.gfx.dlss.preset">Пресет DLSS</String>
|
||||
<String key="Ini.gfx.framegeneration">Генерация кадров</String>
|
||||
<String key="Ini.gfx.reflex">NVIDIA Reflex</String>
|
||||
<String key="Ini.gfx.raytracing">Отражения с трассировкой лучей</String>
|
||||
<String key="Ini.gfx.raytracing.range">Дальность трассировки лучей</String>
|
||||
<String key="Ini.gfx.vulkan.device">Видеокарта (Vulkan)</String>
|
||||
<String key="Ini.gfx.ssr">Отражения в экранном пространстве (SSR)</String>
|
||||
<String key="Ini.gfx.postfx.ao">Фоновое затенение</String>
|
||||
<String key="Ini.gfx.postfx.ao.quality">Качество затенения</String>
|
||||
<String key="Ini.gfx.postfx.ao.lighting">Затенение в фоновом свете</String>
|
||||
<String key="Ini.gfx.lights.clustered">Кластерное освещение</String>
|
||||
<String key="Ini.gfx.lights.shadows">Тени ламп и прожекторов</String>
|
||||
<String key="Ini.gfx.contactshadows">Контактные тени</String>
|
||||
<String key="Ini.gfx.shadow.sdsm">Каскады теней по сцене (SDSM)</String>
|
||||
<String key="Ini.gfx.cabprobe">Зонд кабины</String>
|
||||
<String key="Ini.gfx.cabprobe.interval">Обновление зонда каждые N кадров</String>
|
||||
<String key="Ini.gfx.cabprobe.reflections">Кабина отражает себя</String>
|
||||
<String key="Ini.gfx.cabprobe.bounce">Отражённый свет лампы в кабине</String>
|
||||
<String key="Ini.gfx.fog">Туман</String>
|
||||
<String key="Ini.gfx.fog.quality">Качество тумана</String>
|
||||
<String key="Ini.gfx.clouds">Объёмные облака</String>
|
||||
<String key="Ini.gfx.clouds.shadows">Тени облаков на земле</String>
|
||||
<String key="Ini.gfx.grass">Трава</String>
|
||||
<String key="Ini.gfx.grass.distance">Дальность травы</String>
|
||||
<String key="Ini.gfx.grass.fadedistance">Трава исчезает на</String>
|
||||
<String key="Ini.gfx.grass.density">Густота травы</String>
|
||||
<String key="Ini.gfx.precipitation.particles">Осадки (частицы)</String>
|
||||
<String key="Ini.gfx.postfx.bloom">Свечение ярких мест (bloom)</String>
|
||||
<String key="Ini.gfx.postfx.autoexposure">Автоматическая экспозиция</String>
|
||||
<String key="IniWord.same">Как MSAA выше</String>
|
||||
<String key="IniWord.no">Выкл.</String>
|
||||
<String key="IniWord.off">Выкл.</String>
|
||||
<String key="IniWord.low">Низкое</String>
|
||||
<String key="IniWord.medium">Среднее</String>
|
||||
<String key="IniWord.high">Высокое</String>
|
||||
<String key="IniWord.ultra">Ультра</String>
|
||||
<String key="IniWord.on">Вкл.</String>
|
||||
<String key="IniWord.boost">Вкл. + boost</String>
|
||||
<String key="IniWord.ssao">SSAO</String>
|
||||
<String key="IniWord.gtao">GTAO</String>
|
||||
<String key="IniWord.volumetric">Объёмный</String>
|
||||
<String key="IniWord.analytic">Аналитический</String>
|
||||
<String key="IniWord.default">Автоматически</String>
|
||||
<String key="IniWord.k">K: лучшее качество</String>
|
||||
<String key="IniWord.j">J: меньше размытия</String>
|
||||
<String key="IniWord.m">M: для режима Производительность</String>
|
||||
<String key="IniWord.l">L: для Ультра производительность</String>
|
||||
<String key="IniWord.x2">x2</String>
|
||||
<String key="IniWord.x3">x3</String>
|
||||
<String key="IniWord.x4">x4</String>
|
||||
<String key="IniWord.taa">TAA</String>
|
||||
<String key="IniWord.dlss">DLSS (масштабирование)</String>
|
||||
<String key="IniWord.dlaa">DLAA (родное разрешение)</String>
|
||||
<String key="IniWord.3_4">По умолчанию (3×4)</String>
|
||||
<String key="IniWord.4_6">Высокое (4×6)</String>
|
||||
<String key="IniWord.6_8">Ультра (6×8)</String>
|
||||
<String key="DlssPreset">Пресет DLSS</String>
|
||||
<String key="FrameGeneration">Генерация кадров</String>
|
||||
<String key="Reflex">NVIDIA Reflex</String>
|
||||
<String key="RayTracing">Отражения с трассировкой лучей</String>
|
||||
<String key="RayTracingRange">Дальность трассировки лучей</String>
|
||||
<String key="VulkanDevice">Видеокарта (Vulkan)</String>
|
||||
<String key="Ssr">Отражения в экранном пространстве (SSR)</String>
|
||||
<String key="AmbientOcclusion">Фоновое затенение</String>
|
||||
<String key="AmbientOcclusionQuality">Качество затенения</String>
|
||||
<String key="AoLighting">Затенение в фоновом свете</String>
|
||||
<String key="LightsClustered">Кластерное освещение</String>
|
||||
<String key="LightShadows">Тени ламп и прожекторов</String>
|
||||
<String key="ContactShadows">Контактные тени</String>
|
||||
<String key="ShadowSdsm">Каскады теней по сцене (SDSM)</String>
|
||||
<String key="CabProbe">Зонд кабины</String>
|
||||
<String key="CabProbeInterval">Обновление зонда каждые N кадров</String>
|
||||
<String key="CabProbeReflections">Кабина отражает себя</String>
|
||||
<String key="CabProbeBounce">Отражённый свет лампы в кабине</String>
|
||||
<String key="FogQuality">Качество тумана</String>
|
||||
<String key="Clouds">Объёмные облака</String>
|
||||
<String key="CloudShadows">Тени облаков на земле</String>
|
||||
<String key="Grass">Трава</String>
|
||||
<String key="GrassDistance">Дальность травы</String>
|
||||
<String key="GrassDensity">Густота травы</String>
|
||||
<String key="Precipitation">Осадки (частицы)</String>
|
||||
<String key="Bloom">Свечение ярких мест (bloom)</String>
|
||||
<String key="AutoExposure">Автоматическая экспозиция</String>
|
||||
<String key="LevelOff">Выкл.</String>
|
||||
<String key="LevelLow">Низкое</String>
|
||||
<String key="LevelMedium">Среднее</String>
|
||||
<String key="LevelHigh">Высокое</String>
|
||||
<String key="LevelUltra">Ультра</String>
|
||||
<String key="ReflexOn">Вкл.</String>
|
||||
<String key="ReflexBoost">Вкл. + boost</String>
|
||||
<String key="AaTaa">TAA</String>
|
||||
<String key="AaDlss">DLSS (масштабирование)</String>
|
||||
<String key="AaDlaa">DLAA (родное разрешение)</String>
|
||||
<String key="DlssPresetDefault">Автоматически</String>
|
||||
<String key="DlssPresetK">K: лучшее качество</String>
|
||||
<String key="DlssPresetJ">J: меньше размытия</String>
|
||||
<String key="DlssPresetM">M: для режима Производительность</String>
|
||||
<String key="DlssPresetL">L: для Ультра производительность</String>
|
||||
<String key="Effects">Эффекты</String>
|
||||
<String key="GfxColImage">Разрешение и сглаживание</String>
|
||||
<String key="GfxColLights">Освещение</String>
|
||||
<String key="GfxColAtmosphere">Атмосфера и погода</String>
|
||||
<String key="GfxColPostFx">Постобработка</String>
|
||||
<String key="GfxColNature">Растительность и частицы</String>
|
||||
<String key="AntiAliasing">Сглаживание</String>
|
||||
<String key="VolumetricFog">Объёмный туман</String>
|
||||
<String key="REOpenGLNote">DLSS, генерация кадров, Reflex и трассировка лучей только с Vulkan.</String>
|
||||
<String key="REVulkanNote">Нужен exe с Vulkan и карта с его поддержкой. Иначе симулятор запустит Полный или Старый.</String>
|
||||
<String key="VulkanDeviceAuto">автоматически</String>
|
||||
<String key="DlssPresetInfoDefault">K для DLAA, «Качества» и «Баланса», M для «Производительности», L для «Ультрапроизводительности». Драйвер может изменить это при обновлении.</String>
|
||||
<String key="DlssPresetInfoK">Модель transformer с лучшим качеством изображения, но самая затратная. По умолчанию для DLAA, «Качества» и «Баланса».</String>
|
||||
<String key="DlssPresetInfoJ">Похожа на K: чуть меньше шлейфов за движущимися объектами ценой большего мерцания. NVIDIA скорее рекомендует K.</String>
|
||||
<String key="DlssPresetInfoM">Модель для режима «Производительность» (масштаб около 50%), в нём по умолчанию. Сама вычисляет экспозицию.</String>
|
||||
<String key="DlssPresetInfoL">Модель для режима «Ультрапроизводительность» (масштаб около 33%), в нём по умолчанию. Сама вычисляет экспозицию.</String>
|
||||
<String key="DlssMissingLibraryNote">Рядом с симулятором нет {0}: без этой библиотеки симулятор не использует эту функцию DLSS.</String>
|
||||
<String key="DlssNoPlatformNote">На macOS DLSS недоступен.</String>
|
||||
<String key="FrameGenerationNeedsDlssNote">Генерация кадров работает только с DLSS или DLAA.</String>
|
||||
<String key="ReflexForcedNote">Генерация кадров сама включает Reflex, что бы здесь ни было выбрано.</String>
|
||||
<String key="AoLightingPrepassNote">Нужна глубина всей сцены до цвета; без SSR и контактных теней это лишний проход (нагрузка на ЦП в OpenGL).</String>
|
||||
<String key="AoNeedsPipelineNote">Если постобработка пропущена, AO не работает.</String>
|
||||
<String key="CabProbeReflectionsOnlyNote">Без кластерного освещения и лампы кабины как источника света (gfx.lights.cab) зонд даёт только отражения.</String>
|
||||
<String key="TemporalNeedsPipelineNote">TAA и DLSS работают в постобработке: если её пропустить, края не сгладятся.</String>
|
||||
<String key="SettingsFile">Файл eu07.ini</String>
|
||||
<String key="ImportIni">Импорт…</String>
|
||||
<String key="ImportIniTitle">Импорт настроек из eu07.ini</String>
|
||||
<String key="ImportIniFailed">Не удалось прочитать файл:
|
||||
{0}</String>
|
||||
<String key="ImportIniDone">Импортирован {0}: сохраните, чтобы оставить</String>
|
||||
<String key="ExportIni">Экспорт…</String>
|
||||
<String key="ExportIniTitle">Экспорт настроек в eu07.ini</String>
|
||||
<String key="ExportIniFailed">Не удалось записать файл:
|
||||
{0}</String>
|
||||
<String key="ExportIniDone">Экспортировано в {0}</String>
|
||||
<String key="REFull">Полный</String>
|
||||
<String key="REOld">Старый</String>
|
||||
<String key="RESimp">Упрощённый</String>
|
||||
<String key="REExperimental">Экспериментальный</String>
|
||||
<String key="RenderAngleVulkan">Использовать рендерер ANGLE Vulkan</String>
|
||||
<String key="RenderVBO">Отрисовка VBO</String>
|
||||
<String key="CabShadowsRange">Дальность источников теней в кабине</String>
|
||||
<String key="UseGLES">Использовать OpenGL ES</String>
|
||||
<String key="UseGLESDesc">OpenGL ES вместо OpenGL. Не работает с рендерером legacy.</String>
|
||||
</Language>
|
||||
|
||||
Reference in New Issue
Block a user