mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
106 lines
4.3 KiB
JavaScript
106 lines
4.3 KiB
JavaScript
function createWebGL(gl) {
|
|
var vertexShaderScript = [
|
|
'attribute vec4 vertexPos;',
|
|
'attribute vec4 texturePos;',
|
|
'varying vec2 textureCoord;',
|
|
|
|
'void main()',
|
|
'{',
|
|
'gl_Position = vertexPos;',
|
|
'textureCoord = texturePos.xy;',
|
|
'}'
|
|
].join('\n');
|
|
|
|
var fragmentShaderScript = [
|
|
'precision highp float;',
|
|
'varying highp vec2 textureCoord;',
|
|
'uniform sampler2D ySampler;',
|
|
'uniform sampler2D uSampler;',
|
|
'uniform sampler2D vSampler;',
|
|
'const mat4 YUV2RGB = mat4',
|
|
'(',
|
|
'1.1643828125, 0, 1.59602734375, -.87078515625,',
|
|
'1.1643828125, -.39176171875, -.81296875, .52959375,',
|
|
'1.1643828125, 2.017234375, 0, -1.081390625,',
|
|
'0, 0, 0, 1',
|
|
');',
|
|
|
|
'void main(void) {',
|
|
'highp float y = texture2D(ySampler, textureCoord).r;',
|
|
'highp float u = texture2D(uSampler, textureCoord).r;',
|
|
'highp float v = texture2D(vSampler, textureCoord).r;',
|
|
'gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;',
|
|
'}'
|
|
].join('\n');
|
|
|
|
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
gl.shaderSource(vertexShader, vertexShaderScript);
|
|
gl.compileShader(vertexShader);
|
|
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
|
console.log('Vertex shader failed to compile: ' + gl.getShaderInfoLog(vertexShader));
|
|
}
|
|
|
|
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
gl.shaderSource(fragmentShader, fragmentShaderScript);
|
|
gl.compileShader(fragmentShader);
|
|
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
|
console.log('Fragment shader failed to compile: ' + gl.getShaderInfoLog(fragmentShader));
|
|
}
|
|
|
|
var program = gl.createProgram();
|
|
gl.attachShader(program, vertexShader);
|
|
gl.attachShader(program, fragmentShader);
|
|
gl.linkProgram(program);
|
|
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
console.log('Program failed to compile: ' + gl.getProgramInfoLog(program));
|
|
}
|
|
|
|
gl.useProgram(program);
|
|
|
|
var vertexPosBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW);
|
|
|
|
var vertexPosRef = gl.getAttribLocation(program, 'vertexPos');
|
|
gl.enableVertexAttribArray(vertexPosRef);
|
|
gl.vertexAttribPointer(vertexPosRef, 2, gl.FLOAT, false, 0, 0);
|
|
|
|
var texturePosBuffer = gl.createBuffer();
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]), gl.STATIC_DRAW);
|
|
|
|
var texturePosRef = gl.getAttribLocation(program, 'texturePos');
|
|
gl.enableVertexAttribArray(texturePosRef);
|
|
gl.vertexAttribPointer(texturePosRef, 2, gl.FLOAT, false, 0, 0);
|
|
function _initTexture(name, index) {
|
|
var textureRef = gl.createTexture();
|
|
gl.bindTexture(gl.TEXTURE_2D, textureRef);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
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);
|
|
gl.uniform1i(gl.getUniformLocation(program, name), index);
|
|
return textureRef;
|
|
}
|
|
var yTextureRef = _initTexture('ySampler', 0);
|
|
var uTextureRef = _initTexture('uSampler', 1);
|
|
var vTextureRef = _initTexture('vSampler', 2);
|
|
|
|
return function (w, h, y, u, v) {
|
|
gl.viewport(0, 0, w, h);
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, w, h, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, y);
|
|
gl.activeTexture(gl.TEXTURE1);
|
|
gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, w / 2, h / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, u);
|
|
gl.activeTexture(gl.TEXTURE2);
|
|
gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
|
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, w / 2, h / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, v);
|
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
}
|
|
if (typeof exports !== 'undefined') {
|
|
module.exports = createWebGL;
|
|
} |