render sprite geometry

This commit is contained in:
2025-05-02 11:18:13 -05:00
parent ead61e648a
commit 446ad080e1
4 changed files with 124 additions and 15 deletions

View File

@@ -57,4 +57,9 @@ sprite.geometry = function()
return graphics.make_sprite_mesh(sprites) return graphics.make_sprite_mesh(sprites)
} }
sprite.queue = function()
{
return graphics.make_sprite_queue(sprites)
}
return sprite return sprite

View File

@@ -29,12 +29,11 @@ render.initialize = function(config)
} }
prosperon.window = prosperon.engine_start({width:500,height:500}) prosperon.window = prosperon.engine_start({width:500,height:500})
context = prosperon.window.make_renderer() context = prosperon.window.make_renderer("vulkan")
} }
render.sprite = function(sprite) render.sprite = function(sprite)
{ {
context.sprite(sprite) context.sprite(sprite)
} }

View File

@@ -2880,7 +2880,6 @@ JSC_CCALL(renderer_rects,
return JS_ThrowReferenceError(js, "SDL_RenderFillRects: %s", SDL_GetError()); return JS_ThrowReferenceError(js, "SDL_RenderFillRects: %s", SDL_GetError());
) )
// Should take a single struct with pos, color, uv, and indices arrays // Should take a single struct with pos, color, uv, and indices arrays
JSC_CCALL(renderer_geometry, JSC_CCALL(renderer_geometry,
renderer_ctx *ctx = js2renderer_ctx(js,self); renderer_ctx *ctx = js2renderer_ctx(js,self);
@@ -2890,7 +2889,7 @@ JSC_CCALL(renderer_geometry,
JSValue uv = JS_GetPropertyStr(js,argv[1], "uv"); JSValue uv = JS_GetPropertyStr(js,argv[1], "uv");
JSValue indices = JS_GetPropertyStr(js,argv[1], "indices"); JSValue indices = JS_GetPropertyStr(js,argv[1], "indices");
int vertices = js_getnum_str(js, argv[1], "vertices"); int vertices = js_getnum_str(js, argv[1], "vertices");
int count = js_getnum_str(js, argv[1], "count"); int count = js_getnum_str(js, argv[1], "num_indices");
size_t pos_stride, indices_stride, uv_stride, color_stride; size_t pos_stride, indices_stride, uv_stride, color_stride;
void *posdata = get_gpu_buffer(js,pos, &pos_stride, NULL); void *posdata = get_gpu_buffer(js,pos, &pos_stride, NULL);
@@ -2908,7 +2907,7 @@ JSC_CCALL(renderer_geometry,
trans_pos[i].x = p.x; trans_pos[i].x = p.x;
trans_pos[i].y = p.y; trans_pos[i].y = p.y;
} }
if (!SDL_RenderGeometryRaw(r, tex, trans_pos, pos_stride,colordata,color_stride,uvdata, uv_stride, vertices, idxdata, count, indices_stride)) if (!SDL_RenderGeometryRaw(r, tex, trans_pos, pos_stride,colordata,color_stride,uvdata, uv_stride, vertices, idxdata, count, indices_stride))
ret = JS_ThrowReferenceError(js, "Error rendering geometry: %s",SDL_GetError()); ret = JS_ThrowReferenceError(js, "Error rendering geometry: %s",SDL_GetError());
@@ -2920,6 +2919,73 @@ JSC_CCALL(renderer_geometry,
JS_FreeValue(js,indices); JS_FreeValue(js,indices);
) )
JSC_CCALL(renderer_geometry2,
renderer_ctx *ctx = js2renderer_ctx(js, self);
SDL_Renderer *r = ctx->sdl;
SDL_Texture *tex = js2SDL_Texture(js, argv[0]);
JSValue geo = argv[1];
int vertices = js_getnum_str(js, geo, "vertices");
int count = js_getnum_str(js, geo, "num_indices");
JSValue pos_v = JS_GetPropertyStr(js, geo, "pos");
JSValue color_v = JS_GetPropertyStr(js, geo, "color");
JSValue uv_v = JS_GetPropertyStr(js, geo, "uv");
JSValue idx_v = JS_GetPropertyStr(js, geo, "indices");
size_t pos_stride, color_stride, uv_stride, idx_stride;
void *pos_data = get_gpu_buffer(js, pos_v, &pos_stride, NULL);
void *color_data = get_gpu_buffer(js, color_v, &color_stride, NULL);
void *uv_data = get_gpu_buffer(js, uv_v, &uv_stride, NULL);
void *idx_data = get_gpu_buffer(js, idx_v, &idx_stride, NULL);
SDL_Vertex *verts = malloc(vertices * sizeof *verts);
for(int i = 0; i < vertices; ++i) {
const float *p = (const float *)((uint8_t *)pos_data + i * pos_stride);
const float *u = (const float *)((uint8_t *)uv_data + i * uv_stride);
const float *c = (const float *)((uint8_t *)color_data + i * color_stride);
SDL_FPoint screen = renderer_world_to_screen(ctx,
(HMM_Vec2){ .x = p[0], .y = p[1] });
verts[i].position = screen;
verts[i].tex_coord = (SDL_FPoint){ u[0], u[1] };
verts[i].color = (SDL_FColor){ c[0], c[1], c[2], c[3] };
}
const int *indices32 = NULL;
int *tmp_idx = NULL;
if(idx_data && count) {
if(idx_stride == 4) indices32 = (const int *)idx_data;
else {
tmp_idx = malloc(count * sizeof *tmp_idx);
if(idx_stride == 2) {
const uint16_t *src = idx_data;
for(int i = 0; i < count; ++i) tmp_idx[i] = src[i];
} else { /* 8-bit */
const uint8_t *src = idx_data;
for(int i = 0; i < count; ++i) tmp_idx[i] = src[i];
}
indices32 = tmp_idx;
}
}
printf("num verts, num indices: %d, %d\n", vertices, count);
if(!SDL_RenderGeometry(r, tex, verts, vertices, indices32, count))
printf("Error rendering geometry: %s\n", SDL_GetError());
free(tmp_idx);
free(verts);
JS_FreeValue(js, pos_v);
JS_FreeValue(js, color_v);
JS_FreeValue(js, uv_v);
JS_FreeValue(js, idx_v);
)
JSC_CCALL(renderer_logical_size, JSC_CCALL(renderer_logical_size,
SDL_Renderer *r = js2renderer_ctx(js,self)->sdl; SDL_Renderer *r = js2renderer_ctx(js,self)->sdl;
HMM_Vec2 v = js2vec2(js,argv[0]); HMM_Vec2 v = js2vec2(js,argv[0]);
@@ -3119,6 +3185,7 @@ static const JSCFunctionListEntry js_renderer_ctx_funcs[] = {
MIST_FUNC_DEF(renderer, texture, 5), MIST_FUNC_DEF(renderer, texture, 5),
MIST_FUNC_DEF(renderer, rects, 1), MIST_FUNC_DEF(renderer, rects, 1),
MIST_FUNC_DEF(renderer, geometry, 2), MIST_FUNC_DEF(renderer, geometry, 2),
MIST_FUNC_DEF(renderer, geometry2, 2),
MIST_FUNC_DEF(renderer, sprite, 1), MIST_FUNC_DEF(renderer, sprite, 1),
MIST_FUNC_DEF(renderer, load_texture, 1), MIST_FUNC_DEF(renderer, load_texture, 1),
MIST_FUNC_DEF(renderer, get_image, 1), MIST_FUNC_DEF(renderer, get_image, 1),
@@ -4074,10 +4141,10 @@ JSC_CCALL(gpu_make_sprite_queue,
int needfree = 1; int needfree = 1;
int sort = js2number(js,argv[3]); int sort = js2number(js,argv[3]);
// test for fastest if (JS_IsArrayBuffer(js, argv[0])) {
size_t size; // test for fastest
sprites = JS_GetArrayBuffer(js,&size,argv[0]); size_t size;
if (sprites) { sprite *sprites = JS_GetArrayBuffer(js, &size, argv[0]);
quads = size/sizeof(*sprites); quads = size/sizeof(*sprites);
needfree = 0; needfree = 0;
for (int i = 0; i < quads; i++) for (int i = 0; i < quads; i++)

View File

@@ -33,18 +33,43 @@ var center = [0.5,0.5]
var vel = 50 var vel = 50
for (var i = 0; i < 20000; i++) { function hsl_to_rgb(h, s, l) {
var sp = sprite.create(bunny, [Math.random()*dim.x, Math.random()*dim.y], center) var c = (1 - Math.abs(2 * l - 1)) * s
var x = c * (1 - Math.abs((h / 60) % 2 - 1))
var m = l - c / 2
var r = 0, g = 0, b = 0
if (h < 60) { r = c; g = x }
else if (h < 120) { r = x; g = c }
else if (h < 180) { g = c; b = x }
else if (h < 240) { g = x; b = c }
else if (h < 300) { r = x; b = c }
else { r = c; b = x }
return [r + m, g + m, b + m, 1] // 01 floats, alpha = 1
}
var bunny_count = 2000
for (var i = 0; i < bunny_count; i++) {
var pct = i/bunny_count
var sp = sprite.create(bunny, [Math.random()*dim.x*pct, Math.random()*dim.y*pct], center)
sp.dir = [Math.random()*vel, Math.random()*vel] sp.dir = [Math.random()*vel, Math.random()*vel]
var hue = 270 * i / bunny_count
sp.color = hsl_to_rgb(hue, 0.5, 0.5)
} }
function movendraw(sp) function movendraw(sp)
{ {
// sp.move([sp.dir[0]*dt, sp.dir[1]*dt]) sp.move([sp.dir[0]*dt, sp.dir[1]*dt])
sp.draw() // sp.draw()
} }
var dt = 0 var dt = 0
var fps_samples = []
var fps_window = 10
var fps_update_period = 0.5
var last_fps_update = os.now()
function loop() function loop()
{ {
var now = os.now() var now = os.now()
@@ -52,11 +77,24 @@ function loop()
render.camera(camera) render.camera(camera)
// sprite.forEach(movendraw) // sprite.forEach(movendraw)
var mesh = sprite.geometry() var queue = sprite.queue()
render.geometry(bunny.texture, mesh)
for (var q of queue)
render.geometry(q.image.texture, q.mesh)
render.present() render.present()
dt = os.now() - now dt = os.now() - now
fps_samples.push(dt)
if (fps_samples.length > fps_window) fps_samples.shift()
if (now - last_fps_update >= fps_update_period) {
var sum = 0
for (var i = 0; i < fps_samples.length; i++) sum += fps_samples[i]
prosperon.window.title = `Bunnymark [fps: ${(fps_samples.length/sum).toFixed(1)}]`;
last_fps_update = now
}
var delay = (1/60) - dt var delay = (1/60) - dt
$_.delay(loop, delay) $_.delay(loop, delay)
} }