问题
I'm trying to abstract openGL in Rust. I use glutin to communicate with openGL (here is the code I started with). I'm having problems abstracting Uniforms in fact they randomly get -1
as location (the same code sometimes works and sometimes doesn't).
I checked if the program was in use and it was so I started wondering if there is a problem in the way I send the data to openGL:
// value is initialised here
let name = name.to_string();
let location;
unsafe {
location = gl.GetUniformLocation(program.get_id(), name.as_ptr() as *const GLchar);
};
match value {
UniformType::Float(v) => unsafe {
gl.Uniform1f(location, v);
},
UniformType::Float4(v) => unsafe {
gl.Uniform4fv(location, 1, &v[0]);
},
UniformType::Texture(tex_id) => unsafe {
gl.Uniform1i(location, tex_id);
},
UniformType::Mat4x4(v) => unsafe {
gl.UniformMatrix4fv(location, 1, gl::FALSE, &v[0]);
},
_ => {
panic!("Uniform::new This uniform type is unknown");
}
}
// this scope ends and value if freed
Is it a problem the fact that value
gets freed right after the call to gl.Uniform? If yes, why? I read online that only the draw calls are asynchronous.
Edited: Debugging
The uniforms are actively used inside the shaders.
Gives the right number of active uniforms counting even those that got -1
as location:
let mut param = 0;
unsafe {
gl.GetProgramiv(program.get_id(), gl::ACTIVE_UNIFORMS, &mut param);
}
println!("Number of active uniforms: {}", param);
Always gives 'no error'
:
let err;
unsafe {
err = gl.GetError();
}
match err {
gl::NO_ERROR => {
println!("Uniform '{}': no error", name);
}
gl::INVALID_VALUE => {
println!("Uniform '{}': invalid value", name);
}
gl::INVALID_OPERATION => {
println!("Uniform '{}': invalid operation", name);
}
_ => {
println!("Uniform: '{}' error: {}", name, err);
}
}
回答1:
According to the documentation for GetUniformLocation:
This function returns -1 if name does not correspond to an active uniform variable in program, if name starts with the reserved prefix "gl_", or if name is associated with an atomic counter or a named uniform block.
So you're not error-checking your gl calls, and it looks like there are cases where you're calling GetUniformLocation
incorrectly, which could account for "sometimes it works, sometimes it does not".
回答2:
At the end I found the problem:
// getting a CString from name
let cname = std::ffi::CString::new(name).expect("CString::new failed");
let location;
unsafe {
location = gl.GetUniformLocation(program.get_id(), cname.as_ptr());
}
(sometimes I tend to forget that I'm working with bindings)
来源:https://stackoverflow.com/questions/63339027/how-to-pass-data-to-opengl-functions-correctly-in-rust