optimize makeing sprite queue

This commit is contained in:
2025-01-13 22:11:56 -06:00
parent 9a2e897464
commit 04273b3d43
7 changed files with 76 additions and 33 deletions

View File

@@ -760,8 +760,10 @@ function sprites_to_queue(sprites, ysort = false)
{
return render._main.make_sprite_queue(allsprites, prosperon.camera, sprite_pipeline)
var sprites = allsprites;
for (var i = 0; i < sprites.length; i++)
sprites[i].transform.clean();
// for (var i = 0; i < sprites.length; i++)
// sprites[i].transform.clean();
var dirtysprites = allsprites.filter(x=>x.transform.dirty());
if (dirtysprites.length > 0) console.log(`there was ${dirtysprites.length} dirty sprites`)
// var sprites = os.cull_sprites(allsprites, prosperon.camera);
os.insertion_sort(sprites,render._main.sort_sprite)

View File

@@ -271,7 +271,7 @@ Cmdline.register_order(
render._main = prosperon.window.make_gpu(false, driver);
render._main.window = prosperon.window;
render._main.claim_window(prosperon.window);
render._main.set_swapchain("sdr", "mailbox");
render._main.set_swapchain("sdr", "vsync");
var tt = game.texture('moon');
tt.texture.__proto__.toString = function() { return os.value_id(this); }

View File

@@ -29,6 +29,8 @@
#include "cgltf.h"
#include "physfs.h"
#include "sprite.h"
#include <SDL3/SDL.h>
#include <SDL3/SDL_gpu.h>
#include <SDL3/SDL_error.h>
@@ -1104,6 +1106,8 @@ QJSCLASS(datastream)
QJSCLASS(timer)
QJSCLASS(skin)
QJSCLASS(jssprite)
QJSCLASS(SDL_Window)
QJSCLASS(SDL_Renderer)
QJSCLASS(SDL_Camera)
@@ -1143,6 +1147,8 @@ QJSCLASS(SDL_GPUCopyPass)
QJSCLASS(SDL_GPURenderPass)
QJSCLASS(SDL_Cursor)
int js_arrlen(JSContext *js,JSValue v) {
if (JS_IsUndefined(v)) return 0;
int len;
@@ -4060,7 +4066,9 @@ JSC_CCALL(gpu_sort_sprite,
transform *atr, *btr;
JS_GETATOM(js,atr,a,transform_atom,transform)
JS_GETATOM(js,btr,b,transform_atom,transform);
if (atr->gcache3.Columns[2].y != btr->gcache3.Columns[2].y) return number2js(js,btr->gcache3.Columns[2].y - atr->gcache3.Columns[2].y);
HMM_Mat3 am3 = transform2mat3_global(atr);
HMM_Mat3 bm3 = transform2mat3_global(btr);
if (am3.Columns[2].y != bm3.Columns[2].y) return number2js(js,bm3.Columns[2].y - am3.Columns[2].y);
JSValue aimg,bimg;
aimg = JS_GetProperty(js,a,image_atom);
@@ -4104,10 +4112,10 @@ JSC_CCALL(gpu_make_sprite_queue,
for (int i = 0; i < quads; i++) {
JSValue sub = JS_GetPropertyUint32(js, argv[0], i);
JSValue jstransform = JS_GetPropertyStr(js, sub, "transform");
HMM_Mat3 trmat = js2transform_mat3(js,jstransform);
transform *t;
JS_GETATOM(js,t,sub,transform_atom,transform)
HMM_Mat3 trmat = transform2mat3_global(t);
if (!sprite_in_view(trmat,info.world_to_projection)) {
JS_FreeValue(js,jstransform);
JS_FreeValue(js,sub);
continue;
}
@@ -4141,18 +4149,16 @@ JSC_CCALL(gpu_make_sprite_queue,
arrput(sprites,sp);
JS_FreeValue(js, sub);
JS_FreeValue(js, jstransform);
}
qsort(sprites, arrlen(sprites),sizeof(sprite),sort_sprite);
text_vert *buffer = NULL;
for (int i = 0; i < quads; i++)
arrsetcap(buffer,arrlen(sprites)*4);
for (int i = 0; i < arrlen(sprites); i++)
for (int j = 0; j < 4; j++)
arrpush(buffer, sprites[i].quad.vert[j]);
arrput(buffer, sprites[i].quad.vert[j]);
JSValue mesh = quads_to_mesh(js, buffer);
arrfree(buffer);
ret = JS_NewArray(js);
@@ -4160,7 +4166,7 @@ JSC_CCALL(gpu_make_sprite_queue,
int count = 0;
int n = 0;
JSValue img = JS_UNDEFINED;
for (int i = 0; i < quads; i++) {
for (int i = 0; i < arrlen(sprites); i++) {
if (!JS_SameValue(js,sprites[i].image, img)) {
if (count > 0) {
JSValue q = JS_NewObject(js);
@@ -5870,6 +5876,7 @@ JSC_CCALL(transform_unit,
t->rotation = QUAT1;
t->scale = v3one;
transform_apply(t);
t->parent = NULL;
)
JSC_CCALL(transform_trs,
@@ -5897,35 +5904,40 @@ JSC_CCALL(transform_array,
JS_SetPropertyUint32(js,ret,i, number2js(js,m.em[i]));
)
/*static JSValue js_transform_get_parent(JSContext *js, JSValueConst self)
static JSValue js_transform_get_parent(JSContext *js, JSValueConst self)
{
return JS_GetProperty(js,self,parent_atom);
transform *t = js2transform(js,self);
if (t->parent) return JS_DupValue(js,t->jsparent);
return JS_UNDEFINED;
}
static JSValue js_transform_set_parent(JSContext *js, JSValueConst self, JSValue v)
{
transform *t = js2transform(js,self);
if (t->parent) return JS_UNDEFINED;
transform *p = js2transform(js,v);
if (!p) {
JS_SetProperty(js,self,parent_atom,JS_UNDEFINED);
t->parent = NULL;
}
if (t->parent)
JS_FreeValue(js,t->jsparent);
JS_SetProperty(js,self,parent_atom,JS_DupValue(js,v));
transform *p = js2transform(js,v);
t->parent = p;
if (p)
t->jsparent = JS_DupValue(js,v);
return JS_UNDEFINED;
}
*/
JSC_CCALL(transform_clean,
js2transform_mat3(js,self);
transform2mat3_global(js2transform(js,self));
)
JSC_CCALL(transform_dirty,
return JS_NewBool(js,transform_dirty_chain(js2transform(js,self)));
)
static const JSCFunctionListEntry js_transform_funcs[] = {
CGETSET_ADD(transform, pos),
CGETSET_ADD(transform, scale),
CGETSET_ADD(transform, rotation),
// CGETSET_ADD(transform, parent),
CGETSET_ADD(transform, parent),
MIST_FUNC_DEF(transform, trs, 3),
MIST_FUNC_DEF(transform, phys2d, 3),
MIST_FUNC_DEF(transform, move, 1),
@@ -5937,6 +5949,7 @@ static const JSCFunctionListEntry js_transform_funcs[] = {
MIST_FUNC_DEF(transform, rect, 1),
MIST_FUNC_DEF(transform, array, 0),
MIST_FUNC_DEF(transform, clean, 0),
MIST_FUNC_DEF(transform, dirty, 0),
};
JSC_CCALL(datastream_time, return number2js(js,plm_get_time(js2datastream(js,self)->plm)); )
@@ -7000,11 +7013,6 @@ JSC_CCALL(os_power_state,
return JS_UNDEFINED;
)
JSC_CCALL(os_cull_sprite,
JSValue sprite = argv[0];
JSValue camera = argv[1];
)
JSC_CCALL(os_cull_sprites,
ret = JS_NewArray(js);
int n = 0;
@@ -7091,6 +7099,11 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, cull_sprites, 2),
};
static const JSCFunctionListEntry js_jssprite_funcs[] = {
};
#define JSSTATIC(NAME, PARENT) \
js_##NAME = JS_NewObject(js); \
JS_SetPropertyFunctionList(js, js_##NAME, js_##NAME##_funcs, countof(js_##NAME##_funcs)); \
@@ -7159,6 +7172,7 @@ void ffi_load(JSContext *js) {
QJSCLASSPREP_FUNCS(SDL_GPUTexture)
QJSCLASSPREP_FUNCS(SDL_GPUCommandBuffer)
QJSCLASSPREP_FUNCS(SDL_GPURenderPass)
QJSCLASSPREP_FUNCS(jssprite)
// QJSCLASSPREP_FUNCS(SDL_GPUGraphicsPipeline)
// QJSCLASSPREP_FUNCS(SDL_GPUSampler)
// QJSCLASSPREP_FUNCS(SDL_GPUShader)

View File

@@ -1 +1,6 @@
#include "sprite.h"
void jssprite_free(JSRuntime *rt, jssprite *sprite)
{
free(sprite);
}

View File

@@ -4,10 +4,14 @@
#include "HandmadeMath.h"
#include "script.h"
typedef struct {
struct jssprite{
HMM_Mat3 affine;
JSValue image;
int layer;
} sprite;
};
typedef struct jssprite jssprite;
void jssprite_free(JSRuntime *rt, jssprite *sprite);
#endif

View File

@@ -74,7 +74,23 @@ HMM_Mat3 transform2mat3(transform *t)
HMM_Mat3 transform2mat3_global(transform *t)
{
if (!transform_dirty_chain(t)) return t->gcache3;
HMM_Mat3 tm = transform2mat3(t);
if (t->parent) {
t->gcache3 = HMM_MulM3(transform2mat3(t->parent), tm);
} else
t->gcache3 = tm;
return t->gcache3;
}
int transform_dirty_chain(transform *t)
{
if (t->dirty) return 1;
if (t->parent)
return transform_dirty_chain(t->parent);
return 0;
}
void transform_apply(transform *t)

View File

@@ -14,6 +14,7 @@ typedef struct transform {
HMM_Mat4 gcache;
int dirty;
struct transform *parent;
JSValue jsparent;
struct transform *children;
} transform;
@@ -48,6 +49,7 @@ HMM_Mat4 transform2mat(transform *t);
HMM_Mat3 transform2mat3(transform *t);
HMM_Mat3 transform2mat3_global(transform *t);
int transform_dirty_chain(transform *t);
transform mat2transform(HMM_Mat4 m);