From 4a7543fa68608e805ee8da52f6c1693653e51bd9 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 9 Jan 2025 19:31:08 -0600 Subject: [PATCH] rectangle shading --- scripts/render.js | 142 ++++++++++++---------- shaders/compile.sh | 18 ++- shaders/dxil/dbgline.frag.dxil | Bin 2828 -> 2960 bytes shaders/dxil/dbgline.vert.dxil | Bin 4660 -> 4440 bytes shaders/dxil/model.frag.dxil | Bin 3892 -> 4292 bytes shaders/dxil/model.vert.dxil | Bin 5636 -> 5460 bytes shaders/dxil/model_lit.frag.dxil | Bin 4764 -> 4764 bytes shaders/dxil/post.frag.dxil | Bin 3668 -> 3800 bytes shaders/dxil/post.vert.dxil | Bin 4492 -> 4272 bytes shaders/dxil/rectangle.frag.dxil | Bin 0 -> 2952 bytes shaders/dxil/sprite.frag.dxil | Bin 3872 -> 3968 bytes shaders/dxil/sprite.vert.dxil | Bin 5376 -> 5152 bytes shaders/msl/rectangle.frag.msl | 22 ++++ shaders/rectangle.frag.hlsl | 7 ++ shaders/reflection/rectangle.frag.json | 22 ++++ shaders/sdf.hlsl | 35 ++++++ shaders/spv/rectangle.frag.spv | Bin 0 -> 368 bytes source/jsffi.c | 159 +++++++++---------------- 18 files changed, 239 insertions(+), 166 deletions(-) create mode 100644 shaders/dxil/rectangle.frag.dxil create mode 100644 shaders/msl/rectangle.frag.msl create mode 100644 shaders/rectangle.frag.hlsl create mode 100644 shaders/reflection/rectangle.frag.json create mode 100644 shaders/sdf.hlsl create mode 100644 shaders/spv/rectangle.frag.spv diff --git a/scripts/render.js b/scripts/render.js index ed65921b..438e9983 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -20,6 +20,7 @@ function full_upload(buffers) function queue_sprite_mesh(queue) { var sprites = queue.filter(x => x.type === 'sprite'); + if (sprites.length === 0) return []; var mesh = render._main.make_sprite_mesh(sprites); for (var i = 0; i < sprites.length; i++) { sprites[i].mesh = mesh; @@ -111,6 +112,12 @@ sprite_pipeline.blend = { op_alpha: "add" }; +var rect_pipeline = Object.create(sprite_pipeline) +rect_pipeline.fragment = "rectangle.frag" + +var line_pipeline = Object.create(rect_pipeline); +line_pipeline.primitive = "line" + var dbgline_pipeline = Object.create(base_pipeline); dbgline_pipeline.vertex = "dbgline.vert.hlsl" dbgline_pipeline.fragment = "dbgline.frag.hlsl" @@ -124,7 +131,7 @@ post_camera.size = [640,360]; post_camera.mode = 'keep'; post_camera.viewport = {x:0,y:0,width:1,height:1} post_camera.fov = 45; -post_camera.type = 'ortho'; +post_camera.ortho = true; post_camera.aspect = 16/9; function get_pipeline_ubo_slot(pipeline, name) @@ -227,7 +234,7 @@ render.hotreload = function shader_hotreload(file) { }; function make_pipeline(pipeline) { - if (pipeline.gpu) return; // this pipeline has already been made + if (pipeline.hasOwnProperty("gpu")) return; // this pipeline has already been made if (typeof pipeline.vertex === 'string') pipeline.vertex = make_shader(pipeline.vertex); @@ -302,9 +309,8 @@ var shader_type; function make_shader(sh_file) { var file = `shaders/${shader_type}/${sh_file}.${shader_type}` - - var refl = json.decode(io.slurp(`shaders/reflection/${sh_file}.json`)) if (shader_cache[file]) return shader_cache[file] + var refl = json.decode(io.slurp(`shaders/reflection/${sh_file}.json`)) var shader = { code: io.slurpbytes(file), @@ -358,6 +364,9 @@ render.device = { }; var render_queue = []; +var hud_queue = []; + +var current_queue = render_queue; render.device.doc = `Device resolutions given as [x,y,inches diagonal].`; var std_sampler = { @@ -495,11 +504,15 @@ function render_camera(cmds, camera) }; } - if (render_queue.length == 0) return; - var buffers = queue_sprite_mesh(render_queue); - for (var q of render_queue) { + var buffers = []; + buffers = buffers.concat(queue_sprite_mesh(render_queue)); + for (var q of render_queue) if (q.type === 'geometry') buffers = buffers.concat([q.mesh.pos, q.mesh.color,q.mesh.uv,q.mesh.indices]); - } + + buffers = buffers.concat(queue_sprite_mesh(hud_queue)); + for (var q of hud_queue) + if (q.type === 'geometry') buffers = buffers.concat([q.mesh.pos, q.mesh.color,q.mesh.uv,q.mesh.indices]); + full_upload(buffers) var pass = cmds.render_pass(camera.target); @@ -517,7 +530,7 @@ function render_camera(cmds, camera) var camslot = get_pipeline_ubo_slot(pipeline, 'TransformBuffer'); if (typeof camslot !== 'undefined') - cmds.camera(camera, pass, undefined, camslot); + cmds.camera(camera, camslot); modelslot = get_pipeline_ubo_slot(pipeline, "model"); if (typeof modelslot !== 'undefined') { @@ -531,7 +544,37 @@ function render_camera(cmds, camera) bind_model(pass,pipeline,mesh); } - if (img != group.image) { + if (group.image && img != group.image) { + img = group.image; + img.sampler = std_sampler; + bind_mat(pass,pipeline,{diffuse:img}); + } + + pass.draw_indexed(group.num_indices, 1, group.first_index, 0, 0); + } + + 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); + } + } + + if (mesh != group.mesh) { + mesh = group.mesh; + bind_model(pass,pipeline,mesh); + } + + if (group.image && img != group.image) { img = group.image; img.sampler = std_sampler; bind_mat(pass,pipeline,{diffuse:img}); @@ -597,7 +640,7 @@ function gpupresent() cmds.cancel(); else { var mode = prosperon.camera.presentation || "letterbox" - var src_rect = {x:0,y:0,width:640,height:360} + var src_rect = {x:0,y:0,width:prosperon.camera.size.x,height:prosperon.camera.size.y} var dst_rect = {x:0,y:0,width:swapchain_tex.width,height:swapchain_tex.height}; var torect = mode_rect(src_rect,dst_rect,mode); torect.texture = swapchain_tex; @@ -713,7 +756,8 @@ render.poly = function render_poly(points, color, transform) { }; // render.line has uv and can be texture mapped; dbg_line is hardware standard lines -render.line = function render_line(points, color = Color.white, thickness = 1, pipe = base_pipeline) { +render.line = function render_line(points, color = Color.white, thickness = 1, pipeline = line_pipeline) { + var mesh = os.make_line_prim(points); // render._main.line(points, color); }; @@ -732,14 +776,14 @@ render.point = function (pos, size, color = Color.blue) { render._main.point(pos,color); }; -render.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe = base_pipeline) { +render.cross = function render_cross(pos, size, color = Color.red, thickness = 1, pipe = sprite_pipeline) { var a = [pos.add([0, size]), pos.add([0, -size])]; var b = [pos.add([size, 0]), pos.add([-size, 0])]; render.line(a, color, thickness); render.line(b, color, thickness); }; -render.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe = base_pipeline) { +render.arrow = function render_arrow(start, end, color = Color.red, wingspan = 4, wingangle = 10, pipe = sprite_pipeline) { var dir = end.sub(start).normalized(); var wing1 = [Vector.rotate(dir, wingangle).scale(wingspan).add(end), end]; var wing2 = [Vector.rotate(dir, -wingangle).scale(wingspan).add(end), end]; @@ -755,8 +799,15 @@ render.coordinate = function render_coordinate(pos, size, color) { var queued_shader; var queued_pipe; -render.rectangle = function render_rectangle(rect, color = Color.white, pipe = base_pipeline) { - render._main.fillrect(rect,color); +render.rectangle = function render_rectangle(rect, color = Color.white, pipeline = rect_pipeline) { + var T = os.make_transform(); + T.rect(rect); + current_queue.push({ + type:'sprite', + transform:T, + color, + pipeline + }); }; render.text = function text(text, rect, font = prosperon.font, size = 0, color = Color.white, wrap = 0, pipeline = sprite_pipeline) { @@ -765,7 +816,7 @@ render.text = function text(text, rect, font = prosperon.font, size = 0, color = var mesh = os.make_text_buffer(text, rect, 0, color, wrap, font); // full_upload(mesh) - render_queue.push({ + current_queue.push({ type: 'geometry', mesh: mesh, image: font, @@ -894,12 +945,12 @@ render.image = function image(image, rect = [0,0], rotation = 0, color = Color.w rect.height ??= image.texture.height; var T = os.make_transform(); T.rect(rect); - render_queue.push({ + current_queue.push({ type: 'sprite', transform: T, - color: color, - image:image, - pipeline: pipeline + image, + pipeline, + color }); }; @@ -1019,17 +1070,6 @@ prosperon.make_camera = function make_camera() { cam.screen2cam = screen2cam; cam.screen2hud = screen2hud; cam.zoom = 1; // the "scale factor" this camera demonstrates - // camera renders draw calls, and then hud - cam.render = function() { - prosperon.draw(); - draw_sprites(); - render._main.camera(this.transform,true); - render._main.scale([this.zoom, this.zoom]); - prosperon.hud(); - render._main.scale([1,1]); - render._main.camera(unit_transform,false); - - } return cam; }; @@ -1136,34 +1176,6 @@ var imgui_fn = function imgui_fn() { */ prosperon.imgui(); // imgui.endframe(render._main); -}; - - // figure out the highest resolution we can render at that's an integer -/* var basesize = prosperon.camera.size.slice(); - var baseview = prosperon.camera.view(); - var wh = [baseview[2]-baseview[0], baseview[3]-baseview[1]]; - var mult = 1; - var trysize = basesize.scale(mult); - while (trysize.x <= wh.x && trysize.y <= wh.y) { - mult++; - trysize = basesize.scale(mult); - } - if (Math.abs(wh.x - basesize.scale(mult-1).x) < Math.abs(wh.x - trysize.x)) - mult--; - - \prosperon.window_render(basesize.scale(mult)); -*/ - -prosperon.render = function prosperon_render() { -try{ -try { - imgui_fn(); -} catch(e) { console.error(e) } -} catch(e) { - console.error(e) -} finally { - render._main.present(); -} }; //if (dmon) dmon.watch('.'); @@ -1222,8 +1234,14 @@ try { */ } - try { prosperon.draw(); } catch(e) {console.error(e)} - prosperon.render(); + current_queue = render_queue; + try { prosperon.draw(); } catch(e) { console.error(e) } + current_queue = hud_queue; + try { prosperon.hud(); } catch(e) { console.error(e) } + + try { imgui_fn(); } catch(e) { console.error(e) } + + render._main.present(); } catch(e) { console.error(e) } diff --git a/shaders/compile.sh b/shaders/compile.sh index 6788eb30..2ef9c936 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -1,15 +1,21 @@ #!/usr/bin/env bash # Ensure directories exist -mkdir -p spirv +mkdir -p spv mkdir -p msl +mkdir -p dxil mkdir -p reflection # Vertex shaders for filename in *.vert.hlsl; do if [ -f "$filename" ]; then echo "compiling ${filename}" + # Produce SPIR-V dxc -spirv -T vs_6_0 -Fo "spv/${filename/.hlsl/.spv}" "$filename" + # Produce DXIL + dxc -T vs_6_0 -Fo "dxil/${filename/.hlsl/.dxil}" "$filename" + # Convert SPIR-V to Metal Shader Language spirv-cross "spv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + # Generate reflection spirv-cross "spv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" fi done @@ -17,8 +23,13 @@ done # Fragment shaders for filename in *.frag.hlsl; do if [ -f "$filename" ]; then echo "compiling ${filename}" + # Produce SPIR-V dxc -spirv -T ps_6_0 -Fo "spv/${filename/.hlsl/.spv}" "$filename" + # Produce DXIL + dxc -T ps_6_0 -Fo "dxil/${filename/.hlsl/.dxil}" "$filename" + # Convert SPIR-V to Metal Shader Language spirv-cross "spv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + # Generate reflection spirv-cross "spv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" fi done @@ -26,8 +37,13 @@ done # Compute shaders for filename in *.comp.hlsl; do if [ -f "$filename" ]; then echo "compiling ${filename}" + # Produce SPIR-V dxc -spirv -T cs_6_0 -Fo "spv/${filename/.hlsl/.spv}" "$filename" + # Produce DXIL + dxc -T cs_6_0 -Fo "dxil/${filename/.hlsl/.dxil}" "$filename" + # Convert SPIR-V to Metal Shader Language spirv-cross "spv/${filename/.hlsl/.spv}" --msl > "msl/${filename/.hlsl/.msl}" + # Generate reflection spirv-cross "spv/${filename/.hlsl/.spv}" --reflect > "reflection/${filename/.hlsl/.json}" fi done diff --git a/shaders/dxil/dbgline.frag.dxil b/shaders/dxil/dbgline.frag.dxil index 105930fa4f522634c8ef1cd8e42bdf0af3357764..b34f0bb33a15feea1d8945ae9e43caa02d2b0f92 100644 GIT binary patch delta 1221 zcmeAXn;>5A65-^m%iV3*&v(nOH0SS*uTR2$F)}bPOyFiLCs5FD@qkV1Z_ir}#L zfc)ajlFa-(24{aC{~(~8|3qKuiAz*iR{+^26E6x+e87{+#K-_dr~u@65a0n35Y4%X znRyH_bpjx9C}3o8VP(PZ8(>?a7Udrx`;gE3!|Re3wa`k#{mHvx1C9vy%j)MibLQ zS#L*Rcr`dEfE`sS!N3qdnU}+6aw)Syy;z3xhY1{o6A$M~x|* zP8)MLIyjvU`UrHT9d_~%4vlPfjbZ3ssJ={nC8yIv9|4Z!CI=bmmfqVNcy5-2-b&yN z-|l$8MhzIMA&EulsU^ZKk8W-dNHA!1Eaep|ER|+5ykSt2%#foorGtl|!FAScnY(xD zSsEQO&Mcig;U$} zq;NHJkP}rEW=(jw^G55&n^RBva&}pzROl6FB&MVm`R1pj<^(e>5t5w89V-_TIbrr~ z=~#)_TeEN9nX+J|Gth+TVP(@@%v{CY!p&4vD_#MOnX>cZ$)}Ecm+riH)|d0d0&dB9 zr*A~hm5!Zx=gt%d-p%t__!-rCjwrI%6fjq5w3jusOI~#5`|*J7i2~pA2W;O2_&y!r zdpLpreE|QL$$?zvlX=(#EYIG*eD=?!l)rbZWU~qlf;mBv_X8T4c4(3L04Xv};gPwW z1C+Xq6-;juUwIUC~t^hb2U5yQLZq}G4QAXM0rPQ Tz!fEka>gV{k*6%c90LRZ1qx}t delta 1080 zcmbOr-XrGg65-@*JaPV;irU@3Uibc%u5_2(#K^$Fz{AbJzz(EsfY=9!JAn8I5Jvzd z1=tuEbbvV6&C`GbCDF85w{G z6>veh0w5Z$B{wlMkAVTE79?C5Z881wMa9*`QDX|H)5aW*4o;_o zJ_227O%4*mERSv|B;0IkouIaAQ(O0fExZShrJQ=zt>yD>O;27^fQ7W!qS<@8r1Y9D znX%k&Yh-3la9-$=2z2VDJI`J`Q{!N9O4fV(rn@(%$w9^B*`;&)p1m-WNOoXjOHE)) zPhgvD$Eh9@a7FQO@l0oKW$nq?Rm$4QvxO9+;?sjuO?U3xdvWN+rF(atEo1SO zHL?-ky=BvGl}(zv40dhOJQ&>0bAIWWUOzqlSGs3=^YXj|*kXY?kKKE9=f$ZfKrQK; z=W+@%s`s2wWUnb;E)r-jE?}2L3z;{-+oCK1{Y`bGNKi zYcbtEY5wh#Uo~ClyX>d{2Dr}+Xatx+A^;x#2av*F7asl-CW~^Yn*x&{gOS_}0ZBoh z2|b)@?#Ec17YPBQqa#V9`O^ZePQeBxjTWYbvZoa~929_&35pu$$)y|t^>cU+8aWCu z2!Rrh%ZjcIZS&?W=}_ZvH3CKuFQcKO#x!sQbtE@AC`h-Qy0t-oU&QmWgW$!jiU(%+ zMAinjo}4@NqAxH84?AUCP;+H=b-CWwaN8h7cEiF98GeRU8#dnDx^v0IsXH(FayDtD zROpqZ78Pga=LIt@;*^|c-yJJ4J9g%sDF;?Kw>>v%7jp|!yZ*&3?3kIV$Eyhscivb! z^{(nf-;1pmr}}bEvjS>Q%_}LY49L&SD=7|U;@>=i{NM;8Bl@Cz9 diff --git a/shaders/dxil/dbgline.vert.dxil b/shaders/dxil/dbgline.vert.dxil index 209bc965081959609c43205e79554ee0312360f8..84da4bd6212640b5b0f58b9e11a88e724a2bcd77 100644 GIT binary patch delta 1627 zcma)6eN0nV6o2p0Z(4XN*v>}xkPj;;mWu5pXj(wjK@}}x$E;9Fm73DW`hjDe>7!VN z5e@k0Kx+sf#)=;)f@pCjP!y3!rg2kHRJIwM(<#~1n7BW79|&&yYd1OXoqNvjcg}g| zp8GnZh8HHKsZ&xX?AXiJ+~`Z^QFw0KVCf(XL6CYD1Tn!o8Av7&FAy$pyaIBO4M9J! zYm?HKQl9A*1Qd!H8aibu!7Y#uH{xcn-Kbidu&s6zUr7NdAhq7(CiU#e=hR~+(0iLI zCoc=P7_0`|1f_1w+_)Lovs5|aF)|#M!Lvvu92p^?upcr`!HTs86EIUbA+j0fJLr@K z77VA&R57`S(t?6$5EMM=eeXx6Dx|8Mt`r4221E{o0HVrPWPb;`ln-*e1ZmRL>ociz z6s{H6Q&M{#MsOi$9N2=L82O0fhDGEMQXX+TWbKi;ki~l)k8G;tEGm$;iKkYl=udBf@bl{><}`7s`V#PAwh!Jp*^jvxMBo+}K24e2Pw6tT$`( z3JvDzv@Q1tY**Hqa+_PR<{w1vONyu#a$9+^GGDy3)S%y8f}5>*7Q^jFrnv2CX$=+8z-O|L&{yhcx3_}kC$Cx&PY4>R{Y;^<1>S5&f$^Yv8*vOJ=`^0Y* zqD)k}d>E}p_I3FZWg%ed=Ijl4u&_s!L<1J)$oDC{r+L9z&Iy8ZlHgRtqFx_oN&my) zhmT`eYXq5SRdGeu2)o7SAycILP@2{GA=kq>_0S!_GX5Ram1Lb8Vk+<@tKb`E9=Tk@No6 zTDSj}lI@Hw{4%~&Z?=FDQ6Vktj~e%D1Rl-d(YhvYYULBjH*?c-V(z|5&*_&&%Li+I z@(;L&F8_G_fO|;EKAQO{AY02y^a_&+w`!>|v#4mRS*|21C^*OUg(_gytDKvtV4KI& z7u7Rge>;sHp9+e}uFU4@i%JZE*n==WDkj^Fxo&n}Y#;cvg6(L(w-SN`uk z>JV~6;n1>1CeZ_h$&txh^clI5XQ6*V*gYPyi-$RM32*w}#K;t)7B+Irh$f1MecVQy z_U;64tH6jRC5%b*uj#L)_38C*#=Eo;13iO2{B2bnSIu3Ouxh;$CuoIz%?+Xz1QBaAmKMhw3iT$d%Gt!Bx_NkX8@N1mL{UoRlY$NW{vBIm zWYOZ^Kr3%FyTH7zxLoUQSF#UDKs(HO3vM&(^cI!#Lkzd9hgsE`!YKp2a`ioMw@szw%s{mcEULOkP!7gq-s vobIhsAOt4BymDr%m}6>Ue8ATPL}QA1)q*I9<%FFatDJMJiCIMb6DQZ-3X?5| delta 1839 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 diff --git a/shaders/dxil/model.vert.dxil b/shaders/dxil/model.vert.dxil index f1e54c03c19f5a708929066e67311d3acb94d437..1a758fc29dcdc422c8bb3e3eef259b5575d4e3f9 100644 GIT binary patch delta 2525 zcmbtVdr(tn7QZ*Sc^EF?hL@D!cmYQtKnxnex(vNZ5P1X$5}ee^l7J{t@_+!gqLT-r zSiudwWd;rHf)AufofNGj*v%W6=);*-0v?jNgBJpIE&kDm}aF?Zc%{cfb$?DFYyg1=a+>a=pJ|T<6h%75GCGAf4JQ(VsjUuu^IoU>~1lW#jVJ zZKr%#R5gH%1`||K2^AVj3}uksP^JUAERc8@tPH@QpoV{W=ebh?k)jpI(6vRC`}w*w z@Gc(u(z5~U>(W-}T-2V_!2Io$CzXXF$`b+1S~`xLUHJ-wNn5Tp=pp5Hl`Jc3XA&gK zl4tFNGP8DONaVm*k+Vx=BtM7a;f>@x9Bvi^-EX|zZ-*~p=`>os`|zkxsupZ%U6f_+ zx~M~O%dpffdpZWwlH4+P(QJlb`eMMMOaUg*>ENyWmJ~1r09qB|ktqNmhk0Zw9>|eE zriy`)MVUH&4^ysGkvO&S5amphfd_SjRCyTaH4d0q?0Jq-qHFH;*4*uYxrAF^V{#RY2*m<3SL9rX8dt&+tc?THb6`w*a#i-C+y_}RzYBu(0f4; z^b16$F*9f{TFH-@>&-n?WMTNLb5*ZwWK~WS|9pCt$$?|Th_yHl{bpST#@=ru68sR_ zSzNi_DUpPo>|lT2Bg!n3BP*$?n4+(p0!Ote;Ix0Tv_Mmp9N8JQ? z_nFA-x{jBfr#{Hr{pj1(-;S+r9(U}16qLt%>=;9=O>sCoC`B2-e7L=syu=DM|3&!e z9QS#~>F1YYM&{EEHbTWmr%-{|DU=p!bVX&F{Jq*TPuhQgvM`} z*<`;l*x23Bc>Czc#o5LTtX4<2jY=w54|AEmt9q_o?^;Fc(~0Z}?LYSR#EIp%juxny z+FqssXH{5ORZb0#CpO{iUZ&bb{L;6!giUB%q6JBW9826Xiq+9hUU!P)xnL^z9h0K# z*!2?y+i1DJ2y71qF%8(-f3T&EJevz4JtVJL%? ztwEOd^TSh~RhcA9~bmSiBg=o~$i0 zi{uWz*fTdYHGO|#ybVe6+mx{SrYP>_rtU~d_6hXsB5q7wr~JxneP^96&GKQW%hV9% zsJcw@qa2Pb->r=xc;@BgkZpW?Vy1rvU`)5Mk6@e%3iSTa^A85wfO@D6Ij;a<7l-RJ zg+9+>M(XwYG=iH4oNi4#8=nE$+mLzaY9lW`X&nNv9T z=_Kos4n_^yn4$wm}YJn zmaggT8|RU?o@MCe<6)Nr624vtNMFoZr8_%jr! ze&W;gD{~6`#!7Rmf94Um!5^EW%h3YLqu_@*yJR(5d=Rc_)z+nPI z?eEOcb1gM*y<5GEpo9Zc`c@z)7^;YxIDoJOV4(n}R{-n+0QMCCDgY45T`qxOs6;jD T^~)KRAb|ZVJ6=Qm7b*HL^quwb delta 2706 zcmbtWdr(tX8oxI;2_Y{oZ!plkp^6X?62N3>u}ydt1WJ&=#7Z?$K`9|1QEEXq2_eYT z7xuQxBRb`^Y*vBt&;qjSlF->@6%-$y6{40`}{(tE6cy+S(kij^%zg3#UGCA`0xbw5^7KsMm*ihi37SZvl(+SA=v+;H zLnB|E3!6Y5P#`b(B#;}vyax;L$1M4n2%=v~Lec0Yhbsue0+bTFwD$ovEJm@{1zUg( z1w}wUNDNuB!5#(qU@rmt*YzMD7*eobt%reSL8-AAw#4!fJg*gnz-wm@b0KR2s1&FH zC~^d75zwP>1MZwcrcgQ}hze9@f(Eh5#AFBp>!iRR9WyY=2k$m^QK9xCxt!#!3%=(fwjr}}@_n__k3G(#31(LjFT*Xi+$-h&)%-E~x$o&egq0!W zNlq1+NXtXtBCpZ*z8!#5cf9@(pcw^|BaZltv<9=F5F`L4Z*$)z^XV=QRgJey zL5q!~k?yZ&Tc_<4v%{0q6b)`yF#z`g!W(U z>UX5@^QBcEHVW=s51=cG)LLCmK~aA6v7DUjqJ71=*`Mw^TClIMsNj?A1MnidQumJ= z2o;f*;idGn8Fq#Y=ih#j(w<_yJ=~f+mq$t*`1jB056K(66#;o?Luv$+E~V)$XpHc%)SBsm&Vm++8>E=&8kr_n2zz6%&=46nUzT zv*mZ2zF_Gr;iY7r>*et9Aab!QDX8C6N;WNi!Wvw>XCd%0I+m+9-Q={M_T7M7{qaYS zeJ3nFPakE~?FFzyVuInLI09gaAAc6MBs|;_)C6$H>C{@&=iJsS?9JMZhg6iUJqXT9 zms^qzPUne1PZZ0a8jpQtjQxDWL7Wb0YtxiT3wi9#PJ$gB?HmqyA<7N$As)(;Y`=^RF0V1ByHRlJaU$i;rwv)KIwLs+JKuJ zqeXNcWq+Bx%0_SK5(k&-120kp%@hIqvb5eV&@d_-qtocT^2_5L?3O~Nb(Cop_Sy~1 zZ#wu@{tUBsGG3`Q$w%xJabf0ksaYvC%RDwK>dhS4HTCb3pSj6x9&)wZ%yiFGV>V`o zoYm8z=0iWw{H=lc?G)1_ zP*^*dSuL$M>L+LK!7DEgP7l3UCTK1TW_Jl2DBCmvMKaG~qvr|rpn>&AL=*7udbfdR z=;4~qKbY^1q~MJ6adl68o=#AWuMQ9Y=F-W|3&1C=7gZO}Z~s6dBkXz==EwbB%AHYh z|8C&^LvB7h(mt}~Z0qn@?M__5AJlaQk(Q)Voy7%D8G4!Z!anxm=5z}+&NnQoI`XQp zE3B_Y(iQe?AiAr9eJ8G6GuQT^wpF9uIi>I$)HQ(bGpk5f+Qe#t5Ej3evVaE=6Wqik zKT9L4DQK(3E<(?(eN`ve1{W- zSP_0oSBRA|96nQ>DjYiXsnwyR#uzniaMDVhW=6R$!Du-`AjmJkDkh&fN1#-)j+GfH zsylr8Klvvl3ADJA49)CuI0Yk?r((*6spzwAD#pI~RO~*<5u(KZ8HR8a=940N6zS+B zVLCSm?3+qTzVNFf(QuS)6wM{SYm7*KG4{wpEy|t*ph0^Pqe%O!08$B<9Vo zUMYN4k<1R!4mM^yG}Hf9mFo$vhhGT%Sq@zOUFQ8-V!(n1hg5_~(mSk*>7;8$=~~=@ zN8etBsbWNFIx+;;qQdS=_#3{f`0gy12dI8vDB5?x#_Kiu3>kgSc=;fVGGjFB1U_n{ z6(e6eo2ZCPDAhJNsZft(BPX8if>3QppZPrlP5H{S-Aj~!;8bkd<6ne_%H}qu`i?-Q zIJ;`kbCc3we*d^>4PZa&kziW~P)Sn;n8o@v1gSefm|a7_G5|u=Is^qk;B(g~sAx)| rd0l=c$Y=Z{Oso$p477B^T38Am0L$@TC5(aiF6mF=0W=Ey7XakHDy%s{ diff --git a/shaders/dxil/model_lit.frag.dxil b/shaders/dxil/model_lit.frag.dxil index e6704aec52cc0d02f2e1246cc8b81f85b0947385..5578a0806bce1e776893575da0933064197d5551 100644 GIT binary patch delta 2759 zcmds2eNYo;8h2}qH#Ue)S3cr(|zHz3n`GdKPF?wNf* zp6B?J zBnkkKivUo;lAgRoLBRO5ElE#_u|fxhWjdb!3iQnBiF-^u)p+VmQ2L8AnJ}3+oe8lW z|AE8x0q)ruwDeVLb;TtGr3J-BAY)OcCM|7c5?G$LGL_ZtJIQ)6aIUz0PbK>iG7v=o zd|o$yhYZobKa~#(^#w%`p3b3um5P8Q6czr0A&45Fa3AmpCJhm2CjIFlFrPxFM#P zb`=>A8lUyEb%AxXMEYJs$LOpJdn)y`O|2DbsQ45rz#^z-09dIT=iK;WmvY4BZyP>1BW7>G@!fo-t9EPfj)W!YN#2fLLH9Yze?B59 z7w~Nc21o)nIx9-K3T3_{Sm+9?5C}Z4?J={g*GuS}?80g_1FJwspx2x6yFY1OTE2UK zq(x05k-R{58aq{k)D~lAXAqdN9^{9dUJdV&`2k{nu+=ksD-A%CqtGkPBsjuQ*D*b# zB!nzdRK%+yr8ZO+LEQcNRA&v)YX)nEgyr@K;@}0A?WmQaX9_yqKV0mKssC%;P2bC(U%sA7RTfzI!|b22 z4{qCAaZFknMRoySCE0NhlL(Q1V4w*lXYn<$QUh&^H(I>g=&Dv5@LSxxtG;E!k+c8g z%W9S#U$(8Jh6(5w)^#d{9l|{X zTXb+q!TPm^brRvov6w@fU&N=RSR2X5-~2tbvCwi%blNHU%q=PQXYzP zoWOU^IOWc6`Rc!K{qvi6K-sj@q6IL zUQm8NK@!--k9Feb@IGx|0C)qoc}>2D9w%O*bc@)edX$`_2ZFI#7YgxP#+Ntl`}iZ; zBqFX|O_#@JU3oTPiM_jX!_Z8HXUNYZz|x=C2RT`Yx;)9tz%x^{b?u$=-Wl!R&;Rgu zsmqgU`=09@FcO&PiKNA=tS_$?N@+0{(Icf#^5N@BeclOC)iufz~& zEZxn~Xk6{^bNROc9dRsE>)RI8&}yq+VJRltoFt~mzh;IivCfVaI@fhQ{L5R~9~-KQ zcwLr6ID3#e%7z#+D-$N%40(;C&}l!;D%nbF6Z9aQRes)qgqsmuRkiGTYdzQ}?KYXWW4#s5=8)iVI( zKypchY_#X^4Y>!_?E$(Kf~0N`ppN<|tL4C&;RB>^j*uaECbApi;g~nzIpeO@m>prU z*>=DX*ddykNt@Xz&xHMrmS@mgZd9@YGegsVbZ*b);-^M&4J?Y~JbCw(*HkXS))^PP z@|s(7uv|O)%Dae^VtLG>a7+wWb2THD5Vc(nFVD(()f71HtyWYkh~wTJitHxO4$?xj zOZiCedD$E=L3c$+Qn^>vb}cuWgNA?XZ$Sa8s2z9nqge;r-XY<~0ki<^S|K*q7Wp_2Nt;z)u=Q+l*DT+%wCF$Y>OuRNz-%gUb}J!7d!} Ih#j%v5NLM|KQUz8pjp=#HzF zd_c^hpxD5X4|RMfvjbT~XYJ-Z`D%xXns#MFr5@T*%kel(ZO?|Yf9$;oJ9TIO?B71; zK6#(t^SmFw_sxBO_xQ@=E9(sfI{oDN@j>}VvX`cx8P!|E-!>xvfa8k*5WqGAx)J&r z=+n@{u!xHQV4&x1%4SKJTd?fBEOkBvDD;K==7l0`vH2KV2mnX~dy|Z{51h0K=nyIN zozSN@W0{v78DU$xC$PQ&%k&`fkS*3~i=DB(bV2_UZy@74G;^B7GTJbat25{xid>rl zgoRo6SU($+S|s`Um}{?5`Krv&KtxR^Ue4}{%jr0<#C)>RH6iREWprvOf7tG=_}%0( z6lLH}d9$jHMBv`J5dP>-Qlxd^FB#DSAaiF&ysW-<>Qaua>0LRJXirIO)iFcFOgGX~ zO<02p5LX7y#3ZM?zCx^D?T1tBmjf{3?i8oi$8|FFHKK^okT{1}EOzZ`r4v&nkg@Xc zd+|AI*A8|k_pb`{54w}P8F~!2m1{`Dd6lZIks+Mb8vGW{Q9&#HvzH2QFU`B7Sa!m6 zqH}xaByOwLFoqT4F&0sxyX{)y4Q=U~A@Sj}MoZJ0=HW_ASFn_$aF43qtD$LAiL`+w zu~K72S$VCluC%md-_ANiMQLeWO^JR_<(_>~{0m4kgxg#RWWxo7yL33*C7~{~-4Am}Y{$;ByugU}+sp8=|Nrr>uq@ z1zpPM-^2~|{`%#lKB4YtE-k9kYmIbMl_ONATv8l0(-ZY@D$2Q@c>p9DJb?F3X~+}r z7b)&rqaJ7_kIWN}`rfEnv!hjT(7Wr}gLhUL9}P8I?50|2gC8FEIMFL@6i0q7s0E@o zO#*!)UB`-)=(Y)VmP-Q4rgg1YUI;8Jt=v;oTO-B&#YgXJveMExX3esiin5)RyQDbU zuRiwXKh|YsH4Iaaum3%FxXNJ{z1Jfe^oq_-iOgX{Jn}3tstbO)j)edheKja;ZD*mS4}B#`~p`})1z(M z{;bc1nbI%?GaJT1^!=spR{r03ozlQZ`R z@R}dM-7I1N*bVQc6z5j+pYurQ4K2X*3TlvTQ``VDT~b@&?e-m?w^QObaE7$crlIU6 zV26<(-bfHn2tmEw+}h5)+v1aJc?eOb&3+V780OIlUthaTzWF&aU$)f{rQXbWW_c+li2PW}C|E|GenY}Hxep#$)5c8hyq diff --git a/shaders/dxil/post.frag.dxil b/shaders/dxil/post.frag.dxil index f575e01ba1354aaf51ec70ffc5d2e39a3ef4a557..d3310964e9e7c183676788bfe7b3080905a0eb80 100644 GIT binary patch delta 1034 zcmca2b3-=KCBn)1>9Mbq->nz;DXEennmk|T2qOan!wo(L26iBA1H?W+yatG00Pzi= zqyYy|42Xl>JV8u2@Clv5TqgyL_h&EkOo=859NorMmYQX2e~jf z`}_C@F);W~^p&2tM1}PQP~K$XMd67Lctn{P8Gr~C2ux;Vw3dcl%76Cbbuk!Em+V@LoS149B(!4#m;E)kwSAZG~x`4&KNC+7qA z6nPjJx;JxjtYBnhogBw}iIIP@A&Z90LWdLQ7zE}qF0h%_Byb+&9WbZ_I;CRrK`xug zD_MH$nZ>}~5pGeswSgz?L!+Za$H4+NW(fxA79$5{wcxP$ki??&)Dqzqr&$UDr`ZyD zZX_IbT5)hYTOtG7VM&363vAL%<~IzM9F%5|=33p{%#|?lnVGw}xub%FRB>i{d`^nV zvrFgpJ$s?X;o{t~j_3X9x4!FgnU&a!9oT(j>u(&CX)ujlMKpFFRCD~gAUXF78$YfsLuQr1qMEu@fo;zP`nQ_t?b zdUEX4vt=wHszANFY<6r?FyC&z%U~DKh@F~_VeKF@*1pl}%<0nWS(oFr;VRG|&EmzA zPd7_dc^5C9JzMC2qqvdH^o`rC%y$8;);uW7z_8hjO@L9I=ZGSEO#yS2MtfO9yW~Y@ zz8??Ro+$7=f57%lfbY`*zK0X|-v{u2nVid>Z0Yy+DO3HcOIn@RLXtVeXD^DjTfy`>^&O5dHLu)?YBc~ZEV`Sfqk z%v2R-O?bHTM(f6#Q&0MG_E@D<=oM!qrlc16TIHvt<^(q_;gOuz9dq+e^xQiUH}6bo xSmg}VJUy&zx{H~sxLdfH>V{W91E%b}c=D;^-laP)p7rItK~m^$_T^<~1OTliQ5ygN delta 884 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 diff --git a/shaders/dxil/rectangle.frag.dxil b/shaders/dxil/rectangle.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..2c7f79b15977c1a176af8661b9657f9d79bcdc1a GIT binary patch literal 2952 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 delta 2294 zcmb_ceNapC54BSg1B%Rq2#1nfo}+r&w;9P^F;{oFG{{DFWqut`^LgOz%xez-sA zCIp564uF(7n}`Sa;uaA;lAKJY0E1}tg?8sE0oS6ifq??WfZ8D_6;c&Ti^X&Z(t;9& zfKaZ>F(qK+Vw-qp6UG^m9VJp^mDqk{?h~0T~g=g-rJ6@Sc)7@;Ie;$9f9oN6A&f_ zuZ5t)TnO3-<9nkDX-#c|HEFYLxG(BeYJ7M0mz`hWqftq=boZ|rX4fVwzAx^xO`Fp2 z*={Rd{@QGtb=HYnRcX9-h1Kjr*@F~^R>B-H6te3poY>|#%KcVUUg42SQyGJZDYW?` zxViLH=#w#5sZ05r){@qVgij`1JI1(WY8s4G<2Kda7)kt?xrHP_GMepsYtt0W5wHN_bSY@ z!yxz$m0VKO!16X~v6O^}WcLsJ5q|OR3N?QwlXF+iPxxW$N&d{i8UEL~5-EC~h1{o( z@%H?3mHz2MmrG3&y-iJqAM}j-pY%NCBiAnVVfSq)PBxY2En_ycsNbc{@bhLeTh6`> zXgw@MMk`4Iw3_Gtm3DGyC^GN>?A~Qq`WWpen-t{Zyk#fTQrgM`2Q*T8`d8pYf)dnL z|Ek{VHdSg*v@P3+HpRX)(0+(Y{;p;y)@#b?w`fJw3OCgR(ac)f;a-|eBpn^LD?+@I z#L(MwPioYPsQEh~G*#;j#+~KW#_D%?D{EJF7KJ22)&&+>9Q`}b8FZZziBg?HkzN~B z+mCg~QjJKlu3zN#rxvigGe_B8(y_}Pan_o}ArM!)hRH{ca*aqmU6xMe)e1r$wujB= z6oFrml+3u~N#;rfWWhD3V8SV2dPM=*1|xEwE|XH@D9#Y7zv9td)FyNE$q9O0FiOEW zr0dr*z6{zJJPwJoOUkKmaHu;_{Ta?83uyzhTNEH|+~3;yqw{^2V*byt(g1k;$((CC zj%AVO31dnW!=vs*Y1$k|^cTvQIIO?n(T0YqDko+U3{ONJMEFQ;Ub*nm!{d!cCw4>} z8UCgx0*;EpwHdK*;G|(`(p^W=cwf?Io{M9bd>tp6eYXnf&Q$#&;k$-+%wS%sNNx1Q z-ySdHy2@H7K6anW`QXnPb(~x^f8=Sd`nn_q8)*907ihlu)twuS%{L3_9os;zs7#QNKrY}1le1W+@H44{&6yro0XNau1*M|%Bv4n zSwM9a>AkK3x)*-^>+gQN`h7zmMRfMHtA4q_Kn%6#$o!D|`LZDw2L8n%C;5L2IXsr~ z5uV7Zi${NEe+EGgFiW|1(wp;RPLEecW#fNi<^g4@?IUI1f?H;syp==M{=br|$E@;1x92N&UF zrM8!)7wxI&H4IEMrcJ^|;iH=-r?P;@N!Ng(Aj#k^q;@z~dHX(qSrgExQZvFUz~Uv6 zD|;m^;?9h$?)6gTQRbiic%h(*NZ*Eull#pV8RcDRxa$?}!N8N!NYEb`2%nw|42+(o z_IO0uI|^sh~fzqn(*#TvM4A;by)J;vvW snZ_9XFTqpjOYjt<@8573WNRCjvN0li_$7F1sv-VGe2NhbE(VZ)0k>i+VE_OC diff --git a/shaders/msl/rectangle.frag.msl b/shaders/msl/rectangle.frag.msl new file mode 100644 index 00000000..bc52ad00 --- /dev/null +++ b/shaders/msl/rectangle.frag.msl @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_TARGET [[color(0)]]; +}; + +struct main0_in +{ + float4 in_var_COLOR0 [[user(locn1)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.out_var_SV_TARGET = in.in_var_COLOR0; + return out; +} + diff --git a/shaders/rectangle.frag.hlsl b/shaders/rectangle.frag.hlsl new file mode 100644 index 00000000..c01bd042 --- /dev/null +++ b/shaders/rectangle.frag.hlsl @@ -0,0 +1,7 @@ +#include "common/pixel.hlsl" + +// Pixel shader main function +float4 main(PSInput input) : SV_TARGET +{ + return input.color; +} \ No newline at end of file diff --git a/shaders/reflection/rectangle.frag.json b/shaders/reflection/rectangle.frag.json new file mode 100644 index 00000000..1dbcc5ca --- /dev/null +++ b/shaders/reflection/rectangle.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec4", + "name" : "in.var.COLOR0", + "location" : 1 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/sdf.hlsl b/shaders/sdf.hlsl new file mode 100644 index 00000000..30ec5d7f --- /dev/null +++ b/shaders/sdf.hlsl @@ -0,0 +1,35 @@ +struct SDF { +float circle(vec2 p, float r) +{ + return length(p) - r; +} + +// p = uv point +// b = width,height +// r = roundedness of the 4 corners +float rounded_box(vec2 p, vec2 b, vec4 r) +{ + r.xy = (p.x>0.0)?r.xy : r.zw; + r.x = (p.y>0.0)?r.x : r.y; + vec2 q = abs(p)-b+r.x; + return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; +} + +float box(vec2 p, vec2 b) +{ + vec2 d = abs(p)-b; + return length(max(d,0)) + min(max(d.x,d.y),0); +} + +float heart( in vec2 p ) +{ + p.x = abs(p.x); + + if( p.y+p.x>1.0 ) + return sqrt(dot2(p-vec2(0.25,0.75))) - sqrt(2.0)/4.0; + + return sqrt(min(dot2(p-vec2(0.00,1.00)), dot2(p-0.5*max(p.x+p.y,0.0)))) * sign(p.x-p.y); +} +} + +SDF sdf; \ No newline at end of file diff --git a/shaders/spv/rectangle.frag.spv b/shaders/spv/rectangle.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..87ecffe003a61f43ce04dc39d5c22a14d0c73b6e GIT binary patch literal 368 zcmY+8%L@Tv6veN37_U51>@>2Mm6Rw+vr$t+vePUrj1vBK8|D0FSorFG_i@g-=eo`) zFe{l^(;E7D9do`DH}64P7MQ0@eM!$5fTMuX*3VpvRJrCW9|ihW&N=67{7i4-b-ay} zi7;PGbl1l{2X=?kew9RYz^ literal 0 HcmV?d00001 diff --git a/source/jsffi.c b/source/jsffi.c index 9474ae41..f0907781 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -4545,129 +4545,81 @@ JSC_CCALL(cmd_submit, return SDL_GPUFence2js(js,fence); ) +JSC_CCALL(cmd_hud, + SDL_GPUCommandBuffer *cmds = js2SDL_GPUCommandBuffer(js,self); + HMM_Vec2 size = js2vec2(js,argv[0]); + HMM_Mat4 proj = HMM_Orthographic_RH_NO(0,size.x,0,size.y,-1,1); + shader_globals data = {0}; + data.world_to_projection = proj; + data.projection_to_world = HMM_InvGeneralM4(proj); + data.viewport_min_z = -1, + data.viewport_max_z = 1; + data.render_size = size; + data.view_to_projection = proj; + data.viewport_size = (HMM_Vec2){1,1}; + data.viewport_offset = (HMM_Vec2){0,0}; + data.time = SDL_GetTicksNS() / 1000000000.0f; + SDL_PushGPUVertexUniformData(cmds, js2number(js,argv[1]), &data, sizeof(data)); +) + JSC_CCALL(cmd_camera, SDL_GPUCommandBuffer *cmds = js2SDL_GPUCommandBuffer(js, self); JSValue camera = argv[0]; - SDL_GPURenderPass *pass = js2SDL_GPURenderPass(js, argv[1]); HMM_Vec2 size; - HMM_Vec2 drawsize; - JS_PULLPROPSTR(js,argv[1],size,vec2); - drawsize = size; transform *transform; - - JS_PULLPROPSTR(js, camera, size, vec2) - JS_PULLPROPSTR(js, camera, transform, transform) - - // Pull out fov and aspect if needed (e.g. for perspective) double fov; - JS_PULLPROPSTR(js, camera, fov, number) double aspect; - JS_PULLPROPSTR(js, camera, aspect, number) + int ortho; + double near; + double far; + + JS_GETPROP(js, size, camera, size, vec2) + JS_GETPROP(js, transform, camera, transform, transform) + JS_GETPROP(js, fov, camera, fov, number) + JS_GETPROP(js, aspect, camera, aspect, number) + JS_GETPROP(js, ortho, camera,ortho,bool) + JS_GETPROP(js,near,camera,near,number) + JS_GETPROP(js,far,camera,far,number) - // Retrieve the user-specified viewport (could be normalized or exact) - JSValue jsViewport = JS_GetPropertyStr(js, camera, "viewport"); - SDL_FRect cameraViewport = js2rect(js, jsViewport); // note: rect is typedef SDL_FRect - JS_FreeValue(js, jsViewport); - - // Determine if we're in normalized or exact mode. - // If any dimension is > 1, treat them all as pixels (and clamp). - bool isNormalized = (cameraViewport.x <= 1.0f && cameraViewport.y <= 1.0f && - cameraViewport.w <= 1.0f && cameraViewport.h <= 1.0f); - - if (isNormalized) { - // Convert fraction -> pixels - cameraViewport.x *= drawsize.x; - cameraViewport.y *= drawsize.y; - cameraViewport.w *= drawsize.x; - cameraViewport.h *= drawsize.y; - } else { - // Clamp pixel coords to window bounds - if (cameraViewport.x < 0) cameraViewport.x = 0; - if (cameraViewport.y < 0) cameraViewport.y = 0; - if (cameraViewport.x + cameraViewport.w > drawsize.x) cameraViewport.w = drawsize.x - cameraViewport.x; - if (cameraViewport.y + cameraViewport.h > drawsize.y) cameraViewport.h = drawsize.y - cameraViewport.y; - } - - // Get the camera mode - JSValue jsmode = JS_GetPropertyStr(js, camera, "mode"); - char *mode = JS_ToCString(js, jsmode); - JS_FreeValue(js, jsmode); - - // finalVP: the actual region in which we'll render this camera - SDL_FRect finalVP = cameraViewport; - - // Apply the mode to figure out how to place/scale 'size' in finalVP - // “stretch” = fill entire finalVP - // “fit” = scale down so entire size is visible, preserving aspect - // “cover” = fill the entire region, preserving aspect (crop if needed) - // “keep” (or unknown) = no scaling; just center the camera’s nominal size - if (!strcmp(mode, "stretch")) { - finalVP.w = cameraViewport.w; - finalVP.h = cameraViewport.h; - finalVP.x = cameraViewport.x; - finalVP.y = cameraViewport.y; - } else if (!strcmp(mode, "fit")) { - float scale = fminf(cameraViewport.w / size.x, cameraViewport.h / size.y); - finalVP.w = size.x * scale; - finalVP.h = size.y * scale; - finalVP.x = cameraViewport.x + (cameraViewport.w - finalVP.w) * 0.5f; - finalVP.y = cameraViewport.y + (cameraViewport.h - finalVP.h) * 0.5f; - } else if (!strcmp(mode, "cover")) { - float scale = fmaxf(cameraViewport.w / size.x, cameraViewport.h / size.y); - finalVP.w = size.x * scale; - finalVP.h = size.y * scale; - finalVP.x = cameraViewport.x + (cameraViewport.w - finalVP.w) * 0.5f; - finalVP.y = cameraViewport.y + (cameraViewport.h - finalVP.h) * 0.5f; - } else { - // "keep": do not scale - finalVP.w = size.x; - finalVP.h = size.y; - finalVP.x = cameraViewport.x + (cameraViewport.w - finalVP.w) * 0.5f; - finalVP.y = cameraViewport.y + (cameraViewport.h - finalVP.h) * 0.5f; - } - - JS_FreeCString(js, mode); - - // Build an orthographic projection - // - If pass is defined, treat (0,0) as screen center. - // - Otherwise, treat (0,0) as bottom-left corner. HMM_Mat4 proj; - if (!JS_IsUndefined(argv[2])) { + if (ortho) proj = HMM_Orthographic_RH_NO( - -finalVP.w * 0.5f, finalVP.w * 0.5f, - -finalVP.h * 0.5f, finalVP.h * 0.5f, + -size.x*0.5, 0.5*size.x, + -size.y*0.5, 0.5*size.y, -1.0f, 1.0f ); - } else { - proj = HMM_Orthographic_RH_NO( - 0.0f, finalVP.w, - 0.0f, finalVP.h, - -1.0f, 1.0f - ); - } + else + proj = HMM_Perspective_RH_NO(fov, aspect,near,far); + // Build the view matrix (translate by -camera.pos) - HMM_Mat4 view = HMM_Translate((HMM_Vec3){ -transform->pos.x, -transform->pos.y, 0.0f }); + HMM_Mat4 view; + if (ortho) + view = HMM_Translate((HMM_Vec3){ -transform->pos.x, -transform->pos.y, 0.0f }); + else { + HMM_Mat4 camera_transform = HMM_Translate(transform->pos); + camera_transform = HMM_MulM4(camera_transform, HMM_QToM4(transform->rotation)); +// camera_transform = HMM_MulM4(camera_transform, HMM_Scale(transform->scale)); // don't bother w/ scale + view = HMM_InvGeneralM4(camera_transform); + } // Update your shader globals shader_globals data = {0}; data.world_to_projection = HMM_MulM4(proj, view); + data.projection_to_world = HMM_InvGeneralM4(data.world_to_projection); + data.camera_pos_world = transform->pos; + data.viewport_min_z = near; + data.viewport_max_z = far; + data.render_size = size; + data.world_to_view = view; + data.view_to_projection = proj; + data.camera_dir_world = HMM_NormV3(HMM_QVRot((HMM_Vec3){0,0,-1},transform->rotation)); + data.viewport_size = (HMM_Vec2){0.5,0.5}; + data.viewport_offset = (HMM_Vec2){0,0}; data.time = SDL_GetTicksNS() / 1000000000.0f; - // SDL_SetGPUViewport expects an SDL_GPUViewport (with float x,y,w,h and min/max depth) - // We'll fill that struct from finalVP, with default depth range [0..1]. - SDL_GPUViewport sdlvp; - sdlvp.x = finalVP.x; - sdlvp.y = finalVP.y; - sdlvp.w = finalVP.w; - sdlvp.h = finalVP.h; - sdlvp.min_depth = 0.0f; - sdlvp.max_depth = 1.0f; - - // Set the final viewport and push uniform data -// SDL_SetGPUViewport(pass, &sdlvp); - SDL_PushGPUVertexUniformData(cmds, js2number(js,argv[3]), &data, sizeof(data)); + SDL_PushGPUVertexUniformData(cmds, js2number(js,argv[1]), &data, sizeof(data)); ) JSC_SCALL(cmd_push_debug_group, @@ -4774,7 +4726,8 @@ static const JSCFunctionListEntry js_SDL_GPUCommandBuffer_funcs[] = { MIST_FUNC_DEF(cmd, push_compute_uniform_data, 2), MIST_FUNC_DEF(cmd, submit, 0), MIST_FUNC_DEF(cmd, cancel, 0), - MIST_FUNC_DEF(cmd, camera, 4), + MIST_FUNC_DEF(cmd, camera, 2), + MIST_FUNC_DEF(cmd, hud, 2), MIST_FUNC_DEF(cmd, push_debug_group, 1), MIST_FUNC_DEF(cmd, pop_debug_group, 0), MIST_FUNC_DEF(cmd, debug_label, 1),