mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2025-01-05 19:53:55 +03:00
Merge pull request #835 from blm768/webgl-example
Create basic WebGL example
This commit is contained in:
commit
4ca187cc2b
@ -78,6 +78,7 @@ members = [
|
||||
"examples/smorgasboard",
|
||||
"examples/wasm-in-wasm",
|
||||
"examples/webaudio",
|
||||
"examples/webgl",
|
||||
"tests/no-std",
|
||||
]
|
||||
|
||||
|
4
examples/webgl/.gitignore
vendored
Executable file
4
examples/webgl/.gitignore
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
package-lock.json
|
||||
wasm_bindgen_webgl_demo.js
|
||||
wasm_bindgen_webgl_demo_bg.js
|
||||
wasm_bindgen_webgl_demo_bg.wasm
|
24
examples/webgl/Cargo.toml
Executable file
24
examples/webgl/Cargo.toml
Executable file
@ -0,0 +1,24 @@
|
||||
[package]
|
||||
name = "wasm-bindgen-webgl-demo"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
js-sys = { path = "../../crates/js-sys" }
|
||||
wasm-bindgen = { path = "../.." }
|
||||
|
||||
[dependencies.web-sys]
|
||||
path = "../../crates/web-sys"
|
||||
features = [
|
||||
'Document',
|
||||
'Element',
|
||||
'HtmlCanvasElement',
|
||||
'WebGlBuffer',
|
||||
'WebGlRenderingContext',
|
||||
'WebGlProgram',
|
||||
'WebGlShader',
|
||||
'Window',
|
||||
]
|
15
examples/webgl/README.md
Executable file
15
examples/webgl/README.md
Executable file
@ -0,0 +1,15 @@
|
||||
# WebGL Example
|
||||
|
||||
This directory is an example of using the `web-sys` crate to interact with
|
||||
a WebGL context.
|
||||
|
||||
You can build and run the example with:
|
||||
|
||||
```
|
||||
$ ./build.sh
|
||||
```
|
||||
|
||||
(or running the commands on Windows manually)
|
||||
|
||||
and then opening up `http://localhost:8080/` in a web browser should show a
|
||||
nice triangle.
|
15
examples/webgl/build.sh
Executable file
15
examples/webgl/build.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# For more coments about what's going on here, see the `hello_world` example
|
||||
|
||||
set -ex
|
||||
cd "$(dirname $0)"
|
||||
|
||||
cargo +nightly build --target wasm32-unknown-unknown
|
||||
|
||||
cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \
|
||||
--bin wasm-bindgen -- \
|
||||
../../target/wasm32-unknown-unknown/debug/wasm_bindgen_webgl_demo.wasm --out-dir .
|
||||
|
||||
npm install
|
||||
npm run serve
|
9
examples/webgl/index.html
Executable file
9
examples/webgl/index.html
Executable file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" height="150" width="150" />
|
||||
<script src='./index.js'></script>
|
||||
</body>
|
||||
</html>
|
5
examples/webgl/index.js
Executable file
5
examples/webgl/index.js
Executable file
@ -0,0 +1,5 @@
|
||||
// For more comments about what's going on here, check out the `hello_world`
|
||||
// example.
|
||||
import('./wasm_bindgen_webgl_demo').then(webgl => {
|
||||
webgl.draw();
|
||||
});
|
11
examples/webgl/package.json
Executable file
11
examples/webgl/package.json
Executable file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"webpack": "^4.11.1",
|
||||
"webpack-cli": "^2.0.10",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
121
examples/webgl/src/lib.rs
Executable file
121
examples/webgl/src/lib.rs
Executable file
@ -0,0 +1,121 @@
|
||||
extern crate js_sys;
|
||||
extern crate wasm_bindgen;
|
||||
extern crate web_sys;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{WebGlProgram, WebGlRenderingContext, WebGlShader};
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn draw() {
|
||||
let document = web_sys::Window::document().unwrap();
|
||||
let canvas = document.get_element_by_id("canvas").unwrap();
|
||||
let canvas: web_sys::HtmlCanvasElement = canvas
|
||||
.dyn_into::<web_sys::HtmlCanvasElement>()
|
||||
.map_err(|_| ())
|
||||
.unwrap();
|
||||
|
||||
let context = canvas
|
||||
.get_context("webgl")
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
.dyn_into::<WebGlRenderingContext>()
|
||||
.unwrap();
|
||||
|
||||
let vert_shader = compile_shader(
|
||||
&context,
|
||||
WebGlRenderingContext::VERTEX_SHADER,
|
||||
r#"
|
||||
attribute vec4 position;
|
||||
void main() {
|
||||
gl_Position = position;
|
||||
}
|
||||
"#,
|
||||
).unwrap();
|
||||
let frag_shader = compile_shader(
|
||||
&context,
|
||||
WebGlRenderingContext::FRAGMENT_SHADER,
|
||||
r#"
|
||||
void main() {
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
}
|
||||
"#,
|
||||
).unwrap();
|
||||
let program = link_program(&context, [vert_shader, frag_shader].iter()).unwrap();
|
||||
context.use_program(Some(&program));
|
||||
|
||||
let vertices = [-0.7, -0.7, 0.0, 0.7, -0.7, 0.0, 0.0, 0.7, 0.0];
|
||||
let vert_array = js_sys::Float32Array::new(&wasm_bindgen::JsValue::from(vertices.len() as u32));
|
||||
for (i, f) in vertices.iter().enumerate() {
|
||||
vert_array.fill(*f, i as u32, (i + 1) as u32);
|
||||
}
|
||||
|
||||
let buffer = context.create_buffer().unwrap();
|
||||
context.bind_buffer(WebGlRenderingContext::ARRAY_BUFFER, Some(&buffer));
|
||||
context.buffer_data_with_opt_array_buffer(
|
||||
WebGlRenderingContext::ARRAY_BUFFER,
|
||||
Some(&vert_array.buffer()),
|
||||
WebGlRenderingContext::STATIC_DRAW,
|
||||
);
|
||||
context.vertex_attrib_pointer_with_i32(0,
|
||||
3,
|
||||
WebGlRenderingContext::FLOAT,
|
||||
false,
|
||||
0,
|
||||
0);
|
||||
context.enable_vertex_attrib_array(0);
|
||||
|
||||
context.clear_color(0.0, 0.0, 0.0, 1.0);
|
||||
context.clear(WebGlRenderingContext::COLOR_BUFFER_BIT);
|
||||
|
||||
context.draw_arrays(WebGlRenderingContext::TRIANGLES, 0, (vertices.len() / 3) as i32);
|
||||
}
|
||||
|
||||
pub fn compile_shader(
|
||||
context: &WebGlRenderingContext,
|
||||
shader_type: u32,
|
||||
source: &str,
|
||||
) -> Result<WebGlShader, String> {
|
||||
let shader = context
|
||||
.create_shader(shader_type)
|
||||
.ok_or_else(|| String::from("Unable to create shader object"))?;
|
||||
context.shader_source(&shader, source);
|
||||
context.compile_shader(&shader);
|
||||
|
||||
if context
|
||||
.get_shader_parameter(&shader, WebGlRenderingContext::COMPILE_STATUS)
|
||||
.as_bool()
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Ok(shader)
|
||||
} else {
|
||||
Err(context
|
||||
.get_shader_info_log(&shader)
|
||||
.unwrap_or_else(|| "Unknown error creating shader".into()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link_program<'a, T: IntoIterator<Item = &'a WebGlShader>>(
|
||||
context: &WebGlRenderingContext,
|
||||
shaders: T,
|
||||
) -> Result<WebGlProgram, String> {
|
||||
let program = context
|
||||
.create_program()
|
||||
.ok_or_else(|| String::from("Unable to create shader object"))?;
|
||||
for shader in shaders {
|
||||
context.attach_shader(&program, shader)
|
||||
}
|
||||
context.link_program(&program);
|
||||
|
||||
if context
|
||||
.get_program_parameter(&program, WebGlRenderingContext::LINK_STATUS)
|
||||
.as_bool()
|
||||
.unwrap_or(false)
|
||||
{
|
||||
Ok(program)
|
||||
} else {
|
||||
Err(context
|
||||
.get_program_info_log(&program)
|
||||
.unwrap_or_else(|| "Unknown error creating program object".into()))
|
||||
}
|
||||
}
|
16
examples/webgl/webpack.config.js
Executable file
16
examples/webgl/webpack.config.js
Executable file
@ -0,0 +1,16 @@
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'index.js',
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: "index.html"
|
||||
})
|
||||
],
|
||||
mode: 'development'
|
||||
};
|
@ -62,6 +62,7 @@
|
||||
- [The `fetch` API](./web-sys/examples/fetch.md)
|
||||
- [2D Canvas](./web-sys/examples/2d-canvas.md)
|
||||
- [WebAudio](./web-sys/examples/web-audio.md)
|
||||
- [WebGL](./web-sys/examples/webgl.md)
|
||||
- [A Simple Paint Program](./web-sys/examples/paint.md)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
25
guide/src/web-sys/examples/webgl.md
Normal file
25
guide/src/web-sys/examples/webgl.md
Normal file
@ -0,0 +1,25 @@
|
||||
# 2D Canvas
|
||||
|
||||
This example draws a triangle to the screen using the WebGL API.
|
||||
|
||||
[See the full source at
|
||||
`wasm-bindgen/examples/webgl`.](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webgl)
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to obtain and use a WebGL
|
||||
rendering context.
|
||||
|
||||
```toml
|
||||
{{#include ../../../../examples/webgl/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
This source file handles all of the necessary logic to obtain a rendering
|
||||
context, compile shaders, fill a buffer with vertex coordinates, and draw a
|
||||
triangle to the screen.
|
||||
|
||||
```rust
|
||||
{{#include ../../../../examples/webgl/src/lib.rs}}
|
||||
```
|
Loading…
Reference in New Issue
Block a user