WebGL基本语法 - Wed, Jul 6, 2022
WebGL基本语法
概述
使用Rust和Wasm实现webgl简单用法。
示例
1. 初期化画布
id为html中canvas元件的id.
fn init_canvas(id: String) -> HtmlCanvasElement {
if id.is_empty() {
panic!("canvas id is empty!")
}
let window = window().unwrap();
let canvas = document().get_element_by_id(&id).unwrap();
let canvas: HtmlCanvasElement = canvas
.dyn_into::<HtmlCanvasElement>()
.map_err(|_| ())
.unwrap();
let dpi = window.device_pixel_ratio();
let (w, h) = (
window.inner_width().unwrap().as_f64().unwrap(),
window.inner_height().unwrap().as_f64().unwrap(),
);
canvas.set_width((w * dpi) as u32);
canvas.set_height((h * dpi) as u32);
canvas
.style()
.set_property("width", &format!("{}px", w))
.unwrap();
canvas
.style()
.set_property("height", &format!("{}px", h))
.unwrap();
canvas
}
2. 获取webgl
let opts = match opts {
Some(opts) => opts,
None => WebGlOptions::new(),
};
let opts = JsValue::from_serde(&opts).unwrap();
let gl = canvas
.get_context_with_context_options("webgl", &opts)
.unwrap()
.unwrap()
.dyn_into::<WebGlRenderingContext>()
.unwrap();
3. 创建程序
let vert_shader = self
.compile_shader(WebGlRenderingContext::VERTEX_SHADER, VERTEX_SHADER)
.unwrap();
let frag_shader = self
.compile_shader(WebGlRenderingContext::FRAGMENT_SHADER, FRAGMENT_SHADER)
.unwrap();
// 创建程序
let program = self
.gl
.create_program()
.ok_or_else(|| String::from("Unable to create shader object"))?;
// 添加着色器
self.gl.attach_shader(&program, &vert_shader);
self.gl.attach_shader(&program, &frag_shader);
// 链接程序
self.gl.link_program(&program);
if !self
.gl
.get_program_parameter(&program, WebGlRenderingContext::LINK_STATUS)
.as_bool()
.unwrap_or(false)
{
let err = self
.gl
.get_program_info_log(&program)
.unwrap_or_else(|| String::from("Unknown error creating program object"));
// 清理失败的程序
self.gl.delete_program(Some(&program));
return Err(err);
}
4.创建buffer
pub fn create_buffer(&self, data: &[f32]) {
let buffer = self.gl.create_buffer();
self.gl
.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, buffer.as_ref());
unsafe {
let vert_array = Float32Array::view(data);
self.gl.buffer_data_with_array_buffer_view(
WebGlRenderingContext::ARRAY_BUFFER,
&vert_array,
WebGlRenderingContext::STATIC_DRAW,
);
}
}
5. 整体调用
let canvas = RainEffect::init_canvas(id);
let gl = WebGl::new(&canvas, None);
gl.create_buffer(&[0.0, 0.0, 0.0, 0.5, 0.7, 0.0]);
gl.clear();
gl.use_program();
gl.enable_vertex_attrib();
gl.draw();