Compare commits
No commits in common. "97e258ae7c1ef518539efdf00fafa3c9695262f7" and "0052a89c41e1b9af0239df7c4ec5cc4f5b8749a3" have entirely different histories.
97e258ae7c
...
0052a89c41
2
Makefile
2
Makefile
|
@ -66,7 +66,7 @@ else ifeq ($(OPT), 1)
|
||||||
CPPFLAGS += -O3 -flto
|
CPPFLAGS += -O3 -flto
|
||||||
INFO :=$(INFO)_opt
|
INFO :=$(INFO)_opt
|
||||||
else
|
else
|
||||||
CPPFLAGS += -O2
|
CPPFLAGS += -O0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(SEM)\" -DCOM=\"$(COM)\" -DINFO=\"$(INFO)\" #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t
|
CPPFLAGS += -DHAVE_CEIL -DCP_USE_CGTYPES=0 -DCP_USE_DOUBLES=0 -DHAVE_FLOOR -DHAVE_FMOD -DHAVE_LRINT -DHAVE_LRINTF $(includeflag) -MD $(WARNING_FLAGS) -I. -DVER=\"$(SEM)\" -DCOM=\"$(COM)\" -DINFO=\"$(INFO)\" #-DENABLE_SINC_MEDIUM_CONVERTER -DENABLE_SINC_FAST_CONVERTER -DCP_COLLISION_TYPE_TYPE=uintptr_t -DCP_BITMASK_TYPE=uintptr_t
|
||||||
|
|
|
@ -820,12 +820,6 @@ Object.defineProperty(String.prototype, 'splice', {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'sub', {
|
|
||||||
value: function(index, str) {
|
|
||||||
return this.slice(0,index) + str + this.slice(index+str.length);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'rm', {
|
Object.defineProperty(String.prototype, 'rm', {
|
||||||
value: function(index, endidx = index+1) { return this.slice(0,index) + this.slice(endidx); }
|
value: function(index, endidx = index+1) { return this.slice(0,index) + this.slice(endidx); }
|
||||||
});
|
});
|
||||||
|
@ -1557,63 +1551,10 @@ Math.sortpointsccw = function(points)
|
||||||
return ccw.map(function(x) { return x.add(cm); });
|
return ccw.map(function(x) { return x.add(cm); });
|
||||||
}
|
}
|
||||||
|
|
||||||
var yaml = {};
|
|
||||||
yaml.tojson = function(yaml)
|
|
||||||
{
|
|
||||||
yaml = yaml.replace(/(\w+):/g, '"$1":');
|
|
||||||
yaml = yaml.replace(/: ([\w\.]+)/g, ': "$1"');
|
|
||||||
|
|
||||||
yaml = yaml.split("\n");
|
|
||||||
var cont = {};
|
|
||||||
var cur = 0;
|
|
||||||
for (var i = 0; i < yaml.length; i++) {
|
|
||||||
var line = yaml[i];
|
|
||||||
var indent = line.search(/\S/);
|
|
||||||
|
|
||||||
if (indent > cur) {
|
|
||||||
if (line[indent] == "-") {
|
|
||||||
cont[indent] = "array";
|
|
||||||
yaml[i] = line.sub(indent, '[');
|
|
||||||
} else {
|
|
||||||
cont[indent] = "obj";
|
|
||||||
yaml[i] = line.sub(indent-1, '{');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indent < cur) {
|
|
||||||
while (cur > indent) {
|
|
||||||
if (cont[cur] === "obj")
|
|
||||||
yaml[i-1] = yaml[i-1] + "}";
|
|
||||||
else if (cont[cur] === "array")
|
|
||||||
yaml[i-1] = yaml[i-1] + "]";
|
|
||||||
|
|
||||||
delete cont[cur];
|
|
||||||
cur--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indent === cur) {
|
|
||||||
if (yaml[i][indent] === '-')
|
|
||||||
yaml[i] = yaml[i].sub(indent,',');
|
|
||||||
else
|
|
||||||
yaml[i-1] = yaml[i-1] + ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = indent;
|
|
||||||
}
|
|
||||||
yaml = "{" + yaml.join("\n") + "}";
|
|
||||||
yaml = yaml.replace(/\s/g, '');
|
|
||||||
yaml = yaml.replace(/,}/g, '}');
|
|
||||||
yaml = yaml.replace(/,]/g, ']');
|
|
||||||
return yaml;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
convert,
|
convert,
|
||||||
time,
|
time,
|
||||||
json,
|
json,
|
||||||
Vector,
|
Vector,
|
||||||
bbox,
|
bbox
|
||||||
yaml
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,10 +13,6 @@ this.view2world = function(pos) {
|
||||||
pos = pos.scale(this.zoom);
|
pos = pos.scale(this.zoom);
|
||||||
pos = pos.add(this.pos);
|
pos = pos.add(this.pos);
|
||||||
}
|
}
|
||||||
if (window.mode === window.modetypes.expand) {
|
|
||||||
pos = pos.sub(window.size.scale(0.5));
|
|
||||||
pos = pos.scale([window.rendersize.x/window.size.x, window.rendersize.y/window.size.y]);
|
|
||||||
}
|
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
this.world2view = function(pos) {
|
this.world2view = function(pos) {
|
||||||
|
@ -29,9 +25,6 @@ this.world2view = function(pos) {
|
||||||
pos = pos.sub(this.pos);
|
pos = pos.sub(this.pos);
|
||||||
pos = pos.scale(1/this.zoom);
|
pos = pos.scale(1/this.zoom);
|
||||||
pos = pos.add(window.size.scale(0.5));
|
pos = pos.add(window.size.scale(0.5));
|
||||||
}
|
|
||||||
if (window.mode === window.modetypes.expand) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
|
@ -177,7 +177,7 @@ Object.mixin(os.sprite(true), {
|
||||||
height() { return this.dimensions().y; },
|
height() { return this.dimensions().y; },
|
||||||
});
|
});
|
||||||
globalThis.allsprites = {};
|
globalThis.allsprites = {};
|
||||||
os.sprite().make = function(go)
|
os.sprite(true).make = function(go)
|
||||||
{
|
{
|
||||||
var sp = os.sprite();
|
var sp = os.sprite();
|
||||||
sp.go = go;
|
sp.go = go;
|
||||||
|
|
|
@ -344,7 +344,7 @@ var editor = {
|
||||||
root = root ? root + "." : root;
|
root = root ? root + "." : root;
|
||||||
Object.entries(obj.objects).forEach(function(x) {
|
Object.entries(obj.objects).forEach(function(x) {
|
||||||
var p = root + x[0];
|
var p = root + x[0];
|
||||||
render.text(p, x[1].this2screen(), 1, editor.color_depths[depth]);
|
render.text(p, x[1].screenpos(), 1, editor.color_depths[depth]);
|
||||||
editor.draw_objects_names(x[1], p, depth+1);
|
editor.draw_objects_names(x[1], p, depth+1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -402,7 +402,7 @@ var editor = {
|
||||||
if (this.comp_info && this.sel_comp)
|
if (this.comp_info && this.sel_comp)
|
||||||
render.text(input.print_pawn_kbm(this.sel_comp,false), [100,700],1);
|
render.text(input.print_pawn_kbm(this.sel_comp,false), [100,700],1);
|
||||||
|
|
||||||
render.cross(editor.edit_level.this2screen(),3,Color.blue);
|
render.cross(editor.edit_level.screenpos(),3,Color.blue);
|
||||||
|
|
||||||
var thiso = editor.get_this();
|
var thiso = editor.get_this();
|
||||||
var clvl = thiso;
|
var clvl = thiso;
|
||||||
|
@ -447,16 +447,16 @@ var editor = {
|
||||||
render.text("$$$$$$", [0,ypos],1,editor.color_depths[depth]);
|
render.text("$$$$$$", [0,ypos],1,editor.color_depths[depth]);
|
||||||
|
|
||||||
this.selectlist.forEach(function(x) {
|
this.selectlist.forEach(function(x) {
|
||||||
render.text(x.urstr(), x.this2screen().add([0, render.font.linegap*2]), 1, Color.editor.ur);
|
render.text(x.urstr(), x.screenpos().add([0, render.font.linegap*2]), 1, Color.editor.ur);
|
||||||
render.text(x.pos.map(function(x) { return Math.round(x); }), x.this2screen());
|
render.text(x.pos.map(function(x) { return Math.round(x); }), x.screenpos());
|
||||||
render.cross(x.this2screen(), 10, Color.blue);
|
render.cross(x.screenpos(), 10, Color.blue);
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.entries(thiso.objects).forEach(function(x) {
|
Object.entries(thiso.objects).forEach(function(x) {
|
||||||
var p = x[1].namestr();
|
var p = x[1].namestr();
|
||||||
render.text(p, x[1].this2screen().add([0,render.font.linegap]),1,editor.color_depths[depth]);
|
render.text(p, x[1].screenpos().add([0,render.font.linegap]),1,editor.color_depths[depth]);
|
||||||
render.point(x[1].this2screen(),5,Color.blue.alpha(0.3));
|
render.point(x[1].screenpos(),5,Color.blue.alpha(0.3));
|
||||||
render.point(x[1].this2screen(), 1, Color.red);
|
render.point(x[1].screenpos(), 1, Color.red);
|
||||||
});
|
});
|
||||||
|
|
||||||
var mg = physics.pos_query(input.mouse.worldpos());
|
var mg = physics.pos_query(input.mouse.worldpos());
|
||||||
|
@ -474,7 +474,7 @@ var editor = {
|
||||||
for (var key in this.selectlist[0].components) {
|
for (var key in this.selectlist[0].components) {
|
||||||
var selected = this.sel_comp === this.selectlist[0].components[key];
|
var selected = this.sel_comp === this.selectlist[0].components[key];
|
||||||
var str = (selected ? ">" : " ") + key + " [" + this.selectlist[0].components[key].toString() + "]";
|
var str = (selected ? ">" : " ") + key + " [" + this.selectlist[0].components[key].toString() + "]";
|
||||||
render.text(str, this.selectlist[0].this2screen().add([0,-render.font.linegap*(i++)]));
|
render.text(str, this.selectlist[0].screenpos().add([0,-render.font.linegap*(i++)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.sel_comp) {
|
if (this.sel_comp) {
|
||||||
|
@ -879,7 +879,7 @@ editor.inputs['C-s'] = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var savejs = saveobj.json_obj();
|
var savejs = saveobj.json_obj();
|
||||||
var tur = saveobj.ur;
|
var tur = saveobj.get_ur();
|
||||||
if (!tur) {
|
if (!tur) {
|
||||||
console.warn(`Can't save object because it has no ur.`);
|
console.warn(`Can't save object because it has no ur.`);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -289,6 +289,7 @@ game.engine_start = function(s) {
|
||||||
gggstart(function() {
|
gggstart(function() {
|
||||||
global.mixin("scripts/sound.js");
|
global.mixin("scripts/sound.js");
|
||||||
world_start();
|
world_start();
|
||||||
|
go_init();
|
||||||
window.set_icon(os.make_texture("icons/moon.gif"))
|
window.set_icon(os.make_texture("icons/moon.gif"))
|
||||||
Object.readonly(window.__proto__, 'vsync');
|
Object.readonly(window.__proto__, 'vsync');
|
||||||
Object.readonly(window.__proto__, 'enable_dragndrop');
|
Object.readonly(window.__proto__, 'enable_dragndrop');
|
||||||
|
@ -329,9 +330,9 @@ function process()
|
||||||
}
|
}
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
if (!game.camera)
|
if (!game.camera)
|
||||||
prosperon.window_render(world.transform, 1);
|
prosperon.window_render(world, 1);
|
||||||
else
|
else
|
||||||
prosperon.window_render(game.camera.transform, game.camera.zoom);
|
prosperon.window_render(game.camera, game.camera.zoom);
|
||||||
|
|
||||||
render.set_camera();
|
render.set_camera();
|
||||||
|
|
||||||
|
@ -626,8 +627,7 @@ global.mixin("scripts/actor");
|
||||||
global.mixin("scripts/entity");
|
global.mixin("scripts/entity");
|
||||||
|
|
||||||
function world_start() {
|
function world_start() {
|
||||||
globalThis.world = Object.create(entity);
|
globalThis.world = os.make_gameobject();
|
||||||
world.transform = os.make_transform2d();
|
|
||||||
world.objects = {};
|
world.objects = {};
|
||||||
world.toString = function() { return "world"; };
|
world.toString = function() { return "world"; };
|
||||||
world.ur = "world";
|
world.ur = "world";
|
||||||
|
|
|
@ -12,18 +12,7 @@ function obj_unique_name(name, obj) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unique_name(list, name = "new_object") {
|
var gameobject = {
|
||||||
var str = name.replaceAll('.', '_');
|
|
||||||
var n = 1;
|
|
||||||
var t = str;
|
|
||||||
while (list.indexOf(t) !== -1) {
|
|
||||||
t = str + n;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
|
|
||||||
var entity = {
|
|
||||||
get_comp_by_name(name) {
|
get_comp_by_name(name) {
|
||||||
var comps = [];
|
var comps = [];
|
||||||
for (var c of Object.values(this.components))
|
for (var c of Object.values(this.components))
|
||||||
|
@ -33,6 +22,79 @@ var entity = {
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
check_dirty() {
|
||||||
|
this._ed.urdiff = this.json_obj();
|
||||||
|
this._ed.dirty = !Object.empty(this._ed.urdiff);
|
||||||
|
return; // TODO: IMPLEMENT
|
||||||
|
var lur = this.master.ur;
|
||||||
|
if (!lur) return;
|
||||||
|
var lur = lur.objects[this.toString()];
|
||||||
|
var d = ediff(this._ed.urdiff, lur);
|
||||||
|
if (!d || Object.empty(d))
|
||||||
|
this._ed.inst = true;
|
||||||
|
else
|
||||||
|
this._ed.inst = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
namestr() {
|
||||||
|
var s = this.toString();
|
||||||
|
if (this._ed?.dirty)
|
||||||
|
if (this._ed.inst) s += "#";
|
||||||
|
else s += "*";
|
||||||
|
return s;
|
||||||
|
},
|
||||||
|
|
||||||
|
urstr() {
|
||||||
|
var str = this.ur.name;
|
||||||
|
if (this._ed.dirty) str = "*" + str;
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
|
||||||
|
full_path() {
|
||||||
|
return this.path_from(world);
|
||||||
|
},
|
||||||
|
/* pin this object to the to object */
|
||||||
|
pin(to) {
|
||||||
|
var p = joint.pin(this,to);
|
||||||
|
},
|
||||||
|
slide(to, a = [0,0], b = [0,0], min = 0, max = 50) {
|
||||||
|
var p = joint.slide(this, to, a, b, min, max);
|
||||||
|
p.max_force = 500;
|
||||||
|
p.break();
|
||||||
|
},
|
||||||
|
pivot(to, piv = this.pos) {
|
||||||
|
var p = joint.pivot(this, to, piv);
|
||||||
|
},
|
||||||
|
/* groove is on to, from local points a and b, anchored to this at local anchor */
|
||||||
|
groove(to, a, b, anchor = [0,0]) {
|
||||||
|
var p = joint.groove(to, this, a, b, anchor);
|
||||||
|
},
|
||||||
|
damped_spring(to, length = Vector.length(this.pos,to.pos), stiffness = 1, damping = 1) {
|
||||||
|
var dc = 2 * Math.sqrt(stiffness * this.mass);
|
||||||
|
var p = joint.damped_spring(this, to, [0, 0], [0, 0], stiffness, damping * dc);
|
||||||
|
},
|
||||||
|
damped_rotary_spring(to, angle = 0, stiffness = 1, damping = 1) {
|
||||||
|
/* calculate actual damping value from the damping ratio */
|
||||||
|
/* damping = 1 is critical */
|
||||||
|
var dc = 2 * Math.sqrt(stiffness * this.get_moi()); /* critical damping number */
|
||||||
|
/* zeta = actual/critical */
|
||||||
|
var p = joint.damped_rotary(this, to, angle, stiffness, damping * dc);
|
||||||
|
},
|
||||||
|
rotary_limit(to, min, max) {
|
||||||
|
var p = joint.rotary(this, to, Math.turn2rad(min), Math.turn2rad(max));
|
||||||
|
},
|
||||||
|
ratchet(to, ratch) {
|
||||||
|
var phase = this.angle - to.angle;
|
||||||
|
var p = joint.ratchet(this, to, phase, Math.turn2rad(ratch));
|
||||||
|
},
|
||||||
|
gear(to, ratio = 1, phase = 0) {
|
||||||
|
var phase = this.angle - to.angle;
|
||||||
|
var p = joint.gear(this, to, phase, ratio);
|
||||||
|
},
|
||||||
|
motor(to, rate) {
|
||||||
|
var p = joint.motor(this, to, rate);
|
||||||
|
},
|
||||||
|
|
||||||
path_from(o) {
|
path_from(o) {
|
||||||
var p = this.toString();
|
var p = this.toString();
|
||||||
var c = this.master;
|
var c = this.master;
|
||||||
|
@ -44,8 +106,6 @@ var entity = {
|
||||||
return p;
|
return p;
|
||||||
},
|
},
|
||||||
|
|
||||||
full_path() { return this.path_from(world); },
|
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
for (var k in this.objects) {
|
for (var k in this.objects) {
|
||||||
this.objects[k].kill();
|
this.objects[k].kill();
|
||||||
|
@ -53,11 +113,6 @@ var entity = {
|
||||||
this.objects = {};
|
this.objects = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
sync() {
|
|
||||||
this.components.forEach(function(x) { x.sync?.(); });
|
|
||||||
this.objects.forEach(function(x) { x.sync(); });
|
|
||||||
},
|
|
||||||
|
|
||||||
delay(fn, seconds) {
|
delay(fn, seconds) {
|
||||||
var timers = this.timers;
|
var timers = this.timers;
|
||||||
var stop = function() {
|
var stop = function() {
|
||||||
|
@ -90,60 +145,110 @@ var entity = {
|
||||||
|
|
||||||
cry(file) { return audio.cry(file); },
|
cry(file) { return audio.cry(file); },
|
||||||
|
|
||||||
get pos() { return this.transform.pos; },
|
set pos(x) { this.set_pos(x); },
|
||||||
set pos(x) { this.transform.pos = x; },
|
get pos() { return this.rpos; },
|
||||||
get angle() { return this.transform.angle; },
|
set angle(x) { this.set_angle(x); },
|
||||||
set angle(x) { this.transform.angle = x; },
|
get angle() { return this.rangle; },
|
||||||
get scale() { return this.transform.scale; },
|
set scale(x) { this.set_scale(x); },
|
||||||
set scale(x) { this.transform.scale = x; },
|
get scale() { return this.rscale; },
|
||||||
|
|
||||||
move(vec) { this.pos = this.pos.add(vec); },
|
set_pos(x, relative = world) {
|
||||||
rotate(x) { this.angle += x; },
|
var newpos = relative.this2world(x);
|
||||||
|
var move = newpos.sub(this.pos);
|
||||||
|
this.rpos = newpos;
|
||||||
|
this.objects.forEach(x => x.move(move));
|
||||||
|
},
|
||||||
|
|
||||||
|
set_angle(x, relative = world) {
|
||||||
|
var newangle = relative.angle + x;
|
||||||
|
var diff = newangle - this.angle;
|
||||||
|
this.rangle = newangle;
|
||||||
|
this.objects.forEach(obj => {
|
||||||
|
obj.rotate(diff);
|
||||||
|
obj.set_pos(Vector.rotate(obj.get_pos(obj.master), diff), obj.master);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
set_scale(x, relative = world) {
|
||||||
|
if (typeof x === 'number') x = [x,x,x];
|
||||||
|
var newscale = relative.scale.map((s,i) => x[i]*s);
|
||||||
|
var pct = this.scale.map((s,i) => newscale[i]/s);
|
||||||
|
this.rscale = newscale;
|
||||||
|
this.objects.forEach(obj => {
|
||||||
|
obj.grow(pct);
|
||||||
|
obj.set_pos(obj.get_pos(obj.master).map((x,i) => x*pct[i]), obj.master);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
get_pos(relative = world) {
|
||||||
|
if (relative === world) return this.pos;
|
||||||
|
return relative.world2this(this.pos);
|
||||||
|
//return this.pos.sub(relative.pos);
|
||||||
|
},
|
||||||
|
|
||||||
|
get_angle(relative = world) {
|
||||||
|
if (relative === world) return this.angle;
|
||||||
|
return this.angle - relative.angle;
|
||||||
|
},
|
||||||
|
|
||||||
|
get_scale(relative = world) {
|
||||||
|
if (relative === world) return this.scale;
|
||||||
|
var masterscale = relative.scale;
|
||||||
|
return this.scale.map((x,i) => x/masterscale[i]);
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Moving, rotating, scaling functions, world relative */
|
||||||
|
move(vec) { this.set_pos(this.pos.add(vec)); },
|
||||||
|
rotate(x) { this.set_angle(this.angle + x); },
|
||||||
grow(vec) {
|
grow(vec) {
|
||||||
if (typeof vec === 'number') vec = [vec,vec];
|
if (typeof vec === 'number') vec = [vec,vec,vec];
|
||||||
this.scale = this.scale.map((x,i) => x*vec[i]);
|
this.set_scale(this.scale.map((x, i) => x * vec[i]));
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Reparent 'this' to be 'parent's child */
|
screenpos() { return game.camera.world2view(this.pos); },
|
||||||
reparent(parent) {
|
|
||||||
assert(parent, `Tried to reparent ${this.toString()} to nothing.`);
|
|
||||||
console.spam(`parenting ${this.toString()} to ${parent.toString()}`);
|
|
||||||
if (this.master === parent) {
|
|
||||||
console.warn("not reparenting ...");
|
|
||||||
console.warn(`${this.master} is the same as ${parent}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = unique_name(Object.keys(parent), this.name);
|
get_ur() { return this.ur; },
|
||||||
this.name = name;
|
|
||||||
|
|
||||||
this.master?.remove_obj(this);
|
|
||||||
this.master = parent;
|
|
||||||
parent.objects[this.guid] = this;
|
|
||||||
parent[name] = this;
|
|
||||||
Object.hide(parent, name);
|
|
||||||
},
|
|
||||||
|
|
||||||
remove_obj(obj) {
|
|
||||||
delete this.objects[obj.guid];
|
|
||||||
delete this[obj.name];
|
|
||||||
Object.unhide(this, obj.name);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
/* spawn an entity
|
||||||
|
text can be:
|
||||||
|
the file path of a script
|
||||||
|
an ur object
|
||||||
|
nothing
|
||||||
|
*/
|
||||||
spawn(text, config, callback) {
|
spawn(text, config, callback) {
|
||||||
var st = profile.now();
|
var st = profile.now();
|
||||||
var ent = Object.create(entity);
|
var ent = os.make_gameobject();
|
||||||
ent.transform = os.make_transform2d();
|
|
||||||
|
|
||||||
ent.guid = prosperon.guid();
|
ent.guid = prosperon.guid();
|
||||||
|
|
||||||
ent.components = {};
|
ent.components = {};
|
||||||
ent.objects = {};
|
ent.objects = {};
|
||||||
ent.timers = [];
|
ent.timers = [];
|
||||||
|
|
||||||
if (!text)
|
Object.mixin(ent, {
|
||||||
ent.ur = emptyur;
|
set category(n) {
|
||||||
else if (typeof text === 'object' && text) {// assume it's an ur
|
if (n === 0) {
|
||||||
|
this.categories = n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cat = (1 << (n-1));
|
||||||
|
this.categories = cat;
|
||||||
|
},
|
||||||
|
get category() {
|
||||||
|
if (this.categories === 0) return 0;
|
||||||
|
var pos = 0;
|
||||||
|
var num = this.categories;
|
||||||
|
while (num > 0) {
|
||||||
|
if (num & 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
num >>>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos+1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof text === 'object' && text) {// assume it's an ur
|
||||||
ent.ur = text;
|
ent.ur = text;
|
||||||
text = ent.ur.text;
|
text = ent.ur.text;
|
||||||
config = [ent.ur.data, config].filter(x => x).flat();
|
config = [ent.ur.data, config].filter(x => x).flat();
|
||||||
|
@ -189,7 +294,7 @@ var entity = {
|
||||||
if (sim.playing())
|
if (sim.playing())
|
||||||
if (typeof ent.start === 'function') ent.start();
|
if (typeof ent.start === 'function') ent.start();
|
||||||
|
|
||||||
Object.hide(ent, 'ur', 'components', 'objects', 'timers', 'guid', 'master');
|
Object.hide(ent, 'ur', 'components', 'objects', 'timers', 'guid', 'master', 'categories');
|
||||||
|
|
||||||
ent._ed = {
|
ent._ed = {
|
||||||
selectable: true,
|
selectable: true,
|
||||||
|
@ -219,7 +324,6 @@ var entity = {
|
||||||
|
|
||||||
if (callback) callback(ent);
|
if (callback) callback(ent);
|
||||||
|
|
||||||
|
|
||||||
ent.ur.fresh ??= json.decode(json.encode(ent));
|
ent.ur.fresh ??= json.decode(json.encode(ent));
|
||||||
ent.ur.fresh.objects = {};
|
ent.ur.fresh.objects = {};
|
||||||
for (var i in ent.objects)
|
for (var i in ent.objects)
|
||||||
|
@ -229,17 +333,60 @@ var entity = {
|
||||||
return ent;
|
return ent;
|
||||||
},
|
},
|
||||||
|
|
||||||
disable() { this.components.forEach(function(x) { x.disable(); }); },
|
/* Reparent 'this' to be 'parent's child */
|
||||||
enable() { this.components.forEach(function(x) { x.enable(); }); },
|
reparent(parent) {
|
||||||
|
assert(parent, `Tried to reparent ${this.toString()} to nothing.`);
|
||||||
|
console.spam(`parenting ${this.toString()} to ${parent.toString()}`);
|
||||||
|
if (this.master === parent) {
|
||||||
|
console.warn("not reparenting ...");
|
||||||
|
console.warn(`${this.master} is the same as ${parent}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.master?.remove_obj(this);
|
||||||
|
|
||||||
|
this.master = parent;
|
||||||
|
|
||||||
|
function unique_name(list, name = "new_object") {
|
||||||
|
var str = name.replaceAll('.', '_');
|
||||||
|
var n = 1;
|
||||||
|
var t = str;
|
||||||
|
while (list.indexOf(t) !== -1) {
|
||||||
|
t = str + n;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
var name = unique_name(Object.keys(parent.objects), this.ur.name);
|
||||||
|
|
||||||
|
parent.objects[name] = this;
|
||||||
|
parent[name] = this;
|
||||||
|
Object.hide(parent, name);
|
||||||
|
this.toString = function() { return name; };
|
||||||
|
},
|
||||||
|
|
||||||
|
remove_obj(obj) {
|
||||||
|
delete this.objects[obj.toString()];
|
||||||
|
delete this[obj.toString()];
|
||||||
|
Object.unhide(this, obj.toString());
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {},
|
||||||
|
objects: {},
|
||||||
|
master: undefined,
|
||||||
|
|
||||||
this2screen(pos) { return game.camera.world2view(this.this2world(pos)); },
|
this2screen(pos) { return game.camera.world2view(this.this2world(pos)); },
|
||||||
screen2this(pos) { return this.world2this(game.camera.view2world(pos)); },
|
screen2this(pos) { return this.world2this(game.camera.view2world(pos)); },
|
||||||
|
|
||||||
/* Make a unique object the same as its prototype */
|
in_air() { return this.in_air(); },
|
||||||
revert() { Object.merge(this, this.ur.fresh); },
|
|
||||||
|
hide() { this.components.forEach(x => x.hide?.());
|
||||||
|
this.objects.forEach(x => x.hide?.()); },
|
||||||
|
|
||||||
|
show() { this.components.forEach(function(x) { x.show?.(); });
|
||||||
|
this.objects.forEach(function(x) { x.show?.(); }); },
|
||||||
|
|
||||||
name: "new_object",
|
|
||||||
toString() { return this.name; },
|
|
||||||
width() {
|
width() {
|
||||||
var bb = this.boundingbox();
|
var bb = this.boundingbox();
|
||||||
return bb.r - bb.l;
|
return bb.r - bb.l;
|
||||||
|
@ -250,11 +397,19 @@ var entity = {
|
||||||
return bb.t - bb.b;
|
return bb.t - bb.b;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/* Make a unique object the same as its prototype */
|
||||||
|
revert() { Object.merge(this, this.ur.fresh); },
|
||||||
|
|
||||||
|
toString() { return "new_object"; },
|
||||||
|
|
||||||
flipx() { return this.scale.x < 0; },
|
flipx() { return this.scale.x < 0; },
|
||||||
flipy() { return this.scale.y < 0; },
|
flipy() { return this.scale.y < 0; },
|
||||||
|
|
||||||
mirror(plane) { this.scale = Vector.reflect(this.scale, plane); },
|
mirror(plane) { this.scale = Vector.reflect(this.scale, plane); },
|
||||||
|
|
||||||
|
disable() { this.components.forEach(function(x) { x.disable(); }); },
|
||||||
|
enable() { this.components.forEach(function(x) { x.enable(); }); },
|
||||||
|
|
||||||
/* Bounding box of the object in world dimensions */
|
/* Bounding box of the object in world dimensions */
|
||||||
boundingbox() {
|
boundingbox() {
|
||||||
var boxes = [];
|
var boxes = [];
|
||||||
|
@ -321,7 +476,22 @@ var entity = {
|
||||||
return t;
|
return t;
|
||||||
},
|
},
|
||||||
|
|
||||||
dup(diff) {
|
/* Velocity and angular velocity of the object */
|
||||||
|
phys_obj() {
|
||||||
|
var phys = {};
|
||||||
|
phys.velocity = this.velocity;
|
||||||
|
phys.angularvelocity = this.angularvelocity;
|
||||||
|
return phys;
|
||||||
|
},
|
||||||
|
|
||||||
|
phys_mat() {
|
||||||
|
return {
|
||||||
|
friction: this.friction,
|
||||||
|
elasticity: this.elasticity
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dup(diff) {
|
||||||
var n = this.master.spawn(this.ur);
|
var n = this.master.spawn(this.ur);
|
||||||
Object.totalmerge(n, this.transform());
|
Object.totalmerge(n, this.transform());
|
||||||
return n;
|
return n;
|
||||||
|
@ -362,6 +532,10 @@ dup(diff) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
up() { return [0, 1].rotate(this.angle); },
|
||||||
|
down() { return [0, -1].rotate(this.angle); },
|
||||||
|
right() { return [1, 0].rotate(this.angle); },
|
||||||
|
left() { return [-1, 0].rotate(this.angle); },
|
||||||
|
|
||||||
make_objs(objs) {
|
make_objs(objs) {
|
||||||
for (var prop in objs) {
|
for (var prop in objs) {
|
||||||
|
@ -401,159 +575,19 @@ dup(diff) {
|
||||||
Object.assign(this[name], data);
|
Object.assign(this[name], data);
|
||||||
return this[name];
|
return this[name];
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
|
|
||||||
var gameobject = {
|
function go_init() {
|
||||||
check_dirty() {
|
var gop = os.make_gameobject().__proto__;
|
||||||
this._ed.urdiff = this.json_obj();
|
Object.mixin(gop, gameobject);
|
||||||
this._ed.dirty = !Object.empty(this._ed.urdiff);
|
gop.sync = function() {
|
||||||
return; // TODO: IMPLEMENT
|
this.selfsync();
|
||||||
var lur = this.master.ur;
|
this.components.forEach(function(x) { x.sync?.(); });
|
||||||
if (!lur) return;
|
this.objects.forEach(function(x) { x.sync?.(); });
|
||||||
var lur = lur.objects[this.toString()];
|
|
||||||
var d = ediff(this._ed.urdiff, lur);
|
|
||||||
if (!d || Object.empty(d))
|
|
||||||
this._ed.inst = true;
|
|
||||||
else
|
|
||||||
this._ed.inst = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
namestr() {
|
|
||||||
var s = this.toString();
|
|
||||||
if (this._ed?.dirty)
|
|
||||||
if (this._ed.inst) s += "#";
|
|
||||||
else s += "*";
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
|
|
||||||
urstr() {
|
|
||||||
var str = this.ur.name;
|
|
||||||
if (this._ed.dirty) str = "*" + str;
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
|
|
||||||
/* pin this object to the to object */
|
|
||||||
pin(to) {
|
|
||||||
var p = joint.pin(this,to);
|
|
||||||
},
|
|
||||||
slide(to, a = [0,0], b = [0,0], min = 0, max = 50) {
|
|
||||||
var p = joint.slide(this, to, a, b, min, max);
|
|
||||||
p.max_force = 500;
|
|
||||||
p.break();
|
|
||||||
},
|
|
||||||
pivot(to, piv = this.pos) {
|
|
||||||
var p = joint.pivot(this, to, piv);
|
|
||||||
},
|
|
||||||
/* groove is on to, from local points a and b, anchored to this at local anchor */
|
|
||||||
groove(to, a, b, anchor = [0,0]) {
|
|
||||||
var p = joint.groove(to, this, a, b, anchor);
|
|
||||||
},
|
|
||||||
damped_spring(to, length = Vector.length(this.pos,to.pos), stiffness = 1, damping = 1) {
|
|
||||||
var dc = 2 * Math.sqrt(stiffness * this.mass);
|
|
||||||
var p = joint.damped_spring(this, to, [0, 0], [0, 0], stiffness, damping * dc);
|
|
||||||
},
|
|
||||||
damped_rotary_spring(to, angle = 0, stiffness = 1, damping = 1) {
|
|
||||||
/* calculate actual damping value from the damping ratio */
|
|
||||||
/* damping = 1 is critical */
|
|
||||||
var dc = 2 * Math.sqrt(stiffness * this.get_moi()); /* critical damping number */
|
|
||||||
/* zeta = actual/critical */
|
|
||||||
var p = joint.damped_rotary(this, to, angle, stiffness, damping * dc);
|
|
||||||
},
|
|
||||||
rotary_limit(to, min, max) {
|
|
||||||
var p = joint.rotary(this, to, Math.turn2rad(min), Math.turn2rad(max));
|
|
||||||
},
|
|
||||||
ratchet(to, ratch) {
|
|
||||||
var phase = this.angle - to.angle;
|
|
||||||
var p = joint.ratchet(this, to, phase, Math.turn2rad(ratch));
|
|
||||||
},
|
|
||||||
gear(to, ratio = 1, phase = 0) {
|
|
||||||
var phase = this.angle - to.angle;
|
|
||||||
var p = joint.gear(this, to, phase, ratio);
|
|
||||||
},
|
|
||||||
motor(to, rate) {
|
|
||||||
var p = joint.motor(this, to, rate);
|
|
||||||
},
|
|
||||||
|
|
||||||
set_pos(x, relative = world) {
|
|
||||||
var newpos = relative.this2world(x);
|
|
||||||
var move = newpos.sub(this.pos);
|
|
||||||
this.rpos = newpos;
|
|
||||||
this.objects.forEach(x => x.move(move));
|
|
||||||
},
|
|
||||||
|
|
||||||
set_angle(x, relative = world) {
|
|
||||||
var newangle = relative.angle + x;
|
|
||||||
var diff = newangle - this.angle;
|
|
||||||
this.rangle = newangle;
|
|
||||||
this.objects.forEach(obj => {
|
|
||||||
obj.rotate(diff);
|
|
||||||
obj.set_pos(Vector.rotate(obj.get_pos(obj.master), diff), obj.master);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
set_scale(x, relative = world) {
|
|
||||||
if (typeof x === 'number') x = [x,x,x];
|
|
||||||
var newscale = relative.scale.map((s,i) => x[i]*s);
|
|
||||||
var pct = this.scale.map((s,i) => newscale[i]/s);
|
|
||||||
this.rscale = newscale;
|
|
||||||
this.objects.forEach(obj => {
|
|
||||||
obj.grow(pct);
|
|
||||||
obj.set_pos(obj.get_pos(obj.master).map((x,i) => x*pct[i]), obj.master);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
get_pos(relative = world) {
|
|
||||||
if (relative === world) return this.pos;
|
|
||||||
return relative.world2this(this.pos);
|
|
||||||
//return this.pos.sub(relative.pos);
|
|
||||||
},
|
|
||||||
|
|
||||||
get_angle(relative = world) {
|
|
||||||
if (relative === world) return this.angle;
|
|
||||||
return this.angle - relative.angle;
|
|
||||||
},
|
|
||||||
|
|
||||||
get_scale(relative = world) {
|
|
||||||
if (relative === world) return this.scale;
|
|
||||||
var masterscale = relative.scale;
|
|
||||||
return this.scale.map((x,i) => x/masterscale[i]);
|
|
||||||
},
|
|
||||||
|
|
||||||
in_air() { return this.in_air(); },
|
|
||||||
|
|
||||||
/* Velocity and angular velocity of the object */
|
|
||||||
phys_obj() {
|
|
||||||
var phys = {};
|
|
||||||
phys.velocity = this.velocity;
|
|
||||||
phys.angularvelocity = this.angularvelocity;
|
|
||||||
return phys;
|
|
||||||
},
|
|
||||||
|
|
||||||
set category(n) {
|
|
||||||
if (n === 0) {
|
|
||||||
this.categories = n;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var cat = (1 << (n-1));
|
|
||||||
this.categories = cat;
|
|
||||||
},
|
|
||||||
get category() {
|
|
||||||
if (this.categories === 0) return 0;
|
|
||||||
var pos = 0;
|
|
||||||
var num = this.categories;
|
|
||||||
while (num > 0) {
|
|
||||||
if (num & 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
num >>>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos+1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
gameobject.spawn.doc = `Spawn an entity of type 'ur' on this entity. Returns the spawned entity.`;
|
||||||
|
|
||||||
gameobject.doc = {
|
gameobject.doc = {
|
||||||
doc: "All objects in the game created through spawning have these attributes.",
|
doc: "All objects in the game created through spawning have these attributes.",
|
||||||
|
@ -661,18 +695,8 @@ function apply_ur(u, ent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyur = {
|
|
||||||
name: "empty"
|
|
||||||
}
|
|
||||||
|
|
||||||
var getur = function(text, data)
|
var getur = function(text, data)
|
||||||
{
|
{
|
||||||
if (!text && !data) {
|
|
||||||
console.info('empty ur');
|
|
||||||
return {
|
|
||||||
name: "empty"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var urstr = text + "+" + data;
|
var urstr = text + "+" + data;
|
||||||
if (!ur[urstr]) {
|
if (!ur[urstr]) {
|
||||||
ur[urstr] = {
|
ur[urstr] = {
|
||||||
|
@ -760,4 +784,4 @@ game.ur.save = function(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { entity }
|
return { go_init }
|
|
@ -124,9 +124,9 @@ render.text = function(str, pos, size = 1, color = Color.white, wrap = -1, ancho
|
||||||
};
|
};
|
||||||
|
|
||||||
render.image = function(tex, pos, rotation = 0, color = Color.white, dimensions = [tex.width, tex.height]) {
|
render.image = function(tex, pos, rotation = 0, color = Color.white, dimensions = [tex.width, tex.height]) {
|
||||||
//var scale = [dimensions.x/tex.width, dimensions.y/tex.height];
|
var scale = [dimensions.x/tex.width, dimensions.y/tex.height];
|
||||||
//gui.img(tex,pos, scale, 0.0, false, [0.0,0.0], color);
|
gui.img(tex,pos, scale, 0.0, false, [0.0,0.0], color);
|
||||||
//return bbox.fromcwh([0,0], [tex.width,tex.height]);
|
return bbox.fromcwh([0,0], [tex.width,tex.height]);
|
||||||
}
|
}
|
||||||
|
|
||||||
render.fontcache = {};
|
render.fontcache = {};
|
||||||
|
|
|
@ -476,54 +476,9 @@ Cmdline.register_cmd("l", function(n) {
|
||||||
console.level = n;
|
console.level = n;
|
||||||
}, "Set log level.");
|
}, "Set log level.");
|
||||||
|
|
||||||
function convertYAMLtoJSON(yamlString) {
|
|
||||||
const lines = yamlString.split('\n');
|
|
||||||
const jsonObj = {};
|
|
||||||
|
|
||||||
let currentKey = '';
|
|
||||||
let currentValue = '';
|
|
||||||
let currentDepth = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
const line = lines[i].trim();
|
|
||||||
if (!line || line.startsWith('#')) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const depth = (line.match(/^\s+/g) || [''])[0].length;
|
|
||||||
const keyValue = line.split(':');
|
|
||||||
const key = keyValue[0].trim();
|
|
||||||
const value = keyValue[1].trim();
|
|
||||||
|
|
||||||
if (depth > currentDepth) {
|
|
||||||
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
|
||||||
currentKey = key;
|
|
||||||
currentValue = value;
|
|
||||||
} else if (depth === currentDepth) {
|
|
||||||
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
|
||||||
currentKey = key;
|
|
||||||
currentValue = value;
|
|
||||||
} else {
|
|
||||||
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
|
||||||
currentKey = '';
|
|
||||||
currentValue = '';
|
|
||||||
i--; // To reprocess the current line with updated values
|
|
||||||
}
|
|
||||||
|
|
||||||
currentDepth = depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentKey) {
|
|
||||||
jsonObj[currentKey] = convertYAMLtoJSON(currentValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return jsonObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Resources,
|
Resources,
|
||||||
Cmdline,
|
Cmdline,
|
||||||
cmd_args,
|
cmd_args
|
||||||
convertYAMLtoJSON
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include "stb_ds.h"
|
#include "stb_ds.h"
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
|
|
||||||
|
//#include "diffuse.sglsl.h"
|
||||||
|
#include "unlit.sglsl.h"
|
||||||
|
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
@ -27,8 +30,50 @@ static void processnode();
|
||||||
static void processmesh();
|
static void processmesh();
|
||||||
static void processtexture();
|
static void processtexture();
|
||||||
|
|
||||||
static cgltf_data *cdata;
|
static sg_shader model_shader;
|
||||||
static char *cpath;
|
static sg_pipeline model_pipe;
|
||||||
|
struct bone_weights {
|
||||||
|
char b1;
|
||||||
|
char b2;
|
||||||
|
char b3;
|
||||||
|
char b4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct joints {
|
||||||
|
char j1;
|
||||||
|
char j2;
|
||||||
|
char j3;
|
||||||
|
char j4;
|
||||||
|
};
|
||||||
|
|
||||||
|
void model_init() {
|
||||||
|
model_shader = sg_make_shader(unlit_shader_desc(sg_query_backend()));
|
||||||
|
|
||||||
|
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
|
.shader = model_shader,
|
||||||
|
.layout = {
|
||||||
|
.attrs = {
|
||||||
|
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||||
|
[1].format = SG_VERTEXFORMAT_USHORT2N,
|
||||||
|
[1].buffer_index = 1,
|
||||||
|
[2].format = SG_VERTEXFORMAT_UINT10_N2,
|
||||||
|
[2].buffer_index = 2,
|
||||||
|
[3] = {
|
||||||
|
.format = SG_VERTEXFORMAT_UBYTE4N,
|
||||||
|
.buffer_index = 3
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
.format = SG_VERTEXFORMAT_UBYTE4,
|
||||||
|
.buffer_index = 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.index_type = SG_INDEXTYPE_UINT16,
|
||||||
|
.cull_mode = SG_CULLMODE_FRONT,
|
||||||
|
.depth.write_enabled = true,
|
||||||
|
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cgltf_attribute *get_attr_type(cgltf_primitive *p, cgltf_attribute_type t)
|
cgltf_attribute *get_attr_type(cgltf_primitive *p, cgltf_attribute_type t)
|
||||||
{
|
{
|
||||||
|
@ -64,21 +109,17 @@ void mesh_add_material(primitive *prim, cgltf_material *mat)
|
||||||
{
|
{
|
||||||
if (!mat) return;
|
if (!mat) return;
|
||||||
|
|
||||||
prim->mat = calloc(sizeof(*prim->mat), 1);
|
if (mat->has_pbr_metallic_roughness) {
|
||||||
material *pmat = prim->mat;
|
|
||||||
|
|
||||||
if (mat->has_pbr_metallic_roughness && mat->pbr_metallic_roughness.base_color_texture.texture) {
|
|
||||||
cgltf_image *img = mat->pbr_metallic_roughness.base_color_texture.texture->image;
|
cgltf_image *img = mat->pbr_metallic_roughness.base_color_texture.texture->image;
|
||||||
if (img->buffer_view) {
|
if (img->buffer_view) {
|
||||||
cgltf_buffer_view *buf = img->buffer_view;
|
cgltf_buffer_view *buf = img->buffer_view;
|
||||||
pmat->diffuse = texture_fromdata(buf->buffer->data, buf->size);
|
prim->bind.fs.images[0] = texture_fromdata(buf->buffer->data, buf->size)->id;
|
||||||
} else {
|
} else
|
||||||
char *path = makepath(dirname(cpath), img->uri);
|
prim->bind.fs.images[0] = texture_from_file(img->uri)->id;
|
||||||
pmat->diffuse = texture_from_file(path);
|
|
||||||
free(path);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
pmat->diffuse = texture_from_file("icons/moon.gif");
|
prim->bind.fs.images[0] = texture_from_file("icons/moon.gif")->id;
|
||||||
|
|
||||||
|
prim->bind.fs.samplers[0] = std_sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
||||||
|
@ -106,24 +147,6 @@ sg_buffer normal_floats(float *f, int verts, int comp)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_buffer ubyten_buffer(float *f, int v, int c)
|
|
||||||
{
|
|
||||||
unsigned char b[v*c];
|
|
||||||
for (int i = 0; i < (v*c); i++)
|
|
||||||
b[i] = f[i]*255;
|
|
||||||
|
|
||||||
return sg_make_buffer(&(sg_buffer_desc){.data=SG_RANGE(b)});
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_buffer ubyte_buffer(float *f, int v, int c)
|
|
||||||
{
|
|
||||||
unsigned char b[v*c];
|
|
||||||
for (int i = 0; i < (v*c); i++)
|
|
||||||
b[i] = f[i];
|
|
||||||
|
|
||||||
return sg_make_buffer(&(sg_buffer_desc){.data=SG_RANGE(b)});
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_buffer joint_buf(float *f, int v, int c)
|
sg_buffer joint_buf(float *f, int v, int c)
|
||||||
{
|
{
|
||||||
char joints[v*c];
|
char joints[v*c];
|
||||||
|
@ -160,7 +183,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
idxs[i] = fidx[i];
|
idxs[i] = fidx[i];
|
||||||
|
|
||||||
retp.idx = sg_make_buffer(&(sg_buffer_desc){
|
retp.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = idxs,
|
.data.ptr = idxs,
|
||||||
.data.size = sizeof(*idxs) * n,
|
.data.size = sizeof(*idxs) * n,
|
||||||
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
||||||
|
@ -178,7 +201,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
for (int z = 0; z < c; z++)
|
for (int z = 0; z < c; z++)
|
||||||
idxs[z] = z;
|
idxs[z] = z;
|
||||||
|
|
||||||
retp.idx = sg_make_buffer(&(sg_buffer_desc){
|
retp.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = idxs,
|
.data.ptr = idxs,
|
||||||
.data.size = sizeof(uint16_t) * c,
|
.data.size = sizeof(uint16_t) * c,
|
||||||
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
.type = SG_BUFFERTYPE_INDEXBUFFER});
|
||||||
|
@ -188,6 +211,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
|
|
||||||
printf("adding material\n");
|
printf("adding material\n");
|
||||||
mesh_add_material(&retp, prim->material);
|
mesh_add_material(&retp, prim->material);
|
||||||
|
int has_norm = 0;
|
||||||
|
|
||||||
for (int k = 0; k < prim->attributes_count; k++) {
|
for (int k = 0; k < prim->attributes_count; k++) {
|
||||||
cgltf_attribute attribute = prim->attributes[k];
|
cgltf_attribute attribute = prim->attributes[k];
|
||||||
|
@ -200,7 +224,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
|
|
||||||
switch (attribute.type) {
|
switch (attribute.type) {
|
||||||
case cgltf_attribute_type_position:
|
case cgltf_attribute_type_position:
|
||||||
retp.pos = sg_make_buffer(&(sg_buffer_desc){
|
retp.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = vs,
|
.data.ptr = vs,
|
||||||
.data.size = sizeof(float) * n,
|
.data.size = sizeof(float) * n,
|
||||||
.label = "mesh vert buffer"
|
.label = "mesh vert buffer"
|
||||||
|
@ -208,26 +232,26 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_normal:
|
case cgltf_attribute_type_normal:
|
||||||
retp.norm = normal_floats(vs, verts, comp);
|
has_norm = 1;
|
||||||
|
retp.bind.vertex_buffers[2] = normal_floats(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_tangent:
|
case cgltf_attribute_type_tangent:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_color:
|
case cgltf_attribute_type_color:
|
||||||
retp.color = ubyten_buffer(vs,verts,comp);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_weights:
|
case cgltf_attribute_type_weights:
|
||||||
retp.weight = ubyten_buffer(vs, verts, comp);
|
retp.bind.vertex_buffers[3] = weight_buf(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_joints:
|
case cgltf_attribute_type_joints:
|
||||||
retp.bone = ubyte_buffer(vs, verts, comp);
|
retp.bind.vertex_buffers[4] = joint_buf(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_texcoord:
|
case cgltf_attribute_type_texcoord:
|
||||||
retp.uv = texcoord_floats(vs, verts, comp);
|
retp.bind.vertex_buffers[1] = texcoord_floats(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
case cgltf_attribute_type_invalid:
|
case cgltf_attribute_type_invalid:
|
||||||
YughWarn("Invalid type.");
|
YughWarn("Invalid type.");
|
||||||
|
@ -235,31 +259,12 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
|
|
||||||
case cgltf_attribute_type_custom:
|
case cgltf_attribute_type_custom:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_max_enum:
|
case cgltf_attribute_type_max_enum:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!retp.bone.id) {
|
if (!has_norm) {
|
||||||
char joints[retp.idx_count*4];
|
|
||||||
memset(joints, 0, retp.idx_count*4);
|
|
||||||
retp.bone = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(joints)});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!retp.weight.id) {
|
|
||||||
char weights[retp.idx_count*4];
|
|
||||||
memset(weights,0,retp.idx_count*4);
|
|
||||||
retp.weight = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(weights)});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!retp.color.id) {
|
|
||||||
char colors[retp.idx_count*4];
|
|
||||||
memset(colors,0,retp.idx_count*4);
|
|
||||||
retp.color = sg_make_buffer(&(sg_buffer_desc) { .data = SG_RANGE(colors) });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!retp.norm.id) {
|
|
||||||
YughInfo("Making normals.");
|
YughInfo("Making normals.");
|
||||||
cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position);
|
cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position);
|
||||||
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
||||||
|
@ -278,7 +283,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
face_norms[i] = face_norms[i+1] = face_norms[i+2] = packed_norm;
|
face_norms[i] = face_norms[i+1] = face_norms[i+2] = packed_norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
retp.norm = sg_make_buffer(&(sg_buffer_desc){
|
retp.bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.data.ptr = face_norms,
|
.data.ptr = face_norms,
|
||||||
.data.size = sizeof(uint32_t) * verts});
|
.data.size = sizeof(uint32_t) * verts});
|
||||||
}
|
}
|
||||||
|
@ -286,7 +291,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
return retp;
|
return retp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cgltf_data *cdata;
|
||||||
|
|
||||||
void model_add_cgltf_mesh(mesh *m, cgltf_mesh *gltf_mesh)
|
void model_add_cgltf_mesh(mesh *m, cgltf_mesh *gltf_mesh)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +382,7 @@ void model_add_cgltf_skin(model *model, cgltf_skin *skin)
|
||||||
sk.root = model->nodes+(skin->skeleton-cdata->nodes);
|
sk.root = model->nodes+(skin->skeleton-cdata->nodes);
|
||||||
|
|
||||||
for (int i = 0; i < 50; i++)
|
for (int i = 0; i < 50; i++)
|
||||||
sk.binds[i] = MAT1;
|
sk.binds[i] = HMM_M4D(1);
|
||||||
|
|
||||||
for (int i = 0; i < skin->joints_count; i++) {
|
for (int i = 0; i < skin->joints_count; i++) {
|
||||||
int offset = skin->joints[i]-cdata->nodes;
|
int offset = skin->joints[i]-cdata->nodes;
|
||||||
|
@ -412,7 +417,6 @@ void model_process_node(model *model, cgltf_node *node)
|
||||||
struct model *model_make(const char *path)
|
struct model *model_make(const char *path)
|
||||||
{
|
{
|
||||||
YughInfo("Making the model from %s.", path);
|
YughInfo("Making the model from %s.", path);
|
||||||
cpath = path;
|
|
||||||
cgltf_options options = {0};
|
cgltf_options options = {0};
|
||||||
cgltf_data *data = NULL;
|
cgltf_data *data = NULL;
|
||||||
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
||||||
|
@ -454,28 +458,8 @@ void model_free(model *m)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_bindings primitive_bind(primitive *p)
|
|
||||||
{
|
|
||||||
sg_bindings b = {0};
|
|
||||||
b.vertex_buffers[MAT_POS] = p->pos;
|
|
||||||
b.vertex_buffers[MAT_UV] = p->uv;
|
|
||||||
b.vertex_buffers[MAT_NORM] = p->norm;
|
|
||||||
b.vertex_buffers[MAT_BONE] = p->bone;
|
|
||||||
b.vertex_buffers[MAT_WEIGHT] = p->weight;
|
|
||||||
b.vertex_buffers[MAT_COLOR] = p->color;
|
|
||||||
b.index_buffer = p->idx;
|
|
||||||
b.fs.images[0] = p->mat->diffuse->id;
|
|
||||||
b.fs.samplers[0] = tex_sampler;
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
||||||
{
|
{
|
||||||
HMM_Mat4 view = t3d_go2world(cam);
|
|
||||||
HMM_Mat4 proj = HMM_Perspective_RH_NO(20, 1, 0.01, 10000);
|
|
||||||
HMM_Mat4 vp = HMM_MulM4(proj, view);
|
|
||||||
HMM_Mat4 gom = transform3d2mat(go2t3(go));
|
|
||||||
|
|
||||||
animation_run(&model->anim, apptime());
|
animation_run(&model->anim, apptime());
|
||||||
|
|
||||||
skin *sk = &model->skin;
|
skin *sk = &model->skin;
|
||||||
|
@ -486,21 +470,34 @@ void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
||||||
local = HMM_MulM4(md->parent->t, local);
|
local = HMM_MulM4(md->parent->t, local);
|
||||||
md->t = local;
|
md->t = local;
|
||||||
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
|
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
|
||||||
|
|
||||||
|
//printf("TRANSLATION OF %d IS " HMMFMT_VEC3 "\n", i, HMMPRINT_VEC3(md->pos));
|
||||||
}
|
}
|
||||||
/*sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_skinv, &(sg_range){
|
|
||||||
|
HMM_Mat4 view = t3d_go2world(cam);
|
||||||
|
HMM_Mat4 proj = HMM_Perspective_RH_NO(20, 1, 0.01, 10000);
|
||||||
|
HMM_Mat4 vp = HMM_MulM4(proj, view);
|
||||||
|
HMM_Mat4 gom = transform3d2mat(go2t3(go));
|
||||||
|
|
||||||
|
sg_apply_pipeline(model_pipe);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vp.e));
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_skinv, &(sg_range){
|
||||||
.ptr = sk->binds,
|
.ptr = sk->binds,
|
||||||
.size = sizeof(*sk->binds)*50
|
.size = sizeof(*sk->binds)*50
|
||||||
});
|
});
|
||||||
*/
|
float ambient[4] = {1.0,1.0,1.0,1.0};
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_lightf, SG_RANGE_REF(ambient));
|
||||||
for (int i = 0; i < arrlen(model->meshes); i++) {
|
for (int i = 0; i < arrlen(model->meshes); i++) {
|
||||||
HMM_Mat4 mod = *model->meshes[i].m;
|
HMM_Mat4 mod = *model->meshes[i].m;
|
||||||
mod = HMM_MulM4(mod, gom);
|
mod = HMM_MulM4(mod, gom);
|
||||||
mesh msh = model->meshes[i];
|
mesh msh = model->meshes[i];
|
||||||
for (int j = 0; j < arrlen(msh.primitives); j++) {
|
for (int j = 0; j < arrlen(msh.primitives); j++) {
|
||||||
sg_bindings b = primitive_bind(msh.primitives+j);
|
sg_apply_bindings(&(msh.primitives[j].bind));
|
||||||
sg_apply_bindings(&b);
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vmodel, &(sg_range){
|
||||||
sg_draw(0, msh.primitives[j].idx_count, 1);
|
.ptr = mod.em,
|
||||||
|
.size = sizeof(mod)
|
||||||
|
});
|
||||||
|
sg_draw(0, model->meshes[i].primitives[j].idx_count, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,7 @@
|
||||||
#include "anim.h"
|
#include "anim.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
#define MAT_POS 0
|
extern HMM_Vec3 eye;
|
||||||
#define MAT_UV 1
|
|
||||||
#define MAT_NORM 2
|
|
||||||
#define MAT_BONE 3
|
|
||||||
#define MAT_WEIGHT 4
|
|
||||||
#define MAT_COLOR 5
|
|
||||||
#define MAT_TAN 6
|
|
||||||
|
|
||||||
typedef struct material {
|
typedef struct material {
|
||||||
texture *diffuse;
|
texture *diffuse;
|
||||||
|
@ -32,14 +26,7 @@ typedef struct material {
|
||||||
struct model;
|
struct model;
|
||||||
|
|
||||||
typedef struct primitive {
|
typedef struct primitive {
|
||||||
sg_buffer pos;
|
sg_bindings bind;
|
||||||
sg_buffer norm;
|
|
||||||
sg_buffer uv;
|
|
||||||
sg_buffer bone;
|
|
||||||
sg_buffer weight;
|
|
||||||
sg_buffer color;
|
|
||||||
sg_buffer idx;
|
|
||||||
material *mat;
|
|
||||||
uint32_t idx_count;
|
uint32_t idx_count;
|
||||||
} primitive;
|
} primitive;
|
||||||
|
|
||||||
|
@ -73,7 +60,6 @@ typedef struct skin {
|
||||||
typedef struct model {
|
typedef struct model {
|
||||||
struct mesh *meshes;
|
struct mesh *meshes;
|
||||||
md5joint *nodes;
|
md5joint *nodes;
|
||||||
material *mats;
|
|
||||||
skin skin;
|
skin skin;
|
||||||
struct animation anim;
|
struct animation anim;
|
||||||
} model;
|
} model;
|
||||||
|
@ -84,6 +70,8 @@ void model_free(model *m);
|
||||||
|
|
||||||
void model_draw_go(model *m, gameobject *go, gameobject *cam);
|
void model_draw_go(model *m, gameobject *go, gameobject *cam);
|
||||||
|
|
||||||
|
void model_init();
|
||||||
|
|
||||||
material *material_make();
|
material *material_make();
|
||||||
void material_free(material *mat);
|
void material_free(material *mat);
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,6 @@ typedef union HMM_Vec2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
float Elements[2];
|
float Elements[2];
|
||||||
float e[2];
|
|
||||||
|
|
||||||
cpVect cp;
|
cpVect cp;
|
||||||
|
|
||||||
|
@ -280,7 +279,6 @@ typedef union HMM_Vec3 {
|
||||||
};
|
};
|
||||||
|
|
||||||
float Elements[3];
|
float Elements[3];
|
||||||
float e[3];
|
|
||||||
|
|
||||||
} HMM_Vec3;
|
} HMM_Vec3;
|
||||||
|
|
||||||
|
@ -405,7 +403,6 @@ typedef union HMM_Mat3 {
|
||||||
typedef union HMM_Mat4 {
|
typedef union HMM_Mat4 {
|
||||||
float Elements[4][4];
|
float Elements[4][4];
|
||||||
HMM_Vec4 Columns[4];
|
HMM_Vec4 Columns[4];
|
||||||
HMM_Vec4 col[4];
|
|
||||||
float e[4][4];
|
float e[4][4];
|
||||||
float em[16];
|
float em[16];
|
||||||
} HMM_Mat4;
|
} HMM_Mat4;
|
||||||
|
@ -424,8 +421,6 @@ static const HMM_Vec3 vBKWD = {0,0,-1};
|
||||||
static const HMM_Vec3 vLEFT = {-1,0,0};
|
static const HMM_Vec3 vLEFT = {-1,0,0};
|
||||||
static const HMM_Vec3 vRIGHT = {1,0,0};
|
static const HMM_Vec3 vRIGHT = {1,0,0};
|
||||||
|
|
||||||
static const HMM_Mat4 MAT1 = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Angle unit conversion functions
|
* Angle unit conversion functions
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <window.h>
|
#include <window.h>
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "debugdraw.h"
|
#include "debugdraw.h"
|
||||||
|
#include "text.sglsl.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
||||||
#include "stb_image_write.h"
|
#include "stb_image_write.h"
|
||||||
|
@ -21,7 +22,9 @@
|
||||||
|
|
||||||
struct sFont *use_font;
|
struct sFont *use_font;
|
||||||
|
|
||||||
|
static sg_shader fontshader;
|
||||||
static sg_bindings bind_text;
|
static sg_bindings bind_text;
|
||||||
|
static sg_pipeline pipe_text;
|
||||||
struct text_vert {
|
struct text_vert {
|
||||||
struct draw_p pos;
|
struct draw_p pos;
|
||||||
struct draw_p wh;
|
struct draw_p wh;
|
||||||
|
@ -33,6 +36,26 @@ struct text_vert {
|
||||||
static struct text_vert *text_buffer;
|
static struct text_vert *text_buffer;
|
||||||
|
|
||||||
void font_init() {
|
void font_init() {
|
||||||
|
fontshader = sg_make_shader(text_shader_desc(sg_query_backend()));
|
||||||
|
pipe_text = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
|
.shader = fontshader,
|
||||||
|
.layout = {
|
||||||
|
.attrs = {
|
||||||
|
[ATTR_vs_vert].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[ATTR_vs_vert].buffer_index = 1,
|
||||||
|
[ATTR_vs_pos].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[ATTR_vs_wh].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[ATTR_vs_uv].format = SG_VERTEXFORMAT_USHORT2N,
|
||||||
|
[ATTR_vs_st].format = SG_VERTEXFORMAT_USHORT2N,
|
||||||
|
[ATTR_vs_vColor].format = SG_VERTEXFORMAT_UBYTE4N,
|
||||||
|
},
|
||||||
|
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE
|
||||||
|
},
|
||||||
|
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||||
|
.colors[0].blend = blend_trans,
|
||||||
|
.label = "text",
|
||||||
|
});
|
||||||
|
|
||||||
bind_text.vertex_buffers[1] = sprite_quad;
|
bind_text.vertex_buffers[1] = sprite_quad;
|
||||||
|
|
||||||
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
|
@ -178,7 +201,7 @@ void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba
|
||||||
draw_box(b, wh, color);
|
draw_box(b, wh, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_flush() {
|
void text_flush(HMM_Mat4 *proj) {
|
||||||
if (arrlen(text_buffer) == 0) return;
|
if (arrlen(text_buffer) == 0) return;
|
||||||
|
|
||||||
sg_range verts;
|
sg_range verts;
|
||||||
|
@ -194,7 +217,9 @@ void text_flush() {
|
||||||
|
|
||||||
sg_append_buffer(bind_text.vertex_buffers[0], &verts);
|
sg_append_buffer(bind_text.vertex_buffers[0], &verts);
|
||||||
|
|
||||||
|
sg_apply_pipeline(pipe_text);
|
||||||
sg_apply_bindings(&bind_text);
|
sg_apply_bindings(&bind_text);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(*proj));
|
||||||
sg_draw(0, 4, arrlen(text_buffer));
|
sg_draw(0, 4, arrlen(text_buffer));
|
||||||
arrsetlen(text_buffer, 0);
|
arrsetlen(text_buffer, 0);
|
||||||
}
|
}
|
||||||
|
@ -352,7 +377,7 @@ int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, f
|
||||||
if (*wordstart == '\e')
|
if (*wordstart == '\e')
|
||||||
wordstart = esc_color(wordstart, &usecolor, color);
|
wordstart = esc_color(wordstart, &usecolor, color);
|
||||||
|
|
||||||
//sdrawCharacter(use_font->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
|
sdrawCharacter(use_font->Characters[*wordstart], HMM_AddV2(cursor, HMM_MulV2F((HMM_Vec2){1,-1},scale)), scale, (rgba){0,0,0,255});
|
||||||
sdrawCharacter(use_font->Characters[*wordstart], cursor, scale, usecolor);
|
sdrawCharacter(use_font->Characters[*wordstart], cursor, scale, usecolor);
|
||||||
|
|
||||||
cursor.X += use_font->Characters[*wordstart].Advance * tracking * scale;
|
cursor.X += use_font->Characters[*wordstart].Advance * tracking * scale;
|
||||||
|
|
|
@ -40,6 +40,7 @@ void text_settype(struct sFont *font);
|
||||||
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking);
|
struct boundingbox text_bb(const char *text, float scale, float lw, float tracking);
|
||||||
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking);
|
int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking);
|
||||||
|
|
||||||
void text_flush();
|
// void text_frame();
|
||||||
|
void text_flush(HMM_Mat4 *proj);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -204,3 +204,9 @@ HMM_Vec3 go_pos3d(gameobject *go)
|
||||||
HMM_Vec2 pos2d = go_pos(go);
|
HMM_Vec2 pos2d = go_pos(go);
|
||||||
return (HMM_Vec3){pos2d.x, pos2d.y, go->drawlayer};
|
return (HMM_Vec3){pos2d.x, pos2d.y, go->drawlayer};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gameobject_draw_debug(gameobject *go) {
|
||||||
|
if (!go || !go->body) return;
|
||||||
|
|
||||||
|
cpBodyEachShape(go->body, body_draw_shapes_dbg, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -61,10 +61,7 @@ const char *js2str(JSValue v) {
|
||||||
return JS_ToCString(js, v);
|
return JS_ToCString(js, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jsfreestr(const char *s) { JS_FreeCString(js, s); }
|
|
||||||
QJSCLASS(gameobject)
|
QJSCLASS(gameobject)
|
||||||
QJSCLASS(transform3d)
|
|
||||||
QJSCLASS(transform2d)
|
|
||||||
QJSCLASS(emitter)
|
QJSCLASS(emitter)
|
||||||
QJSCLASS(dsp_node)
|
QJSCLASS(dsp_node)
|
||||||
QJSCLASS(texture)
|
QJSCLASS(texture)
|
||||||
|
@ -143,7 +140,6 @@ JSValue ptr2js(void *ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int js_arrlen(JSValue v) {
|
int js_arrlen(JSValue v) {
|
||||||
if (JS_IsUndefined(v)) return 0;
|
|
||||||
int len;
|
int len;
|
||||||
JS_ToInt32(js, &len, js_getpropstr( v, "length"));
|
JS_ToInt32(js, &len, js_getpropstr( v, "length"));
|
||||||
return len;
|
return len;
|
||||||
|
@ -335,22 +331,6 @@ JSValue vec32js(HMM_Vec3 v)
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
HMM_Vec4 js2vec4(JSValue v)
|
|
||||||
{
|
|
||||||
HMM_Vec4 v4;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
v4.e[i] = js2number(js_getpropidx(v,i));
|
|
||||||
return v4;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue vec42js(HMM_Vec4 v)
|
|
||||||
{
|
|
||||||
JSValue array = JS_NewArray(js);
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
js_setprop_num(array,i,number2js(v.e[i]));
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpBitmask js2bitmask(JSValue v) {
|
cpBitmask js2bitmask(JSValue v) {
|
||||||
cpBitmask a;
|
cpBitmask a;
|
||||||
JS_ToUint32(js, &a, v);
|
JS_ToUint32(js, &a, v);
|
||||||
|
@ -625,10 +605,7 @@ JSC_CCALL(render_line3d,
|
||||||
);
|
);
|
||||||
|
|
||||||
JSC_CCALL(render_emitters, emitters_draw(&useproj))
|
JSC_CCALL(render_emitters, emitters_draw(&useproj))
|
||||||
JSC_CCALL(render_flush, debug_flush(&useproj); )
|
JSC_CCALL(render_flush, debug_flush(&useproj); text_flush(&useproj); )
|
||||||
|
|
||||||
JSC_CCALL(render_flushtext, text_flush())
|
|
||||||
|
|
||||||
JSC_CCALL(render_end_pass,
|
JSC_CCALL(render_end_pass,
|
||||||
sg_end_pass();
|
sg_end_pass();
|
||||||
sg_commit();
|
sg_commit();
|
||||||
|
@ -646,199 +623,8 @@ JSC_CCALL(render_clear_color,
|
||||||
pass_action.colors[0].clear_value = c;
|
pass_action.colors[0].clear_value = c;
|
||||||
)
|
)
|
||||||
|
|
||||||
sg_shader js2shader(JSValue v)
|
JSC_CCALL(render_set_sprite_tex, sprite_tex(js2texture(argv[0])))
|
||||||
{
|
JSC_CCALL(render_sprite_flush, sprite_flush())
|
||||||
sg_shader_desc desc = {0};
|
|
||||||
JSValue prog = v;
|
|
||||||
JSValue vs = js_getpropstr(prog, "vs");
|
|
||||||
JSValue fs = js_getpropstr(prog, "fs");
|
|
||||||
char *vsf = js2str(js_getpropstr(vs, "code"));
|
|
||||||
char *fsf = js2str(js_getpropstr(fs, "code"));
|
|
||||||
desc.vs.source = vsf;
|
|
||||||
desc.fs.source = fsf;
|
|
||||||
char *vsmain = js2str(js_getpropstr(vs, "entry_point"));
|
|
||||||
char *fsmain = js2str(js_getpropstr(fs, "entry_point"));
|
|
||||||
desc.vs.entry = vsmain;
|
|
||||||
desc.fs.entry = fsmain;
|
|
||||||
JSValue vsu = js_getpropstr(vs, "uniform_blocks");
|
|
||||||
int unin = js_arrlen(vsu);
|
|
||||||
for (int i = 0; i < unin; i++) {
|
|
||||||
JSValue u = js_getpropidx(vsu, i);
|
|
||||||
int slot = js2number(js_getpropstr(u, "slot"));
|
|
||||||
desc.vs.uniform_blocks[slot].size = js2number(js_getpropstr(u, "size"));
|
|
||||||
desc.vs.uniform_blocks[slot].layout = SG_UNIFORMLAYOUT_STD140;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue fsu = js_getpropstr(fs, "uniform_blocks");
|
|
||||||
unin = js_arrlen(fsu);
|
|
||||||
for (int i = 0; i < unin; i++) {
|
|
||||||
JSValue u = js_getpropidx(fsu, i);
|
|
||||||
int slot = js2number(js_getpropstr(u, "slot"));
|
|
||||||
desc.fs.uniform_blocks[slot].size = js2number(js_getpropstr(u, "size"));
|
|
||||||
desc.fs.uniform_blocks[slot].layout = SG_UNIFORMLAYOUT_STD140;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue imgs = js_getpropstr(fs, "images");
|
|
||||||
unin = js_arrlen(imgs);
|
|
||||||
for (int i = 0; i < unin; i++) {
|
|
||||||
JSValue u = js_getpropidx(imgs, i);
|
|
||||||
int slot = js2number(js_getpropstr(u, "slot"));
|
|
||||||
desc.fs.images[i].used = true;
|
|
||||||
desc.fs.images[i].multisampled = js2boolean(js_getpropstr(u, "multisampled"));
|
|
||||||
desc.fs.images[i].image_type = SG_IMAGETYPE_2D;
|
|
||||||
desc.fs.images[i].sample_type = SG_IMAGESAMPLETYPE_FLOAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue samps = js_getpropstr(fs, "samplers");
|
|
||||||
unin = js_arrlen(samps);
|
|
||||||
for (int i = 0; i < unin; i++) {
|
|
||||||
desc.fs.samplers[0].used = true;
|
|
||||||
desc.fs.samplers[0].sampler_type = SG_SAMPLERTYPE_FILTERING;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue pairs = js_getpropstr(fs, "image_sampler_pairs");
|
|
||||||
unin = js_arrlen(pairs);
|
|
||||||
for (int i = 0; i < unin; i++) {
|
|
||||||
desc.fs.image_sampler_pairs[0].used = true;
|
|
||||||
desc.fs.image_sampler_pairs[0].image_slot = 0;
|
|
||||||
desc.fs.image_sampler_pairs[0].sampler_slot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_shader sh = sg_make_shader(&desc);
|
|
||||||
|
|
||||||
jsfreestr(vsf);
|
|
||||||
jsfreestr(fsf);
|
|
||||||
jsfreestr(vsmain);
|
|
||||||
jsfreestr(fsmain);
|
|
||||||
|
|
||||||
return sh;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSC_CCALL(render_pipeline3d,
|
|
||||||
sg_shader sgshader = js2shader(argv[0]);
|
|
||||||
sg_pipeline_desc p = {0};
|
|
||||||
p.shader = sgshader;
|
|
||||||
sg_vertex_layout_state st = {0};
|
|
||||||
st.attrs[MAT_POS].format = SG_VERTEXFORMAT_FLOAT3;
|
|
||||||
st.attrs[MAT_UV].format = SG_VERTEXFORMAT_USHORT2N;
|
|
||||||
st.attrs[MAT_UV].buffer_index = MAT_UV;
|
|
||||||
st.attrs[MAT_NORM].format = SG_VERTEXFORMAT_UINT10_N2;
|
|
||||||
st.attrs[MAT_NORM].buffer_index = MAT_NORM;
|
|
||||||
st.attrs[MAT_WEIGHT].format = SG_VERTEXFORMAT_UBYTE4N;
|
|
||||||
st.attrs[MAT_WEIGHT].buffer_index = MAT_WEIGHT;
|
|
||||||
st.attrs[MAT_BONE].format = SG_VERTEXFORMAT_UBYTE4;
|
|
||||||
st.attrs[MAT_BONE].buffer_index = MAT_BONE;
|
|
||||||
st.attrs[MAT_COLOR].format = SG_VERTEXFORMAT_UBYTE4N;
|
|
||||||
st.attrs[MAT_COLOR].buffer_index = MAT_COLOR;
|
|
||||||
p.layout = st;
|
|
||||||
p.index_type = SG_INDEXTYPE_UINT16;
|
|
||||||
p.depth.write_enabled = true;
|
|
||||||
p.depth.compare = SG_COMPAREFUNC_LESS_EQUAL;
|
|
||||||
p.cull_mode = SG_CULLMODE_FRONT;
|
|
||||||
|
|
||||||
sg_pipeline pipe = sg_make_pipeline(&p);
|
|
||||||
return number2js(pipe.id);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_pipelinetext,
|
|
||||||
sg_shader fontshader = js2shader(argv[0]);
|
|
||||||
sg_pipeline_desc p = {0};
|
|
||||||
p.shader = fontshader;
|
|
||||||
sg_vertex_layout_state st = {0};
|
|
||||||
st.attrs[0].format = SG_VERTEXFORMAT_FLOAT2;
|
|
||||||
st.attrs[0].buffer_index = 1;
|
|
||||||
st.attrs[1].format = SG_VERTEXFORMAT_FLOAT2;
|
|
||||||
st.attrs[2].format = SG_VERTEXFORMAT_FLOAT2;
|
|
||||||
st.attrs[3].format = SG_VERTEXFORMAT_USHORT2N;
|
|
||||||
st.attrs[4].format = SG_VERTEXFORMAT_USHORT2N;
|
|
||||||
st.attrs[5].format = SG_VERTEXFORMAT_UBYTE4N;
|
|
||||||
st.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE;
|
|
||||||
p.layout = st;
|
|
||||||
p.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP;
|
|
||||||
p.colors[0].blend = blend_trans;
|
|
||||||
|
|
||||||
sg_pipeline pipe = sg_make_pipeline(&p);
|
|
||||||
return number2js(pipe.id);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_pipeline,
|
|
||||||
sg_shader sgshader = js2shader(argv[0]);
|
|
||||||
|
|
||||||
sg_pipeline_desc pdesc = {0};
|
|
||||||
pdesc.shader = sgshader;
|
|
||||||
pdesc.cull_mode = SG_CULLMODE_FRONT;
|
|
||||||
|
|
||||||
pdesc.layout.attrs[0].format = SG_VERTEXFORMAT_FLOAT2;
|
|
||||||
pdesc.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP;
|
|
||||||
if (js2boolean(js_getpropstr(argv[0], "blend")))
|
|
||||||
pdesc.colors[0].blend = blend_trans;
|
|
||||||
|
|
||||||
sg_pipeline pipe = sg_make_pipeline(&pdesc);
|
|
||||||
|
|
||||||
return number2js(pipe.id);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setuniv,
|
|
||||||
float f = js2number(argv[2]);
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(f));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setuniv2,
|
|
||||||
HMM_Vec2 v = js2vec2(argv[2]);
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setuniv3,
|
|
||||||
HMM_Vec3 v = js2vec3(argv[2]);
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setuniv4,
|
|
||||||
HMM_Vec4 v = js2vec4(argv[2]);
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(v.e));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setuniproj,
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(useproj));
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setunim4,
|
|
||||||
HMM_Mat4 m = MAT1;
|
|
||||||
if (JS_IsArray(js, argv[2])) {
|
|
||||||
JSValue arr = argv[2];
|
|
||||||
int n = js_arrlen(arr);
|
|
||||||
if (n == 1)
|
|
||||||
m = transform2d2mat4(js2transform2d(js_getpropidx(arr,0)));
|
|
||||||
else {
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
HMM_Mat4 p = transform2d2mat4(js2transform2d(js_getpropidx(arr, i)));
|
|
||||||
m = HMM_MulM4(p,m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
m = transform2d2mat4(js2transform2d(argv[2]));
|
|
||||||
|
|
||||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(m.e));
|
|
||||||
);
|
|
||||||
|
|
||||||
JSC_CCALL(render_spdraw,
|
|
||||||
sg_bindings bind = {0};
|
|
||||||
bind.vertex_buffers[0] = sprite_quad;
|
|
||||||
|
|
||||||
for (int i = 0; i < js_arrlen(argv[0]); i++) {
|
|
||||||
bind.fs.images[i] = js2texture(js_getpropidx(argv[0], i))->id;
|
|
||||||
bind.fs.samplers[i] = std_sampler;
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_apply_bindings(&bind);
|
|
||||||
sg_draw(0,4,1);
|
|
||||||
)
|
|
||||||
|
|
||||||
JSC_CCALL(render_setpipeline,
|
|
||||||
sg_pipeline p = {0};
|
|
||||||
p.id = js2number(argv[0]);
|
|
||||||
sg_apply_pipeline(p);
|
|
||||||
)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_render_funcs[] = {
|
static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
MIST_FUNC_DEF(render, grid, 3),
|
MIST_FUNC_DEF(render, grid, 3),
|
||||||
|
@ -848,24 +634,14 @@ static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
MIST_FUNC_DEF(render, line, 3),
|
MIST_FUNC_DEF(render, line, 3),
|
||||||
MIST_FUNC_DEF(render, line3d, 2),
|
MIST_FUNC_DEF(render, line3d, 2),
|
||||||
MIST_FUNC_DEF(render, emitters, 0),
|
MIST_FUNC_DEF(render, emitters, 0),
|
||||||
MIST_FUNC_DEF(render, flushtext, 0),
|
|
||||||
MIST_FUNC_DEF(render, flush, 0),
|
MIST_FUNC_DEF(render, flush, 0),
|
||||||
MIST_FUNC_DEF(render, end_pass, 0),
|
MIST_FUNC_DEF(render, end_pass, 0),
|
||||||
MIST_FUNC_DEF(render, text_size, 3),
|
MIST_FUNC_DEF(render, text_size, 3),
|
||||||
MIST_FUNC_DEF(render, set_camera, 0),
|
MIST_FUNC_DEF(render, set_camera, 0),
|
||||||
MIST_FUNC_DEF(render, hud_res, 1),
|
MIST_FUNC_DEF(render, hud_res, 1),
|
||||||
MIST_FUNC_DEF(render, clear_color, 1),
|
MIST_FUNC_DEF(render, clear_color, 1),
|
||||||
MIST_FUNC_DEF(render, pipeline, 1),
|
MIST_FUNC_DEF(render, set_sprite_tex, 1),
|
||||||
MIST_FUNC_DEF(render, pipeline3d, 1),
|
MIST_FUNC_DEF(render, sprite_flush, 0),
|
||||||
MIST_FUNC_DEF(render, pipelinetext, 1),
|
|
||||||
MIST_FUNC_DEF(render, setuniv3, 2),
|
|
||||||
MIST_FUNC_DEF(render, setuniv, 2),
|
|
||||||
MIST_FUNC_DEF(render, spdraw, 2),
|
|
||||||
MIST_FUNC_DEF(render, setuniproj, 2),
|
|
||||||
MIST_FUNC_DEF(render, setunim4, 3),
|
|
||||||
MIST_FUNC_DEF(render, setuniv2, 2),
|
|
||||||
MIST_FUNC_DEF(render, setuniv4, 2),
|
|
||||||
MIST_FUNC_DEF(render, setpipeline, 1)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
JSC_CCALL(gui_flush, text_flush(&useproj));
|
JSC_CCALL(gui_flush, text_flush(&useproj));
|
||||||
|
@ -883,12 +659,21 @@ JSC_CCALL(gui_text,
|
||||||
return ret;
|
return ret;
|
||||||
)
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(gui_img,
|
||||||
|
transform2d t;
|
||||||
|
t.pos = js2vec2(argv[1]);
|
||||||
|
t.scale = js2vec2(argv[2]);
|
||||||
|
t.angle = js2number(argv[3]);
|
||||||
|
gui_draw_img(js2texture(argv[0]), t, js2boolean(argv[4]), js2vec2(argv[5]), 1.0, js2color(argv[6]));
|
||||||
|
)
|
||||||
|
|
||||||
JSC_CCALL(gui_font_set, font_set(js2font(argv[0])))
|
JSC_CCALL(gui_font_set, font_set(js2font(argv[0])))
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_gui_funcs[] = {
|
static const JSCFunctionListEntry js_gui_funcs[] = {
|
||||||
MIST_FUNC_DEF(gui, flush, 0),
|
MIST_FUNC_DEF(gui, flush, 0),
|
||||||
MIST_FUNC_DEF(gui, scissor, 4),
|
MIST_FUNC_DEF(gui, scissor, 4),
|
||||||
MIST_FUNC_DEF(gui, text, 6),
|
MIST_FUNC_DEF(gui, text, 6),
|
||||||
|
MIST_FUNC_DEF(gui, img, 7),
|
||||||
MIST_FUNC_DEF(gui, font_set,1)
|
MIST_FUNC_DEF(gui, font_set,1)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -960,7 +745,7 @@ static const JSCFunctionListEntry js_input_funcs[] = {
|
||||||
|
|
||||||
JSC_CCALL(prosperon_emitters_step, emitters_step(js2number(argv[0])))
|
JSC_CCALL(prosperon_emitters_step, emitters_step(js2number(argv[0])))
|
||||||
JSC_CCALL(prosperon_phys2d_step, phys2d_update(js2number(argv[0])))
|
JSC_CCALL(prosperon_phys2d_step, phys2d_update(js2number(argv[0])))
|
||||||
JSC_CCALL(prosperon_window_render, openglRender(&mainwin, js2transform2d(argv[0]), js2number(argv[1])))
|
JSC_CCALL(prosperon_window_render, openglRender(&mainwin, js2gameobject(argv[0]), js2number(argv[1])))
|
||||||
JSC_CCALL(prosperon_guid,
|
JSC_CCALL(prosperon_guid,
|
||||||
uint8_t bytes[16];
|
uint8_t bytes[16];
|
||||||
for (int i = 0; i < 16; i++) bytes[i] = rand()%256;
|
for (int i = 0; i < 16; i++) bytes[i] = rand()%256;
|
||||||
|
@ -1108,7 +893,6 @@ JSC_SCALL(io_save_qoa, save_qoa(str))
|
||||||
JSC_SCALL(io_pack_start, pack_start(str))
|
JSC_SCALL(io_pack_start, pack_start(str))
|
||||||
JSC_SCALL(io_pack_add, pack_add(str))
|
JSC_SCALL(io_pack_add, pack_add(str))
|
||||||
JSC_CCALL(io_pack_end, pack_end())
|
JSC_CCALL(io_pack_end, pack_end())
|
||||||
JSC_SCALL(io_mod, ret = number2js(file_mod_secs(str));)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_io_funcs[] = {
|
static const JSCFunctionListEntry js_io_funcs[] = {
|
||||||
MIST_FUNC_DEF(io, exists,1),
|
MIST_FUNC_DEF(io, exists,1),
|
||||||
|
@ -1125,10 +909,11 @@ static const JSCFunctionListEntry js_io_funcs[] = {
|
||||||
MIST_FUNC_DEF(io, save_qoa,1),
|
MIST_FUNC_DEF(io, save_qoa,1),
|
||||||
MIST_FUNC_DEF(io, pack_start, 1),
|
MIST_FUNC_DEF(io, pack_start, 1),
|
||||||
MIST_FUNC_DEF(io, pack_add, 1),
|
MIST_FUNC_DEF(io, pack_add, 1),
|
||||||
MIST_FUNC_DEF(io, pack_end, 0),
|
MIST_FUNC_DEF(io, pack_end, 0)
|
||||||
MIST_FUNC_DEF(io, mod,1)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JSC_CCALL(debug_draw_gameobject, gameobject_draw_debug(js2gameobject(argv[0]));)
|
||||||
|
|
||||||
JSC_GETSET_GLOBAL(disabled_color, color)
|
JSC_GETSET_GLOBAL(disabled_color, color)
|
||||||
JSC_GETSET_GLOBAL(sleep_color, color)
|
JSC_GETSET_GLOBAL(sleep_color, color)
|
||||||
JSC_GETSET_GLOBAL(dynamic_color, color)
|
JSC_GETSET_GLOBAL(dynamic_color, color)
|
||||||
|
@ -1136,6 +921,7 @@ JSC_GETSET_GLOBAL(kinematic_color, color)
|
||||||
JSC_GETSET_GLOBAL(static_color, color)
|
JSC_GETSET_GLOBAL(static_color, color)
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_debug_funcs[] = {
|
static const JSCFunctionListEntry js_debug_funcs[] = {
|
||||||
|
MIST_FUNC_DEF(debug, draw_gameobject, 1),
|
||||||
CGETSET_ADD(global, disabled_color),
|
CGETSET_ADD(global, disabled_color),
|
||||||
CGETSET_ADD(global, sleep_color),
|
CGETSET_ADD(global, sleep_color),
|
||||||
CGETSET_ADD(global, dynamic_color),
|
CGETSET_ADD(global, dynamic_color),
|
||||||
|
@ -1247,8 +1033,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,
|
JSC_CCALL(model_draw_go,
|
||||||
model_draw_go(js2model(this), js2gameobject(argv[0]), js2gameobject(argv[1]))
|
model_draw_go(js2model(this), js2gameobject(argv[0]), js2gameobject(argv[1]))
|
||||||
);
|
);
|
||||||
|
@ -1281,16 +1065,6 @@ static const JSCFunctionListEntry js_emitter_funcs[] = {
|
||||||
CGETSET_ADD(emitter, texture),
|
CGETSET_ADD(emitter, texture),
|
||||||
};
|
};
|
||||||
|
|
||||||
JSC_GETSET(transform2d, pos, vec2)
|
|
||||||
JSC_GETSET(transform2d, scale, vec2)
|
|
||||||
JSC_GETSET(transform2d, angle, number)
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_transform2d_funcs[] = {
|
|
||||||
CGETSET_ADD(transform2d, pos),
|
|
||||||
CGETSET_ADD(transform2d, scale),
|
|
||||||
CGETSET_ADD(transform2d, angle)
|
|
||||||
};
|
|
||||||
|
|
||||||
JSC_GETSET(dsp_node, pass, boolean)
|
JSC_GETSET(dsp_node, pass, boolean)
|
||||||
JSC_GETSET(dsp_node, off, boolean)
|
JSC_GETSET(dsp_node, off, boolean)
|
||||||
JSC_GETSET(dsp_node, gain, number)
|
JSC_GETSET(dsp_node, gain, number)
|
||||||
|
@ -1543,12 +1317,22 @@ static const JSCFunctionListEntry js_pshape_funcs[] = {
|
||||||
|
|
||||||
JSC_GETSET(sprite, color, color)
|
JSC_GETSET(sprite, color, color)
|
||||||
JSC_GETSET(sprite, emissive, color)
|
JSC_GETSET(sprite, emissive, color)
|
||||||
|
JSC_GETSET(sprite, pos, vec2)
|
||||||
|
JSC_GETSET(sprite, scale, vec2)
|
||||||
|
JSC_GETSET(sprite, angle, number)
|
||||||
JSC_GETSET(sprite, spriteoffset, vec2)
|
JSC_GETSET(sprite, spriteoffset, vec2)
|
||||||
|
JSC_GETSET(sprite, spritesize, vec2)
|
||||||
|
JSC_CCALL(sprite_draw, sprite_draw(js2sprite(this), js2gameobject(argv[0])))
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_sprite_funcs[] = {
|
static const JSCFunctionListEntry js_sprite_funcs[] = {
|
||||||
|
CGETSET_ADD(sprite,pos),
|
||||||
|
CGETSET_ADD(sprite,scale),
|
||||||
|
CGETSET_ADD(sprite,angle),
|
||||||
CGETSET_ADD(sprite,color),
|
CGETSET_ADD(sprite,color),
|
||||||
CGETSET_ADD(sprite,emissive),
|
CGETSET_ADD(sprite,emissive),
|
||||||
CGETSET_ADD(sprite, spriteoffset),
|
CGETSET_ADD(sprite, spriteoffset),
|
||||||
|
CGETSET_ADD(sprite, spritesize),
|
||||||
|
MIST_FUNC_DEF(sprite, draw, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSC_GET(texture, width, number)
|
JSC_GET(texture, width, number)
|
||||||
|
@ -1752,22 +1536,11 @@ JSC_SCALL(os_make_texture,
|
||||||
|
|
||||||
JSC_CCALL(os_make_font, return font2js(MakeFont(js2str(argv[0]), js2number(argv[1]))))
|
JSC_CCALL(os_make_font, return font2js(MakeFont(js2str(argv[0]), js2number(argv[1]))))
|
||||||
|
|
||||||
JSC_CCALL(os_make_transform2d,
|
JSC_SCALL(os_system, system(str); )
|
||||||
if (JS_IsUndefined(argv[0]))
|
|
||||||
return transform2d2js(make_transform2d());
|
|
||||||
|
|
||||||
int n = js2number(argv[0]);
|
JSC_SCALL(os_make_model, return model2js(model_make(str)))
|
||||||
transform2d *t = calloc(sizeof(transform2d), n);
|
|
||||||
JSValue arr = JS_NewArray(js);
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
js_setprop_num(arr, i, transform2d2js(t+i));
|
|
||||||
|
|
||||||
return arr;
|
JSC_CCALL(os_sprite_pipe, sprite_pipe())
|
||||||
)
|
|
||||||
|
|
||||||
JSC_SCALL(os_system, return number2js(system(str)); )
|
|
||||||
|
|
||||||
JSC_SCALL(os_make_model, ret = model2js(model_make(str)))
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_os_funcs[] = {
|
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os,sprite,1),
|
MIST_FUNC_DEF(os,sprite,1),
|
||||||
|
@ -1788,7 +1561,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
||||||
MIST_FUNC_DEF(os, make_texture, 1),
|
MIST_FUNC_DEF(os, make_texture, 1),
|
||||||
MIST_FUNC_DEF(os, make_font, 2),
|
MIST_FUNC_DEF(os, make_font, 2),
|
||||||
MIST_FUNC_DEF(os, make_model, 1),
|
MIST_FUNC_DEF(os, make_model, 1),
|
||||||
MIST_FUNC_DEF(os, make_transform2d, 1),
|
MIST_FUNC_DEF(os, sprite_pipe, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "steam.h"
|
#include "steam.h"
|
||||||
|
@ -1797,13 +1570,10 @@ void ffi_load() {
|
||||||
globalThis = JS_GetGlobalObject(js);
|
globalThis = JS_GetGlobalObject(js);
|
||||||
|
|
||||||
QJSCLASSPREP(ptr);
|
QJSCLASSPREP(ptr);
|
||||||
QJSCLASSPREP(transform3d);
|
|
||||||
|
|
||||||
|
|
||||||
QJSGLOBALCLASS(os);
|
QJSGLOBALCLASS(os);
|
||||||
|
|
||||||
QJSCLASSPREP_FUNCS(gameobject);
|
QJSCLASSPREP_FUNCS(gameobject);
|
||||||
QJSCLASSPREP_FUNCS(transform2d);
|
|
||||||
QJSCLASSPREP_FUNCS(dsp_node);
|
QJSCLASSPREP_FUNCS(dsp_node);
|
||||||
QJSCLASSPREP_FUNCS(emitter);
|
QJSCLASSPREP_FUNCS(emitter);
|
||||||
QJSCLASSPREP_FUNCS(warp_gravity);
|
QJSCLASSPREP_FUNCS(warp_gravity);
|
||||||
|
|
|
@ -135,9 +135,4 @@ JSValue str2js(const char *c, ...);
|
||||||
|
|
||||||
void nota_int(char *blob);
|
void nota_int(char *blob);
|
||||||
|
|
||||||
JSValue js_getpropidx(JSValue v, uint32_t i);
|
|
||||||
JSValue js_getpropstr(JSValue v, const char *str);
|
|
||||||
const char *js2str(JSValue v);
|
|
||||||
void jsfreestr(const char *str);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,6 @@ float camzoom = 1;
|
||||||
|
|
||||||
sg_buffer sprite_quad;
|
sg_buffer sprite_quad;
|
||||||
sg_sampler std_sampler;
|
sg_sampler std_sampler;
|
||||||
sg_sampler tex_sampler;
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
sg_swapchain swap;
|
sg_swapchain swap;
|
||||||
|
@ -243,13 +242,6 @@ void render_init() {
|
||||||
});
|
});
|
||||||
|
|
||||||
std_sampler = sg_make_sampler(&(sg_sampler_desc){});
|
std_sampler = sg_make_sampler(&(sg_sampler_desc){});
|
||||||
tex_sampler = sg_make_sampler(&(sg_sampler_desc){
|
|
||||||
.min_filter = SG_FILTER_LINEAR,
|
|
||||||
.mag_filter = SG_FILTER_LINEAR,
|
|
||||||
.mipmap_filter = SG_FILTER_LINEAR,
|
|
||||||
.wrap_u = SG_WRAP_REPEAT,
|
|
||||||
.wrap_v = SG_WRAP_REPEAT
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
|
sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
|
||||||
|
@ -257,6 +249,9 @@ void render_init() {
|
||||||
|
|
||||||
font_init();
|
font_init();
|
||||||
debugdraw_init();
|
debugdraw_init();
|
||||||
|
sprite_initialize();
|
||||||
|
|
||||||
|
model_init();
|
||||||
|
|
||||||
sg_color c = (sg_color){0,0,0,1};
|
sg_color c = (sg_color){0,0,0,1};
|
||||||
pass_action = (sg_pass_action){
|
pass_action = (sg_pass_action){
|
||||||
|
@ -295,9 +290,6 @@ void render_init() {
|
||||||
1, 1, 1, 1
|
1, 1, 1, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
sg_limits ll = sg_query_limits();
|
|
||||||
printf("attribute limits %d\n", ll.max_vertex_attrs);
|
|
||||||
|
|
||||||
sg_gif.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
sg_gif.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
.size = sizeof(gif_quad),
|
.size = sizeof(gif_quad),
|
||||||
.data = gif_quad,
|
.data = gif_quad,
|
||||||
|
@ -338,7 +330,7 @@ HMM_Mat4 useproj = {0};
|
||||||
#define MODE_EXPAND 4
|
#define MODE_EXPAND 4
|
||||||
#define MODE_FULL 5
|
#define MODE_FULL 5
|
||||||
|
|
||||||
void openglRender(struct window *window, transform2d *cam, float zoom) {
|
void openglRender(struct window *window, gameobject *cam, float zoom) {
|
||||||
sg_swapchain sch = sglue_swapchain();
|
sg_swapchain sch = sglue_swapchain();
|
||||||
sg_begin_pass(&(sg_pass){
|
sg_begin_pass(&(sg_pass){
|
||||||
.action = pass_action,
|
.action = pass_action,
|
||||||
|
@ -373,7 +365,7 @@ void openglRender(struct window *window, transform2d *cam, float zoom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2D projection
|
// 2D projection
|
||||||
campos = cam->pos;
|
campos = go_pos(cam);
|
||||||
camzoom = zoom;
|
camzoom = zoom;
|
||||||
|
|
||||||
projection = HMM_Orthographic_RH_NO(
|
projection = HMM_Orthographic_RH_NO(
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
#include "transform.h"
|
|
||||||
|
|
||||||
#define RGBA_MAX 255
|
#define RGBA_MAX 255
|
||||||
|
|
||||||
|
@ -35,7 +34,6 @@ extern sg_pass_action pass_action;
|
||||||
|
|
||||||
extern sg_buffer sprite_quad;
|
extern sg_buffer sprite_quad;
|
||||||
extern sg_sampler std_sampler;
|
extern sg_sampler std_sampler;
|
||||||
extern sg_sampler tex_sampler;
|
|
||||||
|
|
||||||
struct draw_p {
|
struct draw_p {
|
||||||
float x;
|
float x;
|
||||||
|
@ -62,7 +60,7 @@ void render_init();
|
||||||
extern HMM_Vec2 campos;
|
extern HMM_Vec2 campos;
|
||||||
extern float camzoom;
|
extern float camzoom;
|
||||||
|
|
||||||
void openglRender(struct window *window, transform2d *cam, float zoom);
|
void openglRender(struct window *window, gameobject *cam, float zoom);
|
||||||
void opengl_rendermode(enum RenderMode r);
|
void opengl_rendermode(enum RenderMode r);
|
||||||
|
|
||||||
void openglInit3d(struct window *window);
|
void openglInit3d(struct window *window);
|
||||||
|
|
|
@ -126,17 +126,6 @@ char *dirname(const char *path)
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *makepath(char *dir, char *file)
|
|
||||||
{
|
|
||||||
int d = strlen(dir) + strlen(file) + 2;
|
|
||||||
char *path = malloc(d);
|
|
||||||
path[0] = 0;
|
|
||||||
strncat(path, dir, d);
|
|
||||||
strncat(path, "/", d);
|
|
||||||
strncat(path, file, d);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *seprint(char *fmt, ...)
|
char *seprint(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
|
@ -11,8 +11,7 @@ extern int LOADED_GAME;
|
||||||
|
|
||||||
void resources_init();
|
void resources_init();
|
||||||
char *get_filename_from_path(char *path, int extension);
|
char *get_filename_from_path(char *path, int extension);
|
||||||
char *dirname(const char *path);
|
char *get_directory_from_path(char *path);
|
||||||
char *makepath(char *dir, char *file);
|
|
||||||
char *str_replace_ext(const char *s, const char *newext);
|
char *str_replace_ext(const char *s, const char *newext);
|
||||||
FILE *res_open(char *path, const char *tag);
|
FILE *res_open(char *path, const char *tag);
|
||||||
char **ls(const char *path);
|
char **ls(const char *path);
|
||||||
|
@ -23,6 +22,8 @@ void pack_start(const char *name);
|
||||||
void pack_add(const char *path);
|
void pack_add(const char *path);
|
||||||
void pack_end();
|
void pack_end();
|
||||||
|
|
||||||
|
char *dirname(const char *path);
|
||||||
|
|
||||||
void *slurp_file(const char *filename, size_t *size);
|
void *slurp_file(const char *filename, size_t *size);
|
||||||
char *slurp_text(const char *filename, size_t *size);
|
char *slurp_text(const char *filename, size_t *size);
|
||||||
int slurp_write(const char *txt, const char *filename, size_t len);
|
int slurp_write(const char *txt, const char *filename, size_t len);
|
||||||
|
|
|
@ -7,13 +7,182 @@
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "HandmadeMath.h"
|
#include "HandmadeMath.h"
|
||||||
|
|
||||||
|
#include "sprite.sglsl.h"
|
||||||
|
#include "9slice.sglsl.h"
|
||||||
|
|
||||||
|
static sg_shader shader_sprite;
|
||||||
|
static sg_pipeline pip_sprite;
|
||||||
|
sg_bindings bind_sprite;
|
||||||
|
|
||||||
|
static sg_shader slice9_shader;
|
||||||
|
static sg_pipeline slice9_pipe;
|
||||||
|
static sg_bindings slice9_bind;
|
||||||
|
|
||||||
|
struct slice9_vert {
|
||||||
|
HMM_Vec2 pos;
|
||||||
|
struct uv_n uv;
|
||||||
|
unsigned short border[4];
|
||||||
|
HMM_Vec2 scale;
|
||||||
|
struct rgba color;
|
||||||
|
};
|
||||||
|
|
||||||
sprite *sprite_make()
|
sprite *sprite_make()
|
||||||
{
|
{
|
||||||
sprite *sp = calloc(sizeof(*sp), 1);
|
sprite *sp = calloc(sizeof(*sp), 1);
|
||||||
|
sp->pos = v2zero;
|
||||||
|
sp->scale = v2one;
|
||||||
|
sp->angle = 0;
|
||||||
sp->color = color_white;
|
sp->color = color_white;
|
||||||
sp->emissive = color_clear;
|
sp->emissive = color_clear;
|
||||||
sp->rect = (HMM_Vec4){0,0,1,1};
|
sp->spritesize = v2one;
|
||||||
|
sp->spriteoffset = v2zero;
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sprite_free(sprite *sprite) { free(sprite); }
|
void sprite_free(sprite *sprite) { free(sprite); }
|
||||||
|
|
||||||
|
static texture *loadedtex;
|
||||||
|
static int sprite_count = 0;
|
||||||
|
|
||||||
|
void sprite_flush() {
|
||||||
|
return;
|
||||||
|
if (!loadedtex) return;
|
||||||
|
/*
|
||||||
|
int flushed = arrlen(spverts)/4;
|
||||||
|
sg_apply_bindings(&bind_sprite);
|
||||||
|
sg_range data = (sg_range){
|
||||||
|
.ptr = spverts,
|
||||||
|
.size = sizeof(sprite_vert)*arrlen(spverts)
|
||||||
|
};
|
||||||
|
if (sg_query_buffer_will_overflow(bind_sprite.vertex_buffers[0], data.size))
|
||||||
|
bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
||||||
|
.size = data.size,
|
||||||
|
.type = SG_BUFFERTYPE_VERTEXBUFFER,
|
||||||
|
.usage = SG_USAGE_STREAM,
|
||||||
|
.label = "sprite vertex buffer"
|
||||||
|
});
|
||||||
|
|
||||||
|
sg_update_buffer(bind_sprite.vertex_buffers[0], &data);
|
||||||
|
|
||||||
|
sg_draw(sprite_count * 4, 4, flushed);
|
||||||
|
sprite_count += flushed;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprite_initialize() {
|
||||||
|
shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend()));
|
||||||
|
|
||||||
|
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
|
.shader = shader_sprite,
|
||||||
|
.layout = {
|
||||||
|
.attrs = {
|
||||||
|
[0].format = SG_VERTEXFORMAT_FLOAT2
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||||
|
.label = "sprite pipeline",
|
||||||
|
.colors[0].blend = blend_trans,
|
||||||
|
});
|
||||||
|
|
||||||
|
bind_sprite.vertex_buffers[0] = sprite_quad;
|
||||||
|
bind_sprite.fs.samplers[0] = std_sampler;
|
||||||
|
|
||||||
|
slice9_shader = sg_make_shader(slice9_shader_desc(sg_query_backend()));
|
||||||
|
|
||||||
|
slice9_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
|
.shader = slice9_shader,
|
||||||
|
.layout = {
|
||||||
|
.attrs = {
|
||||||
|
[0].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[1].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[2].format = SG_VERTEXFORMAT_USHORT4N,
|
||||||
|
[3].format = SG_VERTEXFORMAT_FLOAT2,
|
||||||
|
[4].format = SG_VERTEXFORMAT_UBYTE4N
|
||||||
|
}},
|
||||||
|
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
|
||||||
|
});
|
||||||
|
|
||||||
|
slice9_bind.vertex_buffers[0] = sprite_quad;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprite_pipe()
|
||||||
|
{
|
||||||
|
sg_apply_pipeline(pip_sprite);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj));
|
||||||
|
sg_apply_bindings(&bind_sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tex_draw(HMM_Mat3 m, struct rect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, HMM_Vec2 wrapscale, struct rgba emissive) {
|
||||||
|
/*
|
||||||
|
struct sprite_vert verts[4];
|
||||||
|
float w = loadedtex->width*r.w;
|
||||||
|
float h = loadedtex->height*r.h;
|
||||||
|
|
||||||
|
HMM_Vec2 sposes[4] = {
|
||||||
|
{0,0},
|
||||||
|
{w,0},
|
||||||
|
{0,h},
|
||||||
|
{w,h}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
verts[i].pos = mat_t_pos(m, sposes[i]);
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
r.w *= wrapscale.x;
|
||||||
|
r.h *= wrapscale.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
verts[0].uv.X = r.x;
|
||||||
|
verts[0].uv.Y = r.y+r.h;
|
||||||
|
verts[1].uv.X = r.x+r.w;
|
||||||
|
verts[1].uv.Y = r.y+r.h;
|
||||||
|
verts[2].uv.X = r.x;
|
||||||
|
verts[2].uv.Y = r.y;
|
||||||
|
verts[3].uv.X = r.x+r.w;
|
||||||
|
verts[3].uv.Y = r.y;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
arrput(spverts, verts[i]);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
transform2d sprite2t(sprite *s)
|
||||||
|
{
|
||||||
|
return (transform2d){
|
||||||
|
.pos = s->pos,
|
||||||
|
.scale = HMM_MulV2(s->scale, (HMM_Vec2){loadedtex->width, loadedtex->height}),
|
||||||
|
.angle = HMM_TurnToRad*s->angle
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprite_tex(texture *t)
|
||||||
|
{
|
||||||
|
loadedtex = t;
|
||||||
|
bind_sprite.fs.images[0] = t->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sprite_draw(struct sprite *sprite, gameobject *go) {
|
||||||
|
HMM_Mat4 m = transform2d2mat4(go2t(go));
|
||||||
|
HMM_Mat4 sm = transform2d2mat4(sprite2t(sprite));
|
||||||
|
struct spriteuni spv;
|
||||||
|
rgba2floats(&spv.color.e, sprite->color);
|
||||||
|
rgba2floats(spv.emissive.e, sprite->emissive);
|
||||||
|
spv.size = sprite->spritesize;
|
||||||
|
spv.offset = sprite->spriteoffset;
|
||||||
|
spv.model = HMM_MulM4(m,sm);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_sprite, SG_RANGE_REF(spv));
|
||||||
|
sg_draw(0,4,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color) {
|
||||||
|
sg_apply_pipeline(pip_sprite);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj));
|
||||||
|
sprite_tex(tex);
|
||||||
|
tex_draw(transform2d2mat(t), ST_UNIT, color, wrap, wrapoffset, (HMM_Vec2){wrapscale,wrapscale}, (struct rgba){0,0,0,0});
|
||||||
|
}
|
||||||
|
|
||||||
|
void slice9_draw(texture *tex, transform2d *t, HMM_Vec4 border, struct rgba color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -7,14 +7,37 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "gameobject.h"
|
#include "gameobject.h"
|
||||||
|
|
||||||
typedef struct sprite {
|
struct sprite {
|
||||||
|
HMM_Vec2 pos;
|
||||||
|
HMM_Vec2 scale;
|
||||||
|
float angle;
|
||||||
struct rgba color;
|
struct rgba color;
|
||||||
struct rgba emissive;
|
struct rgba emissive;
|
||||||
HMM_Vec4 rect;
|
HMM_Vec2 spritesize;
|
||||||
HMM_Vec2 spriteoffset;
|
HMM_Vec2 spriteoffset;
|
||||||
} sprite;
|
};
|
||||||
|
|
||||||
|
struct spriteuni {
|
||||||
|
HMM_Vec4 color;
|
||||||
|
HMM_Vec4 emissive;
|
||||||
|
HMM_Vec2 size;
|
||||||
|
HMM_Vec2 offset;
|
||||||
|
HMM_Mat4 model;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sprite sprite;
|
||||||
|
|
||||||
|
extern sg_bindings bind_sprite;
|
||||||
|
|
||||||
sprite *sprite_make();
|
sprite *sprite_make();
|
||||||
void sprite_free(sprite *sprite);
|
void sprite_free(sprite *sprite);
|
||||||
|
void sprite_tex(texture *t);
|
||||||
|
void sprite_initialize();
|
||||||
|
void sprite_draw(struct sprite *sprite, gameobject *go);
|
||||||
|
void sprite_pipe();
|
||||||
|
void sprite_draw_all();
|
||||||
|
void sprite_flush();
|
||||||
|
|
||||||
|
void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -122,9 +122,11 @@ struct texture *texture_from_file(const char *path) {
|
||||||
unsigned int nw = next_pow2(tex->width);
|
unsigned int nw = next_pow2(tex->width);
|
||||||
unsigned int nh = next_pow2(tex->height);
|
unsigned int nh = next_pow2(tex->height);
|
||||||
|
|
||||||
|
int filter = SG_FILTER_NEAREST;
|
||||||
|
|
||||||
sg_image_data sg_img_data;
|
sg_image_data sg_img_data;
|
||||||
sg_img_data.subimage[0][0] = (sg_range){.ptr = data, .size=tex->width*tex->height*4};
|
sg_img_data.subimage[0][0] = (sg_range){.ptr = data, .size=tex->width*tex->height*4};
|
||||||
|
/*
|
||||||
int mips = mip_levels(tex->width, tex->height)+1;
|
int mips = mip_levels(tex->width, tex->height)+1;
|
||||||
|
|
||||||
YughInfo("Has %d mip levels, from wxh %dx%d, pow2 is %ux%u.", mips, tex->width, tex->height,nw,nh);
|
YughInfo("Has %d mip levels, from wxh %dx%d, pow2 is %ux%u.", mips, tex->width, tex->height,nw,nh);
|
||||||
|
@ -149,18 +151,18 @@ struct texture *texture_from_file(const char *path) {
|
||||||
mipw = w;
|
mipw = w;
|
||||||
miph = h;
|
miph = h;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
tex->id = sg_make_image(&(sg_image_desc){
|
tex->id = sg_make_image(&(sg_image_desc){
|
||||||
.type = SG_IMAGETYPE_2D,
|
.type = SG_IMAGETYPE_2D,
|
||||||
.width = tex->width,
|
.width = tex->width,
|
||||||
.height = tex->height,
|
.height = tex->height,
|
||||||
.usage = SG_USAGE_IMMUTABLE,
|
.usage = SG_USAGE_IMMUTABLE,
|
||||||
.num_mipmaps = mips,
|
//.num_mipmaps = mips,
|
||||||
.data = sg_img_data
|
.data = sg_img_data
|
||||||
});
|
});
|
||||||
|
|
||||||
for (int i = 1; i < mips; i++)
|
/*for (int i = 1; i < mips; i++)
|
||||||
free(mipdata[i]);
|
free(mipdata[i]);*/
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
@ -189,6 +191,8 @@ struct texture *texture_fromdata(void *raw, long size)
|
||||||
|
|
||||||
tex->data = data;
|
tex->data = data;
|
||||||
|
|
||||||
|
int filter = SG_FILTER_NEAREST;
|
||||||
|
|
||||||
sg_image_data sg_img_data;
|
sg_image_data sg_img_data;
|
||||||
|
|
||||||
int mips = mip_levels(tex->width, tex->height)+1;
|
int mips = mip_levels(tex->width, tex->height)+1;
|
||||||
|
|
|
@ -18,8 +18,7 @@ extern struct rect ST_UNIT;
|
||||||
|
|
||||||
/* Represents an actual texture on the GPU */
|
/* Represents an actual texture on the GPU */
|
||||||
struct texture {
|
struct texture {
|
||||||
sg_image id; /* ID reference for the GPU memory location of the
|
sg_image id; /* ID reference for the GPU memory location of the texture */
|
||||||
texture */
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
const transform2d t2d_unit = {
|
const transform2d t2d_unit = {
|
||||||
.pos = {0,0},
|
.pos = {0,0},
|
||||||
|
@ -8,23 +7,6 @@ const transform2d t2d_unit = {
|
||||||
.angle = 0
|
.angle = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
transform3d *make_transform3d()
|
|
||||||
{
|
|
||||||
transform3d *t = calloc(sizeof(transform3d),1);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void transform3d_free(transform3d *t) { free(t); }
|
|
||||||
|
|
||||||
transform2d *make_transform2d()
|
|
||||||
{
|
|
||||||
transform2d *t = calloc(sizeof(transform2d),1);
|
|
||||||
t->scale = (HMM_Vec2){1,1};
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void transform2d_free(transform2d *t) { free(t); }
|
|
||||||
|
|
||||||
HMM_Vec3 trans_forward(const transform3d *const trans) { return HMM_QVRot(vFWD, trans->rotation); }
|
HMM_Vec3 trans_forward(const transform3d *const trans) { return HMM_QVRot(vFWD, trans->rotation); }
|
||||||
HMM_Vec3 trans_back(const transform3d *trans) { return HMM_QVRot(vBKWD, trans->rotation); }
|
HMM_Vec3 trans_back(const transform3d *trans) { return HMM_QVRot(vBKWD, trans->rotation); }
|
||||||
HMM_Vec3 trans_up(const transform3d *trans) { return HMM_QVRot(vUP, trans->rotation); }
|
HMM_Vec3 trans_up(const transform3d *trans) { return HMM_QVRot(vUP, trans->rotation); }
|
||||||
|
@ -58,19 +40,13 @@ HMM_Mat3 transform2d2mat(transform2d trn) {
|
||||||
return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale)));
|
return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale)));
|
||||||
}
|
}
|
||||||
|
|
||||||
HMM_Mat4 transform2d2mat4(transform2d *t)
|
HMM_Mat4 transform2d2mat4(transform2d trn)
|
||||||
{
|
{
|
||||||
HMM_Mat4 T = {0};
|
transform3d t3d;
|
||||||
float c = cosf(t->angle);
|
t3d.pos.xy = trn.pos;
|
||||||
float s = sinf(t->angle);
|
t3d.scale.xy = trn.scale;
|
||||||
T.col[0].x = c*t->scale.x;
|
t3d.rotation = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,-1}, trn.angle);
|
||||||
T.col[0].y = s*t->scale.y;
|
return transform3d2mat(t3d);
|
||||||
T.col[1].x = -s*t->scale.x;
|
|
||||||
T.col[1].y = c*t->scale.y;
|
|
||||||
T.col[3].xy = t->pos;
|
|
||||||
T.col[2].z = 1;
|
|
||||||
T.col[3].w = 1;
|
|
||||||
return T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transform2d mat2transform2d(HMM_Mat3 m)
|
transform2d mat2transform2d(HMM_Mat3 m)
|
||||||
|
|
|
@ -9,18 +9,12 @@ typedef struct transform3d {
|
||||||
HMM_Quat rotation;
|
HMM_Quat rotation;
|
||||||
} transform3d;
|
} transform3d;
|
||||||
|
|
||||||
transform3d *make_transform3d();
|
|
||||||
void transform3d_free(transform3d *t);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
HMM_Vec2 pos;
|
HMM_Vec2 pos;
|
||||||
HMM_Vec2 scale;
|
HMM_Vec2 scale;
|
||||||
float angle;
|
float angle;
|
||||||
} transform2d;
|
} transform2d;
|
||||||
|
|
||||||
transform2d *make_transform2d();
|
|
||||||
void transform2d_free(transform2d *t);
|
|
||||||
|
|
||||||
extern const transform2d t2d_unit;
|
extern const transform2d t2d_unit;
|
||||||
|
|
||||||
#define VEC2_FMT "[%g,%g]"
|
#define VEC2_FMT "[%g,%g]"
|
||||||
|
@ -33,7 +27,7 @@ HMM_Vec3 trans_down(const transform3d *trans);
|
||||||
HMM_Vec3 trans_right(const transform3d *trans);
|
HMM_Vec3 trans_right(const transform3d *trans);
|
||||||
HMM_Vec3 trans_left(const transform3d *trans);
|
HMM_Vec3 trans_left(const transform3d *trans);
|
||||||
|
|
||||||
HMM_Mat4 transform2d2mat4(transform2d *t);
|
HMM_Mat4 transform2d2mat4(transform2d trn);
|
||||||
|
|
||||||
/* Transform a position via the matrix */
|
/* Transform a position via the matrix */
|
||||||
HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos);
|
HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos);
|
||||||
|
|
65
source/shaders/9slice.sglsl
Normal file
65
source/shaders/9slice.sglsl
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
@vs vs9
|
||||||
|
in vec2 vert;
|
||||||
|
in vec2 vuv;
|
||||||
|
in vec4 vborder;
|
||||||
|
in vec2 vscale;
|
||||||
|
in vec4 vcolor;
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
out vec4 border;
|
||||||
|
out vec2 scale;
|
||||||
|
out vec4 fcolor;
|
||||||
|
|
||||||
|
uniform vs9_params { mat4 projection; };
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = projection * vec4(vert, 0.0, 1.0);
|
||||||
|
|
||||||
|
uv = vuv;
|
||||||
|
border = vborder;
|
||||||
|
scale = vscale;
|
||||||
|
fcolor = vcolor;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@fs fs9
|
||||||
|
in vec2 uv; /* image uv */
|
||||||
|
in vec4 border; /* uv length of border, normalized to image dimensions; left, bottom, right, top */
|
||||||
|
in vec2 scale; /* polygon dimensions ~ texture dimensions */
|
||||||
|
in vec4 fcolor;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform texture2D image;
|
||||||
|
uniform sampler smp;
|
||||||
|
|
||||||
|
float map(float value, float min1, float max1, float min2, float max2)
|
||||||
|
{
|
||||||
|
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float processAxis(float coord, float texBorder, float winBorder)
|
||||||
|
{
|
||||||
|
if (coord < winBorder)
|
||||||
|
return map(coord, 0, winBorder, 0, texBorder);
|
||||||
|
if (coord < 1 - winBorder)
|
||||||
|
return map(coord, winBorder, 1 - winBorder, texBorder, 1 - texBorder);
|
||||||
|
|
||||||
|
return map(coord, 1 - winBorder, 1, 1 - texBorder, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 uv9slice(vec2 uv, vec2 s, vec4 b)
|
||||||
|
{
|
||||||
|
vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0.0, 1.0);
|
||||||
|
return mix(uv * s, 1.0 - s * (1.0 - uv), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec2 nuv = uv9slice(uv, scale, border);
|
||||||
|
color = fcolor * texture(sampler2D(image,smp), nuv);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@program slice9 vs9 fs9
|
14
source/shaders/animspritefrag.glsl
Normal file
14
source/shaders/animspritefrag.glsl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#version 330
|
||||||
|
in vec2 TexCoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2DArray image;
|
||||||
|
uniform float frame;
|
||||||
|
uniform vec3 spriteColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = vec4(spriteColor, 1.f) * texture(image, vec3(TexCoords,frame));
|
||||||
|
if (color.a < 0.1)
|
||||||
|
discard;
|
||||||
|
}
|
17
source/shaders/animspritevert.glsl
Normal file
17
source/shaders/animspritevert.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec2 vertex; // <vec2 position, vec2 texCoords>
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
layout (std140) uniform Projection
|
||||||
|
{
|
||||||
|
mat4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
TexCoords = vertex.xy;
|
||||||
|
gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
|
||||||
|
}
|
53
source/shaders/sprite.sglsl
Normal file
53
source/shaders/sprite.sglsl
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
@vs vs
|
||||||
|
in vec2 vertex;
|
||||||
|
|
||||||
|
out vec2 texcoords;
|
||||||
|
out vec4 fcolor;
|
||||||
|
out vec4 femissive;
|
||||||
|
|
||||||
|
uniform app {
|
||||||
|
float time;
|
||||||
|
vec2 window;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform vp {
|
||||||
|
mat4 proj;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform sprite {
|
||||||
|
vec4 vcolor;
|
||||||
|
vec4 vemissive;
|
||||||
|
vec2 spritesize;
|
||||||
|
vec2 spriteoff;
|
||||||
|
mat4 model;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
texcoords = vertex;
|
||||||
|
texcoords.y = 1 - texcoords.y;
|
||||||
|
gl_Position = proj * model * vec4(vertex, 0, 1.0);
|
||||||
|
fcolor = vcolor;
|
||||||
|
femissive = vemissive;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@fs fs
|
||||||
|
in vec2 texcoords;
|
||||||
|
in vec4 fcolor;
|
||||||
|
in vec4 femissive;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform texture2D image;
|
||||||
|
uniform sampler smp;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = texture(sampler2D(image,smp), texcoords);
|
||||||
|
color *= fcolor;
|
||||||
|
color.xyz = mix(color.xyz, femissive.xyz, femissive.a);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@program sprite vs fs
|
12
source/shaders/spritewireframefrag.glsl
Normal file
12
source/shaders/spritewireframefrag.glsl
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
in vec2 texcoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2D image;
|
||||||
|
uniform vec3 spriteColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = vec4(spriteColor, 1.f) * texture(image, texcoords);
|
||||||
|
color.a = 1.f;
|
||||||
|
}
|
42
source/shaders/text.sglsl
Normal file
42
source/shaders/text.sglsl
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
@vs vs
|
||||||
|
in vec2 vert;
|
||||||
|
|
||||||
|
in vec2 pos;
|
||||||
|
in vec2 wh;
|
||||||
|
in vec2 uv;
|
||||||
|
in vec2 st;
|
||||||
|
in vec4 vColor;
|
||||||
|
|
||||||
|
out vec2 TexCoords;
|
||||||
|
out vec4 fColor;
|
||||||
|
|
||||||
|
uniform vs_params { mat4 projection; };
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = projection * vec4(pos + (vert * wh), 0.0, 1.0);
|
||||||
|
|
||||||
|
TexCoords = uv + vec2(vert.x*st.x, st.y - vert.y*st.y);
|
||||||
|
|
||||||
|
fColor = vColor;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@fs fs
|
||||||
|
in vec2 TexCoords;
|
||||||
|
in vec4 fColor;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform texture2D text;
|
||||||
|
uniform sampler smp;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float lettera = texture(sampler2D(text,smp),TexCoords).r;
|
||||||
|
if (lettera < 0.1f) discard;
|
||||||
|
color = fColor;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@program text vs fs
|
|
@ -1,45 +1,30 @@
|
||||||
@block vptr
|
@vs vs
|
||||||
in vec3 a_pos;
|
in vec3 a_pos;
|
||||||
in vec2 a_uv;
|
in vec2 a_tex_coords;
|
||||||
in vec4 a_norm;
|
in vec4 a_norm;
|
||||||
|
in vec4 a_weight;
|
||||||
|
in vec4 a_joint;
|
||||||
|
|
||||||
out vec2 tex_coords;
|
out vec2 tex_coords;
|
||||||
out vec3 normal;
|
out vec3 normal;
|
||||||
|
|
||||||
uniform vs_p { uniform mat4 vp; };
|
uniform vs_p { uniform mat4 vp; };
|
||||||
uniform vmodel { uniform mat4 model; };
|
uniform vmodel { uniform mat4 model; };
|
||||||
@end
|
|
||||||
|
|
||||||
@vs vs
|
|
||||||
@include_block vptr
|
|
||||||
|
|
||||||
in vec4 a_bone;
|
|
||||||
in vec4 a_weight;
|
|
||||||
|
|
||||||
uniform skinv { uniform mat4 bones[50]; };
|
uniform skinv { uniform mat4 bones[50]; };
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 tt = vp;
|
mat4 skin = bones[int(a_joint.x)] * a_weight.x;
|
||||||
mat4 mm = model;
|
skin += bones[int(a_joint.y)] * a_weight.y;
|
||||||
mat4 skin = bones[int(a_bone.x)] * a_weight.x;
|
skin += bones[int(a_joint.z)] * a_weight.z;
|
||||||
skin += bones[int(a_bone.y)] * a_weight.y;
|
skin += bones[int(a_joint.w)] * a_weight.w;
|
||||||
skin += bones[int(a_bone.z)] * a_weight.z;
|
mat4 skinm = model * skin;
|
||||||
skin += bones[int(a_bone.w)] * a_weight.w;
|
gl_Position = vp * skinm * vec4(a_pos,1.0);
|
||||||
mat4 skinm = mm * skin;
|
tex_coords = a_tex_coords;
|
||||||
gl_Position = tt * skinm * vec4(a_pos,1.0);
|
|
||||||
tex_coords = a_uv;
|
|
||||||
normal = (skinm * vec4(a_norm.xyz*2-1,0)).xyz;
|
normal = (skinm * vec4(a_norm.xyz*2-1,0)).xyz;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@vs vs_st
|
|
||||||
@include_block vptr
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vp * model * vec4(a_pos,1.0);
|
|
||||||
tex_coords = a_uv;
|
|
||||||
normal = (model * vec4(a_norm.xyz*2-1,0)).xyz;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@fs fs
|
@fs fs
|
||||||
in vec2 tex_coords;
|
in vec2 tex_coords;
|
||||||
in vec3 normal;
|
in vec3 normal;
|
||||||
|
@ -60,4 +45,3 @@ void main() {
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@program unlit vs fs
|
@program unlit vs fs
|
||||||
@program unlit_st vs_st fs
|
|
||||||
|
|
Loading…
Reference in a new issue