feat(render): SAGE water/ocean shaders, per-user logs, camera & culling
Terrain pass now ports the SAGE water model (Ocean.fx / OpenSAGE Water.frag): a de-gridded procedural wave normal combined with the retail ra3_deepocean flow and ra3_deepocean_nrm bump maps (appended as the last two terrain-atlas layers, no new backend binding), Schlick fresnel, sky reflection + depth-graded refraction, SAGE diffuse/specular lighting, depth-based transparency, and an underwater tint (UnderwaterDeferred.fx). Mirrored across terrain.frag / dx_terrain.hlsl / webgl_terrain_frag.glsl / webgpu_terrain.wgsl. Also: logs move to the per-user state dir (%LOCALAPPDATA%\\OpenRA3\\logs, else XDG) and archive as openra3.<stamp>.log; the FPS label shows the active backend; middle-drag camera reset; objects and roads below the water plane are culled.
This commit is contained in:
+14
-5
@@ -182,7 +182,8 @@ export namespace ender::log {
|
||||
* `path` is the active file. When the sink opens it and the file already
|
||||
* holds data, that file is renamed to a timestamped archive first, so a run
|
||||
* never appends onto a previous run's log: every start begins a fresh file
|
||||
* and the old one is preserved as `<path>.<YYYYmmdd-HHMMSS>`. The same
|
||||
* and the old one is preserved with the timestamp before its extension, as
|
||||
* `<stem>.<YYYYmmdd-HHMMSS>.log`. The same
|
||||
* happens mid-run once the active file passes `file_options::max_file_size`.
|
||||
* `file_options::max_archives` bounds how many archives are kept.
|
||||
*
|
||||
@@ -238,13 +239,21 @@ export namespace ender::log {
|
||||
if (stream_.is_open()) stream_.close();
|
||||
const auto stamp = std::format("{:%Y%m%d-%H%M%S}",
|
||||
std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now()));
|
||||
auto archive = path_;
|
||||
archive += "." + stamp;
|
||||
// Keep the original extension last, with the timestamp in the
|
||||
// middle: `<stem>.<stamp>[.<n>]<ext>`.
|
||||
const auto name = [&](const std::size_t counter) {
|
||||
auto candidate = path_.parent_path() / path_.stem();
|
||||
candidate += ".";
|
||||
candidate += stamp;
|
||||
if (counter > 0) candidate += std::format(".{}", counter);
|
||||
candidate += path_.extension();
|
||||
return candidate;
|
||||
};
|
||||
auto archive = name(0);
|
||||
// Two rotations can land in the same second; disambiguate with a
|
||||
// counter rather than overwrite the earlier archive.
|
||||
for (auto counter = 1; std::filesystem::exists(archive); ++counter) {
|
||||
archive = path_;
|
||||
archive += std::format(".{}.{}", stamp, counter);
|
||||
archive = name(counter);
|
||||
}
|
||||
std::filesystem::rename(path_, archive);
|
||||
archives_.push_back(archive);
|
||||
|
||||
Reference in New Issue
Block a user