import { initBuffers } from "./init-buffers.js"; import { drawScene } from "./draw-scene.js"; export { run }; // 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; } 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); const fpsLimit = 30; const fpsDelta = 1000 / fpsLimit; // 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 run(canvas) { 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("fbm.glsl") .then(fsSource => { renderShader(gl, vsSource, fsSource); }); }