打印!导致OpenGL程序无法运行?

Der*_*yme 0 opengl glfw rust rust-cargo

我目前正在用 Rust 开发一个简单的程序,在屏幕上绘制一个彩色三角形。我按照OpenGL 的说明进行操作。我的程序运行良好,三角形按预期呈现:

在此输入图像描述

之后,我尝试抽象代码: 和VAO成为VBO处理ShaderProgram绑定、附加着色器等的结构。那行得通。现在解决问题:

当我尝试抽象属性时遇到了问题。我将这两个方法添加到结构中ShaderProgram,它们应该处理属性的启用,而不必对诸如步幅或属性在向量中的位置开始的指针之类的内容进行硬编码。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想添加我的属性,如下所示:

shader_program.add_attribute("position", 2);
shader_program.add_attribute("color", 3);
shader_program.apply_attributes();
Run Code Online (Sandbox Code Playgroud)

而不是这个讨厌的块:

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,
    )
}
Run Code Online (Sandbox Code Playgroud)

但这没有用。

所以我尝试调试。(是的,错误的根源在于这段代码,我已经测试过)。我尝试将令人讨厌的代码与我的抽象进行比较。所以我将其添加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,
    )
}
Run Code Online (Sandbox Code Playgroud)

并且三角形停止渲染。把它去掉,三角形又回来了。一个简单的人怎么会println如此有害?是否存在某种时间问题,需要很println!长时间并且一切都以某种方式中断?

kmd*_*eko 5

您的代码具有未定义的行为。Rust 字符串文字并不像glGetAttribLocation预期的那样以 null 结尾。所以存在越界读取,直到谁知道在哪里。

您需要使用"position\0"CString修复它。