104 lines
2.5 KiB
JavaScript
104 lines
2.5 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";
|
|
|
|
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) {
|
|
|
|
}
|
|
} |