orep-js/sunpy/canvas/renderer.js
2020-04-21 15:55:56 +02:00

94 lines
2.4 KiB
JavaScript

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";
import { Entity } from "./entity.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.entities = [];
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(entity) {
if (!(entity instanceof Entity))
throw TypeError("entity must be instance of `Entity`");
this.entities.push(entity);
}
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 entity of this.entities) {
await entity.render(this);
}
}
}