Skip to content

Instantly share code, notes, and snippets.

@f-space
Created Oct 23, 2017
Embed
What would you like to do?
WebGLによるImageのコピー
const VS_SRC = `
attribute vec4 position;
attribute vec2 texcoord;
varying vec2 vTexcoord;
void main(void){
gl_Position = position;
vTexcoord = texcoord;
}
`;
const FS_SRC = `
precision mediump float;
varying vec2 vTexcoord;
uniform sampler2D uSampler;
void main(void){
gl_FragColor = texture2D(uSampler, vTexcoord);
}
`;
const VERTICES = [
-1, -1, 0, 1,
-1, +1, 0, 0,
+1, -1, 1, 1,
+1, +1, 1, 0,
];
function blit(image, canvas) {
const attrs = { depth: false, stencil: false, antialias: false };
const gl = canvas.getContext('webgl', attrs) || canvas.getContext('experimental-webgl', attrs);
if (gl == null) throw new Error('Failed to get WebGL context.');
const vbo = createVBO(gl, VERTICES);
const vs = createShader(gl, gl.VERTEX_SHADER, VS_SRC);
const fs = createShader(gl, gl.FRAGMENT_SHADER, FS_SRC);
const program = createProgram(gl, vs, fs);
const texture = createTexture(gl, image);
const aPosition = gl.getAttribLocation(program, "position");
const aTexcoord = gl.getAttribLocation(program, "texcoord");
const uSampler = gl.getUniformLocation(program, "uSampler");
gl.useProgram(program);
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.enableVertexAttribArray(aPosition);
gl.enableVertexAttribArray(aTexcoord);
gl.vertexAttribPointer(aPosition, 2, gl.BYTE, false, 4, 0);
gl.vertexAttribPointer(aTexcoord, 2, gl.BYTE, false, 4, 2);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(uSampler, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.deleteBuffer(vbo);
gl.deleteShader(vs);
gl.deleteShader(fs);
gl.deleteProgram(program);
gl.deleteTexture(texture);
gl.finish();
}
function createVBO(gl, vertices) {
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Int8Array(vertices), gl.STREAM_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
return vbo;
}
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader));
}
return shader;
}
function createProgram(gl, vs, fs) {
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program));
}
return program;
}
function createTexture(gl, image) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
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);
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
module.exports = blit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment