import { register } from "../node/node.js"; import { PropertyNode } from "../node/nodes/propertynode.js"; import { PropertyReader, Property } from "../node/propertyreader.js"; import { sleep } from "../core/utils.js"; import { Vector } from "../core/vector.js"; register("canvas", initRenderNode); function initRenderNode(node) { const renderNode = new RenderNode(node); renderNode.start(); window.a = renderNode; } const propertyReader = new PropertyReader( new Property("size", "800x600", (v) => new Vector(Int32Array, ...v.split("x").map(x => parseInt(x)))), new Property("fps", "60", (v) => parseInt(v)), ); export class RenderNode extends PropertyNode { constructor(node) { super(node, document.createElement("canvas"), propertyReader); this.gl = this.node.getContext("webgl"); if (!this.gl) throw Error("Unable to initialize webgl"); this.gl.clearDepth(1.0); this.gl.enable(this.gl.DEPTH_TEST); this.gl.depthFunc(this.gl.LEQUAL); this.fps = 0; this.objects = []; this.running = false; } get width() { return this.node.width; } get height() { return this.node.height; } start() { this.running = true; this.loop(); } stop() { this.running = false; } add(object) { if (!(object instanceof Renderable)) throw TypeError("Object must be instance of Renderable"); this.objects.push(object); } async loop() { // TODO: Fix all variables let ts = Date.now(); let tsf = ts; let frames = 0; while (this.running) { await this.render(); let tsn = Date.now(); let ms = tsn - ts; // delta let s = 1000 / this.properties.fps - ms; ts = tsn + s; frames++; if ((frames %= this.properties.fps) == 0) { this.fps = (1000 / (tsn - tsf)) * this.properties.fps; tsf = tsn; //console.log(this.node, this.fps); } await sleep(s); } } async render() { this.gl.clearColor(0.0, 0.0, 0.0, 1.0); this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); for (const object of this.objects) { await object.render(this); } } } export class Renderable { constructor() { } async render(renderNode) { } }