webgl - rishabhkailey/photo-editor GitHub Wiki
gl.clearColor(r, g, b, a)
gl.clearDepth(depth) ------------
gl.clearStencil(s) ------------
gl.getParameter(gl.COLOR_CLEAR_VALUE);
gl.getParameter(gl.DEPTH_CLEAR_VALUE);
gl.getParameter(gl.STENCIL_CLEAR_VALUE);
gl.clear(mask)
gl.COLOR_BUFFER_BIT
gl.DEPTH_BUFFER_BIT
gl.STENCIL_BUFFER_BIT
gl.clear(gl.COLOR_BUFFER_BIT)
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
VERTEX shader (convert vertices to clip space(-1 to 1) coordinates)
Buffer used to send data from js to shader(not randomly accessed, accessed one by one)
Attribute input variable for shader, get data from buffer
Uniform global variables
Textures array of data that can be randomly access
Varrying used to send data from vertex shader to fragment shader
gl_position clip space (-1 to 1) coordinates
vec4 type (0, 0, 0, 0)
source https://webglfundamentals.org/webgl/lessons/webgl-fundamentals.html
e.g.
vertex shader
<script id="vertex-shader-2d" type="notjs">
// an attribute will receive data from a buffer
attribute vec4 a_position;
// all shaders have a main function
void main() {
// gl_Position is a special variable a vertex shader
// is responsible for setting
gl_Position = a_position;
}
</script>
Fragment shader
<script id="fragment-shader-2d" type="notjs">
// fragment shaders don't have a default precision so we need
// to pick one. mediump is a good default
precision mediump float;
void main() {
// gl_FragColor is a special variable a fragment shader
// is responsible for setting
gl_FragColor = vec4(1, 0, 0.5, 1); // return reddish-purple
}
</script>
var canvas = document.querySelector("#c");
var gl = canvas.getContext("webgl");
function createShader(gl, type, source) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
var vertexShaderSource = document.querySelector("#vertex-shader-2d").text;
var fragmentShaderSource = document.querySelector("#fragment-shader-2d").text;
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
function createProgram(gl, vertexShader, fragmentShader) {
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
var success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success) {
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
var program = createProgram(gl, vertexShader, fragmentShader);
# create buffer
var positionBuffer = gl.createBuffer();
# we will not pass positinoBuffer to vertex shader as an argument instead we will bind it to gl.ARRAY_BUFFER thats it, to use it we need to create Attributes in vertexShader
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // gl.ARRAY_BUFFER: Buffer containing vertex attributes, such as vertex coordinates, texture coordinate data, or vertex color data.
# add data to buffer
// three 2d points
var positions = [
0, 0,
0, 0.5,
0.7, 0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); # first argument = buffer where we want to add data, 2nd is the data that we want to add, 3rd is to tell webgl how we will use the data so it can optimise it accordingly (STATIC_DRAW means we are not going to change the data)
# helpful function (optional)
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
# to tell webgl about the canvas size so it can convert gl_position to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
// to tell to use this program (we are not calling the program now)
gl.useProgram(program);
# this should be done after creating the program but i'm putting the related code together
var positionAttributeLocation = gl.getAttribLocation(program, "a_position"); // memory position ?
# setting up how to get data from buffer to a_position
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // this was done above as well ?
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2; // 2 components per iteration
var type = gl.FLOAT; // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0; // start at the beginning of the buffer
# this bind the a_position to ARRAY_BUFFER and which is binded to positionBuffer, and also tells how to get the data from array buffer
gl.vertexAttribPointer(
positionAttributeLocation, size, type, normalize, stride, offset)
# finally LOL draw the data
var primitiveType = gl.TRIANGLES;
var offset = 0;
var count = 3; // buffer size(number of interation or number of vertices)
gl.drawArrays(primitiveType, offset, count);
summary
initialize
create vertex shader and fragment shader
create program (and use v.s. and f.s. inside it)
get positionAttributeLocation (get position of a_position(variable of webgl) in js)
create buffer
bind buffer to ARRAY_BUFFER
addData to buffer
set view Port so webgl can convert gl_position to pixels
draw
clear the canvas before drawing anything
gl.useProgram(program); //tell webgl to use this program
tell webgl how to get input from buffer
draw command