canvas#webgl
View Compiled
html,
body {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
background: #000;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
// πΌοΈ Get Canvas
let canvas: HTMLCanvasElement = document.getElementById('webgl') as HTMLCanvasElement;
canvas.width = canvas.height = 640;
// βͺ Initialization
let gl: WebGLRenderingContext = canvas.getContext('webgl');
if (!gl) {
// This rendering engine failed to start...
throw new Error('WebGL failed to initialize.');
}
// Most WebGL Apps will want to enable these settings:
// β« Set the default clear color when calling `gl.clear`
gl.clearColor(0.0, 0.0, 0.0, 0.0);
// π Write to all channels during a clear
gl.colorMask(true, true, true, true)
// π Test if when something is drawn, it's in front of what was drawn previously
gl.enable(gl.DEPTH_TEST);
// β€ Use this function to test depth values
gl.depthFunc(gl.LEQUAL);
// π Hide triangles who's normals don't face the camera
gl.cullFace(gl.BACK);
// π₯ Properly blend images with alpha channels
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// π Position Vertex Buffer Data
const positions = new Float32Array([
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
0.0, 1.0, 0.0
]);
// π¨ Color Vertex Buffer Data
const colors = new Float32Array([
1.0, 0.0, 0.0, // π΄
0.0, 1.0, 0.0, // π’
0.0, 0.0, 1.0 // π΅
]);
// β Declare Vertex Buffer Handles
let positionBuffer: WebGLBuffer = null;
let colorBuffer: WebGLBuffer = null;
// π Helper function for creating WebGLBuffer(s) out of Typed Arrays
let createBuffer = (arr) => {
// βͺ Create Buffer
let buf = gl.createBuffer();
let bufType =
arr instanceof Uint16Array || arr instanceof Uint32Array ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
// π©Ή Bind Buffer to WebGLState
gl.bindBuffer(bufType, buf);
// πΎ Push data to VBO
gl.bufferData(bufType, arr, gl.STATIC_DRAW);
return buf;
};
// βͺ Create VBO
positionBuffer = createBuffer(positions);
colorBuffer = createBuffer(colors);
// ποΈ Index Buffer Data
const indices = new Uint16Array([ 0, 1, 2 ]);
// β Declare Index Buffer Handle
let indexBuffer: WebGLBuffer = null;
// βͺ Create IBO (β Refer to helper function above)
indexBuffer = createBuffer(indices);
// β Declare Vertex Shader Handle
let vertModule: WebGLShader = null;
// πΈοΈ Vertex Shader Source
const vertShaderCode = `
attribute vec3 inPosition;
attribute vec3 inColor;
varying vec3 vColor;
void main()
{
vColor = inColor;
gl_Position = vec4(inPosition, 1.0);
}
`;
// π Helper function for creating WebGLShader(s) out of strings
let createShader = (source: string, stage) => {
// βͺ Create Shader
let s = gl.createShader(stage);
// π° Pass Vertex Shader String
gl.shaderSource(s, source);
// π¨ Compile Vertex Shader (and check for errors)
gl.compileShader(s);
// β Check if shader compiled correctly
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shader: ' + gl.getShaderInfoLog(s));
}
return s;
};
vertModule = createShader(vertShaderCode, gl.VERTEX_SHADER);
// β Declare Vertex Shader Handle
let fragModule: WebGLShader = null;
// π¦ Fragment Shader Source
const fragShaderCode = `
precision mediump float;
varying highp vec3 vColor;
void main()
{
gl_FragColor = vec4(vColor, 1.0);
}
`;
// βοΈ Refer to vertex sample above
fragModule = createShader(fragShaderCode, gl.FRAGMENT_SHADER);
// β Declare Program Handle
let program: WebGLProgram = null;
// π Helper function for creating WebGLProgram(s) out of WebGLShader(s)
let createProgram = (stages: WebGLShader[]) => {
let p = gl.createProgram();
for (let stage of stages) {
gl.attachShader(p, stage);
}
gl.linkProgram(p);
return p;
};
program = createProgram([vertModule, fragModule]);
// β Declare animation handler
let animationHandler: number = 0;
// πΊ Render triangle
let render = () => {
// ποΈ Encode drawing commands
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(program);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.scissor(0, 0, canvas.width, canvas.height);
// Bind Vertex Layout
let setVertexBuffer = (buf: WebGLBuffer, name: string) => {
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
let loc = gl.getAttribLocation(program, name);
gl.vertexAttribPointer(loc, 3, gl.FLOAT, false, 4 * 3, 0);
gl.enableVertexAttribArray(loc);
};
setVertexBuffer(positionBuffer, 'inPosition');
setVertexBuffer(colorBuffer, 'inColor');
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
// βΏ Refresh canvas
animationHandler = requestAnimationFrame(render);
};
// ποΈ Start the Rendering Engine
render();
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.