8000 Scaled canvas is blurry even when using Sampler::nearest_clamp() · Issue #1138 · ggez/ggez · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Scaled canvas is blurry even when using Sampler::nearest_clamp() #1138
Closed
@londive

Description

@londive

Describe the bug
I'm basically having the same problem as #635 – I'm trying to draw stuff to a smaller canvas, then draw that canvas scaled up on the main canvas in order to achieve a crisp pixel-art effect.

To Reproduce
Here is how I'm setting up the Canvas objects, including setting their samplers:

let mut main_canvas = Canvas::from_frame(ctx, Color::BLACK);
main_canvas.set_sampler(Sampler::nearest_clamp());

let mut sub_image = ScreenImage::new(ctx, None, 1.0 / SCREEN_SCALE, 1.0 / SCREEN_SCALE, 1);
let mut sub_canvas = Canvas::from_screen_image(ctx, &mut sub_image, Color::BLACK);
sub_canvas.set_sampler(Sampler::nearest_clamp());

// Draw stuff...

sub_canvas.finish(ctx)?;
let image = sub_image.image(ctx);

main_canvas.draw(&image, DrawParam::new().scale(glam::vec2(SCREEN_SCALE, SCREEN_SCALE)));
main_canvas.finish(ctx)?;

Expected behavior
A scaled-up canvas to render with nearest-neighbour filtering.

Screenshots or pasted code
This is instead what is produced:
blurry
You can see the edges are significantly blurred.

Here's the source code that produced that image. Dead simple, just draws a rect to the smaller canvas, then draws that to the main canvas.

use std::f32::consts::TAU;

use ggez::{graphics::*, *};

const GAME_SIZE: (f32, f32) = (240.0, 180.0);
const SCREEN_SCALE: f32 = 8.0;

struct MainState {}

impl event::EventHandler<ggez::GameError> for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult {
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let mut main_canvas = Canvas::from_frame(ctx, Color::BLACK);
        main_canvas.set_sampler(Sampler::nearest_clamp());

        let mut sub_image = ScreenImage::new(ctx, None, 1.0 / SCREEN_SCALE, 1.0 / SCREEN_SCALE, 1);
        let mut sub_canvas = Canvas::from_screen_image(ctx, &mut sub_image, Color::BLACK);
        sub_canvas.set_sampler(Sampler::nearest_clamp());

        let rect = Rect::new(55.0, 40.0, 100.0, 50.0);
        sub_canvas.draw(
            &Quad,
            DrawParam::new()
                .dest(rect.point())
                .scale(rect.size())
                .color(Color::WHITE)
                .rotation(TAU / 16.0),
        );

        sub_canvas.finish(ctx)?;
        let image = sub_image.image(ctx);

        main_canvas.draw(&image, DrawParam::new().scale(glam::vec2(SCREEN_SCALE, SCREEN_SCALE)));
        main_canvas.finish(ctx)?;

        Ok(())
    }
}

pub fn main() -> GameResult {
    let cb = ggez::ContextBuilder::new("foo", "bar").window_mode(
        ggez::conf::WindowMode::default().dimensions(GAME_SIZE.0 * SCREEN_SCALE, GAME_SIZE.1 * SCREEN_SCALE),
    );
    let (ctx, event_loop) = cb.build()?;
    let state = MainState {};
    event::run(ctx, event_loop, state)
}

Hardware and Software:

  • ggez version: 0.8.1
  • OS: MacOS 12.5
  • Graphics card: Apple M1 Max

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0