Println!导致OpenGL程序无法工作?

l0oc07j2  于 2023-05-06  发布在  其他
关注(0)|答案(1)|浏览(114)

我目前正在用Rust开发一个简单的程序,在屏幕上画一个彩色三角形。我跟着instructions from OpenGL。我的程序运行良好,三角形渲染如预期:

之后,我尝试抽象代码:VAOVBOShaderProgram变成了一个处理绑定、附加着色器等的结构体。这招奏效了现在来说说问题:
当我试图抽象属性时,我遇到了一个问题。我将这两个方法添加到ShaderProgram结构体中,它应该处理属性的启用,而不必对stride或属性在向量中的起始位置的指针等内容进行硬编码。

pub fn add_attribute(&mut self, name: &'a str, length: i32) {
    let mut props = VertexAttributeProps::new(name, length);
    self.attributes.push(props);
}
pub fn apply_attributes(&self) {
    const GL_FLOAT_SIZE: i32 = mem::size_of::<gl::types::GLfloat>() as i32;
    let stride = self
        .attributes
        .iter()
        .fold(0, |prev, attr| prev + attr.length)
        * GL_FLOAT_SIZE;

    let mut current_pos: i32 = 0;
    for attr_options in self.attributes.iter() {
        // println!("{:?}", current_pos);
        unsafe {
            let attribute = VertexAttribute::new(
                location,
                attr_options.length,
                gl::FLOAT,
                gl::FALSE,
                stride,
                (current_pos * GL_FLOAT_SIZE) as *const c_void,
            );
            attribute.enable();
        }
        current_pos = current_pos + attr_options.length;
    }
}

我想添加我的属性如下:

shader_program.add_attribute("position", 2);
shader_program.add_attribute("color", 3);
shader_program.apply_attributes();

而不是这个讨厌块:

let posAttrib: GLuint;
unsafe {
    posAttrib = gl::GetAttribLocation(
        shader_program.program_handle,
        "position".as_ptr() as *const i8,
    ) as u32;
    gl::EnableVertexAttribArray(posAttrib);
    gl::VertexAttribPointer(
        posAttrib,
        2,
        gl::FLOAT,
        gl::FALSE,
        5 * mem::size_of::<gl::types::GLfloat>() as i32,
        0 as *const c_void,
    )
}

let colAttrib: GLuint;
unsafe {
    colAttrib =
        gl::GetAttribLocation(shader_program.program_handle, "color".as_ptr() as *const i8)
            as u32;
    gl::EnableVertexAttribArray(colAttrib);
    gl::VertexAttribPointer(
        colAttrib,
        3,
        gl::FLOAT,
        gl::FALSE,
        5 * mem::size_of::<gl::types::GLfloat>() as i32,
        (2 * mem::size_of::<gl::types::GLfloat>()) as *const c_void,
    )
}

但这并不奏效。
所以我试着调试。(是的,bug的来源就在这段代码中,我已经测试过了)。我试着将这些讨厌的代码与我的抽象进行比较。所以我把这个println!添加到讨厌的代码中:

let posAttrib: GLuint;
unsafe {
    posAttrib = gl::GetAttribLocation(
        shader_program.program_handle,
        "position".as_ptr() as *const i8,
    ) as u32;

    // ???????
    println!("{}", posAttrib);
    // ???????

    gl::EnableVertexAttribArray(posAttrib);
    gl::VertexAttribPointer(
        posAttrib,
        2,
        gl::FLOAT,
        gl::FALSE,
        5 * mem::size_of::<gl::types::GLfloat>() as i32,
        0 as *const c_void,
    )
}

三角形停止渲染。去掉它,三角形又回来了。一个简单的println怎么会这么有害呢?是不是某种时序问题,println!需要很长时间,所有东西都不知何故坏了?

hfsqlsce

hfsqlsce1#

您的代码具有未定义的行为。Rust字符串字面量不像glGetAttribLocation期望的那样以null结尾。所以有一个出界的阅读,直到谁知道在哪里。
您需要使用"position\0"CString来解决这个问题。

相关问题