diff --git a/scripts/draw2d.js b/scripts/draw2d.js index f9606ba3..50840385 100644 --- a/scripts/draw2d.js +++ b/scripts/draw2d.js @@ -2,92 +2,21 @@ var render = use('render') var graphics = use('graphics') var math = use('math') var util = use('util') - -var base_pipeline = { - vertex: "sprite.vert", - fragment: "sprite.frag", - primitive: "triangle", // point, line, linestrip, triangle, trianglestrip - fill: true, // false for lines - depth: { - compare: "greater_equal", // never/less/equal/less_equal/greater/not_equal/greater_equal/always - test: false, - write: false, - bias: 0, - bias_slope_scale: 0, - bias_clamp: 0 - }, - stencil: { - enabled: true, - front: { - compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always - fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap - depth_fail: "keep", - pass: "keep" - }, - back: { - compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always - fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap - depth_fail: "keep", - pass: "keep" - }, - test: true, - compare_mask: 0, - write_mask: 0 - }, - blend: { - enabled: false, - src_rgb: "one", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate - dst_rgb: "zero", - op_rgb: "add", // add/sub/rev_sub/min/max - src_alpha: "one", - dst_alpha: "zero", - op_alpha: "add" - }, - cull: "none", // none/front/back - face: "cw", // cw/ccw - alpha_to_coverage: false, - multisample: { - count: 1, // number of multisamples - mask: 0xFFFFFFFF, - domask: false - }, - label: "scripted pipeline", - target: {} -} - -var sprite_pipeline = Object.create(base_pipeline); -sprite_pipeline.blend = { - enabled:true, - src_rgb: "src_alpha", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate - dst_rgb: "one_minus_src_alpha", - op_rgb: "add", // add/sub/rev_sub/min/max - src_alpha: "one", - dst_alpha: "zero", - op_alpha: "add" -}; - -sprite_pipeline.target = { - color_targets: [{ - format:"rgba8", - blend:sprite_pipeline.blend - }], - depth: "d32 float s8" -}; - -var rect_pipeline = Object.create(sprite_pipeline) -rect_pipeline.fragment = "rectangle.frag" - -var circle_pipeline = Object.create(sprite_pipeline) -circle_pipeline.fragment = "circle.frag" +var os = use('os') var draw = {} +var whiteimage = {} +whiteimage.surface = graphics.make_surface([1,1]) +whiteimage.surface.rect({x:0,y:0,width:1,height:1}, [1,1,1,1]) +whiteimage.texture = prosperon.gpu.load_texture(whiteimage.surface) + /* All draw in screen space */ draw.point = function (pos, size, color = Color.blue) { render._main.point(pos,color); }; -draw.line = function render_line(points, color = Color.white, thickness = 1, pipeline = rect_pipeline) { +draw.line = function render_line(points, color = Color.white, thickness = 1, pipeline) { var mesh = graphics.make_line_prim(points,thickness, 0,0,color); render.queue({ type: 'geometry', @@ -98,14 +27,14 @@ draw.line = function render_line(points, color = Color.white, thickness = 1, pip }); }; -draw.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe = sprite_pipeline) { +draw.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe) { var a = [pos.add([0, size]), pos.add([0, -size])]; var b = [pos.add([size, 0]), pos.add([-size, 0])]; draw.line(a, color, thickness); draw.line(b, color, thickness); }; -draw.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe = sprite_pipeline) { +draw.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe) { var dir = math.norm(end.sub(start)) var wing1 = [math.rotate(dir, wingangle).scale(wingspan).add(end), end]; var wing2 = [math.rotate(dir, -wingangle).scale(wingspan).add(end), end]; @@ -114,19 +43,20 @@ draw.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, render.line(wing2, color); }; -draw.rectangle = function render_rectangle(rect, color = Color.white, pipeline = rect_pipeline) { +draw.rectangle = function render_rectangle(rect, color = Color.white, pipeline) { var T = os.make_transform(); T.rect(rect); render.queue({ type:'sprite', transform:T, color, - pipeline + pipeline, + image:whiteimage }); }; var tile_def = {repeat_x:true, repeat_y:true}; -draw.tile = function(image, rect, color = Color.white, tile = tile_def, pipeline = sprite_pipeline) +draw.tile = function(image, rect, color = Color.white, tile = tile_def, pipeline) { if (!image) throw Error ('Need an image to render.') if (typeof image === "string") @@ -152,7 +82,7 @@ var slice9_info = { tile_center_x:true, tile_center_right:true }; -draw.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white, info = slice9_info, pipeline = sprite_pipeline) { +draw.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white, info = slice9_info, pipeline) { if (!image) throw Error ('Need an image to render.') if (typeof image === "string") image = graphics.texture(image); @@ -170,7 +100,6 @@ draw.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.whit var std_sprite_cmd = { type: 'sprite', - pipeline: sprite_pipeline, color: [1,1,1,1] } @@ -213,28 +142,27 @@ draw.images = function images(image, rects, config) sprites.push(sprite) } -// var sprites = graphics.rects_to_sprites(image,rects); - var cmds = graphics.make_sprite_queue(sprites, prosperon.camera, sprite_pipeline) + var cmds = graphics.make_sprite_queue(sprites, prosperon.camera, undefined) for (var i = 0; i < cmds.length; i++) render.queue(cmds[i]) return sprites; } -draw.sprites = function(sprites, sort = 0, pipeline = sprite_pipeline) +draw.sprites = function(sprites, sort = 0, pipeline) { var cmds = graphics.make_sprite_queue(sprites, prosperon.camera, pipeline, sort); for (var i = 0; i < cmds.length; i++) render.queue(cmds[i]); } -draw.circle = function render_circle(pos, radius, color, inner_radius = 1, pipeline = circle_pipeline) { +draw.circle = function render_circle(pos, radius, color, inner_radius = 1, pipeline) { render.rectangle({x:pos.x, y:pos.y, width:radius*2,height:radius*2}, color, circle_pipeline); }; var sysfont = graphics.get_font('fonts/c64.ttf', 8); -draw.text = function text(text, rect, font = sysfont, size = 0, color = Color.white, wrap = 0, pipeline = sprite_pipeline) { +draw.text = function text(text, rect, font = sysfont, size = 0, color = Color.white, wrap = 0, pipeline) { if (typeof font === 'string') font = graphics.get_font(font) var mesh = graphics.make_text_buffer(text, rect, 0, color, wrap, font); @@ -250,6 +178,4 @@ draw.text = function text(text, rect, font = sysfont, size = 0, color = Color.wh }); }; -draw.sprite_pipeline = sprite_pipeline; - return draw diff --git a/scripts/modules/sprite.js b/scripts/modules/sprite.js index 68ec319e..085ea74e 100644 --- a/scripts/modules/sprite.js +++ b/scripts/modules/sprite.js @@ -1,77 +1,5 @@ var graphics = use('graphics') -var base_pipeline = { - vertex: "sprite.vert", - fragment: "sprite.frag", - primitive: "triangle", // point, line, linestrip, triangle, trianglestrip - fill: true, // false for lines - depth: { - compare: "greater_equal", // never/less/equal/less_equal/greater/not_equal/greater_equal/always - test: false, - write: false, - bias: 0, - bias_slope_scale: 0, - bias_clamp: 0 - }, - stencil: { - enabled: true, - front: { - compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always - fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap - depth_fail: "keep", - pass: "keep" - }, - back: { - compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always - fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap - depth_fail: "keep", - pass: "keep" - }, - test: true, - compare_mask: 0, - write_mask: 0 - }, - blend: { - enabled: false, - src_rgb: "zero", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate - dst_rgb: "zero", - op_rgb: "add", // add/sub/rev_sub/min/max - src_alpha: "one", - dst_alpha: "zero", - op_alpha: "add" - }, - cull: "none", // none/front/back - face: "cw", // cw/ccw - alpha_to_coverage: false, - multisample: { - count: 1, // number of multisamples - mask: 0xFFFFFFFF, - domask: false - }, - label: "scripted pipeline", - target: {} -} - -var sprite_pipeline = Object.create(base_pipeline); -sprite_pipeline.blend = { - enabled:true, - src_rgb: "src_alpha", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate - dst_rgb: "one_minus_src_alpha", - op_rgb: "add", // add/sub/rev_sub/min/max - src_alpha: "one", - dst_alpha: "zero", - op_alpha: "add" -}; - -sprite_pipeline.target = { - color_targets: [{ - format:"rgba8", - blend:sprite_pipeline.blend - }], - depth: "d32 float s8" -}; - - var sprite = { image: undefined, set color(x) { this._sprite.color = x; }, @@ -285,7 +213,7 @@ sprite.to_queue = function(ysort = false) }; var culled = sprite.tree.query(camrect) if (culled.length == 0) return []; - var cmd = graphics.make_sprite_queue(culled, prosperon.camera, sprite_pipeline, 1); + var cmd = graphics.make_sprite_queue(culled, prosperon.camera, undefined, 1); return cmd; } diff --git a/scripts/render.js b/scripts/render.js index 5c084835..0860c582 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -11,6 +11,78 @@ var event = use('event') var sprite = use('sprite') var graphics = use('graphics') +var base_pipeline = { + vertex: "sprite.vert", + fragment: "sprite.frag", + primitive: "triangle", // point, line, linestrip, triangle, trianglestrip + fill: true, // false for lines + depth: { + compare: "greater_equal", // never/less/equal/less_equal/greater/not_equal/greater_equal/always + test: false, + write: false, + bias: 0, + bias_slope_scale: 0, + bias_clamp: 0 + }, + stencil: { + enabled: true, + front: { + compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always + fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap + depth_fail: "keep", + pass: "keep" + }, + back: { + compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always + fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap + depth_fail: "keep", + pass: "keep" + }, + test: true, + compare_mask: 0, + write_mask: 0 + }, + blend: { + enabled: false, + src_rgb: "zero", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate + dst_rgb: "zero", + op_rgb: "add", // add/sub/rev_sub/min/max + src_alpha: "one", + dst_alpha: "zero", + op_alpha: "add" + }, + cull: "none", // none/front/back + face: "cw", // cw/ccw + alpha_to_coverage: false, + multisample: { + count: 1, // number of multisamples + mask: 0xFFFFFFFF, + domask: false + }, + label: "scripted pipeline", + target: {} +} + +var sprite_pipeline = Object.create(base_pipeline); +sprite_pipeline.blend = { + enabled:true, + src_rgb: "src_alpha", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate + dst_rgb: "one_minus_src_alpha", + op_rgb: "add", // add/sub/rev_sub/min/max + src_alpha: "one", + dst_alpha: "zero", + op_alpha: "add" +}; + +sprite_pipeline.target = { + color_targets: [{ + format:"rgba8", + blend:sprite_pipeline.blend + }], + depth: "d32 float s8" +}; + + var appy = {}; appy.inputs = {}; if (os.platform() === "macos") { @@ -21,6 +93,30 @@ appy.inputs["M-f4"] = os.exit; controller.player[0].control(appy); +var default_conf = { + title:`Prosperon [${prosperon.version}-${prosperon.revision}]`, + width: 1280, + height: 720, + icon: graphics.make_texture(io.slurpbytes('icons/moon.gif')), + high_dpi:0, + alpha:1, + fullscreen:0, + sample_count:1, + enable_clipboard:true, + enable_dragndrop: true, + max_dropped_files: 1, + swap_interval: 1, + name: "Prosperon", + version:prosperon.version + "-" + prosperon.revision, + identifier: "world.pockle.prosperon", + creator: "Pockle World LLC", + copyright: "Copyright Pockle World 2025", + type: "application", + url: "https://github.com/johnbrethauer/prosperon" +} + +config.__proto__ = default_conf + prosperon.window = prosperon.engine_start(config); var driver = "vulkan" @@ -391,7 +487,7 @@ var main_depth = { function render_camera(cmds, camera) { -var pass; + var pass; delete camera.target // TODO: HORRIBLE if (!camera.target) { main_color.width = main_depth.width = camera.size.x; @@ -433,28 +529,25 @@ var pass; var pass = cmds.render_pass(camera.target); var camera = prosperon.camera; - var pipeline ; + var pipeline = sprite_pipeline; + bind_pipeline(pass,pipeline); + + var camslot = get_pipeline_ubo_slot(pipeline, 'TransformBuffer'); + if (typeof camslot !== 'undefined') + cmds.camera(camera, camslot); + + modelslot = get_pipeline_ubo_slot(pipeline, "model"); + if (typeof modelslot !== 'undefined') { + var ubo = ubo_obj_to_array(pipeline, 'model', sprite_model_ubo); + cmds.push_vertex_uniform_data(modelslot, ubo); + } + var mesh; var img; var modelslot; cmds.push_debug_group("draw") for (var group of render_queue) { - if (pipeline != group.pipeline) { - pipeline = group.pipeline; - bind_pipeline(pass, pipeline); - - var camslot = get_pipeline_ubo_slot(pipeline, 'TransformBuffer'); - if (typeof camslot !== 'undefined') - cmds.camera(camera, camslot); - - modelslot = get_pipeline_ubo_slot(pipeline, "model"); - if (typeof modelslot !== 'undefined') { - var ubo = ubo_obj_to_array(pipeline, 'model', sprite_model_ubo); - cmds.push_vertex_uniform_data(modelslot, ubo); - } - } - if (mesh != group.mesh) { mesh = group.mesh; bind_model(pass,pipeline,mesh); @@ -471,23 +564,11 @@ var pass; cmds.pop_debug_group() cmds.push_debug_group("hud") - pipeline = undefined; - for (var group of hud_queue) { - if (pipeline != group.pipeline) { - pipeline = group.pipeline; - bind_pipeline(pass, pipeline); - var camslot = get_pipeline_ubo_slot(pipeline, 'TransformBuffer'); if (typeof camslot !== 'undefined') cmds.hud(camera.size, camslot); - - modelslot = get_pipeline_ubo_slot(pipeline, "model"); - if (typeof modelslot !== 'undefined') { - var ubo = ubo_obj_to_array(pipeline, 'model', sprite_model_ubo); - cmds.push_vertex_uniform_data(modelslot, ubo); - } - } - + + for (var group of hud_queue) { if (mesh != group.mesh) { mesh = group.mesh; bind_model(pass,pipeline,mesh); diff --git a/source/jsffi.c b/source/jsffi.c index 4de813d9..927e88d1 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -2483,9 +2483,14 @@ JSC_CCALL(os_engine_start, JS_SDL_PROP(js, p, SDL_PROP_APP_METADATA_TYPE_STRING, type) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) < 0) - return JS_ThrowReferenceError(js, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return JS_ThrowReferenceError(js, "Couldn't initialize SDL: %s\n", SDL_GetError()); + + char *title; + JS_GETPROP(js,title,argv[0],title,cstring) - SDL_Window *new = SDL_CreateWindow("prosperon", js2number(js, js_getproperty(js,argv[0], width_atom)), js2number(js,js_getproperty(js,argv[0], height_atom)), SDL_WINDOW_RESIZABLE); + SDL_Window *new = SDL_CreateWindow(title, js2number(js, js_getproperty(js,argv[0], width_atom)), js2number(js,js_getproperty(js,argv[0], height_atom)), SDL_WINDOW_RESIZABLE); + + JS_FreeCString(js,title); if (!new) return JS_ThrowReferenceError(js, "Couldn't open window: %s\n", SDL_GetError()); @@ -6528,6 +6533,7 @@ JSC_SSCALL(os_eval, return ret = script_eval(js,str, str2)) JSC_CCALL(os_make_timer, return timer2js(js,timer_make(js,argv[0]))) JSC_CCALL(os_update_timers, timer_update(js, js2number(js,argv[0]))) +// input: (encoded image data of jpg, png, bmp, tiff) JSC_CCALL(os_make_texture, size_t len; void *raw = JS_GetArrayBuffer(js, &len, argv[0]); @@ -6558,6 +6564,7 @@ JSC_CCALL(os_make_texture, ret = SDL_Surface2js(js,surf); ) +// input: (gif image data) JSC_CCALL(os_make_gif, size_t rawlen; void *raw = JS_GetArrayBuffer(js, &rawlen, argv[0]); @@ -6607,6 +6614,7 @@ CLEANUP: free(pixels); ) + JSValue aseframe2js(JSContext *js, ase_frame_t aframe) { JSValue frame = JS_NewObject(js); @@ -6619,6 +6627,7 @@ JSValue aseframe2js(JSContext *js, ase_frame_t aframe) return frame; } +// input: (aseprite data) JSC_CCALL(os_make_aseprite, size_t rawlen; void *raw = JS_GetArrayBuffer(js,&rawlen,argv[0]);