Created
October 23, 2017 09:41
-
-
Save f-space/7efea3e605e6edb79ed6ee0c93b7d0d9 to your computer and use it in GitHub Desktop.
WebGLによるImageのコピー
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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