Draw a mesh in perspective, and in color
This commit is contained in:
parent
fd3cbae1b4
commit
5885189b04
@ -2,9 +2,13 @@
|
|||||||
//
|
//
|
||||||
// https://rustwasm.github.io/wasm-bindgen/examples/webgl.html
|
// https://rustwasm.github.io/wasm-bindgen/examples/webgl.html
|
||||||
//
|
//
|
||||||
|
// and this StackOverflow answer by wangdq
|
||||||
|
//
|
||||||
|
// https://stackoverflow.com/a/39684775
|
||||||
|
//
|
||||||
|
|
||||||
extern crate js_sys;
|
extern crate js_sys;
|
||||||
use std::f64::consts::PI as PI;
|
/* use std::f64::consts::PI as PI; */
|
||||||
use sycamore::{prelude::*, rt::{JsCast, JsValue}};
|
use sycamore::{prelude::*, rt::{JsCast, JsValue}};
|
||||||
use web_sys::{console, WebGl2RenderingContext, WebGlProgram, WebGlShader};
|
use web_sys::{console, WebGl2RenderingContext, WebGlProgram, WebGlShader};
|
||||||
|
|
||||||
@ -19,6 +23,52 @@ fn compile_shader(
|
|||||||
shader
|
shader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load the given data into the vertex input of the given name
|
||||||
|
fn bind_vertex_attrib(
|
||||||
|
context: &WebGl2RenderingContext,
|
||||||
|
program: &WebGlProgram,
|
||||||
|
name: &str,
|
||||||
|
size: i32,
|
||||||
|
data: &[f32]
|
||||||
|
) {
|
||||||
|
// create a data buffer and bind it to ARRAY_BUFFER
|
||||||
|
let buffer = context.create_buffer().unwrap();
|
||||||
|
context.bind_buffer(WebGl2RenderingContext::ARRAY_BUFFER, Some(&buffer));
|
||||||
|
|
||||||
|
// load the given data into the buffer. the function `Float32Array::view`
|
||||||
|
// creates a raw view into our module's `WebAssembly.Memory` buffer.
|
||||||
|
// allocating more memory will change the buffer, invalidating the view.
|
||||||
|
// that means we have to make sure we don't allocate any memory until the
|
||||||
|
// view is dropped
|
||||||
|
unsafe {
|
||||||
|
context.buffer_data_with_array_buffer_view(
|
||||||
|
WebGl2RenderingContext::ARRAY_BUFFER,
|
||||||
|
&js_sys::Float32Array::view(&data),
|
||||||
|
WebGl2RenderingContext::STATIC_DRAW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the target attribute in the program's attribute list
|
||||||
|
let attrib_index = context.get_attrib_location(&program, name);
|
||||||
|
|
||||||
|
// allow the target attribute to be used
|
||||||
|
context.enable_vertex_attrib_array(attrib_index as u32);
|
||||||
|
|
||||||
|
// take whatever's bound to ARRAY_BUFFER---here, the data buffer created
|
||||||
|
// above---and bind it to the target attribute
|
||||||
|
//
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer
|
||||||
|
//
|
||||||
|
context.vertex_attrib_pointer_with_i32(
|
||||||
|
attrib_index as u32,
|
||||||
|
size,
|
||||||
|
WebGl2RenderingContext::FLOAT,
|
||||||
|
false, // don't normalize
|
||||||
|
0, // zero stride
|
||||||
|
0, // zero offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// set up a config option that forwards panic messages to `console.error`
|
// set up a config option that forwards panic messages to `console.error`
|
||||||
#[cfg(feature = "console_error_panic_hook")]
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
@ -40,16 +90,31 @@ fn main() {
|
|||||||
.dyn_into::<WebGl2RenderingContext>()
|
.dyn_into::<WebGl2RenderingContext>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// load the vertex and fragment shaders
|
// compile and attach the vertex and fragment shaders
|
||||||
let vertex_shader = compile_shader(
|
let vertex_shader = compile_shader(
|
||||||
&ctx,
|
&ctx,
|
||||||
WebGl2RenderingContext::VERTEX_SHADER,
|
WebGl2RenderingContext::VERTEX_SHADER,
|
||||||
r##"#version 300 es
|
r##"#version 300 es
|
||||||
|
|
||||||
in vec4 position;
|
in vec3 position;
|
||||||
|
in vec3 color;
|
||||||
|
|
||||||
|
out vec4 vertexColor;
|
||||||
|
|
||||||
|
const float focal_length = 3.0;
|
||||||
|
const float near_clip = 0.1;
|
||||||
|
const float far_clip = 20.0;
|
||||||
|
const float depth_inv = 1. / (far_clip - near_clip);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = position;
|
const mat4 world_to_clip = mat4(
|
||||||
|
focal_length, 0.0, 0.0, 0.0,
|
||||||
|
0.0, focal_length, 0.0, 0.0,
|
||||||
|
0.0, 0.0, (near_clip + far_clip) * depth_inv, -1.,
|
||||||
|
0.0, 0.0, 2. * near_clip * far_clip * depth_inv, 0.0
|
||||||
|
);
|
||||||
|
gl_Position = world_to_clip * vec4(position, 1.);
|
||||||
|
vertexColor = vec4(color, 1.);
|
||||||
}
|
}
|
||||||
"##,
|
"##,
|
||||||
);
|
);
|
||||||
@ -59,10 +124,13 @@ fn main() {
|
|||||||
r##"#version 300 es
|
r##"#version 300 es
|
||||||
|
|
||||||
precision highp float;
|
precision highp float;
|
||||||
|
|
||||||
|
in vec4 vertexColor;
|
||||||
|
|
||||||
out vec4 outColor;
|
out vec4 outColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
outColor = vec4(gl_FragCoord.xy / 600., 1., 1.);
|
outColor = vertexColor;
|
||||||
}
|
}
|
||||||
"##,
|
"##,
|
||||||
);
|
);
|
||||||
@ -82,58 +150,53 @@ fn main() {
|
|||||||
console::log_1(&JsValue::from(link_msg));
|
console::log_1(&JsValue::from(link_msg));
|
||||||
ctx.use_program(Some(&program));
|
ctx.use_program(Some(&program));
|
||||||
|
|
||||||
|
// create a vertex array and bind it to the graphics context
|
||||||
|
let vertex_array = ctx.create_vertex_array().unwrap();
|
||||||
|
ctx.bind_vertex_array(Some(&vertex_array));
|
||||||
|
|
||||||
// set up a repainting routine
|
// set up a repainting routine
|
||||||
create_effect(move || {
|
create_effect(move || {
|
||||||
// list the vertices
|
const VERTEX_CNT: usize = 9;
|
||||||
let vertices: [f32; 9] = [
|
|
||||||
-0.9, 0.9, 0.0,
|
// set the vertex positions
|
||||||
-0.9, -0.9, 0.0,
|
let tip_shift = 4.0/3.0 * tip.get() as f32;
|
||||||
0.9*(tip.get() as f32), 0.0, 0.0
|
let positions: [f32; 3*VERTEX_CNT] = [
|
||||||
|
// triangle 1
|
||||||
|
1.0 - tip_shift, 1.0 - tip_shift, -5.0 - tip_shift,
|
||||||
|
1.0, -1.0, -7.0,
|
||||||
|
-1.0, 1.0, -7.0,
|
||||||
|
// triangle 2
|
||||||
|
1.0 - tip_shift, 1.0 - tip_shift, -5.0 - tip_shift,
|
||||||
|
-1.0, 1.0, -7.0,
|
||||||
|
-1.0, -1.0, -7.0,
|
||||||
|
// triangle 3
|
||||||
|
1.0 - tip_shift, 1.0 - tip_shift, -5.0 - tip_shift,
|
||||||
|
-1.0, -1.0, -7.0,
|
||||||
|
1.0, -1.0, -7.0
|
||||||
];
|
];
|
||||||
|
bind_vertex_attrib(&ctx, &program, "position", 3, &positions);
|
||||||
|
|
||||||
// create a vertex buffer and bind it to ARRAY_BUFFER
|
// set the vertex colors
|
||||||
let position_attribute_location = ctx.get_attrib_location(&program, "position");
|
let colors: [f32; 3*VERTEX_CNT] = [
|
||||||
let buffer = ctx.create_buffer().unwrap();
|
// triangle 1
|
||||||
ctx.bind_buffer(WebGl2RenderingContext::ARRAY_BUFFER, Some(&buffer));
|
1.0, 0.0, 0.5,
|
||||||
|
1.0, 0.0, 0.5,
|
||||||
// load the vertex list into the vertex buffer. the function
|
1.0, 0.0, 0.5,
|
||||||
// `Float32Array::view` creates a raw view into our module's
|
// triangle 2
|
||||||
// `WebAssembly.Memory` buffer. allocating more memory will
|
0.0, 0.5, 1.0,
|
||||||
// change the buffer, invalidating the view. that means we have
|
0.0, 0.5, 1.0,
|
||||||
// to make sure we don't allocate any memory until the view is
|
0.0, 0.5, 1.0,
|
||||||
// dropped
|
// triangle 3
|
||||||
unsafe {
|
0.5, 0.0, 1.0,
|
||||||
ctx.buffer_data_with_array_buffer_view(
|
0.5, 0.0, 1.0,
|
||||||
WebGl2RenderingContext::ARRAY_BUFFER,
|
0.5, 0.0, 1.0
|
||||||
&js_sys::Float32Array::view(&vertices),
|
];
|
||||||
WebGl2RenderingContext::STATIC_DRAW,
|
bind_vertex_attrib(&ctx, &program, "color", 3, &colors);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a vertex array and bind it to the graphics context
|
|
||||||
let vtx_array_obj = ctx.create_vertex_array().unwrap();
|
|
||||||
ctx.bind_vertex_array(Some(&vtx_array_obj));
|
|
||||||
|
|
||||||
// use whatever is bound to ARRAY_BUFFER---here, the vertex
|
|
||||||
// buffer created above---as the vertex attribute array
|
|
||||||
//
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/vertexAttribPointer
|
|
||||||
//
|
|
||||||
ctx.vertex_attrib_pointer_with_i32(
|
|
||||||
position_attribute_location as u32,
|
|
||||||
3, // dimension
|
|
||||||
WebGl2RenderingContext::FLOAT, // type
|
|
||||||
false, // normalized?
|
|
||||||
0, // stride
|
|
||||||
0, // offset
|
|
||||||
);
|
|
||||||
ctx.enable_vertex_attrib_array(position_attribute_location as u32);
|
|
||||||
|
|
||||||
// clear the screen and draw the scene
|
// clear the screen and draw the scene
|
||||||
let vert_count = (vertices.len() / 3) as i32;
|
|
||||||
ctx.clear_color(0.0, 0.0, 0.0, 1.0);
|
ctx.clear_color(0.0, 0.0, 0.0, 1.0);
|
||||||
ctx.clear(WebGl2RenderingContext::COLOR_BUFFER_BIT);
|
ctx.clear(WebGl2RenderingContext::COLOR_BUFFER_BIT);
|
||||||
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, vert_count);
|
ctx.draw_arrays(WebGl2RenderingContext::TRIANGLES, 0, VERTEX_CNT as i32);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user