Gfx: thread 'main' panicked at 'gl function was not loaded'

Created on 8 Jun 2017  路  5Comments  路  Source: gfx-rs/gfx

I'm trying to augment examples/triangle with some components from examples/deferred to get multiple triangles flying around using only one mesh instance.

When I add

astr_slice.instances = Some((ASTERS as gfx::InstanceCount, 0));

I get the error:

thread 'main' panicked at 'gl function was not loaded', [pathToProject]/target/debug/build/gfx_gl-0ed4e69f32e0445b/out/gl_bindings.rs:1504
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: gfx_gl::missing_fn_panic
   6: gfx_gl::Gl::DrawArraysInstancedBaseInstance
   7: gfx_device_gl::Device::process
   8: gfx_device_gl::Device::no_fence_submit
   9: <gfx_device_gl::Device as gfx_core::Device>::submit
  10: <gfx::encoder::Encoder<R, C>>::flush_no_reset
  11: <gfx::encoder::Encoder<R, C>>::flush
  12: yaa::main
  13: std::panicking::try::do_call
  14: __rust_maybe_catch_panic
  15: std::rt::lang_start
  16: main

The error occurs at the end of the loop when flushing:

encoder.flush(&mut device)

I found #979 and checked the docs, but I'm still not sure if it's a bug in gfx or if I'm doing something wrong (Neither the error nor the docs helpped me).

Any suggestions?

I've tried to reduce the program to a minimum, hence it's not complete, but it reproduces the error.
The two lines are marked with ADDED_LINE and CRASHES.

#[macro_use]
extern crate gfx;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate nalgebra;

use gfx::traits::FactoryExt;
use gfx::Device;

pub type ColorFormat = gfx::format::Rgba8;
pub type DepthFormat = gfx::format::DepthStencil;

gfx_defines!{
    vertex Vertex {
        pos: [f32; 3] = "a_Pos",
        color: [f32; 3] = "a_Color",
    }
    constant Transform {
        transform: [[f32; 4];4] = "transform",
    }
    pipeline space_junk_pipe {
        vbuf: gfx::VertexBuffer<Vertex> = (),
        transform_buffer: gfx::ConstantBuffer<Transform> = "TransformBlock",
        out: gfx::RenderTarget<ColorFormat> = "Target0",
    }
}

mod space {
    pub struct SpaceJunk {
        pub orientation: f32,
        pub angular_velocity: f32,
    }

    impl SpaceJunk {
        pub fn new() -> Self {
            SpaceJunk {
                orientation: 0.0,
                angular_velocity: 0.0,
            }
        }

        pub fn iter(&mut self, delta: f32) {
            self.orientation += self.angular_velocity * delta;
        }
    }
}

const SA : f32 = 0.2;
const ASTEROID: [Vertex; 3] = [
    Vertex { pos: [ 1.0*SA,  1.0*SA, 1.0 ], color: [1.0, 0.0, 0.0] },
    Vertex { pos: [ 1.0*SA, -1.0*SA, 1.0 ], color: [0.0, 1.0, 0.0] },
    Vertex { pos: [ 0.0*SA,  0.0*SA, 1.0 ], color: [0.0, 0.0, 1.0] },
];

const CLEAR_COLOR: [f32; 4] = [0.1, 0.2, 0.3, 1.0];


fn main() {
    println!("starting app");
    let trans_base: Transform = Transform { transform: [
    [1.0, 0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0, 0.0],
    [0.0, 0.0, 1.0, 0.0],
    [0.0, 0.0, 0.0, 1.0]
    ] };
    let ASTERS = 4;
    let mut astr_trans: [Transform; 4] = [
        trans_base.clone(),
        trans_base.clone(),
        trans_base.clone(),
        trans_base.clone(),
    ];
    let events_loop = glutin::EventsLoop::new();
    let builder = glutin::WindowBuilder::new()
        .with_title("Hello, world!".to_string())
        .with_dimensions(1024, 1024)
        .with_vsync();

    let (window, mut device, mut factory, render_target_view, mut _main_depth) =
                gfx_window_glutin::init::<ColorFormat, DepthFormat>(builder, &events_loop);

    let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into();

    let astr_pso = factory.create_pipeline_simple(
        include_bytes!("shader/triangle_150.glslv"),
        include_bytes!("shader/triangle_150.glslf"),
        space_junk_pipe::new()
    ).unwrap();

    let mut objects = Vec::<space::SpaceJunk>::new();
    println!("Creating astr pipe");
    let (vertex_buffer, mut astr_slice) = factory.create_vertex_buffer_with_slice(&ASTEROID, ());

    // ADDED_LINE
    astr_slice.instances = Some((ASTERS as gfx::InstanceCount, 0));

    let transform_buffer = factory.create_constant_buffer(ASTERS);
    let astr_data = space_junk_pipe::Data {
        vbuf: vertex_buffer,
        transform_buffer: transform_buffer,
        out: render_target_view
    };
    {
        // add asteroids
        let mut k = 1.0;
        for _ in 0..ASTERS {
            let mut obj = space::SpaceJunk::new();

            obj.angular_velocity = k*0.5;
            objects.push(obj);
            k = k + 1.0;
        }
    }
    println!("{} asteroids created.", objects.len()-1);
    let mut last_time = std::time::Instant::now();
    println!("Entering loop");
    loop {
        let delta = last_time.elapsed();
        let delta = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1000_000_000.0;
        last_time = std::time::Instant::now();
        for i in 0..(ASTERS) {
            objects[i].iter(delta);
        }

        // asteroids
        for i in 0..ASTERS {
            let ref mut trans = &mut astr_trans[i];
            let ref o = objects[i];
            let rot_matrix : nalgebra::Rotation2<f32> = nalgebra::Rotation2::new(o.orientation);
            let t = rot_matrix.matrix();

            for i in 0..2 {
                for j in 0..2 {
                    let v: f32 = 1.0*t[(i, j)];
                    trans.transform[i][j] = v;
                }
            }
        }

        println!("updating asteroids");
        encoder.update_buffer(&astr_data.transform_buffer, &astr_trans, 0).unwrap();

        // draw a frame
        println!("clearing");
        encoder.clear(&astr_data.out, CLEAR_COLOR);
        println!("drawing");
        encoder.draw(&astr_slice, &astr_pso, &astr_data);
        println!("flushing");
        // CRASHES
        encoder.flush(&mut device);
        println!("swaping");
        window.swap_buffers().unwrap();
        println!("cleanup");
        device.cleanup();
    }
}

Dependencies:

[dependencies]
glutin = "*"
gfx = "*"
gfx_window_glutin = "*"
nalgebra = "*"

System:

rustc: rustc 1.17.0 (56124baa9 2017-04-24)
cargo: cargo 0.18.0 (fe7b0cdcf 2017-04-24)
macOS: 10.11.6

OpenGL blocker OSX ready for work bug high

All 5 comments

@Fluci thank you for the report!
It's certainly a bug on our side. We should be checking for the instancing support correctly and requesting the extensions used in your case, so that the function pointers are correct.
How are the other examples running for you (e.g. instancing one)?

Oh, cool, I rarely find bugs. :)

I just ran all the examples, they all work fine.

If someone is interested in taking this issue, these would be steps/targets imo:

  • Fix capability check for instanced drawing (minimal)
  • Fix capability checks for _indexed_ instanced drawing (optional)
  • Improve fallbacks for both (similar to https://github.com/gfx-rs/gfx/blob/master/src/backend/gl/src/lib.rs#L649-L690, but be sure to check if these are supported) (optional)

(Feel free to ping us on gitter!)

I also found this issue on windows 10 (Build 15063.726) when requesting the following:

Registry::new(
    Api::Gl,
    (4, 5),
    Profile::Core,
    Fallbacks::All,
    ["GL_ARB_blend_func_extended"],
).write_bindings(GlobalGenerator, &mut file)
    .unwrap();

Am I doing anything wrong here? I'm not sure whether I need to do anything different to load from nvogld64.dll as supposed to opengl32.dll.

Apologies if this is obvious to everyone already, but from testing on the pre-ll branch I found that this seems to relate to not including an indices array when calling create_vertex_buffer_with_slice.

That is, from the instancing example:

// This works
factory.create_vertex_buffer_with_slice(&QUAD_VERTICES, &QUAD_INDICES[..]);

If we change this:

// This results in `gl function was not loaded`
factory.create_vertex_buffer_with_slice(&QUAD_VERTICES, ());

Presumably, this means that one can work around this bug by including an indices array. 馃檪

Was this page helpful?
0 / 5 - 0 ratings

Related issues

grovesNL picture grovesNL  路  3Comments

djcsdy picture djcsdy  路  4Comments

kvark picture kvark  路  3Comments

Bastacyclop picture Bastacyclop  路  3Comments

kvark picture kvark  路  5Comments