windows - OpenGL gl::GetUniformLocation仅在某些情况下无法定位统一

标签 windows opengl rust

我有点卡住了。我有一个程序抽象可以为我找到制服。我有一个片段着色器,它的 float 着色器已经过去,而顶点着色器的着色器是mat4均匀的。
辅助函数的定义如下:

pub fn find_uniform(&mut self, name: &str) -> Result<(), UniformError> {
    if let Some(_) = self.uniforms.get(name) {
        return Ok(());
    }

    let target_location = unsafe { 
        let location = gl::GetUniformLocation(self.program_id, name.as_bytes().as_ptr() as *const i8);
        let error = gl::GetError();
        if error != gl::NO_ERROR {
            return Err(UniformError::new(true, error));
        }

        location
    };

    if target_location < 0 {
        return Err(UniformError::new(false, UNIFORM_NOT_FOUND));
    }

    self.uniforms.insert(name.to_string(), target_location);

    return Ok(());
}
如果我使用助手功能仅查找过去的,或者如果我使用本地gl调用查找两者,则它起作用:
// No error
if let Err(e) = program.find_uniform("elapsed") {
    eprint!("Failed to find elapsed, probably loading wrong shader. err: {}", e);
    return;
};

// OR
unsafe {
    let location1 = gl::GetUniformLocation(program.program_id, b"elapsed".as_ptr() as *const i8);
    println!("{}", location1); // 0
    let location2 = gl::GetUniformLocation(program.program_id, b"projection".as_ptr() as *const i8);
    println!("{}", location2); // 1
}
但是,如果我同时使用我的辅助函数,它将无法找到我首先要查找的内容:
if let Err(e) = program.find_uniform("elapsed") {
    // Enters error branch here
    eprint!("Failed to find elapsed, probably loading wrong shader. err: {}", e);
    return;
};
        
if let Err(e) = program.find_uniform("projection") {
    eprint!("Failed to find projection, probably loading wrong shader. err: {}", e);
    return;
};
有人知道我在做什么错吗?

最佳答案

查看您的代码,到name.as_bytes().as_ptr() as *const i8的转换是不安全的,并且取决于内存布局。 Rust字符串不是C字符串,默认情况下也不为null终止。使用std::ffi::CString::new();以确保字符串以null终止。因此,如果您幸运地在字节字符串之后有了一个空字节,那么您当前的程序将完全取决于您。
下面的代码应该工作:

let target_location = unsafe { 
    use std::ffi::CString;
    let c_name = CString::new(name).expect("Convert to c-string);
    let location = gl::GetUniformLocation(self.program_id, c_name.as_ptr());
    let error = gl::GetError();
    if error != gl::NO_ERROR {
        return Err(UniformError::new(true, error));
    }
    location
};
也可以看看:
How to pass data to openGL functions correctly in Rust

关于windows - OpenGL gl::GetUniformLocation仅在某些情况下无法定位统一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63624090/

相关文章:

c++ - 如何在 Windows 上制作、制作和编译 C++14

postgresql - 当参数大小超过 393166 个字符时,PSQL 准备好的语句查询会挂起

opengl - 这个 OpenGL Haskell 代码是如何工作的?

c++ - 如何在 openGL 中旋转图像?

rust - 为什么在可变引用上调用方法涉及 "borrowing"?

unit-testing - 跳过单元测试或至少显示它们的警告

c++ - WinAPI SetWindowLongPtr - 改变 windowProc

java - 如何通过java程序获取exe运行的进程id

c++ - glReadPixels() "data"参数用法?

rust - 具有父类(super class)型生命周期的引用不能用于子类型生命周期