|
|
|
@ -1,4 +1,4 @@
@@ -1,4 +1,4 @@
|
|
|
|
|
const vertex_shader_source = ` |
|
|
|
|
const stroke_vs_src = ` |
|
|
|
|
attribute vec2 a_pos; |
|
|
|
|
attribute vec3 a_color; |
|
|
|
|
|
|
|
|
@ -19,7 +19,7 @@ const vertex_shader_source = `
@@ -19,7 +19,7 @@ const vertex_shader_source = `
|
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const fragment_shader_source = ` |
|
|
|
|
const stroke_fs_src = ` |
|
|
|
|
precision mediump float; |
|
|
|
|
|
|
|
|
|
varying vec3 v_color; |
|
|
|
@ -29,6 +29,39 @@ const fragment_shader_source = `
@@ -29,6 +29,39 @@ const fragment_shader_source = `
|
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const tquad_vs_src = ` |
|
|
|
|
attribute vec2 a_pos; |
|
|
|
|
attribute vec2 a_texcoord; |
|
|
|
|
|
|
|
|
|
uniform vec2 u_scale; |
|
|
|
|
uniform vec2 u_res; |
|
|
|
|
uniform vec2 u_translation; |
|
|
|
|
uniform int u_layer; |
|
|
|
|
|
|
|
|
|
varying vec2 v_texcoord; |
|
|
|
|
|
|
|
|
|
void main() { |
|
|
|
|
vec2 screen01 = (a_pos * u_scale + u_translation) / u_res; |
|
|
|
|
vec2 screen02 = screen01 * 2.0; |
|
|
|
|
screen02.y = 2.0 - screen02.y; |
|
|
|
|
vec2 screen11 = screen02 - 1.0; |
|
|
|
|
v_texcoord = a_texcoord; |
|
|
|
|
gl_Position = vec4(screen11, u_layer, 1); |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const tquad_fs_src = ` |
|
|
|
|
precision mediump float; |
|
|
|
|
|
|
|
|
|
varying vec2 v_texcoord; |
|
|
|
|
|
|
|
|
|
uniform sampler2D u_texture; |
|
|
|
|
|
|
|
|
|
void main() { |
|
|
|
|
gl_FragColor = texture2D(u_texture, v_texcoord); |
|
|
|
|
} |
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
function init_webgl(state, context) { |
|
|
|
|
context.canvas = document.querySelector('#c'); |
|
|
|
|
context.gl = context.canvas.getContext('webgl', { |
|
|
|
@ -37,25 +70,88 @@ function init_webgl(state, context) {
@@ -37,25 +70,88 @@ function init_webgl(state, context) {
|
|
|
|
|
'antialias': true, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
context.gl.enable(context.gl.BLEND); |
|
|
|
|
context.gl.blendFunc(context.gl.ONE, context.gl.ONE_MINUS_SRC_ALPHA); |
|
|
|
|
|
|
|
|
|
const vertex_shader = create_shader(context.gl, context.gl.VERTEX_SHADER, vertex_shader_source); |
|
|
|
|
const fragment_shader = create_shader(context.gl, context.gl.FRAGMENT_SHADER, fragment_shader_source); |
|
|
|
|
const program = create_program(context.gl, vertex_shader, fragment_shader) |
|
|
|
|
|
|
|
|
|
context.program = program; |
|
|
|
|
|
|
|
|
|
context.locations['a_pos'] = context.gl.getAttribLocation(program, 'a_pos'); |
|
|
|
|
context.locations['a_color'] = context.gl.getAttribLocation(program, 'a_color'); |
|
|
|
|
|
|
|
|
|
context.locations['u_res'] = context.gl.getUniformLocation(program, 'u_res'); |
|
|
|
|
context.locations['u_scale'] = context.gl.getUniformLocation(program, 'u_scale'); |
|
|
|
|
context.locations['u_translation'] = context.gl.getUniformLocation(program, 'u_translation'); |
|
|
|
|
context.locations['u_layer'] = context.gl.getUniformLocation(program, 'u_layer'); |
|
|
|
|
|
|
|
|
|
context.buffers['b_pos'] = context.gl.createBuffer(); |
|
|
|
|
context.buffers['b_color'] = context.gl.createBuffer(); |
|
|
|
|
const gl = context.gl; |
|
|
|
|
|
|
|
|
|
gl.enable(gl.BLEND); |
|
|
|
|
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); |
|
|
|
|
|
|
|
|
|
const stroke_vs = create_shader(gl, gl.VERTEX_SHADER, stroke_vs_src); |
|
|
|
|
const stroke_fs = create_shader(gl, gl.FRAGMENT_SHADER, stroke_fs_src); |
|
|
|
|
|
|
|
|
|
const quad_vs = create_shader(gl, gl.VERTEX_SHADER, tquad_vs_src); |
|
|
|
|
const quad_fs = create_shader(gl, gl.FRAGMENT_SHADER, tquad_fs_src); |
|
|
|
|
|
|
|
|
|
context.programs['stroke'] = create_program(gl, stroke_vs, stroke_fs); |
|
|
|
|
context.programs['quad'] = create_program(gl, quad_vs, quad_fs); |
|
|
|
|
|
|
|
|
|
context.locations['stroke'] = { |
|
|
|
|
'a_pos': gl.getAttribLocation(context.programs['stroke'], 'a_pos'), |
|
|
|
|
'a_color': gl.getAttribLocation(context.programs['stroke'], 'a_color'), |
|
|
|
|
'u_res': gl.getUniformLocation(context.programs['stroke'], 'u_res'), |
|
|
|
|
'u_scale': gl.getUniformLocation(context.programs['stroke'], 'u_scale'), |
|
|
|
|
'u_translation': gl.getUniformLocation(context.programs['stroke'], 'u_translation'), |
|
|
|
|
'u_layer': gl.getUniformLocation(context.programs['stroke'], 'u_layer'), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.locations['quad'] = { |
|
|
|
|
'a_pos': gl.getAttribLocation(context.programs['quad'], 'a_pos'), |
|
|
|
|
'a_texcoord': gl.getAttribLocation(context.programs['quad'], 'a_texcoord'), |
|
|
|
|
'u_res': gl.getUniformLocation(context.programs['quad'], 'u_res'), |
|
|
|
|
'u_scale': gl.getUniformLocation(context.programs['quad'], 'u_scale'), |
|
|
|
|
'u_translation': gl.getUniformLocation(context.programs['quad'], 'u_translation'), |
|
|
|
|
'u_layer': gl.getUniformLocation(context.programs['quad'], 'u_layer'), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.buffers['stroke'] = { |
|
|
|
|
'b_pos': context.gl.createBuffer(), |
|
|
|
|
'b_color': context.gl.createBuffer(), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.buffers['quad'] = { |
|
|
|
|
'b_pos': context.gl.createBuffer(), |
|
|
|
|
'b_texcoord': context.gl.createBuffer(), |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
context.textures['test'] = gl.createTexture(); |
|
|
|
|
|
|
|
|
|
// Fill the texture with a 1x1 blue pixel.
|
|
|
|
|
gl.bindTexture(gl.TEXTURE_2D, context.textures['test']); |
|
|
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, |
|
|
|
|
new Uint8Array([0, 0, 255, 255])); |
|
|
|
|
|
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); |
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); |
|
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); |
|
|
|
|
|
|
|
|
|
var image = new Image(); |
|
|
|
|
image.src = "http://192.168.100.2/images/3697505915"; |
|
|
|
|
image.addEventListener('load', function() { |
|
|
|
|
// Now that the image has loaded make copy it to the texture.
|
|
|
|
|
context.quad_positions = [ |
|
|
|
|
100, 100, |
|
|
|
|
100, 100 + image.height, |
|
|
|
|
100 + image.width, 100 + image.height, |
|
|
|
|
|
|
|
|
|
100 + image.width, 100, |
|
|
|
|
100, 100, |
|
|
|
|
100 + image.width, 100 + image.height, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
context.quad_texcoords = [ |
|
|
|
|
0, 0, |
|
|
|
|
0, 1, |
|
|
|
|
1, 1, |
|
|
|
|
1, 0, |
|
|
|
|
0, 0, |
|
|
|
|
1, 1, |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
context.quad_positions_f32 = new Float32Array(context.quad_positions); |
|
|
|
|
context.quad_texcoords_f32 = new Float32Array(context.quad_texcoords); |
|
|
|
|
|
|
|
|
|
gl.bindTexture(gl.TEXTURE_2D, context.textures['test']); |
|
|
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, image); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const resize_canvas = (entries) => { |
|
|
|
|
// https://www.khronos.org/webgl/wiki/HandlingHighDPI
|
|
|
|
|