ombre 0.6.7

Shadowy game and graphics library for Rust
Documentation
#[path = "common/runtime.rs"]
mod runtime;

use ombre::prelude::*;

#[repr(C)]
struct Vertex {
    position: [f32; 2],
    color: [f32; 4],
}

pub struct Renderer<T> {
    pipeline: gfx::PipelineId,
    bindings: gfx::Bindings,
    backend: T,
}

impl<T: gfx::RenderBackend> RuntimeRenderer for Renderer<T> {
    type Error = T::Error;

    fn window_resized(&mut self, size: platform::LogicalSize) {
        self.backend.window_resized(size);
    }

    fn frame(&mut self) -> Result<(), Self::Error> {
        let mut frame = self.backend.frame();

        frame.begin_default_pass(Default::default());
        frame.apply_pipeline(&self.pipeline)?;
        frame.apply_bindings(&self.bindings)?;
        frame.draw(0, 3, 1)?;
        frame.end_pass();
        frame.commit();

        Ok(())
    }
}

impl<T: gfx::RenderBackend> Renderer<T> {
    pub fn init(mut backend: T) -> Result<Self, T::Error> {
        #[rustfmt::skip]
        let vertices: [Vertex; 3] = [
            Vertex { position: [-0.5, -0.5], color: [1., 1., 0., 1.] },
            Vertex { position: [ 0.5, -0.5], color: [0., 1., 1., 1.] },
            Vertex { position: [ 0.0,  0.5], color: [1., 0., 1., 1.] },
        ];
        let vertex_buffer = backend.buffer(
            gfx::BufferKind::Vertex,
            gfx::BufferUsage::Immutable,
            gfx::BufferSource::slice(&vertices),
        )?;
        let index_buffer = backend.buffer(
            gfx::BufferKind::Index,
            gfx::BufferUsage::Immutable,
            gfx::BufferSource::slice(&[0, 1, 2]),
        )?;
        let bindings = gfx::Bindings {
            vertex: vec![vertex_buffer],
            index: Some(index_buffer),
            textures: vec![],
        };
        let shader = backend
            .shader(
                gfx::ShaderSource {
                    vertex: shader::VERTEX,
                    fragment: shader::FRAGMENT,
                },
                shader::descriptor(),
            )
            .unwrap();
        let pipeline = backend.pipeline(
            shader,
            gfx::PipelineDescriptor {
                layout: &[gfx::BufferLayout {
                    attrs: &[
                        gfx::VertexAttribute::new("position", gfx::VertexFormat::Float2),
                        gfx::VertexAttribute::new("color", gfx::VertexFormat::Float4),
                    ],
                    ..gfx::BufferLayout::default()
                }],
                ..gfx::PipelineDescriptor::default()
            },
        );

        Ok(Self {
            backend,
            pipeline,
            bindings,
        })
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    logger::init(log::Level::Debug)?;

    let (mut win, events) =
        platform::init("triangle", 640, 480, &[], platform::GraphicsContext::Gl)?;
    let ctx = unsafe { glow::Context::from_loader_function(|p| win.get_proc_address(p)) };
    let backend = gfx::gl::Context::new(ctx, win.size())?;
    let renderer = Renderer::init(backend)?;

    runtime::run(win, events, renderer)?;

    Ok(())
}

mod shader {
    use super::*;

    pub const VERTEX: &str = r#"
    #version 100

    attribute vec2 position;
    attribute vec4 color;

    varying lowp vec4 f_color;

    void main() {
        gl_Position = vec4(position, 0, 1);
        f_color = color;
    }
    "#;

    pub const FRAGMENT: &str = r#"
    #version 100

    varying lowp vec4 f_color;

    void main() {
        gl_FragColor = f_color;
    }
    "#;

    pub fn descriptor() -> gfx::ShaderDescriptor {
        gfx::ShaderDescriptor {
            textures: vec![],
            uniforms: gfx::UniformBlockLayout { uniforms: vec![] },
        }
    }
}