Set uniform data from javascript
This commit is contained in:
parent
71fda604ee
commit
41eadce13e
|
@ -820,6 +820,12 @@ 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); }
|
||||||
});
|
});
|
||||||
|
@ -1551,10 +1557,63 @@ 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
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,12 +26,6 @@
|
||||||
|
|
||||||
#include "sokol/sokol_gfx.h"
|
#include "sokol/sokol_gfx.h"
|
||||||
|
|
||||||
#define POS 0
|
|
||||||
#define UV 1
|
|
||||||
#define NORM 2
|
|
||||||
#define WEIGHT 3
|
|
||||||
#define JOINT 4
|
|
||||||
|
|
||||||
static void processnode();
|
static void processnode();
|
||||||
static void processmesh();
|
static void processmesh();
|
||||||
static void processtexture();
|
static void processtexture();
|
||||||
|
@ -52,6 +46,13 @@ struct joints {
|
||||||
char j4;
|
char j4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAT_POS 0
|
||||||
|
#define MAT_UV 1
|
||||||
|
#define MAT_NORM 2
|
||||||
|
#define MAT_BONE 3
|
||||||
|
#define MAT_WEIGHT 4
|
||||||
|
#define MAT_COLOR 5
|
||||||
|
|
||||||
static cgltf_data *cdata;
|
static cgltf_data *cdata;
|
||||||
static char *cpath;
|
static char *cpath;
|
||||||
|
|
||||||
|
@ -63,18 +64,18 @@ void model_init() {
|
||||||
.shader = sg_make_shader(unlit_shader_desc(sg_query_backend())),
|
.shader = sg_make_shader(unlit_shader_desc(sg_query_backend())),
|
||||||
.layout = {
|
.layout = {
|
||||||
.attrs = {
|
.attrs = {
|
||||||
[POS].format = SG_VERTEXFORMAT_FLOAT3,
|
[MAT_POS].format = SG_VERTEXFORMAT_FLOAT3,
|
||||||
[UV].format = SG_VERTEXFORMAT_USHORT2N,
|
[MAT_UV].format = SG_VERTEXFORMAT_USHORT2N,
|
||||||
[UV].buffer_index = 1,
|
[MAT_UV].buffer_index = MAT_UV,
|
||||||
[NORM].format = SG_VERTEXFORMAT_UINT10_N2,
|
[MAT_NORM].format = SG_VERTEXFORMAT_UINT10_N2,
|
||||||
[NORM].buffer_index = 2,
|
[MAT_NORM].buffer_index = MAT_NORM,
|
||||||
[WEIGHT] = {
|
[MAT_WEIGHT] = {
|
||||||
.format = SG_VERTEXFORMAT_UBYTE4N,
|
.format = SG_VERTEXFORMAT_UBYTE4N,
|
||||||
.buffer_index = 3
|
.buffer_index = MAT_WEIGHT
|
||||||
},
|
},
|
||||||
[JOINT] = {
|
[MAT_BONE] = {
|
||||||
.format = SG_VERTEXFORMAT_UBYTE4,
|
.format = SG_VERTEXFORMAT_UBYTE4,
|
||||||
.buffer_index = 4
|
.buffer_index = MAT_BONE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -89,13 +90,13 @@ void model_init() {
|
||||||
.layout = {
|
.layout = {
|
||||||
.attrs = {
|
.attrs = {
|
||||||
[ATTR_vs_st_a_pos].format = SG_VERTEXFORMAT_FLOAT3,
|
[ATTR_vs_st_a_pos].format = SG_VERTEXFORMAT_FLOAT3,
|
||||||
[ATTR_vs_st_a_tex_coords] = {
|
[ATTR_vs_st_a_uv] = {
|
||||||
.format = SG_VERTEXFORMAT_USHORT2N,
|
.format = SG_VERTEXFORMAT_USHORT2N,
|
||||||
.buffer_index = 1
|
.buffer_index = MAT_UV
|
||||||
},
|
},
|
||||||
[ATTR_vs_st_a_norm] = {
|
[ATTR_vs_st_a_norm] = {
|
||||||
.format = SG_VERTEXFORMAT_UINT10_N2,
|
.format = SG_VERTEXFORMAT_UINT10_N2,
|
||||||
.buffer_index = 2
|
.buffer_index = MAT_NORM
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -141,21 +142,21 @@ void mesh_add_material(primitive *prim, cgltf_material *mat)
|
||||||
{
|
{
|
||||||
if (!mat) return;
|
if (!mat) return;
|
||||||
|
|
||||||
|
prim->mat = calloc(sizeof(*prim->mat), 1);
|
||||||
|
material *pmat = prim->mat;
|
||||||
|
|
||||||
if (mat->has_pbr_metallic_roughness && mat->pbr_metallic_roughness.base_color_texture.texture) {
|
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;
|
||||||
prim->bind.fs.images[0] = texture_fromdata(buf->buffer->data, buf->size)->id;
|
pmat->diffuse = texture_fromdata(buf->buffer->data, buf->size);
|
||||||
} else {
|
} else {
|
||||||
char *path = makepath(dirname(cpath), img->uri);
|
char *path = makepath(dirname(cpath), img->uri);
|
||||||
prim->bind.fs.images[0] = texture_from_file(path)->id;
|
pmat->diffuse = texture_from_file(path);
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
prim->bind.fs.images[0] = texture_from_file("icons/moon.gif")->id;
|
pmat->diffuse = texture_from_file("icons/moon.gif");
|
||||||
|
|
||||||
// TODO: Cache and reuse samplers
|
|
||||||
prim->bind.fs.samplers[0] = tex_sampler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
sg_buffer texcoord_floats(float *f, int verts, int comp)
|
||||||
|
@ -219,7 +220,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.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
retp.idx = 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,
|
||||||
|
@ -237,7 +238,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.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
retp.idx = 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});
|
||||||
|
@ -259,7 +260,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.bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
|
retp.pos = 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"
|
||||||
|
@ -267,7 +268,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_normal:
|
case cgltf_attribute_type_normal:
|
||||||
retp.bind.vertex_buffers[2] = normal_floats(vs, verts, comp);
|
retp.norm = normal_floats(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_tangent:
|
case cgltf_attribute_type_tangent:
|
||||||
|
@ -277,15 +278,15 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_weights:
|
case cgltf_attribute_type_weights:
|
||||||
retp.bind.vertex_buffers[3] = weight_buf(vs, verts, comp);
|
retp.weight = weight_buf(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_joints:
|
case cgltf_attribute_type_joints:
|
||||||
retp.bind.vertex_buffers[4] = joint_buf(vs, verts, comp);
|
retp.bone = joint_buf(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cgltf_attribute_type_texcoord:
|
case cgltf_attribute_type_texcoord:
|
||||||
retp.bind.vertex_buffers[1] = texcoord_floats(vs, verts, comp);
|
retp.uv = texcoord_floats(vs, verts, comp);
|
||||||
break;
|
break;
|
||||||
case cgltf_attribute_type_invalid:
|
case cgltf_attribute_type_invalid:
|
||||||
YughWarn("Invalid type.");
|
YughWarn("Invalid type.");
|
||||||
|
@ -315,7 +316,7 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (retp.bind.vertex_buffers[NORM].id) {
|
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);
|
||||||
|
@ -334,7 +335,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.bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){
|
retp.norm = 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});
|
||||||
}
|
}
|
||||||
|
@ -510,6 +511,20 @@ void model_free(model *m)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sg_bindings primitive_bind(primitive *p)
|
||||||
|
{
|
||||||
|
sg_bindings b = {0};
|
||||||
|
b.vertex_buffers[unlit_attr_slot("a_pos")] = p->pos;
|
||||||
|
b.vertex_buffers[5] = p->uv;
|
||||||
|
b.vertex_buffers[3] = p->norm;
|
||||||
|
//b.vertex_buffers[unlit_attr_slot("a_bone")] = p->bone;
|
||||||
|
//b.vertex_buffers[unlit_attr_slot("a_weight")] = p->weight;
|
||||||
|
b.index_buffer = p->idx;
|
||||||
|
b.fs.images[unlit_image_slot(SG_SHADERSTAGE_FS, "diffuse")] = p->mat->diffuse->id;
|
||||||
|
b.fs.samplers[unlit_sampler_slot(SG_SHADERSTAGE_FS, "smp")] = 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 view = t3d_go2world(cam);
|
||||||
|
@ -538,6 +553,8 @@ void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
||||||
.size = sizeof(*sk->binds)*50
|
.size = sizeof(*sk->binds)*50
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sg_apply_pipeline(model_st_pipe);
|
||||||
|
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vp.e));
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vs_p, SG_RANGE_REF(vp.e));
|
||||||
float ambient[4] = {1.0,1.0,1.0,1.0};
|
float ambient[4] = {1.0,1.0,1.0,1.0};
|
||||||
|
@ -547,12 +564,13 @@ void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
||||||
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_apply_bindings(&(msh.primitives[j].bind));
|
sg_bindings b = primitive_bind(msh.primitives+j);
|
||||||
|
sg_apply_bindings(&b);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vmodel, &(sg_range){
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vmodel, &(sg_range){
|
||||||
.ptr = mod.em,
|
.ptr = mod.em,
|
||||||
.size = sizeof(mod)
|
.size = sizeof(mod)
|
||||||
});
|
});
|
||||||
sg_draw(0, model->meshes[i].primitives[j].idx_count, 1);
|
sg_draw(0, msh.primitives[j].idx_count, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,20 @@ typedef struct material {
|
||||||
struct model;
|
struct model;
|
||||||
|
|
||||||
typedef struct primitive {
|
typedef struct primitive {
|
||||||
sg_bindings bind;
|
sg_buffer pos;
|
||||||
|
sg_buffer norm;
|
||||||
|
sg_buffer uv;
|
||||||
|
sg_buffer bone;
|
||||||
|
sg_buffer weight;
|
||||||
|
sg_buffer idx;
|
||||||
|
material *mat;
|
||||||
uint32_t idx_count;
|
uint32_t idx_count;
|
||||||
} primitive;
|
} primitive;
|
||||||
|
|
||||||
|
typedef struct shader {
|
||||||
|
sg_pipeline pipeline;
|
||||||
|
} shader;
|
||||||
|
|
||||||
/* A single mesh */
|
/* A single mesh */
|
||||||
typedef struct mesh {
|
typedef struct mesh {
|
||||||
primitive *primitives;
|
primitive *primitives;
|
||||||
|
@ -60,6 +70,7 @@ 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;
|
||||||
|
|
|
@ -279,6 +279,7 @@ typedef union HMM_Vec3 {
|
||||||
};
|
};
|
||||||
|
|
||||||
float Elements[3];
|
float Elements[3];
|
||||||
|
float e[3];
|
||||||
|
|
||||||
} HMM_Vec3;
|
} HMM_Vec3;
|
||||||
|
|
||||||
|
|
|
@ -61,6 +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(emitter)
|
QJSCLASS(emitter)
|
||||||
QJSCLASS(dsp_node)
|
QJSCLASS(dsp_node)
|
||||||
|
@ -625,6 +626,110 @@ JSC_CCALL(render_clear_color,
|
||||||
|
|
||||||
JSC_CCALL(render_set_sprite_tex, sprite_tex(js2texture(argv[0])))
|
JSC_CCALL(render_set_sprite_tex, sprite_tex(js2texture(argv[0])))
|
||||||
|
|
||||||
|
JSC_CCALL(render_pipeline,
|
||||||
|
sg_shader_desc desc = {0};
|
||||||
|
JSValue prog = argv[0];
|
||||||
|
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 sgshader = sg_make_shader(&desc);
|
||||||
|
|
||||||
|
sg_pipeline_desc pdesc = {0};
|
||||||
|
pdesc.shader = sgshader;
|
||||||
|
pdesc.cull_mode = SG_CULLMODE_FRONT;
|
||||||
|
pdesc.depth.write_enabled = true;
|
||||||
|
pdesc.depth.compare = SG_COMPAREFUNC_LESS_EQUAL;
|
||||||
|
|
||||||
|
pdesc.layout.attrs[0].format = SG_VERTEXFORMAT_FLOAT2;
|
||||||
|
|
||||||
|
pdesc.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP;
|
||||||
|
//pdesc.colors[0].blend = blend_trans;
|
||||||
|
|
||||||
|
sg_pipeline pipe = sg_make_pipeline(&pdesc);
|
||||||
|
jsfreestr(vsf);
|
||||||
|
jsfreestr(fsf);
|
||||||
|
jsfreestr(vsmain);
|
||||||
|
jsfreestr(fsmain);
|
||||||
|
return number2js(pipe.id);
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(render_spritepipe, pip_sprite.id = js2number(argv[0]))
|
||||||
|
|
||||||
|
JSC_CCALL(render_texture,
|
||||||
|
tex_draw(js2texture(argv[0]), js2gameobject(argv[1]));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(render_setuniv,
|
||||||
|
float f = js2number(argv[0]);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_FS, js2number(argv[1]), SG_RANGE_REF(f));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(render_setuniv3,
|
||||||
|
HMM_Vec3 v = js2vec3(argv[0]);
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_FS, js2number(argv[1]), SG_RANGE_REF(v.e));
|
||||||
|
)
|
||||||
|
|
||||||
|
JSC_CCALL(render_spdraw,
|
||||||
|
gameobject *go = js2gameobject(argv[0]);
|
||||||
|
HMM_Mat4 m = transform2d2mat4(go2t(go));
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 1, SG_RANGE_REF(m.e));
|
||||||
|
sg_bindings bind = {0};
|
||||||
|
bind.vertex_buffers[0] = sprite_quad;
|
||||||
|
sg_apply_bindings(&bind);
|
||||||
|
sg_draw(0,4,1);
|
||||||
|
)
|
||||||
|
|
||||||
static const JSCFunctionListEntry js_render_funcs[] = {
|
static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
MIST_FUNC_DEF(render, grid, 3),
|
MIST_FUNC_DEF(render, grid, 3),
|
||||||
MIST_FUNC_DEF(render, point, 3),
|
MIST_FUNC_DEF(render, point, 3),
|
||||||
|
@ -640,6 +745,12 @@ static const JSCFunctionListEntry js_render_funcs[] = {
|
||||||
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, set_sprite_tex, 1),
|
MIST_FUNC_DEF(render, set_sprite_tex, 1),
|
||||||
|
MIST_FUNC_DEF(render, pipeline, 1),
|
||||||
|
MIST_FUNC_DEF(render, spritepipe, 1),
|
||||||
|
MIST_FUNC_DEF(render, texture, 2),
|
||||||
|
MIST_FUNC_DEF(render, setuniv3, 2),
|
||||||
|
MIST_FUNC_DEF(render, setuniv, 2),
|
||||||
|
MIST_FUNC_DEF(render, spdraw, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
JSC_CCALL(gui_flush, text_flush(&useproj));
|
JSC_CCALL(gui_flush, text_flush(&useproj));
|
||||||
|
@ -891,6 +1002,7 @@ 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),
|
||||||
|
@ -907,7 +1019,8 @@ 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_CCALL(debug_draw_gameobject, gameobject_draw_debug(js2gameobject(argv[0]));)
|
||||||
|
@ -1031,6 +1144,8 @@ 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]))
|
||||||
);
|
);
|
||||||
|
@ -1536,7 +1651,7 @@ JSC_CCALL(os_make_font, return font2js(MakeFont(js2str(argv[0]), js2number(argv[
|
||||||
|
|
||||||
JSC_SCALL(os_system, system(str); )
|
JSC_SCALL(os_system, system(str); )
|
||||||
|
|
||||||
JSC_SCALL(os_make_model, return model2js(model_make(str)))
|
JSC_SCALL(os_make_model, ret = model2js(model_make(str)))
|
||||||
|
|
||||||
JSC_CCALL(os_sprite_pipe, sprite_pipe())
|
JSC_CCALL(os_sprite_pipe, sprite_pipe())
|
||||||
|
|
||||||
|
|
|
@ -135,4 +135,9 @@ 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
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
#include "sprite.sglsl.h"
|
#include "sprite.sglsl.h"
|
||||||
#include "9slice.sglsl.h"
|
#include "9slice.sglsl.h"
|
||||||
|
|
||||||
static sg_shader shader_sprite;
|
sg_pipeline pip_sprite;
|
||||||
static sg_pipeline pip_sprite;
|
|
||||||
sg_bindings bind_sprite;
|
sg_bindings bind_sprite;
|
||||||
|
|
||||||
static sg_shader slice9_shader;
|
static sg_shader slice9_shader;
|
||||||
|
@ -45,10 +44,8 @@ static texture *loadedtex;
|
||||||
static int sprite_count = 0;
|
static int sprite_count = 0;
|
||||||
|
|
||||||
void sprite_initialize() {
|
void sprite_initialize() {
|
||||||
shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend()));
|
|
||||||
|
|
||||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||||
.shader = shader_sprite,
|
.shader = sg_make_shader(sprite_shader_desc(sg_query_backend())),
|
||||||
.layout = {
|
.layout = {
|
||||||
.attrs = {
|
.attrs = {
|
||||||
[0].format = SG_VERTEXFORMAT_FLOAT2
|
[0].format = SG_VERTEXFORMAT_FLOAT2
|
||||||
|
@ -84,7 +81,6 @@ void sprite_pipe()
|
||||||
{
|
{
|
||||||
sg_apply_pipeline(pip_sprite);
|
sg_apply_pipeline(pip_sprite);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj));
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj));
|
||||||
sg_apply_bindings(&bind_sprite);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transform2d sprite2t(sprite *s)
|
transform2d sprite2t(sprite *s)
|
||||||
|
@ -102,6 +98,25 @@ void sprite_tex(texture *t)
|
||||||
bind_sprite.fs.images[0] = t->id;
|
bind_sprite.fs.images[0] = t->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sprite_setpipe(sg_pipeline p)
|
||||||
|
{
|
||||||
|
pip_sprite = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tex_draw(texture *tex, gameobject *go)
|
||||||
|
{
|
||||||
|
HMM_Mat4 m = transform2d2mat4(go2t(go));
|
||||||
|
|
||||||
|
sg_apply_uniforms(SG_SHADERSTAGE_VS, 1, SG_RANGE_REF(m.e));
|
||||||
|
|
||||||
|
sg_bindings bind = {0};
|
||||||
|
bind.vertex_buffers[0] = sprite_quad;
|
||||||
|
bind.fs.images[0] = tex->id;
|
||||||
|
bind.fs.samplers[0] = std_sampler;
|
||||||
|
sg_apply_bindings(&bind);
|
||||||
|
sg_draw(0,4,1);
|
||||||
|
}
|
||||||
|
|
||||||
void sprite_draw(struct sprite *sprite, gameobject *go) {
|
void sprite_draw(struct sprite *sprite, gameobject *go) {
|
||||||
HMM_Mat4 m = transform2d2mat4(go2t(go));
|
HMM_Mat4 m = transform2d2mat4(go2t(go));
|
||||||
HMM_Mat4 sm = transform2d2mat4(sprite2t(sprite));
|
HMM_Mat4 sm = transform2d2mat4(sprite2t(sprite));
|
||||||
|
@ -111,7 +126,11 @@ void sprite_draw(struct sprite *sprite, gameobject *go) {
|
||||||
spv.size = sprite->spritesize;
|
spv.size = sprite->spritesize;
|
||||||
spv.offset = sprite->spriteoffset;
|
spv.offset = sprite->spriteoffset;
|
||||||
spv.model = HMM_MulM4(m,sm);
|
spv.model = HMM_MulM4(m,sm);
|
||||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_sprite, SG_RANGE_REF(spv));
|
|
||||||
|
sg_bindings bind = {0};
|
||||||
|
bind.vertex_buffers[0] = sprite_quad;
|
||||||
|
bind.fs.images[0] = loadedtex->id;
|
||||||
|
bind.fs.samplers[0] = std_sampler;
|
||||||
sg_draw(0,4,1);
|
sg_draw(0,4,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,17 @@ struct spriteuni {
|
||||||
typedef struct sprite sprite;
|
typedef struct sprite sprite;
|
||||||
|
|
||||||
extern sg_bindings bind_sprite;
|
extern sg_bindings bind_sprite;
|
||||||
|
extern sg_pipeline pip_sprite;
|
||||||
|
|
||||||
sprite *sprite_make();
|
sprite *sprite_make();
|
||||||
void sprite_free(sprite *sprite);
|
void sprite_free(sprite *sprite);
|
||||||
void sprite_tex(texture *t);
|
void sprite_tex(texture *t);
|
||||||
void sprite_initialize();
|
void sprite_initialize();
|
||||||
|
void tex_draw(texture *tex, gameobject *go);
|
||||||
void sprite_draw(struct sprite *sprite, gameobject *go);
|
void sprite_draw(struct sprite *sprite, gameobject *go);
|
||||||
void sprite_pipe();
|
void sprite_pipe();
|
||||||
void sprite_draw_all();
|
void sprite_draw_all();
|
||||||
|
void sprite_setpipe(sg_pipeline p);
|
||||||
|
|
||||||
void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color);
|
void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color);
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ struct texture *texture_from_file(const char *path) {
|
||||||
.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]);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@ 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 texture */
|
sg_image id; /* ID reference for the GPU memory location of the
|
||||||
|
texture */
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@block vptr
|
@block vptr
|
||||||
in vec3 a_pos;
|
in vec3 a_pos;
|
||||||
in vec2 a_tex_coords;
|
in vec2 a_uv;
|
||||||
in vec4 a_norm;
|
in vec4 a_norm;
|
||||||
out vec2 tex_coords;
|
out vec2 tex_coords;
|
||||||
out vec3 normal;
|
out vec3 normal;
|
||||||
|
@ -11,21 +11,21 @@ uniform vmodel { uniform mat4 model; };
|
||||||
@vs vs
|
@vs vs
|
||||||
@include_block vptr
|
@include_block vptr
|
||||||
|
|
||||||
|
in vec4 a_bone;
|
||||||
in vec4 a_weight;
|
in vec4 a_weight;
|
||||||
in vec4 a_joint;
|
|
||||||
|
|
||||||
uniform skinv { uniform mat4 bones[50]; };
|
uniform skinv { uniform mat4 bones[50]; };
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 tt = vp;
|
mat4 tt = vp;
|
||||||
mat4 mm = model;
|
mat4 mm = model;
|
||||||
mat4 skin = bones[int(a_joint.x)] * a_weight.x;
|
mat4 skin = bones[int(a_bone.x)] * a_weight.x;
|
||||||
skin += bones[int(a_joint.y)] * a_weight.y;
|
skin += bones[int(a_bone.y)] * a_weight.y;
|
||||||
skin += bones[int(a_joint.z)] * a_weight.z;
|
skin += bones[int(a_bone.z)] * a_weight.z;
|
||||||
skin += bones[int(a_joint.w)] * a_weight.w;
|
skin += bones[int(a_bone.w)] * a_weight.w;
|
||||||
mat4 skinm = mm * skin;
|
mat4 skinm = mm * skin;
|
||||||
gl_Position = tt * skinm * vec4(a_pos,1.0);
|
gl_Position = tt * skinm * vec4(a_pos,1.0);
|
||||||
tex_coords = a_tex_coords;
|
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
|
||||||
|
@ -35,7 +35,7 @@ void main() {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = vp * model * vec4(a_pos,1.0);
|
gl_Position = vp * model * vec4(a_pos,1.0);
|
||||||
tex_coords = a_tex_coords;
|
tex_coords = a_uv;
|
||||||
normal = (model * vec4(a_norm.xyz*2-1,0)).xyz;
|
normal = (model * vec4(a_norm.xyz*2-1,0)).xyz;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in a new issue