Last active
June 15, 2023 08:35
-
-
Save janispritzkau/d9370d56d65eda9993391fda56fd29c6 to your computer and use it in GitHub Desktop.
Simple WebGL example with basic error handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const canvas = document.querySelector("canvas") | |
canvas.width = 800, canvas.height = 600 | |
canvas.style.width = `${canvas.width / devicePixelRatio}px` | |
const gl = canvas.getContext("webgl") | |
const vertexShader = gl.createShader(gl.VERTEX_SHADER) | |
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER) | |
gl.shaderSource(vertexShader, ` | |
attribute vec4 position; | |
void main() { | |
gl_Position = position; | |
} | |
`) | |
gl.shaderSource(fragmentShader, ` | |
precision highp float; | |
uniform float time; | |
uniform vec2 resolution; | |
void main() { | |
vec2 uv = gl_FragCoord.xy / resolution.xy; | |
gl_FragColor = vec4(0.5 + 0.5 * cos(time + uv.xyx + vec3(0, 2, 4)), 1); | |
} | |
`) | |
const program = gl.createProgram() | |
for (const shader of [vertexShader, fragmentShader]) { | |
gl.compileShader(shader) | |
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
throw new Error(gl.getShaderInfoLog(shader)) | |
} | |
gl.attachShader(program, shader) | |
} | |
gl.linkProgram(program) | |
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { | |
throw new Error(gl.getProgramInfoLog(program)) | |
} | |
gl.useProgram(program) | |
const buffer = gl.createBuffer() | |
gl.bindBuffer(gl.ARRAY_BUFFER, buffer) | |
const posAttr = gl.getAttribLocation(program, "position"); | |
gl.enableVertexAttribArray(posAttr) | |
gl.vertexAttribPointer(posAttr, 2, gl.FLOAT, false, 0, 0) | |
// pass resolution to shader as global variable | |
gl.uniform2f(gl.getUniformLocation(program, "resolution"), canvas.width, canvas.height) | |
// add time uniform for animation | |
const timeU = gl.getUniformLocation(program, "time") | |
const array = new Float32Array([ | |
-1, -1, -1, 1, 1, -1, | |
1, -1, 1, 1, 0, 0 | |
]) | |
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW) | |
function frame() { | |
gl.clearColor(0, 0, 0, 0) | |
gl.clear(gl.COLOR_BUFFER_BIT) | |
gl.uniform1f(timeU, performance.now() / 1000) | |
gl.drawArrays(gl.TRIANGLES, 0, array.length / 2) | |
const error = gl.getError() | |
if (error) throw new Error(`WebGL error code: ${error}`) | |
requestAnimationFrame(frame) | |
} | |
requestAnimationFrame(frame) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment