WebGL基本语法

  1. 概述
  2. 示例
    1. 1. 初期化画布
    2. 2. 获取webgl
    3. 3. 创建程序
    4. 4.创建buffer
    5. 5. 整体调用

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();

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wind.kaisa@gmail.com

💰

×

Help us with donation