This commit is contained in:
John Alanbrook 2024-04-20 12:55:20 -05:00
parent 17d89f6314
commit 0c2d344259
18 changed files with 240 additions and 172 deletions

View file

@ -332,12 +332,13 @@ function process()
render.set_camera(); render.set_camera();
render.sprites(); // blits all sprites render.sprites(); // blits all sprites
render.models(); // blits all models
render.emitters(); // blits emitters render.emitters(); // blits emitters
prosperon.draw(); // draw calls prosperon.draw(); // draw calls
debug.draw(); // calls needed debugs debug.draw(); // calls needed debugs
render.flush(); render.flush();
prosperon.hook3d?.();
render.hud_res(window.rendersize); render.hud_res(window.rendersize);
prosperon.gui(); prosperon.gui();
render.flush(); render.flush();

View file

@ -644,8 +644,8 @@ gameobject.doc = {
global.ur = {}; global.ur = {};
if (io.exists(".prosperon/ur.json")) if (io.exists(`${io.dumpfolder}/ur.json`))
ur = json.decode(io.slurp(".prosperon/ur.json")); ur = json.decode(io.slurp(`${io.dumpfolder}/ur.json`));
else { else {
ur = {}; ur = {};
ur._list = []; ur._list = [];

View file

@ -47,8 +47,8 @@ render.point = function(pos,size,color = Color.blue) {
var tmpline = render.line; var tmpline = render.line;
render.line = function(points, color = Color.white, thickness = 1) { render.line = function(points, color = Color.white, thickness = 1) {
tmpline(points,color,thickness); tmpline(points,color,thickness);
}; };
render.cross = function(pos, size, color = Color.red) { render.cross = function(pos, size, color = Color.red) {
var a = [ var a = [

View file

@ -45,6 +45,7 @@ os.openurl = function(url) {
} }
var projectfile = "project.prosperon"; var projectfile = "project.prosperon";
io.dumpfolder = '.prosperon';
Resources.is_sound = function(path) { Resources.is_sound = function(path) {
var ext = path.ext(); var ext = path.ext();
@ -185,7 +186,7 @@ Cmdline.register_order = function(order, fn, doc, usage = "") {
} }
Cmdline.register_order("edit", function() { Cmdline.register_order("edit", function() {
if (!io.exists(".prosperon")) { if (!io.exists(projectfile)) {
say("No game to edit. Try making one with 'prosperon init'."); say("No game to edit. Try making one with 'prosperon init'.");
return; return;
} }
@ -209,12 +210,12 @@ Cmdline.register_order("init", function() {
return; return;
} }
if (!(io.ls().length === 0)) { if (!(io.ls().filter(x => x[0] !== '.').length === 0)) {
say("Directory is not empty. Make an empty one and init there."); say("Directory is not empty. Make an empty one and init there.");
return; return;
} }
io.mkdir(".prosperon"); io.mkdir(io.dumpfolder);
var project = {}; var project = {};
project.version = prosperon.version; project.version = prosperon.version;
project.revision = prosperon.revision; project.revision = prosperon.revision;

View file

@ -26,13 +26,6 @@
#include "sokol/sokol_gfx.h" #include "sokol/sokol_gfx.h"
static struct {
char *key;
struct model *value;
} *modelhash = NULL;
struct drawmodel **models = NULL;
static void processnode(); static void processnode();
static void processmesh(); static void processmesh();
static void processtexture(); static void processtexture();
@ -55,23 +48,6 @@ struct mesh_v {
}; };
void model_init() { void model_init() {
/* model_shader = sg_make_shader(diffuse_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,
},
},
.index_type = SG_INDEXTYPE_UINT16,
.cull_mode = SG_CULLMODE_FRONT,
.depth.write_enabled = true,
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
});
*/
model_shader = sg_make_shader(unlit_shader_desc(sg_query_backend())); model_shader = sg_make_shader(unlit_shader_desc(sg_query_backend()));
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){ model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
@ -79,8 +55,8 @@ void model_init() {
.layout = { .layout = {
.attrs = { .attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT3, [0].format = SG_VERTEXFORMAT_FLOAT3,
[1].format = SG_VERTEXFORMAT_USHORT2N, [1].format = SG_VERTEXFORMAT_USHORT2N,
[1].buffer_index = 1, [1].buffer_index = 1,
}, },
}, },
.index_type = SG_INDEXTYPE_UINT16, .index_type = SG_INDEXTYPE_UINT16,
@ -90,15 +66,6 @@ void model_init() {
}); });
} }
struct model *GetExistingModel(const char *path) {
if (!path || path[0] == '\0') return NULL;
int index = shgeti(modelhash, path);
if (index != -1) return modelhash[index].value;
return MakeModel(path);
}
cgltf_attribute *get_attr_type(cgltf_primitive *p, cgltf_attribute_type t) cgltf_attribute *get_attr_type(cgltf_primitive *p, cgltf_attribute_type t)
{ {
for (int i = 0; i < p->attributes_count; i++) { for (int i = 0; i < p->attributes_count; i++) {
@ -141,13 +108,10 @@ void mesh_add_material(mesh *mesh, cgltf_material *mat)
if (img->buffer_view) { if (img->buffer_view) {
cgltf_buffer_view *buf = img->buffer_view; cgltf_buffer_view *buf = img->buffer_view;
mesh->bind.fs.images[0] = texture_fromdata(buf->buffer->data, buf->size)->id; mesh->bind.fs.images[0] = texture_fromdata(buf->buffer->data, buf->size)->id;
} else { } else
// char *imp = seprint("%s/%s", dirname(mesh->model->path), img->uri); mesh->bind.fs.images[0] = texture_from_file(img->uri)->id;
// mesh->bind.fs.images[0] = texture_from_file(imp)->id;
// free(imp);
}
} else } else
mesh->bind.fs.images[0] = texture_from_file("k")->id; mesh->bind.fs.images[0] = texture_from_file("icons/moon.gif")->id;
mesh->bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); mesh->bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){});
/* /*
@ -245,8 +209,8 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim)
break; break;
case cgltf_attribute_type_normal: case cgltf_attribute_type_normal:
has_norm = 1; // has_norm = 1;
mesh->bind.vertex_buffers[2] = normal_floats(vs, verts, comp); // mesh->bind.vertex_buffers[2] = normal_floats(vs, verts, comp);
break; break;
case cgltf_attribute_type_tangent: case cgltf_attribute_type_tangent:
@ -337,7 +301,7 @@ void model_process_scene(model *model, cgltf_scene *scene)
model_process_node(model, scene->nodes[i]); model_process_node(model, scene->nodes[i]);
} }
struct model *MakeModel(const char *path) struct model *model_make(const char *path)
{ {
YughInfo("Making the model from %s.", path); YughInfo("Making the model from %s.", path);
cgltf_options options = {0}; cgltf_options options = {0};
@ -357,8 +321,6 @@ struct model *MakeModel(const char *path)
} }
struct model *model = calloc(1, sizeof(*model)); struct model *model = calloc(1, sizeof(*model));
model->path = path;
if (data->scenes_count == 0 || data->scenes_count > 1) return NULL; if (data->scenes_count == 0 || data->scenes_count > 1) return NULL;
model_process_scene(model, data->scene); model_process_scene(model, data->scene);
@ -369,76 +331,34 @@ struct model *MakeModel(const char *path)
for (int i = 0; i < data->animations_count; i++) for (int i = 0; i < data->animations_count; i++)
model_add_cgltf_anim(model, &data->animations[i]); model_add_cgltf_anim(model, &data->animations[i]);
shput(modelhash, path, model);
return model; return model;
} }
/* eye position */ void model_free(model *m)
HMM_Vec3 eye = {0,0,100}; {
void draw_model(struct model *model, HMM_Mat4 amodel, HMM_Mat4 *proj) { }
HMM_Vec3 center = {0.f, 0.f, 0.f};
HMM_Mat4 view = HMM_LookAt_RH(eye, center, vUP);
HMM_Mat4 vp = HMM_MulM4(*proj, view);
HMM_Vec3 dir_dir = HMM_NormV3(HMM_SubV3(center, dirl_pos));
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);
vs_p_t vs_p; vs_p_t vs_p;
memcpy(vs_p.vp, vp.Elements, sizeof(float)*16); memcpy(vs_p.vp, vp.Elements, sizeof(float)*16);
memcpy(vs_p.model, amodel.Elements, sizeof(float)*16); memcpy(vs_p.model, t3d_go2world(go).Elements, sizeof(float)*16);
sg_apply_pipeline(model_pipe); sg_apply_pipeline(model_pipe);
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vs_p)); sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vs_p));
for (int i = 0; i < arrlen(model->meshes); i++) { for (int i = 0; i < arrlen(model->meshes); i++) {
sg_apply_bindings(&model->meshes[i].bind); sg_apply_bindings(&model->meshes[i].bind);
sg_draw(0, model->meshes[i].idx_count, 1); sg_draw(0, model->meshes[i].idx_count, 1);
} }
} }
struct drawmodel *make_drawmodel(gameobject *go)
{
struct drawmodel *dm = malloc(sizeof(struct drawmodel));
dm->model = NULL;
dm->amodel = HMM_M4D(1.f);
dm->go = go;
arrpush(models,dm);
return dm;
}
void model_draw_all()
{
for (int i = 0; i < arrlen(models); i++)
draw_drawmodel(models[i]);
}
void draw_drawmodel(struct drawmodel *dm)
{
if (!dm->model) return;
struct gameobject *go = dm->go;
HMM_Mat4 rst = t3d_go2world(go);
draw_model(dm->model, rst, &useproj);
}
void drawmodel_free(struct drawmodel *dm) {
int rm;
for (int i = 0; i < arrlen(models); i++)
if (models[i] == dm) {
rm = i;
break;
}
arrdelswap(models,rm);
free(dm);
}
void material_free(material *mat) void material_free(material *mat)
{ {
} }
void mesh_free(mesh *m)
{
}

View file

@ -23,42 +23,23 @@ typedef struct mesh {
/* A collection of meshes which create a full figure */ /* A collection of meshes which create a full figure */
typedef struct model { typedef struct model {
struct mesh *meshes; struct mesh *meshes;
const char *path;
HMM_Mat4 matrix; HMM_Mat4 matrix;
} model; } model;
/* A model with draw information */
typedef struct drawmodel {
struct model *model;
HMM_Mat4 amodel;
gameobject *go;
} drawmodel;
typedef struct bone { typedef struct bone {
transform3d t; transform3d t;
struct bone *children; struct bone *children;
} bone; } bone;
/* Get the model at a path, or create and return if it doesn't exist */
struct model *GetExistingModel(const char *path);
/* Make a Model struct */ /* Make a Model struct */
struct model *MakeModel(const char *path); struct model *model_make(const char *path);
void model_free(model *m);
/* Load a model from memory into the GPU */ void model_draw_go(model *m, gameobject *go, gameobject *cam);
void loadmodel(struct model *model);
void model_init(); void model_init();
struct drawmodel *make_drawmodel(gameobject *go);
void draw_drawmodel(struct drawmodel *dm);
void model_draw_all();
void drawmodel_free(struct drawmodel *dm);
material *material_make(); material *material_make();
void material_free(material *mat); void material_free(material *mat);
mesh *mesh_make();
void mesh_free(mesh *m);
#endif #endif

View file

@ -895,11 +895,14 @@ static inline HMM_Vec2 HMM_V2Rotate(HMM_Vec2 v, float angle)
return (HMM_Vec2){r*cos(angle), r*sin(angle)}; return (HMM_Vec2){r*cos(angle), r*sin(angle)};
} }
static inline float HMM_LenV3(HMM_Vec3 A) { static inline float HMM_LenV3(HMM_Vec3 A) {
return HMM_SqrtF(HMM_LenSqrV3(A)); return HMM_SqrtF(HMM_LenSqrV3(A));
} }
static inline float HMM_DistV3(HMM_Vec3 a, HMM_Vec3 b) {
return HMM_LenV3(HMM_SubV3(a,b));
}
static inline float HMM_AngleV3(HMM_Vec3 a, HMM_Vec3 b) static inline float HMM_AngleV3(HMM_Vec3 a, HMM_Vec3 b)
{ {
return acos(HMM_DotV3(a,b)/(HMM_LenV3(a)*HMM_LenV3(b))); return acos(HMM_DotV3(a,b)/(HMM_LenV3(a)*HMM_LenV3(b)));

View file

@ -15,6 +15,8 @@
#include "line.sglsl.h" #include "line.sglsl.h"
#include "grid.sglsl.h" #include "grid.sglsl.h"
#include "grid3d.sglsl.h"
#define PAR_STREAMLINES_IMPLEMENTATION #define PAR_STREAMLINES_IMPLEMENTATION
#include "par/par_streamlines.h" #include "par/par_streamlines.h"
@ -57,7 +59,7 @@ static sg_shader point_shader;
static sg_pipeline point_pipe; static sg_pipeline point_pipe;
static sg_bindings point_bind; static sg_bindings point_bind;
struct point_vertex { struct point_vertex {
struct draw_p pos; struct draw_p3 pos;
struct rgba color; struct rgba color;
float radius; float radius;
}; };
@ -109,6 +111,9 @@ struct circle_vertex {
float fill; float fill;
}; };
static sg_pipeline g3_pipe;
static sg_shader g3_shader;
void debug_nextpass() void debug_nextpass()
{ {
point_sc = point_c; point_sc = point_c;
@ -191,6 +196,14 @@ static sg_shader_uniform_block_desc time_ubo = {
void debugdraw_init() void debugdraw_init()
{ {
/*
g3_shader = sg_make_shader(grid3d_shader_desc(sg_query_backend()));
g3_pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = g3_shader,
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
.index_type = SG_INDEXTYPE_UINT32
});
*/
point_shader = sg_make_shader(point_shader_desc(sg_query_backend())); point_shader = sg_make_shader(point_shader_desc(sg_query_backend()));
point_pipe = sg_make_pipeline(&(sg_pipeline_desc){ point_pipe = sg_make_pipeline(&(sg_pipeline_desc){
@ -219,7 +232,7 @@ void debugdraw_init()
.shader = line_shader, .shader = line_shader,
.layout = { .layout = {
.attrs = { .attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2, /* pos */ [0].format = SG_VERTEXFORMAT_FLOAT3, /* pos */
[1].format = SG_VERTEXFORMAT_FLOAT, /* dist */ [1].format = SG_VERTEXFORMAT_FLOAT, /* dist */
[2].format = SG_VERTEXFORMAT_UBYTE4N, /* color */ [2].format = SG_VERTEXFORMAT_UBYTE4N, /* color */
[3].format = SG_VERTEXFORMAT_FLOAT, /* seg length */ [3].format = SG_VERTEXFORMAT_FLOAT, /* seg length */
@ -331,7 +344,7 @@ void debugdraw_init()
}); });
} }
void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float seg_speed) void draw_line3d(HMM_Vec3 *points, int n, struct rgba color, float seg_len, float seg_speed)
{ {
if (n < 2) return; if (n < 2) return;
@ -339,7 +352,7 @@ void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float
struct line_vert v[n]; struct line_vert v[n];
float dist = 0; float dist = 0;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
v[i].pos.x = points[i].x; v[i].pos.x = points[i].x;
v[i].pos.y = points[i].y; v[i].pos.y = points[i].y;
@ -347,10 +360,10 @@ void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float
v[i].seg_len = seg_len; v[i].seg_len = seg_len;
v[i].seg_speed = seg_speed; v[i].seg_speed = seg_speed;
} }
v[0].dist = 0; v[0].dist = 0;
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
dist += HMM_DistV2(points[i-1], points[i]); dist += HMM_DistV3(points[i-1], points[i]);
v[i].dist = dist; v[i].dist = dist;
} }
@ -375,11 +388,22 @@ void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float
if (sg_query_buffer_will_overflow(line_bind.vertex_buffers[0], vr.size) || sg_query_buffer_will_overflow(line_bind.index_buffer, ir.size)) return; if (sg_query_buffer_will_overflow(line_bind.vertex_buffers[0], vr.size) || sg_query_buffer_will_overflow(line_bind.index_buffer, ir.size)) return;
sg_append_buffer(line_bind.vertex_buffers[0], &vr); sg_append_buffer(line_bind.vertex_buffers[0], &vr);
sg_append_buffer(line_bind.index_buffer, &ir); sg_append_buffer(line_bind.index_buffer, &ir);
line_c += i_c; line_c += i_c;
line_v += n; line_v += n;
} }
void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float seg_speed)
{
if (n < 2) return;
HMM_Vec3 points3[n];
for (int i = 0; i < n; i++)
points3[i].xy = points[i];
draw_line3d(points3, n, color, seg_len, seg_speed);
}
HMM_Vec2 center_of_vects(HMM_Vec2 *v, int n) HMM_Vec2 center_of_vects(HMM_Vec2 *v, int n)
{ {
HMM_Vec2 c; HMM_Vec2 c;

View file

@ -9,6 +9,7 @@ void draw_cppoint(HMM_Vec2 point, float r, struct rgba color);
void draw_points(HMM_Vec2 *points, int n, float size, struct rgba color); void draw_points(HMM_Vec2 *points, int n, float size, struct rgba color);
void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float seg_speed); void draw_line(HMM_Vec2 *points, int n, struct rgba color, float seg_len, float seg_speed);
void draw_line3d(HMM_Vec3 *points, int n, struct rgba color, float seg_len, float seg_speed);
void draw_edge(HMM_Vec2 *points, int n, struct rgba color, float thickness, int flags, struct rgba line_color, float line_seg); void draw_edge(HMM_Vec2 *points, int n, struct rgba color, float thickness, int flags, struct rgba line_color, float line_seg);
/* pixels - how many pixels thick, segsize - dashed line seg len */ /* pixels - how many pixels thick, segsize - dashed line seg len */

View file

@ -31,9 +31,7 @@ transform3d go2t3(gameobject *go)
t.pos.Z = go->drawlayer; t.pos.Z = go->drawlayer;
t.scale = go->scale; t.scale = go->scale;
t.scale.Z = go->scale.X; t.scale.Z = go->scale.X;
t.rotation = HMM_QFromAxisAngle_RH(vFWD, go_angle(go)); t.rotation = go->quat;
t.rotation = HMM_MulQ(HMM_QFromAxisAngle_RH(vRIGHT, -t.pos.Y/100), t.rotation);
t.rotation = HMM_MulQ(HMM_QFromAxisAngle_RH(vUP, t.pos.X/100), t.rotation);
return t; return t;
} }
@ -140,7 +138,8 @@ gameobject *MakeGameobject() {
.ref = JS_UNDEFINED, .ref = JS_UNDEFINED,
.mask = ~0, .mask = ~0,
.categories = 1, .categories = 1,
.warp_mask = ~0 .warp_mask = ~0,
.quat = HMM_QFromAxisAngle_RH((HMM_Vec3){0,1,0}, 0)
}; };
go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f)); go.body = cpSpaceAddBody(space, cpBodyNew(go.mass, 1.f));
@ -200,6 +199,12 @@ void body_draw_shapes_dbg(cpBody *body, cpShape *shape, void *data) {
s->debugdraw(s->data); s->debugdraw(s->data);
} }
HMM_Vec3 go_pos3d(gameobject *go)
{
HMM_Vec2 pos2d = go_pos(go);
return (HMM_Vec3){pos2d.x, pos2d.y, go->drawlayer};
}
void gameobject_draw_debug(gameobject *go) { void gameobject_draw_debug(gameobject *go) {
if (!go || !go->body) return; if (!go || !go->body) return;

View file

@ -30,6 +30,7 @@ struct gameobject {
cpBodyType phys; cpBodyType phys;
cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */ cpBody *body; /* NULL if this object is dead; has 2d position and rotation, relative to global 0 */
HMM_Vec3 scale; /* local */ HMM_Vec3 scale; /* local */
HMM_Quat quat;
int next; int next;
float mass; float mass;
float friction; float friction;
@ -79,6 +80,8 @@ HMM_Mat3 t_world2go(gameobject *go);
HMM_Mat4 t3d_go2world(gameobject *go); HMM_Mat4 t3d_go2world(gameobject *go);
HMM_Mat4 t3d_world2go(gameobject *go); HMM_Mat4 t3d_world2go(gameobject *go);
HMM_Vec3 go_pos3d(gameobject *go);
HMM_Vec2 go_pos(gameobject *go); HMM_Vec2 go_pos(gameobject *go);
void gameobject_setpos(gameobject *go, cpVect vec); void gameobject_setpos(gameobject *go, cpVect vec);
float go_angle(gameobject *go); float go_angle(gameobject *go);

View file

@ -70,9 +70,8 @@ QJSCLASS(sprite)
QJSCLASS(warp_gravity) QJSCLASS(warp_gravity)
QJSCLASS(warp_damp) QJSCLASS(warp_damp)
QJSCLASS(material) QJSCLASS(material)
QJSCLASS(mesh) QJSCLASS(model)
QJSCLASS(window) QJSCLASS(window)
QJSCLASS(drawmodel)
QJSCLASS(constraint) QJSCLASS(constraint)
static JSValue sound_proto; static JSValue sound_proto;
@ -350,6 +349,16 @@ HMM_Vec2 *js2cpvec2arr(JSValue v) {
return arr; return arr;
} }
HMM_Vec3 *js2cpvec3arr(JSValue v)
{
HMM_Vec3 *arr = NULL;
int n = js_arrlen(v);
arrsetlen(arr,n);
for (int i = 0; i < n; i++)
arr[i] = js2vec3(js_getpropidx(v,i));
return arr;
}
HMM_Vec2 *jsfloat2vec(JSValue v) HMM_Vec2 *jsfloat2vec(JSValue v)
{ {
size_t s; size_t s;
@ -549,14 +558,6 @@ static const JSCFunctionListEntry js_warp_damp_funcs [] = {
CGETSET_ADD(warp_damp, damp) CGETSET_ADD(warp_damp, damp)
}; };
JSC_CCALL(drawmodel_draw, draw_drawmodel(js2drawmodel(this)))
JSC_SCALL(drawmodel_path, js2drawmodel(this)->model = GetExistingModel(str))
static const JSCFunctionListEntry js_drawmodel_funcs[] = {
MIST_FUNC_DEF(drawmodel, draw, 0),
MIST_FUNC_DEF(drawmodel, path, 1)
};
JSC_GETSET(emitter, life, number) JSC_GETSET(emitter, life, number)
JSC_GETSET(emitter, life_var, number) JSC_GETSET(emitter, life_var, number)
JSC_GETSET(emitter, speed, number) JSC_GETSET(emitter, speed, number)
@ -581,7 +582,6 @@ JSC_CCALL(emitter_start, start_emitter(js2emitter(this)))
JSC_CCALL(emitter_stop, stop_emitter(js2emitter(this))) JSC_CCALL(emitter_stop, stop_emitter(js2emitter(this)))
JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]))) JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0])))
JSC_CCALL(render_grid, draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2]));) JSC_CCALL(render_grid, draw_grid(js2number(argv[0]), js2number(argv[1]), js2color(argv[2]));)
JSC_CCALL(render_point, draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2]))) JSC_CCALL(render_point, draw_cppoint(js2vec2(argv[0]), js2number(argv[1]), js2color(argv[2])))
JSC_CCALL(render_circle, draw_circle(js2vec2(argv[0]), js2number(argv[1]), js2number(argv[2]), js2color(argv[3]), -1);) JSC_CCALL(render_circle, draw_circle(js2vec2(argv[0]), js2number(argv[1]), js2number(argv[2]), js2color(argv[3]), -1);)
@ -596,10 +596,16 @@ JSC_CCALL(render_poly,
JSC_CCALL(render_line, JSC_CCALL(render_line,
void *v1 = js2cpvec2arr(argv[0]); void *v1 = js2cpvec2arr(argv[0]);
draw_edge(v1, js_arrlen(argv[0]), js2color(argv[1]), js2number(argv[2]), 0, js2color(argv[1]), 10); draw_edge(v1, js_arrlen(argv[0]), js2color(argv[1]), js2number(argv[2]), 0, js2color(argv[1]), 10);
arrfree(v1);
) )
JSC_CCALL(render_line3d,
void *v1 = js2cpvec3arr(argv[0]);
draw_line3d(v1, js_arrlen(argv[0]), js2color(argv[1]), 0, 0);
arrfree(v1);
);
JSC_CCALL(render_sprites, sprite_draw_all()) JSC_CCALL(render_sprites, sprite_draw_all())
JSC_CCALL(render_models, model_draw_all())
JSC_CCALL(render_emitters, emitters_draw(&useproj)) JSC_CCALL(render_emitters, emitters_draw(&useproj))
JSC_CCALL(render_flush, debug_flush(&useproj); text_flush(&useproj); ) JSC_CCALL(render_flush, debug_flush(&useproj); text_flush(&useproj); )
JSC_CCALL(render_end_pass, JSC_CCALL(render_end_pass,
@ -612,7 +618,7 @@ JSC_SCALL(render_text_size, ret = bb2js(text_bb(str, js2number(argv[1]), js2numb
JSC_CCALL(render_set_camera, useproj = projection) JSC_CCALL(render_set_camera, useproj = projection)
JSC_CCALL(render_hud_res, JSC_CCALL(render_hud_res,
HMM_Vec2 xy = js2vec2(argv[0]); HMM_Vec2 xy = js2vec2(argv[0]);
useproj = HMM_Orthographic_LH_ZO(0, xy.x, 0, xy.y, -1, 1); useproj = HMM_Orthographic_RH_ZO(0, xy.x, 0, xy.y, -1, 1);
) )
JSC_CCALL(render_clear_color, JSC_CCALL(render_clear_color,
sg_color c; sg_color c;
@ -626,8 +632,8 @@ static const JSCFunctionListEntry js_render_funcs[] = {
MIST_FUNC_DEF(render, circle, 3), MIST_FUNC_DEF(render, circle, 3),
MIST_FUNC_DEF(render, poly, 2), MIST_FUNC_DEF(render, poly, 2),
MIST_FUNC_DEF(render, line, 3), MIST_FUNC_DEF(render, line, 3),
MIST_FUNC_DEF(render, line3d, 2),
MIST_FUNC_DEF(render, sprites, 0), MIST_FUNC_DEF(render, sprites, 0),
MIST_FUNC_DEF(render, models, 0),
MIST_FUNC_DEF(render, emitters, 0), MIST_FUNC_DEF(render, emitters, 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),
@ -1026,6 +1032,14 @@ static const JSCFunctionListEntry js_physics_funcs[] = {
MIST_FUNC_DEF(physics, make_gravity, 0), MIST_FUNC_DEF(physics, make_gravity, 0),
}; };
JSC_CCALL(model_draw_go,
model_draw_go(js2model(this), js2gameobject(argv[0]), js2gameobject(argv[1]))
);
static const JSCFunctionListEntry js_model_funcs[] = {
MIST_FUNC_DEF(model, draw_go, 1)
};
static const JSCFunctionListEntry js_emitter_funcs[] = { static const JSCFunctionListEntry js_emitter_funcs[] = {
CGETSET_ADD(emitter, life), CGETSET_ADD(emitter, life),
CGETSET_ADD(emitter, life_var), CGETSET_ADD(emitter, life_var),
@ -1171,6 +1185,24 @@ JSC_CCALL(gameobject_this2world, return vec22js(go2world(js2gameobject(this), js
JSC_CCALL(gameobject_dir_world2this, return vec22js(mat_t_dir(t_world2go(js2gameobject(this)), js2vec2(argv[0])))) JSC_CCALL(gameobject_dir_world2this, return vec22js(mat_t_dir(t_world2go(js2gameobject(this)), js2vec2(argv[0]))))
JSC_CCALL(gameobject_dir_this2world, return vec22js(mat_t_dir(t_go2world(js2gameobject(this)), js2vec2(argv[0])))) JSC_CCALL(gameobject_dir_this2world, return vec22js(mat_t_dir(t_go2world(js2gameobject(this)), js2vec2(argv[0]))))
JSC_CCALL(gameobject_rotate3d,
HMM_Vec3 rot = js2vec3(argv[0]);
HMM_Quat qrot = HMM_QFromAxisAngle_RH((HMM_Vec3){1,0,0}, rot.x);
qrot = HMM_MulQ(qrot, HMM_QFromAxisAngle_RH((HMM_Vec3){0,1,0}, rot.y));
qrot = HMM_MulQ(qrot, HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,1}, rot.z));
gameobject *go = js2gameobject(this);
go->quat = HMM_MulQ(go->quat, qrot);
return JS_UNDEFINED;
)
JSC_CCALL(gameobject_lookat,
HMM_Vec3 point = js2vec3(argv[0]);
gameobject *go = js2gameobject(this);
HMM_Vec3 pos = go_pos3d(go);
HMM_Mat4 m = HMM_LookAt_RH(pos, point, (HMM_Vec3){0,1,0});
go->quat = HMM_M4ToQ_RH(m);
)
static const JSCFunctionListEntry js_gameobject_funcs[] = { static const JSCFunctionListEntry js_gameobject_funcs[] = {
CGETSET_ADD(gameobject, friction), CGETSET_ADD(gameobject, friction),
CGETSET_ADD(gameobject, elasticity), CGETSET_ADD(gameobject, elasticity),
@ -1200,6 +1232,8 @@ static const JSCFunctionListEntry js_gameobject_funcs[] = {
MIST_FUNC_DEF(gameobject, dir_world2this, 1), MIST_FUNC_DEF(gameobject, dir_world2this, 1),
MIST_FUNC_DEF(gameobject, dir_this2world, 1), MIST_FUNC_DEF(gameobject, dir_this2world, 1),
MIST_FUNC_DEF(gameobject, selfsync, 0), MIST_FUNC_DEF(gameobject, selfsync, 0),
MIST_FUNC_DEF(gameobject, rotate3d, 1),
MIST_FUNC_DEF(gameobject, lookat, 1)
}; };
JSC_CCALL(joint_pin, return constraint2js(constraint_make(cpPinJointNew(js2gameobject(argv[0])->body, js2gameobject(argv[1])->body, cpvzero,cpvzero)))) JSC_CCALL(joint_pin, return constraint2js(constraint_make(cpPinJointNew(js2gameobject(argv[0])->body, js2gameobject(argv[1])->body, cpvzero,cpvzero))))
@ -1367,7 +1401,10 @@ const char *STRTEST = "TEST STRING";
JSC_CCALL(performance_barecall,) JSC_CCALL(performance_barecall,)
JSC_CCALL(performance_unpack_num, int i = js2number(argv[0])) JSC_CCALL(performance_unpack_num, int i = js2number(argv[0]))
JSC_CCALL(performance_unpack_array, js2cpvec2arr(argv[0])) JSC_CCALL(performance_unpack_array,
void *v = js2cpvec2arr(argv[0]);
arrfree(v);
)
JSC_CCALL(performance_pack_num, return number2js(1.0)) JSC_CCALL(performance_pack_num, return number2js(1.0))
JSC_CCALL(performance_pack_string, return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST))) JSC_CCALL(performance_pack_string, return JS_NewStringLen(js, STRTEST, sizeof(*STRTEST)))
JSC_CCALL(performance_unpack_string, js2str(argv[0])) JSC_CCALL(performance_unpack_string, js2str(argv[0]))
@ -1502,18 +1539,12 @@ JSC_SCALL(os_make_texture,
JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0])); JS_SetPropertyStr(js, ret, "path", JS_DupValue(js,argv[0]));
) )
JSC_CCALL(os_make_model,
gameobject *go = js2gameobject(argv[0]);
struct drawmodel *dm = make_drawmodel(go);
JSValue ret = JS_NewObject(js);
js_setprop_str(ret, "id", ptr2js(dm));
return ret;
)
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_SCALL(os_system, system(str); ) JSC_SCALL(os_system, system(str); )
JSC_SCALL(os_make_model, return 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),
MIST_FUNC_DEF(os, cwd, 0), MIST_FUNC_DEF(os, cwd, 0),
@ -1530,9 +1561,9 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, make_circle2d, 2), MIST_FUNC_DEF(os, make_circle2d, 2),
MIST_FUNC_DEF(os, make_poly2d, 2), MIST_FUNC_DEF(os, make_poly2d, 2),
MIST_FUNC_DEF(os, make_edge2d, 2), MIST_FUNC_DEF(os, make_edge2d, 2),
MIST_FUNC_DEF(os, make_model, 2),
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)
}; };
#include "steam.h" #include "steam.h"
@ -1554,7 +1585,7 @@ void ffi_load() {
QJSCLASSPREP_FUNCS(font); QJSCLASSPREP_FUNCS(font);
QJSCLASSPREP_FUNCS(constraint); QJSCLASSPREP_FUNCS(constraint);
QJSCLASSPREP_FUNCS(window); QJSCLASSPREP_FUNCS(window);
QJSCLASSPREP_FUNCS(drawmodel); QJSCLASSPREP_FUNCS(model);
QJSGLOBALCLASS(nota); QJSGLOBALCLASS(nota);
QJSGLOBALCLASS(input); QJSGLOBALCLASS(input);

View file

@ -349,7 +349,7 @@ void openglRender(struct window *window, gameobject *cam, float zoom) {
campos = go_pos(cam); campos = go_pos(cam);
camzoom = zoom; camzoom = zoom;
projection = HMM_Orthographic_LH_NO( projection = HMM_Orthographic_RH_NO(
campos.x - camzoom * usesize.x / 2, campos.x - camzoom * usesize.x / 2,
campos.x + camzoom * usesize.x / 2, campos.x + camzoom * usesize.x / 2,
campos.y - camzoom * usesize.y / 2, campos.y - camzoom * usesize.y / 2,

View file

@ -37,6 +37,12 @@ struct draw_p {
float y; float y;
}; };
struct draw_p3 {
float x;
float y;
float z;
};
#include <chipmunk/chipmunk.h> #include <chipmunk/chipmunk.h>
enum RenderMode { enum RenderMode {

View file

@ -0,0 +1,86 @@
@vs vsg3
// Shared set between most vertex shaders
uniform ViewUniforms {
uniform mat4 view;
uniform mat4 proj;
};
out vec3 nearPoint;
out vec3 farPoint;
out mat4 fragView;
out mat4 fragProj;
// Grid position are in xy clipped space
vec3 gridPlane[6] = vec3[](
vec3(1, 1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3(-1, -1, 0), vec3(1, 1, 0), vec3(1, -1, 0)
);
// normal vertice projection
vec3 UnprojectPoint(float x, float y, float z, mat4 view, mat4 projection) {
mat4 viewInv = inverse(view);
mat4 projInv = inverse(projection);
vec4 unprojectedPoint = viewInv * projInv * vec4(x, y, z, 1.0);
return unprojectedPoint.xyz / unprojectedPoint.w;
}
void main() {
vec3 p = gridPlane[gl_VertexIndex].xyz;
nearPoint = UnprojectPoint(p.x, p.y, 0.0, view, proj).xyz; // unprojecting on the near plane
farPoint = UnprojectPoint(p.x, p.y, 1.0, view, proj).xyz; // unprojecting on the far plane
fragView = view;
fragProj = proj;
gl_Position = vec4(p, 1.0); // using directly the clipped coordinates
}
@end
@fs fsg3
float near = 0.01;
float far = 100;
in vec3 nearPoint;
in vec3 farPoint;
in mat4 fragView;
in mat4 fragProj;
out vec4 outColor;
vec4 grid(vec3 fragPos3D, float scale, bool drawAxis) {
vec2 coord = fragPos3D.xz * scale;
vec2 derivative = fwidth(coord);
vec2 grid = abs(fract(coord - 0.5) - 0.5) / derivative;
float line = min(grid.x, grid.y);
float minimumz = min(derivative.y, 1);
float minimumx = min(derivative.x, 1);
vec4 color = vec4(0.2, 0.2, 0.2, 1.0 - min(line, 1.0));
// z axis
if(fragPos3D.x > -0.1 * minimumx && fragPos3D.x < 0.1 * minimumx)
color.z = 1.0;
// x axis
if(fragPos3D.z > -0.1 * minimumz && fragPos3D.z < 0.1 * minimumz)
color.x = 1.0;
return color;
}
float computeDepth(vec3 pos) {
vec4 clip_space_pos = fragProj * fragView * vec4(pos.xyz, 1.0);
return (clip_space_pos.z / clip_space_pos.w);
}
float computeLinearDepth(vec3 pos) {
vec4 clip_space_pos = fragProj * fragView * vec4(pos.xyz, 1.0);
float clip_space_depth = (clip_space_pos.z / clip_space_pos.w) * 2.0 - 1.0; // put back between -1 and 1
float linearDepth = (2.0 * near * far) / (far + near - clip_space_depth * (far - near)); // get linear value between 0.01 and 100
return linearDepth / far; // normalize
}
void main() {
float t = -nearPoint.y / (farPoint.y - nearPoint.y);
vec3 fragPos3D = nearPoint + t * (farPoint - nearPoint);
gl_FragDepth = computeDepth(fragPos3D);
float linearDepth = computeLinearDepth(fragPos3D);
float fading = max(0, (0.5 - linearDepth));
outColor = (grid(fragPos3D, 10, true) + grid(fragPos3D, 1, true))* float(t > 0); // adding multiple resolution for the grid
outColor.a *= fading;
}
@end
@program grid3d vsg3 fsg3

View file

@ -1,5 +1,5 @@
@vs lvs @vs lvs
in vec2 apos; in vec3 apos;
in float adist; in float adist;
in vec4 acolor; in vec4 acolor;
in float aseglen; in float aseglen;
@ -14,7 +14,7 @@ uniform lvs_params { mat4 proj; };
void main() void main()
{ {
gl_Position = proj * vec4(apos, 0.0, 1.0); gl_Position = proj * vec4(apos, 1.0);
fcolor = acolor; fcolor = acolor;
dist = adist; dist = adist;
seg_len = aseglen; seg_len = aseglen;

View file

@ -12,7 +12,7 @@ void main()
{ {
gl_Position = proj * vec4(apos, 0.0, 1.0); gl_Position = proj * vec4(apos, 0.0, 1.0);
fcolor = acolor; fcolor = acolor;
gl_PointSize = aradius; gl_PointSize = 1.0;
} }
@end @end
@ -24,7 +24,7 @@ in vec4 fcolor;
void main() void main()
{ {
float d = length(gl_FragCoord.xy - vec2(0.5,0.5)); /* Should really pointcoord, normalized */ float d = length(gl_FragCoord.xy - vec2(0.5,0.5)); /* Should really pointcoord, normalized */
if (d >= 0.47) if (d >= 0.1)
discard; discard;
color = fcolor; color = fcolor;

View file

@ -1,8 +1,10 @@
@vs vs @vs vs
in vec3 a_pos; in vec3 a_pos;
in vec2 a_tex_coords; in vec2 a_tex_coords;
//in vec3 a_norm;
out vec2 tex_coords; out vec2 tex_coords;
//out vec3 normal;
uniform vs_p { uniform vs_p {
uniform mat4 vp; uniform mat4 vp;
@ -12,17 +14,21 @@ uniform mat4 model;
void main() { void main() {
gl_Position = vp * vec4(vec3(model * vec4(a_pos,1.0)), 1.0); gl_Position = vp * vec4(vec3(model * vec4(a_pos,1.0)), 1.0);
tex_coords = a_tex_coords; tex_coords = a_tex_coords;
//normal = a_norm;
} }
@end @end
@fs fs @fs fs
in vec2 tex_coords; in vec2 tex_coords;
//in vec3 normal;
out vec4 color; out vec4 color;
uniform texture2D diffuse; uniform texture2D diffuse;
uniform sampler smp; uniform sampler smp;
void main() { void main() {
//vec3 lightDir = normalize(vec3(0.5f, 0.5f, 1.0f));
//float diff = max(dot(normal, lightDir), 0.0f);
color = texture(sampler2D(diffuse,smp),tex_coords); color = texture(sampler2D(diffuse,smp),tex_coords);
} }
@end @end