3D pixel look follows the window size
The 3D resolution setting refers to a window 1080 device pixels high; smaller windows use a proportionally smaller divisor (1/1 stays full resolution). Settings show the divisor in effect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
05d9cf8824
commit
036c13577c
3 files changed
+38
-3
No files matched your search
+9
-1
@@ -111,7 +111,15 @@ fn item_value(it: Item, s: &Settings) -> String {
|
||||
format!("{}x", s.ui_factor)
|
||||
}
|
||||
}
|
||||
Item::RenderScale => format!("1/{}", s.render_scale.max(1)),
|
||||
Item::RenderScale => {
|
||||
// the setting is for a 1080 pixel high window; show what applies to this one
|
||||
let now = crate::render3d::effective_div(s.render_scale.max(1) as u32, crate::ui::sh());
|
||||
if now as u8 == s.render_scale.max(1) {
|
||||
format!("1/{}", s.render_scale.max(1))
|
||||
} else {
|
||||
format!("1/{} (1/{})", s.render_scale.max(1), now)
|
||||
}
|
||||
}
|
||||
Item::GameSpeed => format!("{}x", s.game_speed as i32),
|
||||
Item::Hints => onoff(s.hints),
|
||||
Item::TouchUi => match s.touch_ui {
|
||||
|
||||
+28
-1
@@ -762,6 +762,18 @@ pub struct R3d {
|
||||
target: Option<(RenderTarget, u32, u32)>, // low resolution render target
|
||||
}
|
||||
|
||||
// The 3D resolution setting refers to a window 1080 device pixels high: smaller windows use a
|
||||
// proportionally smaller divisor, so the 3D pixels keep their size relative to the window.
|
||||
// 1 (full resolution) stays 1.
|
||||
pub const RENDER_REF_HEIGHT: f32 = 1080.0;
|
||||
|
||||
pub fn effective_div(setting: u32, height: f32) -> u32 {
|
||||
if setting <= 1 {
|
||||
return 1;
|
||||
}
|
||||
((setting as f32 * height / RENDER_REF_HEIGHT).round() as u32).max(1)
|
||||
}
|
||||
|
||||
fn rgba(u: u32) -> Color {
|
||||
Color::from_rgba(u as u8, (u >> 8) as u8, (u >> 16) as u8, (u >> 24) as u8)
|
||||
}
|
||||
@@ -950,9 +962,9 @@ impl R3d {
|
||||
self.update_chunks(g, gfx, &m);
|
||||
EYE.with(|e| e.set(cam.eye_dir()));
|
||||
// pixel look: render the world at 1/div resolution and scale it up by exactly div
|
||||
let div = self.render_div.max(1);
|
||||
let d = crate::ui::dpr();
|
||||
let (pw, ph) = ((screen_width() * d).round(), (screen_height() * d).round());
|
||||
let div = effective_div(self.render_div, ph);
|
||||
let mut cam3 = cam.camera();
|
||||
if div > 1 {
|
||||
let (tw, th) = ((pw / div as f32).ceil() as u32, (ph / div as f32).ceil() as u32);
|
||||
@@ -1554,3 +1566,18 @@ pub fn minimap_color(tile: &Tile) -> [u8; 4] {
|
||||
Kind::Shard => [255, 60, 120, 255],
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn pixel_size_follows_the_window() {
|
||||
assert_eq!(effective_div(1, 400.0), 1);
|
||||
assert_eq!(effective_div(4, 1080.0), 4);
|
||||
assert_eq!(effective_div(4, 540.0), 2);
|
||||
assert_eq!(effective_div(4, 2160.0), 8);
|
||||
assert_eq!(effective_div(16, 200.0), 3);
|
||||
assert_eq!(effective_div(2, 100.0), 1);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user