0

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);
  }
}

2 Answers 2

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".

Sign up to request clarification or add additional context in comments.

1 Comment

I asked openGL for errors useing gl.GetError() but it returns GL_NO_ERROR even when I get location -1 and clearly I get errors if there are (I managed to get GL_INVALID_OPERATION by violating the "gl_" prefix rule).
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.