Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manual creation example viewport scrolls faster than window #2090

Open
jasoneveleth opened this issue Dec 13, 2023 · 0 comments
Open

Manual creation example viewport scrolls faster than window #2090

jasoneveleth opened this issue Dec 13, 2023 · 0 comments

Comments

@jasoneveleth
Copy link

I modified the manual-creation.rs example to render a triangle. When I resize the window, it seems like the viewport is being scaled faster than the window is resize (it seems like exactly twice as fast).

ss ss 1

I added this drawing code on each redraw:

const RECTANGLE_VERTEX_SHADER_SOURCE: &str = r#"
    #version 140

    in vec2 position;

    void main() {
        gl_Position = vec4(position, 0.0, 1.0);
    }
"#;

const RECTANGLE_FRAGMENT_SHADER_SOURCE: &str = r#"
    #version 140

    out vec4 c;

    void main() {
        c = vec4(0.5, 0.0, 0.2, 0.1);;
    }
"#;


pub fn draw(disp: &glium::Display<WindowSurface>, size: LogicalSize<i32>) -> Result<(), Box<dyn std::error::Error>> {
    let mut target = disp.draw();
    target.clear_color_srgb(0.98, 0.98, 0.98, 1.);

    let rectangle_program = Program::from_source(disp, RECTANGLE_VERTEX_SHADER_SOURCE, RECTANGLE_FRAGMENT_SHADER_SOURCE, None).unwrap();
    let coords = [[0., 0.], [800., 0.], [400., 600.]];
    let coords = coords.map(|[a, b]| CursorVertex{position: [a/(size.width as f32)*2.-1., -b/(size.height as f32)*2.+1.]});
    let titlebar_vertex_buffer = VertexBuffer::new(disp, &coords).unwrap();
    let titlebar_index_buffer = IndexBuffer::new(disp, PrimitiveType::TrianglesList, &[0u32, 1u32, 2u32]).unwrap();

    target.draw(&titlebar_vertex_buffer, &titlebar_index_buffer, &rectangle_program, &EmptyUniforms, &Default::default()).unwrap();

    target.finish()?;
    Ok(())
}

It seems like the display resizing is out of sync with the window size. I was wondering what I've done wrong, since this seems very similar to the example. It might be related to winit #1561. I'm happy to dive into the code, but I'm not sure where to look.

Full file for `manual-creation.rs`
/*!

This example demonstrates how to manually create a glium context with any backend you want, most
notably without glutin.

There are three concepts in play:

 - The `Backend` trait, which defines how glium interfaces with the OpenGL context
   provider (glutin, SDL, glfw, etc.).

 - The `Context` struct, which is the main object of glium. The context also provides
   OpenGL-related functions like `get_free_video_memory` or `get_supported_glsl_version`.

 - The `Facade` trait, which is the trait required to be implemented on objects that you pass
   to functions like `VertexBuffer::new`. This trait is implemented on `Rc<Context>`, which
   means that you can direct pass the context.

*/

use crate::glium::index::PrimitiveType;
use crate::glium::implement_vertex;
use crate::glium::{Program, VertexBuffer, IndexBuffer};

use glium::{self};
use winit::event_loop::EventLoopBuilder;
use winit::window::WindowBuilder;
use glium::Surface;
use glutin::surface::WindowSurface;
use glutin::config::ConfigTemplateBuilder;
use glutin::context::{ContextApi, ContextAttributesBuilder};
use glutin::display::GetGlDisplay;
use glutin::prelude::*;
use winit::dpi::LogicalSize;
use glutin::surface::SurfaceAttributesBuilder;
use glutin_winit::DisplayBuilder;
use raw_window_handle::HasRawWindowHandle;
use glium::uniforms::EmptyUniforms;

use std::num::NonZeroU32;

#[derive(Copy, Clone, Debug)]
pub struct CursorVertex {
    position: [f32; 2],
}

implement_vertex!(CursorVertex, position);

const RECTANGLE_VERTEX_SHADER_SOURCE: &str = r#"
    #version 140

    in vec2 position;

    void main() {
        gl_Position = vec4(position, 0.0, 1.0);
    }
"#;

const RECTANGLE_FRAGMENT_SHADER_SOURCE: &str = r#"
    #version 140

    out vec4 c;

    void main() {
        c = vec4(0.5, 0.0, 0.2, 0.1);;
    }
"#;


pub fn draw(disp: &glium::Display<WindowSurface>, size: LogicalSize<i32>) -> Result<(), Box<dyn std::error::Error>> {
    let mut target = disp.draw();
    target.clear_color_srgb(0.98, 0.98, 0.98, 1.);

    let rectangle_program = Program::from_source(disp, RECTANGLE_VERTEX_SHADER_SOURCE, RECTANGLE_FRAGMENT_SHADER_SOURCE, None).unwrap();
    let coords = [[0., 0.], [800., 0.], [400., 600.]];
    let coords = coords.map(|[a, b]| CursorVertex{position: [a/(size.width as f32)*2.-1., -b/(size.height as f32)*2.+1.]});
    let titlebar_vertex_buffer = VertexBuffer::new(disp, &coords).unwrap();
    let titlebar_index_buffer = IndexBuffer::new(disp, PrimitiveType::TrianglesList, &[0u32, 1u32, 2u32]).unwrap();

    target.draw(&titlebar_vertex_buffer, &titlebar_index_buffer, &rectangle_program, &EmptyUniforms, &Default::default()).unwrap();

    target.finish()?;
    Ok(())
}

fn main() {
    let event_loop = EventLoopBuilder::new()
        .build()
        .expect("event loop building");
    let window_builder = WindowBuilder::new();
    let config_template_builder = ConfigTemplateBuilder::new();
    let display_builder = DisplayBuilder::new().with_window_builder(Some(window_builder));

    // First we create a window
    let (window, gl_config) = display_builder
        .build(&event_loop, config_template_builder, |mut configs| {
            // Just use the first configuration since we don't have any special preferences here
            configs.next().unwrap()
        })
        .unwrap();
    let window = window.unwrap();

    // Then the configuration which decides which OpenGL version we'll end up using, here we just use the default which is currently 3.3 core
    // When this fails we'll try and create an ES context, this is mainly used on mobile devices or various ARM SBC's
    // If you depend on features available in modern OpenGL Versions you need to request a specific, modern, version. Otherwise things will very likely fail.
    let raw_window_handle = window.raw_window_handle();
    let context_attributes = ContextAttributesBuilder::new().build(Some(raw_window_handle));
    let fallback_context_attributes = ContextAttributesBuilder::new()
        .with_context_api(ContextApi::Gles(None))
        .build(Some(raw_window_handle));


    let not_current_gl_context = Some(unsafe {
        gl_config.display().create_context(&gl_config, &context_attributes).unwrap_or_else(|_| {
            gl_config.display()
                .create_context(&gl_config, &fallback_context_attributes)
                .expect("failed to create context")
        })
    });

    // Determine our framebuffer size based on the window size, or default to 800x600 if it's invisible
    let (width, height): (u32, u32) = window.inner_size().into();
    let attrs = SurfaceAttributesBuilder::<WindowSurface>::new().build(
        raw_window_handle,
        NonZeroU32::new(width).unwrap(),
        NonZeroU32::new(height).unwrap(),
    );
    // Now we can create our surface, use it to make our context current and finally create our display

    let surface = unsafe { gl_config.display().create_window_surface(&gl_config, &attrs).unwrap() };
    let context = not_current_gl_context.unwrap().make_current(&surface).unwrap();
    let display = glium::Display::new(context, surface).unwrap();

    // the window is still available
    event_loop.run(|event, window_target| {
        match event {
            winit::event::Event::WindowEvent { event, .. } => match event {
                winit::event::WindowEvent::CloseRequested => window_target.exit(),
                winit::event::WindowEvent::RedrawRequested => {
                    let size = LogicalSize::from_physical(window.inner_size(), window.scale_factor());
                    draw(&display, size).unwrap()
                }
                _ => (),
            },
            _ => (),
        }
    })
    .unwrap();
}

I'm on macOS 13.5.2 (22G91), M1 Pro chip. glium version 0.33.0. Thank you for your time, glium is an amazing crate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant