WEBGL PROGRAMS
1. Five sequential steps followed to draw a simple triangle using WebGL
<!doctype html>
<html>
<body>
<canvas width = "300" height = "300" id =
"my_Canvas"></canvas>
<script>
/* Step1: Prepare the canvas and get WebGL
context */
var canvas =
document.getElementById('my_Canvas');
var gl = canvas.getContext('experimental-
webgl');
/* Step2: Define the geometry and store it in
buffer objects */
var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0,
-0.5,];
// Create a new buffer object
var vertex_buffer = gl.createBuffer();
// Bind an empty array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
// Pass the vertices data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new
Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
/* Step3: Create and compile Shader programs
*/
// Vertex shader source code
var vertCode =
'attribute vec2 coordinates;' +
'void main(void) {' + ' gl_Position =
vec4(coordinates,0.0, 1.0);' + '}';
//Create a vertex shader object
var vertShader =
gl.createShader(gl.VERTEX_SHADER);
//Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
//Compile the vertex shader
gl.compileShader(vertShader);
//Fragment shader source code
var fragCode = 'void main(void) {' +
'gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' + '}';
// Create fragment shader object
var fragShader =
gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragment shader
gl.compileShader(fragShader);
// Create a shader program object to store
combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram, vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram, fragShader);
// Link both programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
/* Step 4: Associate the shader programs to
buffer objects */
//Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
//Get the attribute location
var coord =
gl.getAttribLocation(shaderProgram, "coordinates");
//point an attribute to the currently bound
VBO
gl.vertexAttribPointer(coord, 2, gl.FLOAT,
false, 0, 0);
//Enable the attribute
gl.enableVertexAttribArray(coord);
/* Step5: Drawing the required object (triangle)
*/
// Clear the canvas
gl.clearColor(0.5, 0.5, 0.5, 0.9);
// Enable the depth test
gl.enable(gl.DEPTH_TEST);
// Clear the color buffer bit
gl.clear(gl.COLOR_BUFFER_BIT);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>
2. The following example shows how to create a canvas element with the
dimensions 500 × 500. We have created a border to the canvas using CSS for
visibility.
<!DOCTYPE HTML>
<html>
<head>
<style>
#mycanvas{border:1px solid blue;}
</style>
</head>
<body>
<canvas id = "mycanvas" width = "300" height =
"300"></canvas>
</body>
</html>
3. The following example shows how to draw three parallel lines using gl.LINES.
<!doctype html>
<html>
<body>
<canvas width = "300" height = "300" id =
"my_Canvas"></canvas>
<script>
/*======= Creating a canvas =========*/
var canvas =
document.getElementById('my_Canvas');
var gl = canvas.getContext('experimental-
webgl');
/*======= Defining and storing the
geometry ======*/
var vertices = [
-0.7,-0.1,0,
-0.3,0.6,0,
-0.3,-0.3,0,
0.2,0.6,0,
0.3,-0.3,0,
0.7,0.6,0
]
// Create an empty buffer object
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new
Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
/*=================== Shaders
====================*/
// Vertex shader source code
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates,
1.0);' +
'}';
// Create a vertex shader object
var vertShader =
gl.createShader(gl.VERTEX_SHADER);
// Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
// Compile the vertex shader
gl.compileShader(vertShader);
// Fragment shader source code
var fragCode =
'void main(void) {' +
'gl_FragColor = vec4(0.0, 0.0, 0.0,
0.1);' +
'}';
// Create fragment shader object
var fragShader =
gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragmentt shader
gl.compileShader(fragShader);
// Create a shader program object to store
// the combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram,
vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram,
fragShader);
// Link both the programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
/*======= Associating shaders to buffer
objects ======*/
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
// Get the attribute location
var coord =
gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently
bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT,
false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
/*============ Drawing the triangle
=============*/
// Clear the canvas
gl.clearColor(0.5, 0.5, 0.5, 0.9);
// Enable the depth test
gl.enable(gl.DEPTH_TEST);
// Clear the color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT |
gl.DEPTH_BUFFER_BIT);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawArrays(gl.LINES, 0, 6);
// POINTS, LINE_STRIP, LINE_LOOP, LINES,
// TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES
</script>
</body>
</html>
4. The following program shows how to create a WebGL application to draw a
quadrilateral.
<!doctype html>
<html>
<body>
<canvas width = "570" height = "570" id =
"my_Canvas"></canvas>
<script>
/*============ Creating a canvas
=================*/
var canvas =
document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-
webgl');
/*========== Defining and storing the
geometry =========*/
var vertices = [
-0.5,0.5,0.0,
-0.5,-0.5,0.0,
0.5,-0.5,0.0,
0.5,0.5,0.0
];
indices = [3,2,1,3,1,0];
// Create an empty buffer object to store
vertex buffer
var vertex_buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new
Float32Array(vertices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, null);
// Create an empty buffer object to store
Index buffer
var Index_Buffer = gl.createBuffer();
// Bind appropriate array buffer to it
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,
Index_Buffer);
// Pass the vertex data to the buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new
Uint16Array(indices), gl.STATIC_DRAW);
// Unbind the buffer
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,
null);
/*====================== Shaders
=======================*/
// Vertex shader source code
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates,
1.0);' +
'}';
// Create a vertex shader object
var vertShader =
gl.createShader(gl.VERTEX_SHADER);
// Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
// Compile the vertex shader
gl.compileShader(vertShader);
// Fragment shader source code
var fragCode =
'void main(void) {' +
' gl_FragColor = vec4(0.0, 0.0, 0.0,
0.1);' +
'}';
// Create fragment shader object
var fragShader =
gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragmentt shader
gl.compileShader(fragShader);
// Create a shader program object to
// store the combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram, vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram, fragShader);
// Link both the programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
/* ======= Associating shaders to buffer
objects =======*/
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER,
vertex_buffer);
// Bind index buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,
Index_Buffer);
// Get the attribute location
var coord =
gl.getAttribLocation(shaderProgram, "coordinates");
// Point an attribute to the currently bound
VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT,
false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
/*============= Drawing the Quad
================*/
// Clear the canvas
gl.clearColor(0.5, 0.5, 0.5, 0.9);
// Enable the depth test
gl.enable(gl.DEPTH_TEST);
// Clear the color buffer bit
gl.clear(gl.COLOR_BUFFER_BIT);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
// Draw the triangle
gl.drawElements(gl.TRIANGLES,
indices.length, gl.UNSIGNED_SHORT,0);
</script>
</body>
</html>
5. Translation of a triangle
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Translation in WebGL</title>
</head>
<body>
<canvas id="glCanvas" width="800" height="400"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec2 aVertexPosition;
uniform vec2 uTranslation;
void main() {
gl_Position = vec4(aVertexPosition + uTranslation, 0.0, 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White color
}
</script>
<script>
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('Unable to initialize WebGL. Your browser may not
support it.');
}
const originalVertices = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
];
const translation = [0.0, 0.0]; // Translation vector
const vertexShaderSource =
document.querySelector('#vertexShader').textContent;
const fragmentShaderSource =
document.querySelector('#fragmentShader').textContent;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('Vertex shader compilation failed:',
gl.getShaderInfoLog(vertexShader));
}
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('Fragment shader compilation failed:',
gl.getShaderInfoLog(fragmentShader));
}
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.error('Shader program linking failed:',
gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram,
'aVertexPosition');
const translationUniformLocation =
gl.getUniformLocation(shaderProgram, 'uTranslation');
const originalVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, originalVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(originalVertices),
gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0,
0);
gl.enableVertexAttribArray(positionAttributeLocation);
// Clear canvas
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw original triangle
gl.uniform2fv(translationUniformLocation, translation);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Translate triangle
translation[0] = 0.5; // Translation along x-axis
// Draw translated triangle
gl.uniform2fv(translationUniformLocation, translation);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>
6. Scaling a Triangle
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scaling in WebGL</title>
</head>
<body>
<canvas id="glCanvas" width="800" height="400"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec2 aVertexPosition;
uniform vec2 uScale;
void main() {
// Apply scaling
vec2 scaledPosition = aVertexPosition * uScale;
gl_Position = vec4(scaledPosition, 0.0, 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White color
}
</script>
<script>
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('Unable to initialize WebGL. Your browser may not support
it.');
}
const originalVertices = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
];
let scale = [1.0, 1.0]; // Scale vector
const vertexShaderSource =
document.querySelector('#vertexShader').textContent;
const fragmentShaderSource =
document.querySelector('#fragmentShader').textContent;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('Vertex shader compilation failed:',
gl.getShaderInfoLog(vertexShader));
}
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('Fragment shader compilation failed:',
gl.getShaderInfoLog(fragmentShader));
}
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.error('Shader program linking failed:',
gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram,
'aVertexPosition');
const scaleUniformLocation = gl.getUniformLocation(shaderProgram,
'uScale');
const originalVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, originalVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(originalVertices),
gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
// Clear canvas
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw original triangle
gl.uniform2fv(scaleUniformLocation, scale);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Scale triangle
scale = [0.5, 2.0]; // Scale along x and y axes
// Draw scaled triangle
gl.uniform2fv(scaleUniformLocation, scale);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>
7. Rotation of Triangle
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rotation in WebGL</title>
</head>
<body>
<canvas id="glCanvas" width="800" height="400"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec2 aVertexPosition;
uniform float uRotationAngle;
void main() {
// Apply rotation
float angle = uRotationAngle * 3.14159 / 180.0;
float cosAngle = cos(angle);
float sinAngle = sin(angle);
vec2 rotatedPosition = vec2(
aVertexPosition.x * cosAngle - aVertexPosition.y * sinAngle,
aVertexPosition.x * sinAngle + aVertexPosition.y * cosAngle
);
gl_Position = vec4(rotatedPosition, 0.0, 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // White color
}
</script>
<script>
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('Unable to initialize WebGL. Your browser may not support it.');
}
const originalVertices = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5,
];
let rotationAngle = 45; // Rotation angle in degrees
const vertexShaderSource =
document.querySelector('#vertexShader').textContent;
const fragmentShaderSource =
document.querySelector('#fragmentShader').textContent;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.error('Vertex shader compilation failed:',
gl.getShaderInfoLog(vertexShader));
}
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.error('Fragment shader compilation failed:',
gl.getShaderInfoLog(fragmentShader));
}
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.error('Shader program linking failed:',
gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram,
'aVertexPosition');
const rotationUniformLocation = gl.getUniformLocation(shaderProgram,
'uRotationAngle');
const originalVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, originalVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(originalVertices),
gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
// Clear canvas
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw original triangle
gl.uniform1f(rotationUniformLocation, 0); // No rotation
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Draw rotated triangle
gl.uniform1f(rotationUniformLocation, rotationAngle);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>