import { initBuffers } from "./init-buffers.js"; import { drawScene } from "./draw-scene.js"; main(); // Initialize a shader program, so WebGL knows how to draw our data function initShaderProgram(gl, vsSource, fsSource) { const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); // Create the shader program const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); // If creating the shader program failed, alert if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { alert( `Unable to initialize the shader program: ${gl.getProgramInfoLog( program, )}`, ); return null; } return program; } // Creates a shader of the given type, uploads the source and compiles function loadShader(gl, type, source) { const shader = gl.createShader(type); // Send the source to the shader object gl.shaderSource(shader, source); // Compile the shader program gl.compileShader(shader); // See if it compiled successfully if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { gl.deleteShader(shader); throw new Error(`An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`); } return shader; } function renderShader(gl, vsSource, fsSource) { const shaderProgram = initShaderProgram(gl, vsSource, fsSource); // Collect all the info needed to use the shader program. // Look up which attribute our shader program is using // for aVertexPosition and look up uniform locations. const programInfo = { program: shaderProgram, attribLocations: { vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"), }, uniformLocations: { resolution: gl.getUniformLocation(shaderProgram, "u_resolution"), time: gl.getUniformLocation(shaderProgram, "u_time"), }, }; // Here's where we call the routine that builds all the // objects we'll be drawing. const buffers = initBuffers(gl); // Draw the scene // drawScene(gl, programInfo, buffers, 0); const fpsLimit = 30; const fpsDelta = 1000 / 30; // let timePrev = 0; // requestAnimationFrame asks the browser to call render, // providing the time in milliseconds since the page loaded function render(time) { time *= 0.001; // convert to seconds // delta = time - timePrev; drawScene(gl, programInfo, buffers, time); setTimeout(() => requestAnimationFrame(render), fpsDelta); } function update() { requestAnimationFrame(render); } // XXX: TODO: read this guide it's great! https://stackoverflow.com/questions/56998225/why-is-rendering-blurred-in-webgl // window.addEventListener('resize', render); requestAnimationFrame(render); // update(); // setInterval(update, 1000 / fpsLimit); } function fetchShader(name) { return fetch(`../shaders/${name}`) .then(res => { if (!res.ok) throw new Error(`Failed to load fragment shader source ${url}: ${res.status}`); return res.text(); }); } function main() { const canvas = document.querySelector("#gl-canvas"); // Initialize the GL context const gl = canvas.getContext("webgl"); // XXX: TODO: use `window.addEventListener('resize', ...);` canvas.setAttribute('width', window.innerWidth); canvas.setAttribute('height', window.innerHeight); // Only continue if WebGL is available and working if (gl === null) { throw new Error("Unable to initialize WebGL. Your browser or machine may not support it."); } // Vertex shader program const vsSource = ` attribute vec4 aVertexPosition; void main() { gl_Position = aVertexPosition; } `; // Fetch fragment shader program fetchShader("segfault.glsl") .then(fsSource => { renderShader(gl, vsSource, fsSource); }); }