我目前正在用 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;
}
}
我想像这样添加我的属性:
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,
)
}
但这没有用。
所以我尝试调试。 (是的,错误的根源在于这段代码,我已经测试过了)。我尝试将讨厌的代码与我的抽象进行比较。所以我把这个
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!
需要很长时间并且一切都以某种方式中断,这是某种时间问题吗?