import { showError } from "./debug"; import "./style.css"; import vsSource from "./shaders/basic.vert?raw"; import fsSource from "./shaders/basic.frag?raw"; import { loadBuffer, loadProgram, loadShader } from "./utils/shader"; import Vector2D from "./geometry/Vector2D"; import { createBasicVao } from "./utils/vao"; import Shape2D from "./geometry/Shape2D"; import outline from "./data/letter_outline.json"; function render() { const canvas = document.querySelector("#canvas"); if (!canvas) { throw new Error("Canvas does not exist"); } const gl = canvas.getContext("webgl2"); if (!gl) { throw new Error("This browser does not support WebGL 2"); } const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); const program = loadProgram(gl, vertexShader, fragmentShader); gl.useProgram(program); const vertexPositionAttribLocation = gl.getAttribLocation(program, "vertexPosition"); if (vertexPositionAttribLocation < 0) { throw new Error("Failed to get attrib location for vertexPosition"); } const kVerts = new Float32Array(outline.k.vertices); const kBuffer = loadBuffer(gl, kVerts); const kVao = createBasicVao(gl, kBuffer, vertexPositionAttribLocation); const eVerts = new Float32Array(outline.e.vertices); const eBuffer = loadBuffer(gl, eVerts); const eVao = createBasicVao(gl, eBuffer, vertexPositionAttribLocation); const aVerts = new Float32Array(outline.a.vertices); const aBuffer = loadBuffer(gl, aVerts); const aVao = createBasicVao(gl, aBuffer, vertexPositionAttribLocation); const shapes: Shape2D[] = [ new Shape2D(new Vector2D(300, canvas.height/2), 200, [0.22745, 0.35294, 0.25098], kVerts.length / 2, kVao, gl.LINES), new Shape2D(new Vector2D(600, canvas.height/2), 200, [0.22745, 0.35294, 0.25098], eVerts.length / 2, eVao, gl.LINES), new Shape2D(new Vector2D(900, canvas.height/2), 200, [0.22745, 0.35294, 0.25098], aVerts.length / 2, aVao, gl.LINES), ] const fragmentColorUniform = gl.getUniformLocation(program, "uColor"); const canvasSizeUniform = gl.getUniformLocation(program, "uCanvasSize"); const shapeLocationUniform = gl.getUniformLocation(program, "uLocation"); const shapeScaleUniform = gl.getUniformLocation(program, "uScale"); if (!(fragmentColorUniform && canvasSizeUniform && shapeLocationUniform && shapeScaleUniform)) { throw new Error(`Some uniform not found: ${fragmentColorUniform ? "" : "uColor"}; ${canvasSizeUniform ? "" : "uCanvasSize"}; ${shapeLocationUniform ? "" : "uLocation"}; ${shapeScaleUniform ? "" : "uScale"}; `); } const frame = () => { canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; gl.clearColor(0.1, 0.1, 0.1, 1.0); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.viewport(0, 0, canvas.width, canvas.height); gl.uniform2f(canvasSizeUniform, canvas.width, canvas.height); shapes.forEach((shape) => { gl.uniform3f(fragmentColorUniform, shape.color[0], shape.color[1], shape.color[2]); gl.uniform2f(shapeLocationUniform, shape.position.x, shape.position.y); gl.uniform1f(shapeScaleUniform, shape.scale); gl.bindVertexArray(shape.vao); gl.drawArrays(shape.renderType, 0, shape.verticesCount); }); } requestAnimationFrame(frame); } try { render(); } catch (err) { showError(err); }