Skip to content

Instantly share code, notes, and snippets.

@jdmichaud
Last active November 6, 2018 19:38
Show Gist options
  • Save jdmichaud/660e55bf80272ff8fedd9bc08c220b69 to your computer and use it in GitHub Desktop.
Save jdmichaud/660e55bf80272ff8fedd9bc08c220b69 to your computer and use it in GitHub Desktop.
WebGL Hello World !
window.onload = function () {
// Create the canvas
const canvas = document.createElement('canvas');
canvas.width = canvas.height = 512;
document.body.appendChild(canvas)
const gl = canvas.getContext("webgl");
// Set clear color to black, fully opaque
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Create vertex shader
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const vertexShaderSource = `
attribute vec4 aVertexPosition;
attribute vec2 aTextureCoord;
varying highp vec2 vTextureCoord;
void main() {
gl_Position = aVertexPosition;
vTextureCoord = aTextureCoord;
}
`;
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
// Create fragment shader
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
const fragmentShaderSource = `
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// Create the shader program
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
// Create the image plane
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [ -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 ];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// Create bindings
const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
// Prepare the vertex position to be loaded into the GPU
gl.vertexAttribPointer(
vertexPosition,
2, // pull out 2 values per iteration
gl.FLOAT, // the data in the buffer is 32bit floats
false, // don't normalize
0, // how many bytes to get from one set of values to the next
0, // how many bytes inside the buffer to start from
);
gl.enableVertexAttribArray(vertexPosition)
// Texture
// Retrieve image from url
const image = new Image();
image.crossOrigin = 'anonymous'; // ask for CORS permission
image.onload = function() {
document.body.appendChild(image);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Load the image in GPU memory
gl.texImage2D(
gl.TEXTURE_2D,
0, // level
gl.RGBA, // internalFormat,
gl.RGBA, // srcFormat
gl.UNSIGNED_BYTE, // srcType
image, // image
);
// Dimensions are powers of 2. Generate mips.
gl.generateMipmap(gl.TEXTURE_2D);
// Texture loading boilerplate
gl.activeTexture(gl.TEXTURE0);
const uSampler = gl.getUniformLocation(shaderProgram, 'uSampler');
gl.uniform1i(uSampler, 0);
// Create the texture coordinates
const textureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
const textureCoordinates = [ 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 ];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
const textureCoord = gl.getAttribLocation(shaderProgram, 'aTextureCoord');
gl.vertexAttribPointer(textureCoord, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(textureCoord);
// Draw the scene
const offset = 0;
const vertexCount = 6;
gl.drawArrays(
gl.TRIANGLES,
offset, // offset
vertexCount, // vertexCount
);
}
image.onerror = function () { console.log('error loading texture'); }
// https://www.the.me/wp-content/uploads/2014/08/story_lena_lenna_1.jpg
image.src = 'story_lena_lenna_1.jpg';
}
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const texture = gl.createTexture();
const frame = new Uint8Array(512 * 512 * 256 * 4);
gl.bindTexture(gl.TEXTURE_2D, texture);
console.log('loading texture...');
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 8192, 8192, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
canvas = document.createElement('canvas');
gl = canvas.getContext('webgl');
const textures = Array.from({ length: 256 }, _ => gl.createTexture());
const data = Array.from({length: 512 * 512 * 4}, _ => Math.floor(Math.random() * 100));
const frame = new Uint8Array(data);
const then = performance.now();
textures.forEach((texture, index) => {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 512, 512, 0, gl.RGBA, gl.UNSIGNED_BYTE, frame);
});
console.log(`textures loaded in ${(performance.now() - then).toFixed(2)}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment