Coder Social home page Coder Social logo

glium_graphics's Introduction

glium_graphics Build Status

A Glium 2D back-end for the Piston game engine

glium_graphics's People

Contributors

3c1u avatar abonander avatar atul9 avatar bvssvni avatar ebarnard avatar geal avatar kalexmills avatar kerollmops avatar milibopp avatar mitchmindtree avatar potpourri avatar samestep avatar tomaka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

glium_graphics's Issues

image dependency should be optional

image is a large crate which takes a long time to compile and which brings in lots of dependencies.

It should be possible to disable image using a Cargo feature.

Similarly to #156, I am happy to implement if the PR will be considered.

Rationale for `GliumWindow` design

The previous design did not work well because Glium uses &self on glium::Context in combination with some unfortunate left-right evaluation rules in Rust. This leads to a situation where while let in the event loop borrows the window for the scope of the whole loop, instead of just the right argument:

while let Some(e) = { let mut b = window.borrow_mut(); events.next(&mut *b) } { ... }

(yes, that was the real code! ๐Ÿ˜ฑ )

You also had to import Rc and RefCell and write two lines to create a window. By implement BuildFromWindowSettings from the Piston core, this was reduced to one line.

Glium swaps buffers in the drop of glium::Frame, which means swapping of buffers should be disabled in the Piston event loop. By moving the event loop state inside GliumWindow, this setting can be turned off by default.

To make glium_graphics work for other backends than Glutin, the OpenGLWindow trait was required from pistoncore-window. Since we already depended on this in previous design, it was a small step to swap out this dependency with the piston core, which reexports input, window and event_loop.

In most cases, people are using Glutin as window backend. The new design uses Glutin as the default backend. It means you can type GliumWindow to use Glutin or GliumWindow<Sdl2Window> to use SDL2 (or another window backend).

The previous design required constructing an GliumGraphics object to render 2D. The problem was that it borrows a mutable reference to Frame, which prevents other code to use it in within the same scope. By adding Glium2d::draw, this moves 2D rendering inside a closure, similarly to opengl_graphics.

With Glutin as the default window backend, shader_version::OpenGL was reexported to not need depending on Glutin directly.

Old code for image_test example:

extern crate graphics;
extern crate glium;
extern crate glium_graphics;
extern crate image;
extern crate piston;
extern crate glutin_window;

use std::rc::Rc;
use std::cell::RefCell;
use glium::Surface;
use glium_graphics::{
    Flip, Glium2d, GliumGraphics, GliumWindow, Texture, TextureSettings
};
use piston::event_loop::*;
use piston::input::RenderEvent;
use piston::window::WindowSettings;
use glutin_window::{ GlutinWindow, OpenGL };

fn main() {
    let opengl = OpenGL::V3_2;
    let (w, h) = (300, 300);
    let ref window: Rc<RefCell<GlutinWindow>> = Rc::new(RefCell::new(
        WindowSettings::new("glium_graphics: image_test", [w, h])
        .exit_on_esc(true).build().unwrap()
    ));
    let ref mut glium_window = GliumWindow::new(window).unwrap();
    let rust_logo = Texture::from_path(glium_window, "assets/rust.png",
        Flip::None, &TextureSettings::new()).unwrap();

    let mut g2d = Glium2d::new(opengl, glium_window);
    let transform = graphics::math::abs_transform(w as f64, h as f64);

    let mut events = window.borrow().events().swap_buffers(false);
    // Temporary fix for https://github.com/rust-lang/rust/issues/30832.
    while let Some(e) = { let mut b = window.borrow_mut(); events.next(&mut *b) } {
        use graphics::*;

        if let Some(_) = e.render_args() {
            let mut target = glium_window.draw();
            {
                let mut g = GliumGraphics::new(&mut g2d, &mut target);

                clear(color::WHITE, &mut g);
                rectangle([1.0, 0.0, 0.0, 1.0],
                          [0.0, 0.0, 100.0, 100.0],
                          transform,
                          &mut g);
                rectangle([0.0, 1.0, 0.0, 0.3],
                          [50.0, 50.0, 100.0, 100.0],
                          transform,
                          &mut g);
                image(&rust_logo, transform.trans(100.0, 100.0), &mut g);
            }
            target.finish().unwrap();
        }

    }
}

New code for image_test example:

extern crate graphics;
extern crate glium;
extern crate glium_graphics;
extern crate image;
extern crate piston;

use glium::Surface;
use glium_graphics::{
    Flip, Glium2d, GliumWindow, OpenGL, Texture, TextureSettings
};
use piston::input::RenderEvent;
use piston::window::WindowSettings;

fn main() {
    let opengl = OpenGL::V3_2;
    let (w, h) = (300, 300);
    let ref mut window: GliumWindow =
        WindowSettings::new("glium_graphics: image_test", [w, h])
        .exit_on_esc(true).opengl(opengl).build().unwrap();

    let rust_logo = Texture::from_path(window, "assets/rust.png",
        Flip::None, &TextureSettings::new()).unwrap();

    let mut g2d = Glium2d::new(opengl, window);
    while let Some(e) = window.next() {
        use graphics::*;

        if let Some(args) = e.render_args() {
            let mut target = window.draw();
            g2d.draw(&mut target, args.viewport(), |c, g| {
                clear(color::WHITE, g);
                rectangle([1.0, 0.0, 0.0, 1.0],
                          [0.0, 0.0, 100.0, 100.0],
                          c.transform, g);
                rectangle([0.0, 1.0, 0.0, 0.3],
                          [50.0, 50.0, 100.0, 100.0],
                          c.transform, g);
                image(&rust_logo, c.transform.trans(100.0, 100.0), g);
            });
            target.finish().unwrap();
        }

    }
}

Examples fail to compile

Output from cargo build --example text_test:

   Compiling pistoncore-glutin_window v0.16.0
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:95:27: 95:53 error: mismatched types:
 expected `*const libc::types::common::c95::c_void`,
    found `*const ()`
(expected enum `libc::types::common::c95::c_void`,
    found ()) [E0308]
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:95         gl::load_with(|s| window.get_proc_address(s));
                                                                                                                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:95:27: 95:53 help: run `rustc --explain E0308` to see a detailed explanation
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:223:9: 223:48 error: mismatched types:
 expected `*const libc::types::common::c95::c_void`,
    found `*const ()`
(expected enum `libc::types::common::c95::c_void`,
    found ()) [E0308]
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:223         self.window.get_proc_address(proc_name)
                                                                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wizeman/.cargo/registry/src/github.com-0a35038f75765ae4/pistoncore-glutin_window-0.16.0/src/lib.rs:223:9: 223:48 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to 2 previous errors
Could not compile `pistoncore-glutin_window`.

To learn more, run the command again with --verbose.

Examples are Broken, attempts to fix lead to dependency hell

The Piston Ecosystem has gotten a lot messier since I last checked in. What should be a simple dependency version bump and refactor leads to a downward spiral into madness as every crate in the dependency chain tries to compile a different version of its ancestors.

I just want to bootstrap a game using the latest version of everything, not to have to hunt down or try to figure out a list of crate versions that don't break each other.

I don't know what's going on here but it's a huge barrier to (re)entry.

image_test failing to initialize textured shader

rustc 1.0.0-nightly (b47aebe3f 2015-02-26) (built 2015-02-26)

$ RUST_BACKTRACE=1 cargo run --example image_test
     Running `target/examples/image_test`
thread '<main>' panicked at 'failed to initialize textured shader', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/libcore/option.rs:330
stack backtrace:
   1:          0x41daac3 - sys::backtrace::write::h0c33dfca8f99823a7hA
   2:          0x41efd7e - panicking::on_panic::h63c237d7347b7375J0I
   3:          0x41c79f8 - rt::unwind::begin_unwind_inner::h6bff9e2dc073eba1FJI
   4:          0x41c820e - rt::unwind::begin_unwind_fmt::hf76b8aeb755b5841iII
   5:          0x41ef60e - rust_begin_unwind
   6:          0x420f206 - panicking::panic_fmt::h5f34c3efe193c29bY9r
   7:          0x40067ff - option::Option<T>::expect::h6139455589386592302
   8:          0x3fe6460 - backend::Glium2d::new::hac57dee2683b98815ka
   9:          0x3ea4995 - main::hcd2c44beb3bacb19jaa
  10:          0x41f1b29 - rust_try_inner
  11:          0x41f1b16 - rust_try
  12:          0x41f06f3 - rt::lang_start::h5ff98173978cc505pVI
  13:          0x3ea6def - main
An unknown error occurred

Some improvements

I want to make it more similar to the gfx_graphics API for consistency.

  • Rename DrawTexture to Texture
  • Add Texture::empty
  • Add Flip enum
  • Add Texture::from_path
  • Add Texture::from_image
  • Add Texture::from_memory_alpha
  • Add Texture::update

Add support for draw state

See PistonDevelopers/graphics#989

Could copy the "draw_state" example from piston-examples https://github.com/PistonDevelopers/piston-examples/blob/master/src/draw_state.rs and modify it to use glium_graphics.

Docs:

Blending:

  • Add
  • Multiply
  • Invert
  • Alpha

Clipping:

  • default
  • clip
  • inside
  • outside

Scissors:

  • scissors

Others:

  • color mask
  • multi sample
  • stencil
  • depth
  • primitve
  • culling

Comments:

  • The Gfx draw state has no provoking vertex. Use the default.
  • RasterMethod::Point => PolygonMode::Point
  • RasterMethod::Line => PolygonMode::Line + DrawParameters::line_width
  • RasterMethod::Fill(CullFace) => PolygonMode::Fill + BackfaceCullingMode?

Examples don't compile

I'd give more information but I honestly can't even figure out how to do anything with this. There's not exactly much documentation.

These should probably be included in cargo test so this doesn't happen again.

Use it within 3D game

Is it possible to use this library backend, while still using glium directly to render a 3D game?

Implement texture filtering

Depends on PistonDevelopers/texture#32.

Change Texture into:

pub struct Texture {
    pub texture: Texture2d,
    pub min_filter: MinifySamplerFilter,
    pub mag_filter: MagnifySamplerFilter,
}
  • Map TextureSettings::get_mag for MagnifySamplerFilter
  • Add a function that maps TextureSettings::get_generate_mipmaps, TextureSettings::get_min and TextureSettings::get_mipmap for MinifySamplerFilter
  • If TextureSettings::get_generate_mipmaps is true, call Texture2d::with_mipmaps
  • In the impl of Graphics::tri_list_uv, use .sampled() to set .mag_filter and .min_filter.

Change `Texture` to struct tuple

Currently the design is as following:

pub struct Texture {
    pub texture: Texture2d,
}

This could be changed to:

pub struct Texture(pub Texture2d);

pistoncore-glutin_window dependency should be optional

I am using glium_graphics without any of the functionality from pistoncore-glutin_window.

It should be possible to remove the dependency on pistoncore-glutin_window using a Cargo feature.

I am happy to implement if you will consider the PR.

Memory leak

Seems to be a memory leak associated with rendering.

Upgrade to latest piston-graphics

The draw state has been simplified, which requires a different mapping to Glium draw state.

Convert from sRGB to linear color space.

GlyphCache constructor should take in-memory font

Currently, the only GlyphCache constructor (GlyphCache::new) takes an AsRef<Path> as an argument to specify the font. This makes it impossible to construct a GlyphCache without having the font in its own file on disk. I propose that the GlyphCache constructor be altered to instead take a Vec<u8> or a Font, to allow the user to pass an in-memory font.

srgb hardcoded to true

BuildFromWindowSettings hardcodes srgb to true, but the upstream API settings in Piston has an srgb flag.

Running from within WSL, I can get the following glium code to render properly through a local X Server.

example glium code
#[macro_use]
extern crate glium;

fn main() {
    use glium::{glutin, Surface};
    use glutin::*;

    let mut event_loop = glutin::event_loop::EventLoop::new();
    let wb = glutin::window::WindowBuilder::new();
    let cb = glutin::ContextBuilder::new()
        .with_gl(GlRequest::Specific(Api::OpenGl, (3,2)))
        .with_srgb(false)  // breaks if true
        .with_vsync(true); // breaks if false
    let display = glium::Display::new(wb, cb, &event_loop).unwrap();
    event_loop.run(move |ev, _, control_flow| {

        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 1.0, 1.0);
        target.finish().unwrap();

        let next_frame_time = std::time::Instant::now() +
            std::time::Duration::from_nanos(16_666_667);

        *control_flow = glutin::event_loop::ControlFlow::WaitUntil(next_frame_time);
        match ev {
            glutin::event::Event::WindowEvent { event, .. } => match event {
                glutin::event::WindowEvent::CloseRequested => {
                    *control_flow = glutin::event_loop::ControlFlow::Exit;
                    return;
                },
                _ => return,
            },
            _ => (),
        }
    });
}

Some slightly modified code from this library fails to render for me in part because of these lines.

example glium_graphics code
extern crate glium_graphics;
extern crate graphics;
extern crate piston;

use glium_graphics::{Flip, Glium2d, GliumWindow, OpenGL, Texture, TextureSettings};
use piston::event_loop::EventLoop;
use piston::input::RenderEvent;
use piston::window::WindowSettings;

fn main() {
    let opengl = OpenGL::V3_2;
    let (w, h) = (300, 300);
    let ref mut window: GliumWindow = WindowSettings::new("glium_graphics: image_test", [w, h])
        .exit_on_esc(true)
        .graphics_api(opengl)
        .srgb(false)
        .vsync(true)
        .build()
        .unwrap();

    let mut g2d = Glium2d::new(opengl, window);
    window.set_lazy(true);
    while let Some(e) = window.next() {
        use graphics::*;

        if let Some(args) = e.render_args() {
            let mut target = window.draw();
            g2d.draw(&mut target, args.viewport(), |c, g| {
                clear(color::WHITE, g);
                rectangle(
                    [1.0, 0.0, 0.0, 1.0],
                    [0.0, 0.0, 100.0, 100.0],
                    c.transform,
                    g,
                );
                rectangle(
                    [0.0, 1.0, 0.0, 0.3],
                    [50.0, 50.0, 100.0, 100.0],
                    c.transform,
                    g,
                );
            });
            target.finish().unwrap();
        }
    }
}

I'd like to open a PR to resolve this.

Font Artifacts

I'm getting really bad artifacts when using glium_graphics for rendering fonts (especially with any Anti Aliasing). Is there anything I can do about it?

http://puu.sh/q3Atn.png

Don't put texture in an Arc

Currently the Glium textures are wrapped in an Arc. I did this to conform to the BackEnd trait, but I think there should be a better way to do this. Possibly the BackEnd trait leaks the state machine logic through its interface by having methods such as color, enable_texture and disable_texture. This is not necessary for Glium, as it does not expose such state.

Notes on window.rs

Posting notes here to improve the documentation.

  1. Glium's Backend takes &self in all methods
  2. Because of 1) a mutable reference to the window must be created from an immutable one
  3. To solve 2) a Rc<RefCell<W>> is used in the Wrapper struct, which implements Backend
  4. Because of 3) the user is required to wrap the window in Rc<RefCell<W>> at startup

Rc<RefCell<W>> might have some issues with if let and while let expressions. When using GliumWindow::next, this is not a problem.

Doesn't compile

rustc 1.0.0-nightly (3e4be02b8 2015-03-13) (built 2015-03-13)

src/glyph_cache.rs:28:19: 28:33 error: the trait `glium::texture::Texture2dDataSource<'_>` is not implemented for the type `image::buffer::ImageBuffer<image::color::Luma<u8>, collections::vec::Vec<u8>>` [E0277]
src/glyph_cache.rs:28     let texture = Texture2d::new(
                                        ^~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `glium_graphics`.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.