93 lines
3.4 KiB
TypeScript
93 lines
3.4 KiB
TypeScript
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<HTMLCanvasElement>("#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);
|
|
} |