import { initBuffers } from "./init-buffers.js"; import { drawScene } from "./draw-scene.js"; main(); /* XXX: TODO: Avoid using alerts! Check return values instead, * XXX: TODO: or create/use a Result like object. */ // 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)) { alert( `An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`, ); gl.deleteShader(shader); return null; } return shader; } function main() { const canvas = document.querySelector("#gl-canvas"); // Initialize the GL context const gl = canvas.getContext("webgl"); // Only continue if WebGL is available and working if (gl === null) { alert( "Unable to initialize WebGL. Your browser or machine may not support it.", ); return; } // Vertex shader program const vsSource = ` attribute vec4 aVertexPosition; void main() { gl_Position = aVertexPosition; } `; // const fsSource = ` // // is highp wasteful for this shader? // #ifdef GL_FRAGMENT_PRECISION_HIGH // precision highp float; // #else // precision mediump float; // #endif // // shadertoy-like parameters // // uniform vec2 uResolution; // uniform float uTime; // void main() { // vec2 uv = gl_FragCoord.xy/vec2(300, 300).xy; // // Time varying pixel color // vec3 col = 0.5 + 0.5*cos(uTime+uv.xyx+vec3(0,2,4)); // // Output to screen // gl_FragColor = vec4(col,1.0); // // gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // } // `; const fsSource = (async () => { const res = await fetch("../shaders/segfault.glsl"); if (!res.ok) { const error = `Failed to load fragment shader source ${url}: ${res.status}`; alert(error); throw new Error(error); } return await res.text() })(); 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: context.getUniformLocation(program, "uResolution"), time: gl.getUniformLocation(shaderProgram, "uTime"), }, }; // 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); // 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 // deltaTime = time - prevTime; // prevTime = time; drawScene(gl, programInfo, buffers, time); requestAnimationFrame(render); } requestAnimationFrame(render); }