Move rendering functions into prosperon
This commit is contained in:
parent
f1813a046a
commit
cadf10b3a9
|
@ -110,6 +110,7 @@ var sprite = {
|
||||||
if (!self.gameobject) return;
|
if (!self.gameobject) return;
|
||||||
//self.path = playing.path;
|
//self.path = playing.path;
|
||||||
self.frame = playing.frames[f].rect;
|
self.frame = playing.frames[f].rect;
|
||||||
|
self.rect = [self.frame.x, self.frame.y, self.frame.w, self.frame.h];
|
||||||
f = (f+1)%playing.frames.length;
|
f = (f+1)%playing.frames.length;
|
||||||
if (f === 0) {
|
if (f === 0) {
|
||||||
self.anim_done?.();
|
self.anim_done?.();
|
||||||
|
@ -133,6 +134,8 @@ var sprite = {
|
||||||
this._p = p;
|
this._p = p;
|
||||||
this.del_anim?.();
|
this.del_anim?.();
|
||||||
this.texture = game.texture(p);
|
this.texture = game.texture(p);
|
||||||
|
this.diffuse = this.texture;
|
||||||
|
this.rect = [0,0,1,1];
|
||||||
|
|
||||||
var anim = SpriteAnim.make(p);
|
var anim = SpriteAnim.make(p);
|
||||||
if (!anim) return;
|
if (!anim) return;
|
||||||
|
@ -140,6 +143,7 @@ var sprite = {
|
||||||
this.play();
|
this.play();
|
||||||
|
|
||||||
this.pos = this.dimensions().scale(this.anchor);
|
this.pos = this.dimensions().scale(this.anchor);
|
||||||
|
|
||||||
},
|
},
|
||||||
get path() {
|
get path() {
|
||||||
return this._p;
|
return this._p;
|
||||||
|
@ -179,6 +183,7 @@ var sprite = {
|
||||||
globalThis.allsprites = {};
|
globalThis.allsprites = {};
|
||||||
sprite.make = function(go)
|
sprite.make = function(go)
|
||||||
{
|
{
|
||||||
|
var sp = Object.create(sprite);
|
||||||
sp.go = go;
|
sp.go = go;
|
||||||
sp.gameobject = go;
|
sp.gameobject = go;
|
||||||
sp.guid = prosperon.guid();
|
sp.guid = prosperon.guid();
|
||||||
|
|
|
@ -296,6 +296,31 @@ game.engine_start = function(s) {
|
||||||
Object.readonly(window.__proto__, 'high_dpi');
|
Object.readonly(window.__proto__, 'high_dpi');
|
||||||
Object.readonly(window.__proto__, 'sample_count');
|
Object.readonly(window.__proto__, 'sample_count');
|
||||||
s();
|
s();
|
||||||
|
|
||||||
|
shape.quad = {
|
||||||
|
pos:os.make_buffer([
|
||||||
|
0,0,0,
|
||||||
|
1,0,0,
|
||||||
|
0,1,0,
|
||||||
|
1,1,0
|
||||||
|
],0),
|
||||||
|
verts: 4,
|
||||||
|
uv: os.make_buffer([0,1,1,1,0,0,1,0],2),
|
||||||
|
index: os.make_buffer([0,1,2,2,1,3], 1),
|
||||||
|
count: 6
|
||||||
|
};
|
||||||
|
|
||||||
|
shape.triangle = {
|
||||||
|
pos: os.make_buffer([
|
||||||
|
0,0,0,
|
||||||
|
0.5,1,0,
|
||||||
|
1,0,0]
|
||||||
|
,0),
|
||||||
|
uv: os.make_buffer([0,0,0.5,1,1,0],2),
|
||||||
|
verts: 3,
|
||||||
|
count: 3,
|
||||||
|
index: os.make_buffer([0,2,1],1),
|
||||||
|
};
|
||||||
}, process);
|
}, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,30 +352,11 @@ function process()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
if (!game.camera)
|
prosperon.window_render();
|
||||||
prosperon.window_render(world.transform, 1);
|
prosperon.draw();
|
||||||
else
|
|
||||||
prosperon.window_render(game.camera.transform, game.camera.zoom);
|
|
||||||
|
|
||||||
//render.set_camera();
|
|
||||||
|
|
||||||
/*os.sprite_pipe();
|
|
||||||
allsprites.forEach(function(x) {
|
|
||||||
render.set_sprite_tex(x.texture);
|
|
||||||
x.draw(x.go);
|
|
||||||
render.sprite_flush();
|
|
||||||
});
|
|
||||||
render.sprite_flush();*/
|
|
||||||
prosperon.draw(); // draw calls
|
|
||||||
debug.draw(); // calls needed debugs
|
|
||||||
|
|
||||||
prosperon.hook3d?.();
|
|
||||||
|
|
||||||
prosperon.gui();
|
prosperon.gui();
|
||||||
prosperon.screengui();
|
prosperon.screengui();
|
||||||
|
|
||||||
prosperon.hookend?.();
|
prosperon.hookend?.();
|
||||||
//render.end_pass();
|
|
||||||
profile.addreport(profcache, "render frame", st);
|
profile.addreport(profcache, "render frame", st);
|
||||||
frames.push(profile.secs(profile.now()-startframe));
|
frames.push(profile.secs(profile.now()-startframe));
|
||||||
if (frames.length > 20) frames.shift();
|
if (frames.length > 20) frames.shift();
|
||||||
|
|
|
@ -44,6 +44,8 @@ var entity = {
|
||||||
return p;
|
return p;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
drawlayer: 0,
|
||||||
|
|
||||||
full_path() { return this.path_from(world); },
|
full_path() { return this.path_from(world); },
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
|
|
|
@ -144,4 +144,300 @@ render.cross.doc = "Draw a cross centered at pos, with arm length size.";
|
||||||
render.arrow.doc = "Draw an arrow from start to end, with wings of length wingspan at angle wingangle.";
|
render.arrow.doc = "Draw an arrow from start to end, with wings of length wingspan at angle wingangle.";
|
||||||
render.rectangle.doc = "Draw a rectangle, with its corners at lowerleft and upperright.";
|
render.rectangle.doc = "Draw a rectangle, with its corners at lowerleft and upperright.";
|
||||||
|
|
||||||
|
var shaderlang = {
|
||||||
|
macos: "metal_macos",
|
||||||
|
windows: "hlsl5",
|
||||||
|
linux: "glsl330",
|
||||||
|
web: "wgsl",
|
||||||
|
ios: "metal_ios",
|
||||||
|
}
|
||||||
|
|
||||||
|
var attr_map = {
|
||||||
|
a_pos: 0,
|
||||||
|
a_uv: 1,
|
||||||
|
a_norm: 2,
|
||||||
|
a_bone: 3,
|
||||||
|
a_weight: 4,
|
||||||
|
a_color: 5,
|
||||||
|
a_tan: 6,
|
||||||
|
a_angle: 7,
|
||||||
|
a_wh: 8,
|
||||||
|
a_st: 9,
|
||||||
|
a_ppos: 10,
|
||||||
|
a_scale: 11
|
||||||
|
}
|
||||||
|
|
||||||
|
var blend_map = {
|
||||||
|
mix: true,
|
||||||
|
none: false
|
||||||
|
}
|
||||||
|
|
||||||
|
var primitive_map = {
|
||||||
|
point: 1,
|
||||||
|
line: 2,
|
||||||
|
linestrip: 3,
|
||||||
|
triangle: 4,
|
||||||
|
trianglestrip: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
var cull_map = {
|
||||||
|
none: 1,
|
||||||
|
front: 2,
|
||||||
|
back: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
var depth_map = {
|
||||||
|
off: false,
|
||||||
|
on: true
|
||||||
|
}
|
||||||
|
|
||||||
|
var face_map = {
|
||||||
|
cw: 2,
|
||||||
|
ccw: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
render.poly_prim = function(verts)
|
||||||
|
{
|
||||||
|
var index = [];
|
||||||
|
if (verts.length < 1) return undefined;
|
||||||
|
|
||||||
|
for (var i = 0; i < verts.length; i++)
|
||||||
|
verts[i][2] = 0;
|
||||||
|
|
||||||
|
for (var i = 2; i < verts.length; i++) {
|
||||||
|
index.push(0);
|
||||||
|
index.push(i-1);
|
||||||
|
index.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
pos: os.make_buffer(verts.flat()),
|
||||||
|
verts: verts.length,
|
||||||
|
index: os.make_buffer(index, 1),
|
||||||
|
count: index.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function shader_directive(shader, name, map)
|
||||||
|
{
|
||||||
|
var reg = new RegExp(`#${name}.*`, 'g');
|
||||||
|
var mat = shader.match(reg);
|
||||||
|
if (!mat) return 0;
|
||||||
|
|
||||||
|
reg = new RegExp(`#${name}\s*`, 'g');
|
||||||
|
var ff = mat.map(d=>d.replace(reg,''))[0].trim();
|
||||||
|
|
||||||
|
return map[ff];
|
||||||
|
}
|
||||||
|
|
||||||
|
function global_uni(uni, stage)
|
||||||
|
{
|
||||||
|
switch(uni.name) {
|
||||||
|
case "time":
|
||||||
|
render.setuniv(stage, uni.slot, profile.secs(profile.now()));
|
||||||
|
return true;
|
||||||
|
case "projection":
|
||||||
|
render.setuniproj(stage, uni.slot);
|
||||||
|
return true;
|
||||||
|
case "view":
|
||||||
|
render.setuniview(stage, uni.slot);
|
||||||
|
return true;
|
||||||
|
case "vp":
|
||||||
|
render.setunivp(stage, uni.slot);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render.make_shader = function(shader)
|
||||||
|
{
|
||||||
|
var file = shader;
|
||||||
|
shader = io.slurp(shader);
|
||||||
|
var writejson = `${file.name()}_c.json`;
|
||||||
|
var st = profile.now();
|
||||||
|
|
||||||
|
breakme: if (io.exists(writejson)) {
|
||||||
|
var data = json.decode(io.slurp(writejson));
|
||||||
|
var filemod = io.mod(writejson);
|
||||||
|
if (!data.files) break breakme;
|
||||||
|
for (var i of data.files)
|
||||||
|
if (io.mod(i) > filemod)
|
||||||
|
break breakme;
|
||||||
|
|
||||||
|
profile.report(st, `CACHE make shader from ${file}`);
|
||||||
|
var shaderobj = json.decode(io.slurp(writejson));
|
||||||
|
shaderobj.pipe = render.pipeline(shaderobj);
|
||||||
|
return shaderobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
var out = `${file.name()}.shader`;
|
||||||
|
|
||||||
|
var files = [file];
|
||||||
|
|
||||||
|
var incs = shader.match(/#include <.*>/g);
|
||||||
|
if (incs)
|
||||||
|
for (var inc of incs) {
|
||||||
|
var filez = inc.match(/#include <(.*)>/)[1];
|
||||||
|
var macro = io.slurp(filez);
|
||||||
|
shader = shader.replace(inc, macro);
|
||||||
|
files.push(filez);
|
||||||
|
}
|
||||||
|
|
||||||
|
var blend = shader_directive(shader, 'blend', blend_map);
|
||||||
|
var primitive = shader_directive(shader, 'primitive', primitive_map);
|
||||||
|
var cull = shader_directive(shader, 'cull', cull_map);
|
||||||
|
var depth = shader_directive(shader, 'depth', depth_map);
|
||||||
|
var face = shader_directive(shader, 'face', face_map);
|
||||||
|
|
||||||
|
shader = shader.replace(/uniform\s+(\w+)\s+(\w+);/g, "uniform _$2 { $1 $2; };");
|
||||||
|
shader = shader.replace(/(texture2D|sampler) /g, "uniform $1 ");
|
||||||
|
shader = shader.replace(/uniform texture2D ?(.*);/g, "uniform _$1_size { vec2 $1_size; };\nuniform texture2D $1;");
|
||||||
|
|
||||||
|
io.slurpwrite(out, shader);
|
||||||
|
var backend = shaderlang[os.sys()];
|
||||||
|
var ret = os.system(`sokol-shdc -b -f bare_yaml --slang=${backend} -i ${out} -o ${out}`);
|
||||||
|
if (ret) {
|
||||||
|
console.info(`error compiling shader`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io.rm(out);
|
||||||
|
|
||||||
|
/* Take YAML and create the shader object */
|
||||||
|
var yamlfile = `${out}_reflection.yaml`;
|
||||||
|
console.info(`slurping ${yamlfile}`);
|
||||||
|
var obj = json.decode(yaml.tojson(io.slurp(yamlfile)));
|
||||||
|
io.rm(yamlfile);
|
||||||
|
|
||||||
|
obj = obj.shaders[0].programs[0];
|
||||||
|
function add_code(stage) {
|
||||||
|
console.info(json.encode(stage));
|
||||||
|
stage.code = io.slurp(stage.path);
|
||||||
|
io.rm(stage.path);
|
||||||
|
delete stage.path;
|
||||||
|
}
|
||||||
|
console.info(json.encode(obj));
|
||||||
|
add_code(obj.vs);
|
||||||
|
if (!obj.fs)
|
||||||
|
if (obj.vs.fs) {
|
||||||
|
obj.fs = obj.vs.fs;
|
||||||
|
delete obj.vs.fs;
|
||||||
|
}
|
||||||
|
add_code(obj.fs);
|
||||||
|
|
||||||
|
obj.blend = blend;
|
||||||
|
obj.cull = cull;
|
||||||
|
obj.primitive = primitive;
|
||||||
|
obj.depth = depth;
|
||||||
|
obj.face = face;
|
||||||
|
|
||||||
|
if (obj.vs.inputs)
|
||||||
|
for (var i of obj.vs.inputs) {
|
||||||
|
if (!(i.name in attr_map))
|
||||||
|
i.mat = -1;
|
||||||
|
else
|
||||||
|
i.mat = attr_map[i.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_unimap(stage) {
|
||||||
|
if (!stage.uniform_blocks) return {};
|
||||||
|
var unimap = {};
|
||||||
|
for (var uni of stage.uniform_blocks) {
|
||||||
|
if (uni.struct_name[0] == "_")
|
||||||
|
uni.struct_name = uni.struct_name.slice(1);
|
||||||
|
|
||||||
|
unimap[uni.struct_name] = {
|
||||||
|
name: uni.struct_name,
|
||||||
|
slot: Number(uni.slot),
|
||||||
|
size: Number(uni.size)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return unimap;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.vs.unimap = make_unimap(obj.vs);
|
||||||
|
obj.fs.unimap = make_unimap(obj.fs);
|
||||||
|
|
||||||
|
obj.files = files;
|
||||||
|
|
||||||
|
obj.name = file;
|
||||||
|
|
||||||
|
io.slurpwrite(writejson, json.encode(obj));
|
||||||
|
profile.report(st, `make shader from ${file}`);
|
||||||
|
|
||||||
|
console.info(`pipeline for ${file}`);
|
||||||
|
obj.pipe = render.pipeline(obj);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shader_unisize = {
|
||||||
|
4: render.setuniv,
|
||||||
|
8: render.setuniv2,
|
||||||
|
12: render.setuniv3,
|
||||||
|
16: render.setuniv4
|
||||||
|
};
|
||||||
|
|
||||||
|
render.shader_apply_material = function(shader, material = {})
|
||||||
|
{
|
||||||
|
for (var p in shader.vs.unimap) {
|
||||||
|
if (global_uni(shader.vs.unimap[p], 0)) continue;
|
||||||
|
if (!(p in material)) continue;
|
||||||
|
var s = shader.vs.unimap[p];
|
||||||
|
shader_unisize[s.size](0, s.slot, material[p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var p in shader.fs.unimap) {
|
||||||
|
if (global_uni(shader.fs.unimap[p], 1)) continue;
|
||||||
|
if (!(p in material)) continue;
|
||||||
|
var s = shader.fs.unimap[p];
|
||||||
|
shader_unisize[s.size](1, s.slot, material[p]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("diffuse_size" in shader.fs.unimap)
|
||||||
|
render.setuniv2(1, shader.fs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]);
|
||||||
|
|
||||||
|
if ("diffuse_size" in shader.vs.unimap)
|
||||||
|
render.setuniv2(0, shader.vs.unimap.diffuse_size.slot, [material.diffuse.width, material.diffuse.height]);
|
||||||
|
}
|
||||||
|
|
||||||
|
render.sg_bind = function(shader, mesh = {}, material = {}, ssbo)
|
||||||
|
{
|
||||||
|
var bind = {};
|
||||||
|
bind.attrib = [];
|
||||||
|
if (shader.vs.inputs)
|
||||||
|
for (var a of shader.vs.inputs) {
|
||||||
|
if (!(a.name in mesh)) {
|
||||||
|
if (!(a.name.slice(2) in mesh)) {
|
||||||
|
console.error(`cannot draw shader ${shader.name}; there is no attrib ${a.name} in the given mesh.`);
|
||||||
|
return undefined;
|
||||||
|
} else
|
||||||
|
bind.attrib.push(mesh[a.name.slice(2)]);
|
||||||
|
} else
|
||||||
|
bind.attrib.push(mesh[a.name]);
|
||||||
|
}
|
||||||
|
bind.images = [];
|
||||||
|
if (shader.fs.images)
|
||||||
|
for (var img of shader.fs.images) {
|
||||||
|
if (material[img.name])
|
||||||
|
bind.images.push(material[img.name]);
|
||||||
|
else
|
||||||
|
bind.images.push(game.texture("icons/no_tex.gif"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.index) {
|
||||||
|
bind.index = mesh.index;
|
||||||
|
bind.count = mesh.count;
|
||||||
|
} else
|
||||||
|
bind.count = mesh.verts;
|
||||||
|
|
||||||
|
bind.ssbo = [];
|
||||||
|
if (shader.vs.storage_buffers)
|
||||||
|
for (var b of shader.vs.storage_buffers)
|
||||||
|
bind.ssbo.push(ssbo);
|
||||||
|
|
||||||
|
return bind;
|
||||||
|
}
|
||||||
|
|
||||||
return {render};
|
return {render};
|
||||||
|
|
|
@ -79,8 +79,6 @@ QJSCLASS(texture)
|
||||||
QJSCLASS(font)
|
QJSCLASS(font)
|
||||||
QJSCLASS(warp_gravity)
|
QJSCLASS(warp_gravity)
|
||||||
QJSCLASS(warp_damp)
|
QJSCLASS(warp_damp)
|
||||||
QJSCLASS(material)
|
|
||||||
QJSCLASS(model)
|
|
||||||
QJSCLASS(window)
|
QJSCLASS(window)
|
||||||
QJSCLASS(constraint)
|
QJSCLASS(constraint)
|
||||||
QJSCLASS(sg_buffer)
|
QJSCLASS(sg_buffer)
|
||||||
|
@ -1367,14 +1365,6 @@ static const JSCFunctionListEntry js_physics_funcs[] = {
|
||||||
MIST_FUNC_DEF(physics, make_gravity, 0),
|
MIST_FUNC_DEF(physics, make_gravity, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSC_CCALL(model_draw_go,
|
|
||||||
model_draw_go(js2model(this), js2gameobject(argv[0]))
|
|
||||||
);
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_model_funcs[] = {
|
|
||||||
MIST_FUNC_DEF(model, draw_go, 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_emitter_funcs[] = {
|
static const JSCFunctionListEntry js_emitter_funcs[] = {
|
||||||
CGETSET_ADD(emitter, life),
|
CGETSET_ADD(emitter, life),
|
||||||
CGETSET_ADD(emitter, life_var),
|
CGETSET_ADD(emitter, life_var),
|
||||||
|
@ -1891,7 +1881,14 @@ JSValue primitive2js(primitive *p)
|
||||||
PRIMCHECK(p,v,index)
|
PRIMCHECK(p,v,index)
|
||||||
js_setpropstr(v, "count", number2js(p->idx_count));
|
js_setpropstr(v, "count", number2js(p->idx_count));
|
||||||
|
|
||||||
printf("new primitive with count %d\n", p->idx_count);
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSValue material2js(material *m)
|
||||||
|
{
|
||||||
|
JSValue v = JS_NewObject(js);
|
||||||
|
if (m->diffuse)
|
||||||
|
js_setpropstr(v, "diffuse", texture2js(m->diffuse));
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -1901,7 +1898,10 @@ JSC_SCALL(os_make_model,
|
||||||
if (arrlen(m->meshes) != 1) return JSUNDEF;
|
if (arrlen(m->meshes) != 1) return JSUNDEF;
|
||||||
mesh *me = m->meshes+0;
|
mesh *me = m->meshes+0;
|
||||||
|
|
||||||
return primitive2js(me->primitives+0);
|
JSValue v = JS_NewObject(js);
|
||||||
|
js_setpropstr(v, "mesh", primitive2js(me->primitives+0));
|
||||||
|
js_setpropstr(v, "material", material2js(me->primitives[0].mat));
|
||||||
|
return v;
|
||||||
)
|
)
|
||||||
JSC_CCALL(os_make_emitter,
|
JSC_CCALL(os_make_emitter,
|
||||||
emitter *e = make_emitter();
|
emitter *e = make_emitter();
|
||||||
|
@ -2122,7 +2122,6 @@ void ffi_load() {
|
||||||
QJSCLASSPREP_FUNCS(font);
|
QJSCLASSPREP_FUNCS(font);
|
||||||
QJSCLASSPREP_FUNCS(constraint);
|
QJSCLASSPREP_FUNCS(constraint);
|
||||||
QJSCLASSPREP_FUNCS(window);
|
QJSCLASSPREP_FUNCS(window);
|
||||||
QJSCLASSPREP_FUNCS(model);
|
|
||||||
QJSCLASSPREP_FUNCS(datastream);
|
QJSCLASSPREP_FUNCS(datastream);
|
||||||
|
|
||||||
QJSGLOBALCLASS(nota);
|
QJSGLOBALCLASS(nota);
|
||||||
|
|
Loading…
Reference in a new issue