scriptable rendering pipeline

This commit is contained in:
John Alanbrook 2024-10-04 00:45:44 -05:00
parent 0ffef3b602
commit 179e883d0e
3 changed files with 42 additions and 22 deletions

View file

@ -739,6 +739,7 @@ render.flush = check_flush;
render.forceflush = function() render.forceflush = function()
{ {
if (nextflush) nextflush(); if (nextflush) nextflush();
nextflush = undefined;
} }
var poly_cache = []; var poly_cache = [];
@ -893,12 +894,6 @@ function img_e() {
return img_cache[img_idx - 1]; return img_cache[img_idx - 1];
} }
render.floodmask = function(val)
{
render.use_shader(polyshader);
render.use_mat({});
}
var stencil_write = { var stencil_write = {
compare: compare.always, compare: compare.always,
fail_op: stencilop.replace, fail_op: stencilop.replace,
@ -906,7 +901,7 @@ var stencil_write = {
pass_op: stencilop.replace pass_op: stencilop.replace
}; };
function stencil_writer(ref) var stencil_writer = function stencil_writer(ref)
{ {
var pipe = Object.create(base_pipeline); var pipe = Object.create(base_pipeline);
Object.assign(pipe, { Object.assign(pipe, {
@ -920,32 +915,56 @@ function stencil_writer(ref)
}, },
write_mask: colormask.none write_mask: colormask.none
}); });
} return pipe;
}.hashify();
// objects by default draw where the stencil buffer is 0 // objects by default draw where the stencil buffer is 0
render.fillmask = function(ref)
var pipe_stencil_on = stencil_writer(1);
var pipe_stencil_off = stencil_writer(0);
render.fillmask = function(on)
{ {
var pipe = on ? pipe_stencil_on : pipe_stencil_off; render.forceflush();
var pipe = stencil_writer(ref);
render.use_shader('shaders/screenfill.cg', pipe); render.use_shader('shaders/screenfill.cg', pipe);
render.draw(shape.quad); render.draw(shape.quad);
} }
render.mask = function mask(tex, pos, scale, rotation = 0) var stencil_invert = {
compare: compare.always,
fail_op: stencilop.invert,
depth_fail_op: stencilop.invert,
pass_op: stencilop.invert
};
var stencil_inverter = Object.create(base_pipeline);
Object.assign(stencil_inverter, {
stencil: {
enabled: true,
front: stencil_invert,
back:stencil_invert,
write:true,
read:true,
ref: 0
},
write_mask: colormask.none
});
render.invertmask = function()
{
render.forceflush();
render.use_shader('shaders/screenfill.cg', stencil_inverter);
render.draw(shape.quad);
}
render.mask = function mask(tex, pos, scale, rotation = 0, ref = 1)
{ {
if (typeof tex === 'string') tex = game.texture(tex); if (typeof tex === 'string') tex = game.texture(tex);
var pipe = stencil_writer(ref);
render.use_shader(spritessboshader, pipe_stencil_on); render.use_shader('shaders/sprite.cg', pipe);
var t = os.make_transform(); var t = os.make_transform();
t.pos = pos; t.pos = pos;
t.scale = scale; t.scale = scale.div(tex.dimensions);
set_model(t); set_model(t);
render.use_mat({ render.use_mat({
diffuse:tex, diffuse:tex,
rect: [0,0,1,1] rect: [0,0,1,1],
shade: Color.white
}); });
render.draw(shape.quad); render.draw(shape.quad);
} }

View file

@ -9,11 +9,11 @@ void vert()
@end @end
@block frag @block frag
uniform vec4 shade;
void frag() void frag()
{ {
color = texture(sampler2D(diffuse,smp), uv); color = texture(sampler2D(diffuse,smp), uv);
color *= shade; if (color.a != 0) discard;
} }
@end @end

View file

@ -995,6 +995,7 @@ sg_stencil_state js2stencil(JSValue v)
stencil.write_mask = js2boolean(js_getpropstr(v, "write")) ? 0xFF : 0x00; stencil.write_mask = js2boolean(js_getpropstr(v, "write")) ? 0xFF : 0x00;
stencil.front = js2face_state(js_getpropstr(v, "front")); stencil.front = js2face_state(js_getpropstr(v, "front"));
stencil.back = js2face_state(js_getpropstr(v, "back")); stencil.back = js2face_state(js_getpropstr(v, "back"));
stencil.ref = js2number(js_getpropstr(v, "ref"));
return stencil; return stencil;
} }