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
@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:
(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. 馃檪