le but de cette partie est d'expliquer le concept de "binding".
"use strict";
let lx=4;
let ly=2;
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = lx;
canvas.height=ly;
const gl = canvas.getContext('webgl');
gl.getExtension('OES_texture_float');
let vertex = `
attribute vec2 vertexPosition;
void main() {
gl_Position = vec4(vertexPosition, 1, 1);
}
`;
let fragment = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform sampler2D texture;
void main() {
vec4 data = texture2D(
texture ,
gl_FragCoord.xy / vec2(${lx},${ly})
);
gl_FragColor=data;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(vertexShader))
};
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(fragmentShader))
};
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program))
};
gl.useProgram(program);
let vertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array([
-1, -1,
+1, -1,
-1, +1,
-1, +1,
+1, -1,
+1, +1
]),gl.STATIC_DRAW
);
const vertexPositionAttributeLocation = gl.getAttribLocation( program,"vertexPosition");
gl.enableVertexAttribArray(vertexPositionAttributeLocation);
gl.vertexAttribPointer(vertexPositionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
//gl.activeTexture(gl.TEXTURE1);
//gl.bindTexture(gl.TEXTURE_2D, targetTexture);
//let textureUniformLocation = gl.getUniformLocation(program,"texture");
//gl.uniform1i(textureUniformLocation, 1);
//gl.activeTexture(gl.TEXTURE0);
let targetTexture2 = gl.createTexture();
//gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, targetTexture2);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,lx,ly,0,gl.RGBA,gl.FLOAT,null);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let fbEcran = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,fbEcran);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
targetTexture2,
0
);
//gl.uniform1i(textureUniformLocation, 0);
let targetTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, targetTexture);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let fuck= new Float32Array(
[ 10, 10, 10, 255, 20, 20, 20, 255, 30, 30, 30, 255, 40, 40, 40, 255,
50, 50, 50, 255, 60, 60, 60, 255, 70, 70, 70, 255, 80, 80, 80, 255
]
);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, lx, ly, 0, gl.RGBA, gl.FLOAT, fuck);
gl.drawArrays(gl.TRIANGLES, 0, 6);
let data = new Float32Array(4 * gl.canvas.width * gl.canvas.height);
gl.readPixels(0, 0, gl.canvas.width, gl.canvas.height, gl.RGBA, gl.FLOAT, data);
console.log(data);
Maintenant j'explique le code
let lx=4;
let ly=2;
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = lx;
canvas.height = ly;
const gl = canvas.getContext('webgl');
ajout d'une extension pour stocker dans les textures les valeurs des couleurs (R,G,B et A) au format "32bit float formats". C'est à dire non restreintes à l'intervalle [0,1].
gl.getExtension('OES_texture_float');
let vertex = `
attribute vec2 vertexPosition;
void main() {
gl_Position = vec4(vertexPosition, 1, 1);
}
`;
let fragment = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform sampler2D texture;
void main() {
vec4 data = texture2D(
texture ,
gl_FragCoord.xy / vec2(${lx},${ly})
);
gl_FragColor=data;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(vertexShader))
};
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(fragmentShader))
};
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program))
};
let vertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array([
-1, -1,
+1, -1,
-1, +1,
-1, +1,
+1, -1,
+1, +1
]),gl.STATIC_DRAW
);
let targetTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, targetTexture);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let fuck= new Float32Array(
[ 10, 10, 10, 255, 20, 20, 20, 255, 30, 30, 30, 255, 40, 40, 40, 255,
50, 50, 50, 255, 60, 60, 60, 255, 70, 70, 70, 255, 80, 80, 80, 255
]
);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, lx, ly, 0, gl.RGBA, gl.FLOAT, fuck);
const vertexPositionAttributeLocation = gl.getAttribLocation( program,"vertexPosition");
gl.enableVertexAttribArray(vertexPositionAttributeLocation);
gl.vertexAttribPointer(vertexPositionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
let targetTexture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, targetTexture2);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,lx,ly,0,gl.RGBA,gl.FLOAT,null);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let fbEcran = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,fbEcran);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
targetTexture2,
0
);
gl.drawArrays(gl.TRIANGLES, 0, 6);
let data = new Float32Array(4 * gl.canvas.width * gl.canvas.height);
gl.readPixels(0, 0, gl.canvas.width, gl.canvas.height, gl.RGBA, gl.FLOAT, data);
console.log(data);
'use strict';
let lx=4;
let ly=2;
const canvas = document.querySelector('canvas');
canvas.width = lx;
canvas.height=ly;
const gl = canvas.getContext('webgl');
const vsGLSL = `
attribute vec2 vertexPosition;
void main() {
gl_Position = vec4(vertexPosition, 1, 1);
}
`;
const fsGLSL = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform sampler2D texture;
void main() {
vec4 data = texture2D(
texture ,
gl_FragCoord.xy / vec2(${lx},${ly})
);
gl_FragColor=data;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsGLSL);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(vertexShader))
};
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsGLSL);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(fragmentShader))
};
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program))
};
gl.detachShader(program, vertexShader);
gl.deleteShader(vertexShader);
gl.detachShader(program, fragmentShader);
gl.deleteShader(fragmentShader);
gl.useProgram(program);
const vertexPositionAttributeLocation = gl.getAttribLocation( program,"vertexPosition");
let vertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new Float32Array([
-1, -1,
1, -1,
-1, 1,
-1, 1,
1, -1,
1, 1
]),
gl.STATIC_DRAW);
gl.enableVertexAttribArray(vertexPositionAttributeLocation);
gl.vertexAttribPointer(vertexPositionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
/*
gl = {
activeTextureUnit: 0,
textureUnits: []
}
*/
let textureCopie = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, textureCopie);
/*
gl = {
activeTextureUnit: 0,
textureUnits:
[
{texture2D: textureCopie},
]
}
*/
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,lx,ly,0,gl.RGBA,gl.UNSIGNED_BYTE,null);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let fbEcran = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER,fbEcran);
/*
gl = {
activeTextureUnit: 0,
textureUnits:
[
{texture2D: textureCopie},
],
framebufferBinding: fbEcran
}
*/
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
textureCopie,
0
);
/*
gl = {
activeTextureUnit: 0,
textureUnits:
[
{texture2D: textureCopie},
],
framebufferBinding: fbEcran
}
framebuffer[fbEcran]= {
attachmentPoint: COLOR_ATTACHMENT0,
attachment: textureCopie
}
*/
let textureOriginal = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, textureOriginal);
/*
gl = {
activeTextureUnit: 0,
textureUnits:
[
{texture2D: textureOriginal},
],
framebufferBinding: fbEcran
}
framebuffer[fbEcran]= {
attachmentPoint: COLOR_ATTACHMENT0,
attachment: textureCopie
}
*/
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
let couleurs= new Uint8Array(
[ 10, 10, 10, 255, 20, 20, 20, 255, 30, 30, 30, 255, 40, 40, 40, 255,
50, 50, 50, 255, 60, 60, 60, 255, 70, 70, 70, 255, 80, 80, 80, 255
]
);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
lx,
ly,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
couleurs);
the texture affected is the current active texture
on the specified bing point
*/
/*
gl = {
activeTextureUnit: 0,
textureUnits:
[
{texture2D: textureOriginal},
],
framebufferBinding: fbEcran
}
framebuffer[fbEcran]= {
attachmentPoint: COLOR_ATTACHMENT0,
attachment: textureCopie
}
texture[textureOriginal]={
mips: [50,50,50,255,.....]
}
*/
gl.drawArrays(gl.TRIANGLES, 0, 6);