You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gl::GetAttribLocation返回-1但属性已列为活跃属性的问题

OpenGL中glGetAttribLocation获取"pos"属性返回-1的问题

顶点着色器代码

#version 440

in vec3 pos;
in vec3 col;

out vec4 vertexColor;

void main()
{
    gl_Position = vec4(pos, 1.0);
    vertexColor = vec4(col, 1.0);
}

片段着色器代码

#version 440 core

out vec4 fragColor;

in vec4 vertexColor;

void main()
{
    fragColor = vertexColor;
}

获取属性位置的Rust代码

let position_attr = gl::GetAttribLocation(shader_program, "pos".as_ptr() as *const i8);
let color_attr = gl::GetAttribLocation(shader_program, "col".as_ptr() as *const i8);

获取结果

4294967295 (-1 unsigned)
1

排查用的Rust函数

unsafe fn check_active_atributes(shader_program: u32){
    let mut count = 0;
    gl::GetProgramiv(shader_program, gl::ACTIVE_ATTRIBUTES, &mut count);

    println!("Number of active attributes: {}", count);
}

fn print_active_attributes(program: gl::types::GLuint) {
    let mut num_active_attrs = 0;
    unsafe {
        gl::GetProgramiv(program, gl::ACTIVE_ATTRIBUTES, &mut num_active_attrs);
    }

    println!("Active attributes:");
    for i in 0..num_active_attrs {
        let mut name: [u8; 256] = [0; 256];
        let mut length = 0;
        let mut size = 0;
        let mut gl_type = 0;
        unsafe {
            gl::GetActiveAttrib(
                program,
                i as gl::types::GLuint,
                256,
                &mut length,
                &mut size,
                &mut gl_type,
                name.as_mut_ptr() as *mut gl::types::GLchar,
            );
        }
        let name_str = std::str::from_utf8(&name[..length as usize]).unwrap();
        println!("- {}.", name_str);
    }
}

排查函数输出

Number of active attributes: 2
Active attributes:
- pos.
- col.

已知条件

  • 着色器编译、链接均无错误或警告
  • 操作系统:Linux

可能的原因

  1. C风格字符串格式问题:OpenGL要求属性名称必须是以null结尾的C风格字符串,原代码中直接使用"pos".as_ptr()传递字符串,Rust的字符串字面量默认不带null终止符,导致OpenGL无法正确解析名称。改用CString构造符合要求的字符串即可:
    use std::ffi::CString;
    let pos_name = CString::new("pos").unwrap();
    let position_attr = gl::GetAttribLocation(shader_program, pos_name.as_ptr());
    
  2. 驱动优化误删属性:部分Linux开源驱动的编译器优化可能误判pos属性未被实际使用(尽管它被赋值给gl_Position)。可以在顶点着色器中添加无意义的引用强制保留属性,比如:
    void main()
    {
        vec3 temp = pos; // 强制编译器保留pos属性
        gl_Position = vec4(temp, 1.0);
        vertexColor = vec4(col, 1.0);
    }
    
  3. 提前绑定属性冲突:如果在程序链接前调用过glBindAttribLocation绑定属性位置,且绑定的名称或位置存在错误,会导致glGetAttribLocation返回异常。检查代码中是否有提前绑定属性的逻辑,确保绑定名称与着色器一致。

内容的提问来源于stack exchange,提问作者JAUME VAQUER

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:27:22