我目前正在用Rust开发一个简单的程序,在屏幕上画一个彩色三角形。我跟着instructions from OpenGL。我的程序运行良好,三角形渲染如预期:
之后,我尝试抽象代码:VAO
、VBO
和ShaderProgram
变成了一个处理绑定、附加着色器等的结构体。这招奏效了现在来说说问题:
当我试图抽象属性时,我遇到了一个问题。我将这两个方法添加到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!
需要很长时间,所有东西都不知何故坏了?
1条答案
按热度按时间hfsqlsce1#
您的代码具有未定义的行为。Rust字符串字面量不像
glGetAttribLocation
期望的那样以null结尾。所以有一个出界的阅读,直到谁知道在哪里。您需要使用
"position\0"
或CString
来解决这个问题。