Sprite, transform, render overhaul
This commit is contained in:
parent
41eadce13e
commit
e86e126894
|
@ -13,6 +13,10 @@ this.view2world = function(pos) {
|
|||
pos = pos.scale(this.zoom);
|
||||
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;
|
||||
};
|
||||
this.world2view = function(pos) {
|
||||
|
@ -25,6 +29,9 @@ this.world2view = function(pos) {
|
|||
pos = pos.sub(this.pos);
|
||||
pos = pos.scale(1/this.zoom);
|
||||
pos = pos.add(window.size.scale(0.5));
|
||||
}
|
||||
if (window.mode === window.modetypes.expand) {
|
||||
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
|
|
@ -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]) {
|
||||
var scale = [dimensions.x/tex.width, dimensions.y/tex.height];
|
||||
gui.img(tex,pos, scale, 0.0, false, [0.0,0.0], color);
|
||||
return bbox.fromcwh([0,0], [tex.width,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);
|
||||
//return bbox.fromcwh([0,0], [tex.width,tex.height]);
|
||||
}
|
||||
|
||||
render.fontcache = {};
|
||||
|
|
|
@ -30,84 +30,9 @@ static void processnode();
|
|||
static void processmesh();
|
||||
static void processtexture();
|
||||
|
||||
static sg_pipeline model_pipe;
|
||||
static sg_pipeline model_st_pipe;
|
||||
struct bone_weights {
|
||||
char b1;
|
||||
char b2;
|
||||
char b3;
|
||||
char b4;
|
||||
};
|
||||
|
||||
struct joints {
|
||||
char j1;
|
||||
char j2;
|
||||
char j3;
|
||||
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 char *cpath;
|
||||
|
||||
struct joints joint_nul = { 0, 0, 0, 0 };
|
||||
struct bone_weights weight_nul = {0, 0, 0, 0};
|
||||
|
||||
void model_init() {
|
||||
model_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = sg_make_shader(unlit_shader_desc(sg_query_backend())),
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[MAT_POS].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[MAT_UV].format = SG_VERTEXFORMAT_USHORT2N,
|
||||
[MAT_UV].buffer_index = MAT_UV,
|
||||
[MAT_NORM].format = SG_VERTEXFORMAT_UINT10_N2,
|
||||
[MAT_NORM].buffer_index = MAT_NORM,
|
||||
[MAT_WEIGHT] = {
|
||||
.format = SG_VERTEXFORMAT_UBYTE4N,
|
||||
.buffer_index = MAT_WEIGHT
|
||||
},
|
||||
[MAT_BONE] = {
|
||||
.format = SG_VERTEXFORMAT_UBYTE4,
|
||||
.buffer_index = MAT_BONE
|
||||
}
|
||||
},
|
||||
},
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_FRONT,
|
||||
.depth.write_enabled = true,
|
||||
.depth.compare = SG_COMPAREFUNC_LESS_EQUAL
|
||||
});
|
||||
|
||||
model_st_pipe = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = sg_make_shader(unlit_st_shader_desc(sg_query_backend())),
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[ATTR_vs_st_a_pos].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[ATTR_vs_st_a_uv] = {
|
||||
.format = SG_VERTEXFORMAT_USHORT2N,
|
||||
.buffer_index = MAT_UV
|
||||
},
|
||||
[ATTR_vs_st_a_norm] = {
|
||||
.format = SG_VERTEXFORMAT_UINT10_N2,
|
||||
.buffer_index = MAT_NORM
|
||||
}
|
||||
},
|
||||
},
|
||||
.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)
|
||||
{
|
||||
for (int i = 0; i < p->attributes_count; i++) {
|
||||
|
@ -184,6 +109,24 @@ 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)
|
||||
{
|
||||
char joints[v*c];
|
||||
|
@ -275,14 +218,15 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
|||
break;
|
||||
|
||||
case cgltf_attribute_type_color:
|
||||
retp.color = ubyten_buffer(vs,verts,comp);
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_weights:
|
||||
retp.weight = weight_buf(vs, verts, comp);
|
||||
retp.weight = ubyten_buffer(vs, verts, comp);
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_joints:
|
||||
retp.bone = joint_buf(vs, verts, comp);
|
||||
retp.bone = ubyte_buffer(vs, verts, comp);
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_texcoord:
|
||||
|
@ -294,29 +238,31 @@ struct primitive mesh_add_primitive(cgltf_primitive *prim)
|
|||
|
||||
case cgltf_attribute_type_custom:
|
||||
break;
|
||||
|
||||
case cgltf_attribute_type_max_enum:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (!retp.bind.vertex_buffers[JOINT].id) {
|
||||
struct joints jnts[retp.idx_count];
|
||||
for (int i = 0; i < retp.idx_count; i++)
|
||||
jnts[i] = joint_nul;
|
||||
|
||||
retp.bind.vertex_buffers[JOINT] = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(jnts)});
|
||||
if (!retp.bone.id) {
|
||||
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.bind.vertex_buffers[WEIGHT].id) {
|
||||
struct bone_weights v[retp.idx_count];
|
||||
for (int i = 0; i < retp.idx_count; i++)
|
||||
v[i] = weight_nul;
|
||||
|
||||
retp.bind.vertex_buffers[WEIGHT] = sg_make_buffer(&(sg_buffer_desc){ .data = SG_RANGE(v)});
|
||||
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.norm.id) {
|
||||
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.");
|
||||
cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position);
|
||||
int n = cgltf_accessor_unpack_floats(pa->data, NULL,0);
|
||||
|
@ -535,26 +481,19 @@ void model_draw_go(model *model, gameobject *go, gameobject *cam)
|
|||
animation_run(&model->anim, apptime());
|
||||
|
||||
skin *sk = &model->skin;
|
||||
if (arrlen(sk->joints) == 0) {
|
||||
sg_apply_pipeline(model_st_pipe);
|
||||
} else {
|
||||
sg_apply_pipeline(model_pipe);
|
||||
|
||||
for (int i = 0; i < arrlen(sk->joints); i++) {
|
||||
md5joint *md = sk->joints[i];
|
||||
HMM_Mat4 local = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);
|
||||
if (md->parent)
|
||||
local = HMM_MulM4(md->parent->t, local);
|
||||
md->t = local;
|
||||
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
|
||||
}
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_skinv, &(sg_range){
|
||||
.ptr = sk->binds,
|
||||
.size = sizeof(*sk->binds)*50
|
||||
});
|
||||
for (int i = 0; i < arrlen(sk->joints); i++) {
|
||||
md5joint *md = sk->joints[i];
|
||||
HMM_Mat4 local = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);
|
||||
if (md->parent)
|
||||
local = HMM_MulM4(md->parent->t, local);
|
||||
md->t = local;
|
||||
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
|
||||
}
|
||||
|
||||
sg_apply_pipeline(model_st_pipe);
|
||||
/*sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_skinv, &(sg_range){
|
||||
.ptr = sk->binds,
|
||||
.size = sizeof(*sk->binds)*50
|
||||
});
|
||||
*/
|
||||
|
||||
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};
|
||||
|
|
|
@ -8,7 +8,13 @@
|
|||
#include "anim.h"
|
||||
#include "texture.h"
|
||||
|
||||
extern HMM_Vec3 eye;
|
||||
#define MAT_POS 0
|
||||
#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 {
|
||||
texture *diffuse;
|
||||
|
@ -31,15 +37,12 @@ typedef struct primitive {
|
|||
sg_buffer uv;
|
||||
sg_buffer bone;
|
||||
sg_buffer weight;
|
||||
sg_buffer color;
|
||||
sg_buffer idx;
|
||||
material *mat;
|
||||
uint32_t idx_count;
|
||||
} primitive;
|
||||
|
||||
typedef struct shader {
|
||||
sg_pipeline pipeline;
|
||||
} shader;
|
||||
|
||||
/* A single mesh */
|
||||
typedef struct mesh {
|
||||
primitive *primitives;
|
||||
|
|
|
@ -221,6 +221,7 @@ typedef union HMM_Vec2 {
|
|||
};
|
||||
|
||||
float Elements[2];
|
||||
float e[2];
|
||||
|
||||
cpVect cp;
|
||||
|
||||
|
@ -404,6 +405,7 @@ typedef union HMM_Mat3 {
|
|||
typedef union HMM_Mat4 {
|
||||
float Elements[4][4];
|
||||
HMM_Vec4 Columns[4];
|
||||
HMM_Vec4 col[4];
|
||||
float e[4][4];
|
||||
float em[16];
|
||||
} HMM_Mat4;
|
||||
|
|
|
@ -63,6 +63,8 @@ const char *js2str(JSValue v) {
|
|||
|
||||
void jsfreestr(const char *s) { JS_FreeCString(js, s); }
|
||||
QJSCLASS(gameobject)
|
||||
QJSCLASS(transform3d)
|
||||
QJSCLASS(transform2d)
|
||||
QJSCLASS(emitter)
|
||||
QJSCLASS(dsp_node)
|
||||
QJSCLASS(texture)
|
||||
|
@ -141,6 +143,7 @@ JSValue ptr2js(void *ptr) {
|
|||
}
|
||||
|
||||
int js_arrlen(JSValue v) {
|
||||
if (JS_IsUndefined(v)) return 0;
|
||||
int len;
|
||||
JS_ToInt32(js, &len, js_getpropstr( v, "length"));
|
||||
return len;
|
||||
|
@ -332,6 +335,22 @@ JSValue vec32js(HMM_Vec3 v)
|
|||
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 a;
|
||||
JS_ToUint32(js, &a, v);
|
||||
|
@ -624,11 +643,10 @@ JSC_CCALL(render_clear_color,
|
|||
pass_action.colors[0].clear_value = c;
|
||||
)
|
||||
|
||||
JSC_CCALL(render_set_sprite_tex, sprite_tex(js2texture(argv[0])))
|
||||
|
||||
JSC_CCALL(render_pipeline,
|
||||
sg_shader js2shader(JSValue v)
|
||||
{
|
||||
sg_shader_desc desc = {0};
|
||||
JSValue prog = argv[0];
|
||||
JSValue prog = v;
|
||||
JSValue vs = js_getpropstr(prog, "vs");
|
||||
JSValue fs = js_getpropstr(prog, "fs");
|
||||
char *vsf = js2str(js_getpropstr(vs, "code"));
|
||||
|
@ -683,53 +701,107 @@ JSC_CCALL(render_pipeline,
|
|||
desc.fs.image_sampler_pairs[0].sampler_slot = 0;
|
||||
}
|
||||
|
||||
sg_shader sgshader = sg_make_shader(&desc);
|
||||
sg_shader sh = 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 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_spritepipe, pip_sprite.id = js2number(argv[0]))
|
||||
JSC_CCALL(render_pipeline,
|
||||
sg_shader sgshader = js2shader(argv[0]);
|
||||
|
||||
JSC_CCALL(render_texture,
|
||||
tex_draw(js2texture(argv[0]), js2gameobject(argv[1]));
|
||||
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[0]);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, js2number(argv[1]), SG_RANGE_REF(f));
|
||||
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[0]);
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_FS, js2number(argv[1]), SG_RANGE_REF(v.e));
|
||||
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 = transform2d2mat4(js2transform2d(argv[2]));
|
||||
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(m.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;
|
||||
|
||||
for (int i = 0; i < js_arrlen(argv[1]); i++) {
|
||||
bind.fs.images[i] = js2texture(js_getpropidx(argv[1], 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[] = {
|
||||
MIST_FUNC_DEF(render, grid, 3),
|
||||
MIST_FUNC_DEF(render, point, 3),
|
||||
|
@ -744,13 +816,16 @@ static const JSCFunctionListEntry js_render_funcs[] = {
|
|||
MIST_FUNC_DEF(render, set_camera, 0),
|
||||
MIST_FUNC_DEF(render, hud_res, 1),
|
||||
MIST_FUNC_DEF(render, clear_color, 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, pipeline3d, 1),
|
||||
MIST_FUNC_DEF(render, setuniv3, 2),
|
||||
MIST_FUNC_DEF(render, setuniv, 2),
|
||||
MIST_FUNC_DEF(render, spdraw, 1)
|
||||
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));
|
||||
|
@ -768,21 +843,12 @@ JSC_CCALL(gui_text,
|
|||
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])))
|
||||
|
||||
static const JSCFunctionListEntry js_gui_funcs[] = {
|
||||
MIST_FUNC_DEF(gui, flush, 0),
|
||||
MIST_FUNC_DEF(gui, scissor, 4),
|
||||
MIST_FUNC_DEF(gui, text, 6),
|
||||
MIST_FUNC_DEF(gui, img, 7),
|
||||
MIST_FUNC_DEF(gui, font_set,1)
|
||||
};
|
||||
|
||||
|
@ -1178,6 +1244,16 @@ static const JSCFunctionListEntry js_emitter_funcs[] = {
|
|||
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, off, boolean)
|
||||
JSC_GETSET(dsp_node, gain, number)
|
||||
|
@ -1430,22 +1506,12 @@ static const JSCFunctionListEntry js_pshape_funcs[] = {
|
|||
|
||||
JSC_GETSET(sprite, color, 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, spritesize, vec2)
|
||||
JSC_CCALL(sprite_draw, sprite_draw(js2sprite(this), js2gameobject(argv[0])))
|
||||
|
||||
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,emissive),
|
||||
CGETSET_ADD(sprite, spriteoffset),
|
||||
CGETSET_ADD(sprite, spritesize),
|
||||
MIST_FUNC_DEF(sprite, draw, 1)
|
||||
};
|
||||
|
||||
JSC_GET(texture, width, number)
|
||||
|
@ -1649,12 +1715,14 @@ JSC_SCALL(os_make_texture,
|
|||
|
||||
JSC_CCALL(os_make_font, return font2js(MakeFont(js2str(argv[0]), js2number(argv[1]))))
|
||||
|
||||
JSC_SCALL(os_system, system(str); )
|
||||
JSC_CCALL(os_make_transform2d,
|
||||
return transform2d2js(make_transform2d());
|
||||
)
|
||||
|
||||
JSC_SCALL(os_system, return number2js(system(str)); )
|
||||
|
||||
JSC_SCALL(os_make_model, ret = model2js(model_make(str)))
|
||||
|
||||
JSC_CCALL(os_sprite_pipe, sprite_pipe())
|
||||
|
||||
static const JSCFunctionListEntry js_os_funcs[] = {
|
||||
MIST_FUNC_DEF(os,sprite,1),
|
||||
MIST_FUNC_DEF(os, cwd, 0),
|
||||
|
@ -1674,7 +1742,7 @@ static const JSCFunctionListEntry js_os_funcs[] = {
|
|||
MIST_FUNC_DEF(os, make_texture, 1),
|
||||
MIST_FUNC_DEF(os, make_font, 2),
|
||||
MIST_FUNC_DEF(os, make_model, 1),
|
||||
MIST_FUNC_DEF(os, sprite_pipe, 0)
|
||||
MIST_FUNC_DEF(os, make_transform2d, 0),
|
||||
};
|
||||
|
||||
#include "steam.h"
|
||||
|
@ -1683,10 +1751,13 @@ void ffi_load() {
|
|||
globalThis = JS_GetGlobalObject(js);
|
||||
|
||||
QJSCLASSPREP(ptr);
|
||||
QJSCLASSPREP(transform3d);
|
||||
|
||||
|
||||
QJSGLOBALCLASS(os);
|
||||
|
||||
QJSCLASSPREP_FUNCS(gameobject);
|
||||
QJSCLASSPREP_FUNCS(transform2d);
|
||||
QJSCLASSPREP_FUNCS(dsp_node);
|
||||
QJSCLASSPREP_FUNCS(emitter);
|
||||
QJSCLASSPREP_FUNCS(warp_gravity);
|
||||
|
|
|
@ -257,7 +257,6 @@ void render_init() {
|
|||
|
||||
font_init();
|
||||
debugdraw_init();
|
||||
sprite_initialize();
|
||||
|
||||
model_init();
|
||||
|
||||
|
|
|
@ -7,141 +7,13 @@
|
|||
#include "texture.h"
|
||||
#include "HandmadeMath.h"
|
||||
|
||||
#include "sprite.sglsl.h"
|
||||
#include "9slice.sglsl.h"
|
||||
|
||||
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 *sp = calloc(sizeof(*sp), 1);
|
||||
sp->pos = v2zero;
|
||||
sp->scale = v2one;
|
||||
sp->angle = 0;
|
||||
sp->color = color_white;
|
||||
sp->emissive = color_clear;
|
||||
sp->spritesize = v2one;
|
||||
sp->spriteoffset = v2zero;
|
||||
sp->rect = (HMM_Vec4){0,0,1,1};
|
||||
return sp;
|
||||
}
|
||||
|
||||
void sprite_free(sprite *sprite) { free(sprite); }
|
||||
|
||||
static texture *loadedtex;
|
||||
static int sprite_count = 0;
|
||||
|
||||
void sprite_initialize() {
|
||||
pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = sg_make_shader(sprite_shader_desc(sg_query_backend())),
|
||||
.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));
|
||||
}
|
||||
|
||||
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_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) {
|
||||
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_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);
|
||||
}
|
||||
|
||||
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,39 +7,14 @@
|
|||
#include "transform.h"
|
||||
#include "gameobject.h"
|
||||
|
||||
struct sprite {
|
||||
HMM_Vec2 pos;
|
||||
HMM_Vec2 scale;
|
||||
float angle;
|
||||
typedef struct sprite {
|
||||
struct rgba color;
|
||||
struct rgba emissive;
|
||||
HMM_Vec2 spritesize;
|
||||
HMM_Vec4 rect;
|
||||
HMM_Vec2 spriteoffset;
|
||||
};
|
||||
|
||||
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;
|
||||
extern sg_pipeline pip_sprite;
|
||||
} sprite;
|
||||
|
||||
sprite *sprite_make();
|
||||
void sprite_free(sprite *sprite);
|
||||
void sprite_tex(texture *t);
|
||||
void sprite_initialize();
|
||||
void tex_draw(texture *tex, gameobject *go);
|
||||
void sprite_draw(struct sprite *sprite, gameobject *go);
|
||||
void sprite_pipe();
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "transform.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
const transform2d t2d_unit = {
|
||||
.pos = {0,0},
|
||||
|
@ -7,6 +8,23 @@ const transform2d t2d_unit = {
|
|||
.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_back(const transform3d *trans) { return HMM_QVRot(vBKWD, trans->rotation); }
|
||||
HMM_Vec3 trans_up(const transform3d *trans) { return HMM_QVRot(vUP, trans->rotation); }
|
||||
|
@ -40,13 +58,19 @@ HMM_Mat3 transform2d2mat(transform2d trn) {
|
|||
return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale)));
|
||||
}
|
||||
|
||||
HMM_Mat4 transform2d2mat4(transform2d trn)
|
||||
HMM_Mat4 transform2d2mat4(transform2d *t)
|
||||
{
|
||||
transform3d t3d;
|
||||
t3d.pos.xy = trn.pos;
|
||||
t3d.scale.xy = trn.scale;
|
||||
t3d.rotation = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,-1}, trn.angle);
|
||||
return transform3d2mat(t3d);
|
||||
HMM_Mat4 T = {0};
|
||||
float c = cosf(t->angle);
|
||||
float s = sinf(t->angle);
|
||||
T.col[0].x = c*t->scale.x;
|
||||
T.col[0].y = s*t->scale.y;
|
||||
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)
|
||||
|
|
|
@ -9,12 +9,18 @@ typedef struct transform3d {
|
|||
HMM_Quat rotation;
|
||||
} transform3d;
|
||||
|
||||
transform3d *make_transform3d();
|
||||
void transform3d_free(transform3d *t);
|
||||
|
||||
typedef struct {
|
||||
HMM_Vec2 pos;
|
||||
HMM_Vec2 scale;
|
||||
float angle;
|
||||
} transform2d;
|
||||
|
||||
transform2d *make_transform2d();
|
||||
void transform2d_free(transform2d *t);
|
||||
|
||||
extern const transform2d t2d_unit;
|
||||
|
||||
#define VEC2_FMT "[%g,%g]"
|
||||
|
@ -27,7 +33,7 @@ HMM_Vec3 trans_down(const transform3d *trans);
|
|||
HMM_Vec3 trans_right(const transform3d *trans);
|
||||
HMM_Vec3 trans_left(const transform3d *trans);
|
||||
|
||||
HMM_Mat4 transform2d2mat4(transform2d trn);
|
||||
HMM_Mat4 transform2d2mat4(transform2d *t);
|
||||
|
||||
/* Transform a position via the matrix */
|
||||
HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos);
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
@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
|
|
@ -1,14 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
#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);
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
@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;
|
||||
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
|
|
@ -1,12 +0,0 @@
|
|||
#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;
|
||||
}
|
Loading…
Reference in a new issue