How to pass data to openGL functions correctly in Rust

|▌冷眼眸甩不掉的悲伤 提交于 2021-01-29 17:44:59

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!