From b698b1862e55cc205839ec128ba95ab4634f034f Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 9 Jan 2025 13:23:18 -0600 Subject: [PATCH] shaders cleanup; add imgui sdl3 gpu support --- .gitignore | 3 +- meson.build | 2 +- scripts/render.js | 47 +- shaders/dbgline.frag.hlsl | 10 + shaders/dbgline.vert.hlsl | 21 + shaders/dxil/dbgline.frag.dxil | Bin 0 -> 2828 bytes shaders/dxil/dbgline.vert.dxil | Bin 0 -> 4660 bytes shaders/dxil/model.frag.dxil | Bin 0 -> 3892 bytes shaders/dxil/model.vert.dxil | Bin 0 -> 5636 bytes shaders/dxil/model_lit.frag.dxil | Bin 0 -> 4764 bytes shaders/dxil/post.frag.dxil | Bin 0 -> 3668 bytes shaders/dxil/post.vert.dxil | Bin 0 -> 4492 bytes shaders/dxil/ps1.frag.dxil | 0 shaders/dxil/ps1.vert.dxil | 0 shaders/dxil/sprite.frag.dxil | Bin 0 -> 3872 bytes shaders/dxil/sprite.vert.dxil | Bin 0 -> 5376 bytes shaders/msl/dbgline.frag.msl | 22 + shaders/msl/dbgline.vert.msl | 41 + shaders/msl/model.frag.msl | 23 + shaders/msl/model.vert.msl | 49 ++ shaders/msl/model_lit.frag.msl | 30 + shaders/msl/post.frag.msl | 22 + shaders/msl/post.vert.msl | 41 + shaders/msl/ps1.frag.msl | 0 shaders/msl/ps1.vert.msl | 0 shaders/msl/sprite.frag.msl | 29 + shaders/msl/sprite.vert.msl | 50 ++ shaders/ps1.frag.hlsl | 61 ++ shaders/ps1.vert.hlsl | 41 + shaders/reflection/dbgline.frag.json | 22 + shaders/reflection/dbgline.vert.json | 111 +++ shaders/reflection/model.frag.json | 43 ++ shaders/reflection/model.vert.json | 136 ++++ shaders/reflection/model_lit.frag.json | 74 ++ shaders/reflection/post.frag.json | 38 + shaders/reflection/post.vert.json | 111 +++ shaders/reflection/ps1.frag.json | 0 shaders/reflection/ps1.vert.json | 0 shaders/reflection/sprite.frag.json | 43 ++ shaders/reflection/sprite.vert.json | 145 ++++ shaders/spv/dbgline.frag.spv | Bin 0 -> 368 bytes shaders/spv/dbgline.vert.spv | Bin 0 -> 1660 bytes shaders/spv/model.frag.spv | Bin 0 -> 1016 bytes shaders/spv/model.vert.spv | Bin 0 -> 2328 bytes shaders/spv/model_lit.frag.spv | Bin 0 -> 1504 bytes shaders/spv/post.frag.spv | Bin 0 -> 752 bytes shaders/spv/post.vert.spv | Bin 0 -> 1656 bytes shaders/spv/ps1.frag.spv | 0 shaders/spv/ps1.vert.spv | 0 shaders/spv/sprite.frag.spv | Bin 0 -> 1012 bytes shaders/spv/sprite.vert.spv | Bin 0 -> 2208 bytes source/jsffi.c | 18 +- source/qjs_imgui.cpp | 57 +- source/thirdparty/imgui/imgui.cpp | 729 +++++++++--------- source/thirdparty/imgui/imgui.h | 15 +- source/thirdparty/imgui/imgui_draw.cpp | 76 +- source/thirdparty/imgui/imgui_impl_sdl3.cpp | 7 +- source/thirdparty/imgui/imgui_impl_sdl3.h | 1 + .../thirdparty/imgui/imgui_impl_sdlgpu3.cpp | 619 +++++++++++++++ source/thirdparty/imgui/imgui_impl_sdlgpu3.h | 48 ++ .../imgui/imgui_impl_sdlgpu3_shaders.h | 372 +++++++++ source/thirdparty/imgui/imgui_internal.h | 20 +- source/thirdparty/imgui/imgui_tables.cpp | 8 +- source/thirdparty/imgui/imgui_widgets.cpp | 235 +++--- 64 files changed, 2887 insertions(+), 533 deletions(-) create mode 100644 shaders/dbgline.frag.hlsl create mode 100644 shaders/dbgline.vert.hlsl create mode 100644 shaders/dxil/dbgline.frag.dxil create mode 100644 shaders/dxil/dbgline.vert.dxil create mode 100644 shaders/dxil/model.frag.dxil create mode 100644 shaders/dxil/model.vert.dxil create mode 100644 shaders/dxil/model_lit.frag.dxil create mode 100644 shaders/dxil/post.frag.dxil create mode 100644 shaders/dxil/post.vert.dxil create mode 100644 shaders/dxil/ps1.frag.dxil create mode 100644 shaders/dxil/ps1.vert.dxil create mode 100644 shaders/dxil/sprite.frag.dxil create mode 100644 shaders/dxil/sprite.vert.dxil create mode 100644 shaders/msl/dbgline.frag.msl create mode 100644 shaders/msl/dbgline.vert.msl create mode 100644 shaders/msl/model.frag.msl create mode 100644 shaders/msl/model.vert.msl create mode 100644 shaders/msl/model_lit.frag.msl create mode 100644 shaders/msl/post.frag.msl create mode 100644 shaders/msl/post.vert.msl create mode 100644 shaders/msl/ps1.frag.msl create mode 100644 shaders/msl/ps1.vert.msl create mode 100644 shaders/msl/sprite.frag.msl create mode 100644 shaders/msl/sprite.vert.msl create mode 100644 shaders/ps1.frag.hlsl create mode 100644 shaders/ps1.vert.hlsl create mode 100644 shaders/reflection/dbgline.frag.json create mode 100644 shaders/reflection/dbgline.vert.json create mode 100644 shaders/reflection/model.frag.json create mode 100644 shaders/reflection/model.vert.json create mode 100644 shaders/reflection/model_lit.frag.json create mode 100644 shaders/reflection/post.frag.json create mode 100644 shaders/reflection/post.vert.json create mode 100644 shaders/reflection/ps1.frag.json create mode 100644 shaders/reflection/ps1.vert.json create mode 100644 shaders/reflection/sprite.frag.json create mode 100644 shaders/reflection/sprite.vert.json create mode 100644 shaders/spv/dbgline.frag.spv create mode 100644 shaders/spv/dbgline.vert.spv create mode 100644 shaders/spv/model.frag.spv create mode 100644 shaders/spv/model.vert.spv create mode 100644 shaders/spv/model_lit.frag.spv create mode 100644 shaders/spv/post.frag.spv create mode 100644 shaders/spv/post.vert.spv create mode 100644 shaders/spv/ps1.frag.spv create mode 100644 shaders/spv/ps1.vert.spv create mode 100644 shaders/spv/sprite.frag.spv create mode 100644 shaders/spv/sprite.vert.spv create mode 100644 source/thirdparty/imgui/imgui_impl_sdlgpu3.cpp create mode 100644 source/thirdparty/imgui/imgui_impl_sdlgpu3.h create mode 100644 source/thirdparty/imgui/imgui_impl_sdlgpu3_shaders.h diff --git a/.gitignore b/.gitignore index 4ab14093..d4389a9b 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ jsc *.icns game.zip icon.ico -steam/ \ No newline at end of file +steam/ +subprojects/*/ diff --git a/meson.build b/meson.build index 695a201f..10ebe6b9 100644 --- a/meson.build +++ b/meson.build @@ -91,7 +91,7 @@ endif sources = [] src += ['anim.c', 'config.c', 'datastream.c','font.c','gameobject.c','HandmadeMath.c','jsffi.c','model.c','render.c','script.c','simplex.c','spline.c', 'timer.c', 'transform.c','warp.c','yugine.c', 'wildmatch.c', 'sprite.c'] -imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp', 'imgui_impl_sdlrenderer3.cpp', 'imgui_impl_sdl3.cpp'] +imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp', 'imgui_impl_sdlrenderer3.cpp', 'imgui_impl_sdl3.cpp', 'imgui_impl_sdlgpu3.cpp'] srceng = 'source' tp = srceng / 'thirdparty' diff --git a/scripts/render.js b/scripts/render.js index a303451c..ed65921b 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -10,10 +10,10 @@ var cur = {}; cur.images = []; cur.samplers = []; -function full_upload(mesh) +function full_upload(buffers) { var cmds = render._main.acquire_cmd_buffer(); - render._main.upload(cmds, [mesh.pos, mesh.uv, mesh.color, mesh.indices]); + render._main.upload(cmds, buffers); cmds.submit(); } @@ -27,7 +27,7 @@ function queue_sprite_mesh(queue) sprites[i].num_indices = 6; } - full_upload(mesh); + return [mesh.pos,mesh.uv,mesh.color,mesh.indices] } function bind_pipeline(pass, pipeline) { @@ -496,7 +496,11 @@ function render_camera(cmds, camera) } if (render_queue.length == 0) return; - queue_sprite_mesh(render_queue); + var buffers = 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]); + } + full_upload(buffers) var pass = cmds.render_pass(camera.target); var camera = prosperon.camera; @@ -597,12 +601,20 @@ function gpupresent() 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; - if (swapchain_tex) cmds.blit({ - src: prosperon.camera.target.color_targets[0].texture, - dst: torect, - filter:"nearest", - load: "clear" - }); + if (swapchain_tex) { + cmds.blit({ + src: prosperon.camera.target.color_targets[0].texture, + dst: torect, + filter:"nearest", + load: "clear" + }); + + // now imgui + var pass = cmds.render_pass({ + color_targets:[{texture:swapchain_tex}]}); + imgui.endframe(cmds,pass); + pass.end(); + } cmds.submit() } } @@ -635,6 +647,7 @@ render.init = function () { cmds.__proto__.upload_model = upload_model; cmds.upload_model(quad_model); cmds.submit(); + imgui.init(render._main, prosperon.window); }; render.draw_sprites = true; @@ -750,7 +763,7 @@ render.text = function text(text, rect, font = prosperon.font, size = 0, color = if (typeof font === 'string') font = render.get_font(font) var mesh = os.make_text_buffer(text, rect, 0, color, wrap, font); - full_upload(mesh) +// full_upload(mesh) render_queue.push({ type: 'geometry', @@ -900,7 +913,7 @@ render.images = function images(image, rects) // slice is given in pixels render.slice9 = function slice9(image, rect = [0,0], slice = 0, color = Color.white) { render.image(image,rect,undefined,color); - render._main.slice9(image.texture, rect, slice); +// render._main.slice9(image.texture, rect, slice); }; var textssbos = []; @@ -1044,8 +1057,7 @@ var imdebug = function imdebug() { var observed_tex = undefined; var imgui_fn = function imgui_fn() { - return; - imgui.newframe(prosperon.size.x, prosperon.size.y, 0.01); + imgui.newframe(); if (debug.console) debug.console = imgui.window("console", _ => { imgui.text(console.transcript); @@ -1123,7 +1135,7 @@ var imgui_fn = function imgui_fn() { }); */ prosperon.imgui(); - imgui.endframe(render._main); +// imgui.endframe(render._main); }; // figure out the highest resolution we can render at that's an integer @@ -1144,12 +1156,13 @@ var imgui_fn = function imgui_fn() { prosperon.render = function prosperon_render() { try{ -//if (debug.show) try { imgui_fn(); } catch(e) { console.error(e) } +try { + imgui_fn(); +} catch(e) { console.error(e) } } catch(e) { console.error(e) } finally { render._main.present(); - } }; diff --git a/shaders/dbgline.frag.hlsl b/shaders/dbgline.frag.hlsl new file mode 100644 index 00000000..b14b01dd --- /dev/null +++ b/shaders/dbgline.frag.hlsl @@ -0,0 +1,10 @@ +struct VSOutput +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return input.color; +} \ No newline at end of file diff --git a/shaders/dbgline.vert.hlsl b/shaders/dbgline.vert.hlsl new file mode 100644 index 00000000..eb631bd3 --- /dev/null +++ b/shaders/dbgline.vert.hlsl @@ -0,0 +1,21 @@ +#include "common/common.hlsl" + +struct VSInput +{ + float3 pos : pos; + float4 color : color; +}; + +struct VSOutput +{ + float4 pos : SV_POSITION; + float4 color : COLOR; +}; + +VSOutput main(VSInput input) +{ + VSOutput output; + output.pos = mul(float4(input.pos, 1.0f), world_to_projection); + output.color = input.color; + return output; +} \ No newline at end of file diff --git a/shaders/dxil/dbgline.frag.dxil b/shaders/dxil/dbgline.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..105930fa4f522634c8ef1cd8e42bdf0af3357764 GIT binary patch literal 2828 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 literal 0 HcmV?d00001 diff --git a/shaders/dxil/model.frag.dxil b/shaders/dxil/model.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..c13a7636b731f8d846c4d5ec93c096760c19765d GIT binary patch literal 3892 zcmeHKeNYo;8h?{rb{9!D3yF3yh#M3N747n2KnY$xFoI$Yf}V4u;|4@wj$rr@0qab@ zB%t&zC~B0O7KA$7we`S{QSPh-f?kSXQ(G;Zj)n4Z*Be?HKU$pW%-y>PoW1GXAN{L; z_)MPneZHT4-+gy~o0M%@9sRclgBEu51N|ZTX53N7SpfhbUIG9PXBFgh$gPk^ArC-j zDgnSQ$eH>y7EW`Nmboq_3u;2hv-Z?EF967ljLZs9=l!!PKl8nDzA>b%wcB)?Hf>Jf z0F!&c*Y&6y({y0-yy5EHH1zCJ^YRb*N60 z0HjcS4!=b++caZ;ehuif2JcOlCMypEfP?yJSUhE0S~}l^?`42?t*-NdLIgk^v<29h z>FeRwid&b|X}o9}M#Zi=DsYIx{fOXD^hmZvwpOS;8lY{VVr7X0y zG#JOPNowP?OgaIt4uBd403DoT!&3d3U5C(PVJ!|gj5wNHvY_QnbSiHN2nVv= zV4UdWeg~p%Fb- z;&48|hkgA*SeY8Hjy-Ll}obXTo^#JU@(E-aiC8boUi zLAeHUEFnudlU3#IkCx-FJ zb=G4WE(A0$+aRbZ>MF7pHMO_b2{cVL?J)t;3xV&Y4N|BSJ>zDm8<>$%5~xN{SZGs+ z$g2=V1aacJJ-WZ|{laqvHZ>zf!v-0uzsg})P({<-gOo~&PJG3Ffn63T!fF(laDYme z69j1Ww}Aqn6!q*g5p7}*mn(IM?okCx|K5H3ezjq~QJkEd7Pyg`muEAi$c5Q9L#h_A!27KyGBH?j9uJCr&EXXZR%*bBSvi(-yAx~aacC{hc1BSw`n4gm0WD@ z)3x&>_HWfEXd+wvwHX^JVz-^e_O=-n14F;Hv%uaZCRmGItO+Tg@2W|Q_|Tnxjh~Or zIS|m?kW)9VT$hlbVHPed$=|cHV3!o_Zi+cs_T9>L&=?w4np?iJaBs0mUcZ_~lCB^s zFOocftfBwZ);@TtqowY6$EO?pZLjSrUs0A@T#~=HFjIKOKltq z5$jx_-x~476aCg3%5ZhBYq-OEy#K>HAHQ|Hf1`ivdYD^UVb0YQ7Va%ImckMxnYQ;y zzQ%6`cLWW}cF;Qp>$&$}q0Qs^S5M+kPmJpm62jf~6)-br@4muP*f~?U2JrWu$EG;K z64EmqvRfuduGS?wJhfU2UQv#hxQj&NK=KVmKCzH-B5i1Q*P>fZA-h?>=`g#z4}s5h zaxIeFS6*9c#t#s9MXJ+m#w*Q8S-I29ID`8F$q5(#1Q)WBkx6pWK*mu$iykOK1{90B zjiI~Qnxw1tB%f~8MMQPgu5utreUq{>4nL5GC*(Pc;b?K1T~0HHmqp@bQ+}}Qev5M_ z;Vhz^#cpSX+Zz4tB>C+S`LvUqV3BNZQ^;sjNZ<5$-x$)X2NR3_UGV**Tjib} zuXqycb&1tTQoZMO*z^Zm(&tE0o2S;Rz~3|@#gwzejPPsWoMx|ce=A<;wyH)gl0vm) z%tubb{VHMr2!gYo5ubdhx<&@W$ae|AR$sFJRFhUt-ZqEc!WEG;{9Y^s}*u|8D##ETXO((C`dw%n zZHF~}HV#D)J?$D=G|yZjMTLVb;~%4GixfftI>k`EnANOY+S481T{4BVhROFdty{HyY0{Q1~~zeH&aheV%TKbKy( z;+uZcdUd?QQ_>!gb79%Bh9G*McXIo|Z<<%YS=R2YV zTbwX=#Rn5BY6=dos6AJ(p1T9{qe_~O-LzM3C~0nJ2)ZhGi2=V53@|bPB*ODAMK#g< zcOC!Vo@UTye>0tzFN<=B$J|Mnkd{K-3k#?1P(YKm_2nE1@ E0GYF>$N&HU literal 0 HcmV?d00001 diff --git a/shaders/dxil/model.vert.dxil b/shaders/dxil/model.vert.dxil new file mode 100644 index 0000000000000000000000000000000000000000..f1e54c03c19f5a708929066e67311d3acb94d437 GIT binary patch literal 5636 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 AegFUf literal 0 HcmV?d00001 diff --git a/shaders/dxil/model_lit.frag.dxil b/shaders/dxil/model_lit.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..e6704aec52cc0d02f2e1246cc8b81f85b0947385 GIT binary patch literal 4764 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 literal 0 HcmV?d00001 diff --git a/shaders/dxil/ps1.frag.dxil b/shaders/dxil/ps1.frag.dxil new file mode 100644 index 00000000..e69de29b diff --git a/shaders/dxil/ps1.vert.dxil b/shaders/dxil/ps1.vert.dxil new file mode 100644 index 00000000..e69de29b diff --git a/shaders/dxil/sprite.frag.dxil b/shaders/dxil/sprite.frag.dxil new file mode 100644 index 0000000000000000000000000000000000000000..171839cdf1891c3dba053a2485c2a58525e791ff GIT binary patch literal 3872 zcmeGfZBSEJ_P)Hwdk+XN4-;!3XkQRg?b0?NVvx|y2S%u{MnR=r9TUEU8G_-X6s$Xw zF9~XPH)v4QU6;7H!&+xIth&}2>jr{0TGaSaD~gVk58aMiS*>3)o!z~cuXT6&%U}KB znVfshJ?GqW?z!*2b6&CvHQF-gzjVnpv))Tkm^@#vk-0Dc04D%|f>a4H7h)&GVTjkE zGL;5E4>4btBZp)fa`KlZ7r+@0;*>mlS_=R^$>UQDoFhGohX9EYFMzQT6f7y!E?>Sf z3-QaL?^H;Ue#-Yeq=2A;IOTG3Dac>FzQ92gNHMiH0`lm5@(a`j1tb6l$hSgeR$)#qGD5MGP_EJXZ%g?Apobl4ma-n1CVpm}b5EVofh+q0?}W7P`nBopmc9gX$j=PQ1&{8KNA=7z zmEbWa7~!Z6KlMb<45<<7=(9P&|r)-$FMvk8tsut`qUv{SVlWpXpsQ%u7YQ*EG- zL5TeO3ug5yYLkJg3z4HNRX<^AV4#Ny%TcImr=X4L4g>v6dKi~z_fNls05mB{cKZJE z8(9vZONc=HFjWQMB^w9%u+=jD8lf2%32o5*O_|dsiiys3yTWBl&k)-9L^)5-U!tE; zs-Lq(pH%Q(5z$UZcvZm*fZdO^D|gx0i#V{VIOL=e-kU~9WAR+KjwkF*<^mF}b?34p zk-z`RGHh#gceS3rYesy|iQRGg5A@8{U_O%DBQO=59RKdTfHuCL`^k;gG<{8lN+yUylHXc}~e z+dw5qTL#fbl_y${PjVHKw`SOyc5>Zqm!YYB}rqa@MN0 zf%ju>5ngv%5+T`aVo8JiHyB1%_@rigR3P>w=JWa%D>^}JS>;A!U9FI?8CyovmM&VP z=3--OD>kgJEJ+=`eBspSz2;Es;4e;mcJ`P_KWt#`wKMm@346NV?v0S_Teojn?E8Bp zw>(^@rs;0c8rh=VPe#)cxxMbe6W6zN^|zkQ3*WZ5q~Yz_a$`wpP2R?m(#m{Z2R~;2 z_O<;3KmYAOVgG=~awx0mu4Xs2=C$F`C%RcWde%~G}V~xG@GeS zX1u<^Y37_UebLN)H+oyE&HVS(CmUW4^t^ zJoYp9<#l+^jjB)3ralO{r=ZxevH>@?<^tSQw(}2RGRW#!np1?aW==Zja zt9XVl;0j8q&1SrYb=I13l#9V>4mv;Tq&Br#mBSW6l}a!YV#eTkRdWE$fKF2hhJ`Rxwjb&{>}frbxPlx}A574JZS8D?<31k@#(;Ch^XY#o0ZS9S z@jCPYT>sKNM@IK{sm1&VGc3)#emNJOto9}FV6)l7vFAvuIW3{LC$%@kUTgw;Il~pw z;cjaZ(*~{F#KnVl869&>>XXqt)q%H?&i|5L6@4vqWvA#8;VqZZTaHLM8GU+zn%foC z^VC#Gn}!x|9HSY28WAA878y+(Q9lbB0x9K^H^|#^5?@0~9CA4>oBmi9I^u8m*mB=N z_2*H=Ds!n%s)tP_<}hq3{*<&%%bS&z^`^HgN?@_hx3x#WYQJvJz}g%8Zh9=`s87r~ zQw9rmq8yd@KJS*6*0T#gYiaGu3*V6fOMFdf?Zyvlic4XEKg6K5AM~%A(JxvjUf1vO zAJR76T{)_IV>k79*QgE_eFOR=d{y^k+pHKFaeU?% z6EUrEnTDvCo5`$r}fYVyL<#EZ?{IP{uY?B|?pLb%w1d0aBWUv6Vv zGJa1vFIn6b{JeR|ySk)@$we&}C){u*^Fej2152LRMz&;ag`2!0e{p8uCZb@M$u+SZ K*i4u&g8u-PTCg4f literal 0 HcmV?d00001 diff --git a/shaders/dxil/sprite.vert.dxil b/shaders/dxil/sprite.vert.dxil new file mode 100644 index 0000000000000000000000000000000000000000..4abd9aa94e98c45348ac2e9b8bca0532dccd7d49 GIT binary patch literal 5376 zcmeHLe^e7!zMsiVCKD3EAZZ8$=l~@}MLPU2YNhQYK?K1y3QK99J`)6lmS7M{K|E)Z z5D98@WAO*d?iz%;?ACUXqAS+N$q#BHVjHnl5z0YJsr6ZxZQa#fJm{@DBasCir<2}We4$+oL!dncK^*YN06hSQ)I3?{=k!AGxS_J zaOrJ~oS{QPeDi`8Mang6)@3rYHNdwXJpZn5KBMhxKjzyH?NzAu>v>}WwAZ(v_tz`cI^a8?$HYK_PJ^xoJ-~fE!Y(1OiL`2%ocKJR(G&z zh9MDBOEojZ(-5~C$^m-JnuZzG3NjDJ0153RA&A-A)VOReS+WCdjq5Uj;R{oTRX8ti zmxX8Q$|LII!MX{{plRH$-V4n?Pnv{^<6=Fr4(sS_zIe39Y~5bfx$8jNqg$s#Q_hPE z?nNa3%o(HjR%we6vDohryC}uG!X`_~?MtEPhw3h3UXB3e#}mqVpK44RaTd`$D_D6% z1l4q309X&l@bWI_&bB=Zg5ngGQ&%UdIp^zD19x;?6)B9AgDP5Bba00ZTtp;gqX9% zH1W6TG!%Hzsi_A2V=J{g9)>BO7DS71C>qeIF>T_A&^)V!D_waWRmLSyEERvp8kG%R zp~6d5f`qktn4PH7BkXKd2Ms0Xd2S4#D z^koDzk_Po{hFU&>R8L>jh>54^?U0@Zhlo$Z&p=QEI4946;3JVdYZfbPFokqUl!n&a z_j#QQbK#xUj%q`7$H|lXV0p*RlPSEg_e0;w870s#)Y(Q7A7L6&hNE&vRh5w@CCx~z z6pxIw9=q7IaQ4_+yqfm3#@5%vew&uIu(h2eE?_3rL4#PVHrjs!KXo?aOz-bbFX>G^ z&1H2|(%4rK%`i)bukJHI5Vwsi*=$d-{SadIY-8)D_}OEPv&PoO{DqRv+{PLJdl5CL zW&CTUtBIB}BfT^Xy>*z(EbEcW7w|6P+Oeg3;REa2#(pu{zP?@c%fqi69uNP;c>AlP z;te<2$HG4!yY_i|lw=e&=w)QfX3glYwRgLxoa58O6H_-#cZP?DrUvd!OkH;m+@2V? zJ2G@nif8u0a;M#yn&Oe|nhSks!>gm81JEa2pa!dq#3PD|3b7km)ZCOJd9N>Q<;@x! z+kM%Ae6FAdn~Zcvl$6`F71qn0a~7dDci{(3jjf%tujSUvjsX47FyxgcOK{&FHJuPX zE!+HO={0G==CVTRgT2J3ekmfs^?h&C75Et#`5ht?mKfE~KF{>XoVE%AUYi79CW%b?yj=QzzC%YA(z zNPY}MzHS;0>C-A*wQ340vte3@Q={fI*f~F=06+ASre zl^Zv0sob(vA~Xqm*Nn-MgWn5A(u3aa=^ztTI6J?M#O;{cMRzF{RN@617iDuU$Ro}! zzE1S9cAoA@UlJGix`mnI_)>g_xDs#SDpD|sDQT>S=plH$6!`P7VtJ=}V#Tr~Bx%r? zG;U1d_fc-eqDuS(S0Ts3P~#X`@o(59(~mi zeZvv`+n$r7r~1409q7NjnrmE8QlDH`y0r$B8~Lnb+=yT8-XLz@aCm&bty|grRjOH( zRVcl7KdbP(EP)=f-t2cDxb$D2UD$Kr(rRwkDqvgNpevPERc)!&FcnKpKAK;&<9PtK&4{oQ7<(PRH4%L+a|yI?^0594feL72Kpks;H1JW&|@TK^id_JrNsq zJvQ2@i7BIYE_htn5CIx@83+_@#vAZK`sv~OHJC19jhGL@z4bejy?5b6{ z%&lD3<{i(tmhM+BZ9$grcRdH3J~A%<6j|QmvbbY8+jYoR!d#<6m|WCmo!k6oH)mU$ zA!AA(QbmV+=@HC;^{OU)HJ+>|_|P9R1_;#(dFI;)KS2Yrro(@)Wsm6o^6?kEP&h9W zPj@Mb?CI+VzI(VE;TM0WYTY<~np@!da{14nTm6$v+o$)voX~8B^HS(#6BNoIKqx}` z3&U)Aezp+!WZFkx|MlE=76(clk3Z+kOe$sSs7IivVd|=v=G0YFfFG!(q9Q z4g;T>i+y_}OBLUNkIcaewLQ3mDlfB_4&CA1(I)Rn{^pX_sLGRwQi?#aAxjneO}h+{ zeU4^0cpSQ}D!L}gqo0z=K9C(s?@e8DcD`J-ga65g@8wl7)~o3BSXa$S-lq3KH8@ZF zhI?lHw8!ZlnmRJ!9=d)U&520O2=DLh|NZm*Cwu$n8w$+8Hu>GV$vZ1|C0pLBTt$Bd z?B~~Xwq9)7mRr-=-ahXf{O`N}|M=anA;EnQ-kUH~p2Yl4W`mx&>m6Z`2D9B=wRaU) z73KZu6pwKsqnfN}YAtoN$XR+)oGtld$ziJ43XwR5iOKzltl@iP!^G-xn^Snv4EKdZ*ph)s@L7I74i$v0tp z-Wm{Z_nZr5bBt8G^MJ$?JV?p>4tA3QfP=k zn>L4d?ENgB@V5Bv3!4Wam?ro!FBKu#yd*mgch2pHh`UC`h7m z`BQ1ddM2_p$!$gybF{$Bre&Pf1?>&Dh)J-Tj`w-pHl3lgj0|9IlRvc}75A^hA9wt; zWsvlH_$s`p18%Y}U2Oft4|H=fNF0gAV>np-nHJYVRT<%jO%wD$`{a~=U6%DJ7Myeb zU}u^_PmoW?7s+4D>M?G&sM&w_=asRZ0@mt1-gCxyqZ#Xw@2!D&a`Jm?AfDs}fuaVq F{{_D(xVQiS literal 0 HcmV?d00001 diff --git a/shaders/msl/dbgline.frag.msl b/shaders/msl/dbgline.frag.msl new file mode 100644 index 00000000..5095153b --- /dev/null +++ b/shaders/msl/dbgline.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_COLOR [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]]) +{ + main0_out out = {}; + out.out_var_SV_TARGET = in.in_var_COLOR; + return out; +} + diff --git a/shaders/msl/dbgline.vert.msl b/shaders/msl/dbgline.vert.msl new file mode 100644 index 00000000..a21e013d --- /dev/null +++ b/shaders/msl/dbgline.vert.msl @@ -0,0 +1,41 @@ +#include +#include + +using namespace metal; + +struct type_TransformBuffer +{ + float4x4 world_to_projection; + float4x4 projection_to_world; + float4x4 world_to_view; + float4x4 view_to_projection; + packed_float3 camera_pos_world; + float viewport_min_z; + packed_float3 camera_dir_world; + float viewport_max_z; + float2 viewport_size; + float2 viewport_offset; + float2 render_size; + float time; +}; + +struct main0_out +{ + float4 out_var_COLOR [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float3 in_var_pos [[attribute(0)]]; + float4 in_var_color [[attribute(1)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_TransformBuffer& TransformBuffer [[buffer(0)]]) +{ + main0_out out = {}; + out.gl_Position = float4(in.in_var_pos, 1.0) * TransformBuffer.world_to_projection; + out.out_var_COLOR = in.in_var_color; + return out; +} + diff --git a/shaders/msl/model.frag.msl b/shaders/msl/model.frag.msl new file mode 100644 index 00000000..03d67f1d --- /dev/null +++ b/shaders/msl/model.frag.msl @@ -0,0 +1,23 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_TARGET [[color(0)]]; +}; + +struct main0_in +{ + float2 in_var_TEXCOORD0 [[user(locn0)]]; + float3 in_var_COLOR1 [[user(locn3)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d diffuse [[texture(0)]], sampler smp [[sampler(0)]]) +{ + main0_out out = {}; + out.out_var_SV_TARGET = float4(diffuse.sample(smp, in.in_var_TEXCOORD0).xyz * in.in_var_COLOR1, 1.0); + return out; +} + diff --git a/shaders/msl/model.vert.msl b/shaders/msl/model.vert.msl new file mode 100644 index 00000000..c1d3cd14 --- /dev/null +++ b/shaders/msl/model.vert.msl @@ -0,0 +1,49 @@ +#include +#include + +using namespace metal; + +struct type_TransformBuffer +{ + float4x4 world_to_projection; + float4x4 projection_to_world; + float4x4 world_to_view; + float4x4 view_to_projection; + packed_float3 camera_pos_world; + float viewport_min_z; + packed_float3 camera_dir_world; + float viewport_max_z; + float2 viewport_size; + float2 viewport_offset; + float2 render_size; + float time; +}; + +struct main0_out +{ + float2 out_var_TEXCOORD0 [[user(locn0)]]; + float4 out_var_COLOR0 [[user(locn1)]]; + float3 out_var_NORMAL [[user(locn2)]]; + float3 out_var_COLOR1 [[user(locn3)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float3 in_var_pos [[attribute(0)]]; + float2 in_var_uv [[attribute(1)]]; + float4 in_var_color [[attribute(2)]]; + float3 in_var_norm [[attribute(3)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_TransformBuffer& TransformBuffer [[buffer(0)]]) +{ + main0_out out = {}; + out.gl_Position = TransformBuffer.world_to_projection * float4(in.in_var_pos, 1.0); + out.out_var_TEXCOORD0 = in.in_var_uv; + out.out_var_COLOR0 = in.in_var_color; + out.out_var_NORMAL = in.in_var_norm; + out.out_var_COLOR1 = float3(0.20000000298023223876953125) + (float3(1.0) * precise::max(dot(in.in_var_norm, fast::normalize(-fast::normalize(float3(1.0)))), 0.0)); + return out; +} + diff --git a/shaders/msl/model_lit.frag.msl b/shaders/msl/model_lit.frag.msl new file mode 100644 index 00000000..6b03c511 --- /dev/null +++ b/shaders/msl/model_lit.frag.msl @@ -0,0 +1,30 @@ +#include +#include + +using namespace metal; + +struct type_LightBuffer +{ + float4 uDiffuseColor; + float3 uLightDirection; + float4 uLightColor; +}; + +struct main0_out +{ + float4 out_var_SV_TARGET [[color(0)]]; +}; + +struct main0_in +{ + float2 in_var_TEXCOORD0 [[user(locn0)]]; + float3 in_var_NORMAL [[user(locn1)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], constant type_LightBuffer& LightBuffer [[buffer(0)]], texture2d uDiffuseTexture [[texture(0)]], sampler samplerState [[sampler(0)]]) +{ + main0_out out = {}; + out.out_var_SV_TARGET = uDiffuseTexture.sample(samplerState, in.in_var_TEXCOORD0) * (LightBuffer.uLightColor * fast::clamp(dot(fast::normalize(in.in_var_NORMAL), -LightBuffer.uLightDirection), 0.0, 1.0)); + return out; +} + diff --git a/shaders/msl/post.frag.msl b/shaders/msl/post.frag.msl new file mode 100644 index 00000000..ae298675 --- /dev/null +++ b/shaders/msl/post.frag.msl @@ -0,0 +1,22 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_TARGET [[color(0)]]; +}; + +struct main0_in +{ + float2 in_var_TEXCOORD0 [[user(locn0)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d diffuse [[texture(0)]], sampler smp [[sampler(0)]]) +{ + main0_out out = {}; + out.out_var_SV_TARGET = diffuse.sample(smp, in.in_var_TEXCOORD0); + return out; +} + diff --git a/shaders/msl/post.vert.msl b/shaders/msl/post.vert.msl new file mode 100644 index 00000000..6fea5760 --- /dev/null +++ b/shaders/msl/post.vert.msl @@ -0,0 +1,41 @@ +#include +#include + +using namespace metal; + +struct type_TransformBuffer +{ + float4x4 world_to_projection; + float4x4 projection_to_world; + float4x4 world_to_view; + float4x4 view_to_projection; + packed_float3 camera_pos_world; + float viewport_min_z; + packed_float3 camera_dir_world; + float viewport_max_z; + float2 viewport_size; + float2 viewport_offset; + float2 render_size; + float time; +}; + +struct main0_out +{ + float2 out_var_TEXCOORD0 [[user(locn0)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float2 in_var_pos [[attribute(0)]]; + float2 in_var_uv [[attribute(1)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_TransformBuffer& TransformBuffer [[buffer(0)]]) +{ + main0_out out = {}; + out.gl_Position = TransformBuffer.world_to_projection * float4(in.in_var_pos, 0.0, 1.0); + out.out_var_TEXCOORD0 = in.in_var_uv; + return out; +} + diff --git a/shaders/msl/ps1.frag.msl b/shaders/msl/ps1.frag.msl new file mode 100644 index 00000000..e69de29b diff --git a/shaders/msl/ps1.vert.msl b/shaders/msl/ps1.vert.msl new file mode 100644 index 00000000..e69de29b diff --git a/shaders/msl/sprite.frag.msl b/shaders/msl/sprite.frag.msl new file mode 100644 index 00000000..979ac850 --- /dev/null +++ b/shaders/msl/sprite.frag.msl @@ -0,0 +1,29 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float4 out_var_SV_TARGET [[color(0)]]; +}; + +struct main0_in +{ + float2 in_var_TEXCOORD0 [[user(locn0)]]; + float4 in_var_COLOR0 [[user(locn1)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], texture2d diffuse [[texture(0)]], sampler smp [[sampler(0)]]) +{ + main0_out out = {}; + float4 _29 = diffuse.sample(smp, in.in_var_TEXCOORD0); + float4 _30 = _29 * in.in_var_COLOR0; + if ((_30.w - 0.00999999977648258209228515625) < 0.0) + { + discard_fragment(); + } + out.out_var_SV_TARGET = _30; + return out; +} + diff --git a/shaders/msl/sprite.vert.msl b/shaders/msl/sprite.vert.msl new file mode 100644 index 00000000..221a41ed --- /dev/null +++ b/shaders/msl/sprite.vert.msl @@ -0,0 +1,50 @@ +#include +#include + +using namespace metal; + +struct type_TransformBuffer +{ + float4x4 world_to_projection; + float4x4 projection_to_world; + float4x4 world_to_view; + float4x4 view_to_projection; + packed_float3 camera_pos_world; + float viewport_min_z; + packed_float3 camera_dir_world; + float viewport_max_z; + float2 viewport_size; + float2 viewport_offset; + float2 render_size; + float time; +}; + +struct type_model +{ + float4x4 model; + float4 color; +}; + +struct main0_out +{ + float2 out_var_TEXCOORD0 [[user(locn0)]]; + float4 out_var_COLOR0 [[user(locn1)]]; + float4 gl_Position [[position]]; +}; + +struct main0_in +{ + float2 in_var_pos [[attribute(0)]]; + float2 in_var_uv [[attribute(1)]]; + float4 in_var_color [[attribute(2)]]; +}; + +vertex main0_out main0(main0_in in [[stage_in]], constant type_TransformBuffer& TransformBuffer [[buffer(0)]], constant type_model& model [[buffer(1)]]) +{ + main0_out out = {}; + out.gl_Position = TransformBuffer.world_to_projection * (model.model * float4(in.in_var_pos, 0.0, 1.0)); + out.out_var_TEXCOORD0 = in.in_var_uv; + out.out_var_COLOR0 = in.in_var_color * model.color; + return out; +} + diff --git a/shaders/ps1.frag.hlsl b/shaders/ps1.frag.hlsl new file mode 100644 index 00000000..e2add747 --- /dev/null +++ b/shaders/ps1.frag.hlsl @@ -0,0 +1,61 @@ +SamplerState pointSampler +{ + Filter = MIN_MAG_MIP_POINT; // Nearest-neighbor + AddressU = Wrap; + AddressV = Wrap; +}; + +Texture2D diffuseTexture : register(t0); + +struct PSInput +{ + float4 position : SV_POSITION; + float2 texcoord : TEXCOORD0; +}; + +float ditherPattern2x2[4] = { + 0.0, 0.5, + 0.75, 0.25 +}; + +float4 mainPS(PSInput input) : SV_TARGET +{ + // Sample texture with nearest-neighbor + float4 color = diffuseTexture.Sample(pointSampler, input.texcoord); + + // Optional: Affine distortion effect + // If you want to simulate affine warping, you could do some screen-space + // dependent manipulation of texcoords. For simplicity, we won't do that here, + // but one trick is to modify the texcoord by input.position.z or w in some + // simplified manner. The vertex shader step is often enough to simulate "no perspective". + + // Dithering (optional): + // Compute a screen-space coordinate from SV_POSITION + // Use a small dithering pattern + int x = (int)input.position.x; + int y = (int)input.position.y; + int idx = (y & 1) * 2 + (x & 1); + float dither = ditherPattern2x2[idx]; + + // To simulate PS1 color quantization (e.g. to 5 bits for R,G,B): + // We'll quantize each channel. + // Suppose colorBitDepth.x = 5 means 5 bits for R/G/B, that’s 32 steps. + float stepsRGB = pow(2.0, colorBitDepth.x); + float stepsA = pow(2.0, colorBitDepth.y); + + // Add dithering before quantization to reduce banding + // Adjust dithering scale if desired + float ditherStrength = 1.0 / stepsRGB; // dither scale can be tweaked + float4 colorDithered = color + ditherStrength * dither; + + // Clamp after dithering + colorDithered = saturate(colorDithered); + + // Quantize + float3 quantizedRGB = round(colorDithered.rgb * (stepsRGB - 1.0)) / (stepsRGB - 1.0); + float quantizedA = round(colorDithered.a * (stepsA - 1.0)) / (stepsA - 1.0); + + float4 finalColor = float4(quantizedRGB, quantizedA); + + return finalColor; +} diff --git a/shaders/ps1.vert.hlsl b/shaders/ps1.vert.hlsl new file mode 100644 index 00000000..9daff9da --- /dev/null +++ b/shaders/ps1.vert.hlsl @@ -0,0 +1,41 @@ +struct VSInput +{ + float3 position : POSITION; + float2 texcoord : TEXCOORD0; +}; + +struct VSOutput +{ + float4 position : SV_POSITION; + float2 texcoord : TEXCOORD0; +}; + +VSOutput mainVS(VSInput input) +{ + VSOutput output; + + // Standard transform + float4 worldPos = mul(float4(input.position, 1.0), gWorldViewProj); + + // Simulate wobble by snapping coordinates to a lower precision grid. + // For a PS1-style effect, we can quantize the projected coordinates. + // For instance, if wobbleIntensity is something small like 1.0 or 0.5, + // multiply, floor, and divide back: + float factor = 1.0 / wobbleIntensity; + worldPos.x = floor(worldPos.x * factor) / factor; + worldPos.y = floor(worldPos.y * factor) / factor; + worldPos.z = floor(worldPos.z * factor) / factor; + worldPos.w = floor(worldPos.w * factor) / factor; + + // Output position + output.position = worldPos; + + // Pass through texture coordinate as-is. + // We do not do perspective correction here intentionally (PS1 didn't). + // PS1 essentially did affine mapping in screen space. To simulate this, + // we can just pass the original texcoords and let the pixel shader + // treat them linearly. + output.texcoord = input.texcoord; + + return output; +} diff --git a/shaders/reflection/dbgline.frag.json b/shaders/reflection/dbgline.frag.json new file mode 100644 index 00000000..7cbc1a14 --- /dev/null +++ b/shaders/reflection/dbgline.frag.json @@ -0,0 +1,22 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec4", + "name" : "in.var.COLOR", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/dbgline.vert.json b/shaders/reflection/dbgline.vert.json new file mode 100644 index 00000000..0af5c768 --- /dev/null +++ b/shaders/reflection/dbgline.vert.json @@ -0,0 +1,111 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_6" : { + "name" : "type.TransformBuffer", + "members" : [ + { + "name" : "world_to_projection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "projection_to_world", + "type" : "mat4", + "offset" : 64, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "world_to_view", + "type" : "mat4", + "offset" : 128, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "view_to_projection", + "type" : "mat4", + "offset" : 192, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "camera_pos_world", + "type" : "vec3", + "offset" : 256 + }, + { + "name" : "viewport_min_z", + "type" : "float", + "offset" : 268 + }, + { + "name" : "camera_dir_world", + "type" : "vec3", + "offset" : 272 + }, + { + "name" : "viewport_max_z", + "type" : "float", + "offset" : 284 + }, + { + "name" : "viewport_size", + "type" : "vec2", + "offset" : 288 + }, + { + "name" : "viewport_offset", + "type" : "vec2", + "offset" : 296 + }, + { + "name" : "render_size", + "type" : "vec2", + "offset" : 304 + }, + { + "name" : "time", + "type" : "float", + "offset" : 312 + } + ] + } + }, + "inputs" : [ + { + "type" : "vec3", + "name" : "in.var.pos", + "location" : 0 + }, + { + "type" : "vec4", + "name" : "in.var.color", + "location" : 1 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.COLOR", + "location" : 0 + } + ], + "ubos" : [ + { + "type" : "_6", + "name" : "type.TransformBuffer", + "block_size" : 316, + "set" : 1, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/model.frag.json b/shaders/reflection/model.frag.json new file mode 100644 index 00000000..e3049a16 --- /dev/null +++ b/shaders/reflection/model.frag.json @@ -0,0 +1,43 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.TEXCOORD0", + "location" : 0 + }, + { + "type" : "vec3", + "name" : "in.var.COLOR1", + "location" : 3 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ], + "separate_images" : [ + { + "type" : "texture2D", + "name" : "diffuse", + "set" : 2, + "binding" : 0 + } + ], + "separate_samplers" : [ + { + "type" : "sampler", + "name" : "smp", + "set" : 2, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/model.vert.json b/shaders/reflection/model.vert.json new file mode 100644 index 00000000..d8949366 --- /dev/null +++ b/shaders/reflection/model.vert.json @@ -0,0 +1,136 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_12" : { + "name" : "type.TransformBuffer", + "members" : [ + { + "name" : "world_to_projection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "projection_to_world", + "type" : "mat4", + "offset" : 64, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "world_to_view", + "type" : "mat4", + "offset" : 128, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "view_to_projection", + "type" : "mat4", + "offset" : 192, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "camera_pos_world", + "type" : "vec3", + "offset" : 256 + }, + { + "name" : "viewport_min_z", + "type" : "float", + "offset" : 268 + }, + { + "name" : "camera_dir_world", + "type" : "vec3", + "offset" : 272 + }, + { + "name" : "viewport_max_z", + "type" : "float", + "offset" : 284 + }, + { + "name" : "viewport_size", + "type" : "vec2", + "offset" : 288 + }, + { + "name" : "viewport_offset", + "type" : "vec2", + "offset" : 296 + }, + { + "name" : "render_size", + "type" : "vec2", + "offset" : 304 + }, + { + "name" : "time", + "type" : "float", + "offset" : 312 + } + ] + } + }, + "inputs" : [ + { + "type" : "vec3", + "name" : "in.var.pos", + "location" : 0 + }, + { + "type" : "vec2", + "name" : "in.var.uv", + "location" : 1 + }, + { + "type" : "vec4", + "name" : "in.var.color", + "location" : 2 + }, + { + "type" : "vec3", + "name" : "in.var.norm", + "location" : 3 + } + ], + "outputs" : [ + { + "type" : "vec2", + "name" : "out.var.TEXCOORD0", + "location" : 0 + }, + { + "type" : "vec4", + "name" : "out.var.COLOR0", + "location" : 1 + }, + { + "type" : "vec3", + "name" : "out.var.NORMAL", + "location" : 2 + }, + { + "type" : "vec3", + "name" : "out.var.COLOR1", + "location" : 3 + } + ], + "ubos" : [ + { + "type" : "_12", + "name" : "type.TransformBuffer", + "block_size" : 316, + "set" : 1, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/model_lit.frag.json b/shaders/reflection/model_lit.frag.json new file mode 100644 index 00000000..ba8372ab --- /dev/null +++ b/shaders/reflection/model_lit.frag.json @@ -0,0 +1,74 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "types" : { + "_6" : { + "name" : "type.LightBuffer", + "members" : [ + { + "name" : "uDiffuseColor", + "type" : "vec4", + "offset" : 0 + }, + { + "name" : "uLightDirection", + "type" : "vec3", + "offset" : 16 + }, + { + "name" : "uLightColor", + "type" : "vec4", + "offset" : 32 + } + ] + } + }, + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.TEXCOORD0", + "location" : 0 + }, + { + "type" : "vec3", + "name" : "in.var.NORMAL", + "location" : 1 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ], + "separate_images" : [ + { + "type" : "texture2D", + "name" : "uDiffuseTexture", + "set" : 0, + "binding" : 0 + } + ], + "separate_samplers" : [ + { + "type" : "sampler", + "name" : "samplerState", + "set" : 0, + "binding" : 0 + } + ], + "ubos" : [ + { + "type" : "_6", + "name" : "type.LightBuffer", + "block_size" : 48, + "set" : 1, + "binding" : 2 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/post.frag.json b/shaders/reflection/post.frag.json new file mode 100644 index 00000000..463f0bde --- /dev/null +++ b/shaders/reflection/post.frag.json @@ -0,0 +1,38 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.TEXCOORD0", + "location" : 0 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ], + "separate_images" : [ + { + "type" : "texture2D", + "name" : "diffuse", + "set" : 2, + "binding" : 0 + } + ], + "separate_samplers" : [ + { + "type" : "sampler", + "name" : "smp", + "set" : 2, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/post.vert.json b/shaders/reflection/post.vert.json new file mode 100644 index 00000000..522fdf37 --- /dev/null +++ b/shaders/reflection/post.vert.json @@ -0,0 +1,111 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_6" : { + "name" : "type.TransformBuffer", + "members" : [ + { + "name" : "world_to_projection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "projection_to_world", + "type" : "mat4", + "offset" : 64, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "world_to_view", + "type" : "mat4", + "offset" : 128, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "view_to_projection", + "type" : "mat4", + "offset" : 192, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "camera_pos_world", + "type" : "vec3", + "offset" : 256 + }, + { + "name" : "viewport_min_z", + "type" : "float", + "offset" : 268 + }, + { + "name" : "camera_dir_world", + "type" : "vec3", + "offset" : 272 + }, + { + "name" : "viewport_max_z", + "type" : "float", + "offset" : 284 + }, + { + "name" : "viewport_size", + "type" : "vec2", + "offset" : 288 + }, + { + "name" : "viewport_offset", + "type" : "vec2", + "offset" : 296 + }, + { + "name" : "render_size", + "type" : "vec2", + "offset" : 304 + }, + { + "name" : "time", + "type" : "float", + "offset" : 312 + } + ] + } + }, + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.pos", + "location" : 0 + }, + { + "type" : "vec2", + "name" : "in.var.uv", + "location" : 1 + } + ], + "outputs" : [ + { + "type" : "vec2", + "name" : "out.var.TEXCOORD0", + "location" : 0 + } + ], + "ubos" : [ + { + "type" : "_6", + "name" : "type.TransformBuffer", + "block_size" : 316, + "set" : 1, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/ps1.frag.json b/shaders/reflection/ps1.frag.json new file mode 100644 index 00000000..e69de29b diff --git a/shaders/reflection/ps1.vert.json b/shaders/reflection/ps1.vert.json new file mode 100644 index 00000000..e69de29b diff --git a/shaders/reflection/sprite.frag.json b/shaders/reflection/sprite.frag.json new file mode 100644 index 00000000..b7fbb15c --- /dev/null +++ b/shaders/reflection/sprite.frag.json @@ -0,0 +1,43 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "frag" + } + ], + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.TEXCOORD0", + "location" : 0 + }, + { + "type" : "vec4", + "name" : "in.var.COLOR0", + "location" : 1 + } + ], + "outputs" : [ + { + "type" : "vec4", + "name" : "out.var.SV_TARGET", + "location" : 0 + } + ], + "separate_images" : [ + { + "type" : "texture2D", + "name" : "diffuse", + "set" : 2, + "binding" : 0 + } + ], + "separate_samplers" : [ + { + "type" : "sampler", + "name" : "smp", + "set" : 2, + "binding" : 0 + } + ] +} \ No newline at end of file diff --git a/shaders/reflection/sprite.vert.json b/shaders/reflection/sprite.vert.json new file mode 100644 index 00000000..1eac9000 --- /dev/null +++ b/shaders/reflection/sprite.vert.json @@ -0,0 +1,145 @@ +{ + "entryPoints" : [ + { + "name" : "main", + "mode" : "vert" + } + ], + "types" : { + "_8" : { + "name" : "type.TransformBuffer", + "members" : [ + { + "name" : "world_to_projection", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "projection_to_world", + "type" : "mat4", + "offset" : 64, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "world_to_view", + "type" : "mat4", + "offset" : 128, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "view_to_projection", + "type" : "mat4", + "offset" : 192, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "camera_pos_world", + "type" : "vec3", + "offset" : 256 + }, + { + "name" : "viewport_min_z", + "type" : "float", + "offset" : 268 + }, + { + "name" : "camera_dir_world", + "type" : "vec3", + "offset" : 272 + }, + { + "name" : "viewport_max_z", + "type" : "float", + "offset" : 284 + }, + { + "name" : "viewport_size", + "type" : "vec2", + "offset" : 288 + }, + { + "name" : "viewport_offset", + "type" : "vec2", + "offset" : 296 + }, + { + "name" : "render_size", + "type" : "vec2", + "offset" : 304 + }, + { + "name" : "time", + "type" : "float", + "offset" : 312 + } + ] + }, + "_10" : { + "name" : "type.model", + "members" : [ + { + "name" : "model", + "type" : "mat4", + "offset" : 0, + "matrix_stride" : 16, + "row_major" : true + }, + { + "name" : "color", + "type" : "vec4", + "offset" : 64 + } + ] + } + }, + "inputs" : [ + { + "type" : "vec2", + "name" : "in.var.pos", + "location" : 0 + }, + { + "type" : "vec2", + "name" : "in.var.uv", + "location" : 1 + }, + { + "type" : "vec4", + "name" : "in.var.color", + "location" : 2 + } + ], + "outputs" : [ + { + "type" : "vec2", + "name" : "out.var.TEXCOORD0", + "location" : 0 + }, + { + "type" : "vec4", + "name" : "out.var.COLOR0", + "location" : 1 + } + ], + "ubos" : [ + { + "type" : "_8", + "name" : "type.TransformBuffer", + "block_size" : 316, + "set" : 1, + "binding" : 0 + }, + { + "type" : "_10", + "name" : "type.model", + "block_size" : 80, + "set" : 1, + "binding" : 1 + } + ] +} \ No newline at end of file diff --git a/shaders/spv/dbgline.frag.spv b/shaders/spv/dbgline.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..15bc58d8fb91fcf4d6109590caccd343f0c55313 GIT binary patch literal 368 zcmY+9y9>f#48&s}))zhybd!pEM-fCpL|g-*dof)j&zRNTIwAd>z0wH3QA~&r9IF%e literal 0 HcmV?d00001 diff --git a/shaders/spv/dbgline.vert.spv b/shaders/spv/dbgline.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..a44be3fed8e7e2cbc83f5f68c3a1f84632a7af97 GIT binary patch literal 1660 zcmZXUOK;Oa6orSRX$zD-=>sTjLN`cA5i3*)@m{nGqyl2W&ax6mGHUE-;y&oAe}R9* z&tikb`DQ%nU>x1doOAEFj~OTJ*1>`?w~R5%rl)V7HPfn@w!?T=%L< z+BY;oE?WKtm!BSH`tv-y5DvNN4XTlP=BMvLI?imGOv-7U*y(+4W+4V$z`6^*#9dSv!z(_;m60`zZchUwuP63 z;h1$t-}kh_f$=YE#ow;+N{y+#Cog@Vi7jZtiYA!vWzM}HT2^m>SFthab#+gI{Pz9b$Q? z`&-$zwZ2j;eecM~52nutGPIwiW$uSEVt4}gNP9T)25z_J$n{ARkn6DwJ@NRt!*|Nd m%=~VdlRKw2^Y6>xe=5eGq36i+T3s<`x85@&z5Y=bhqAv~q=#_; literal 0 HcmV?d00001 diff --git a/shaders/spv/model.frag.spv b/shaders/spv/model.frag.spv new file mode 100644 index 0000000000000000000000000000000000000000..6e83e47f36badeb7070e8a3e43e652c5bcad6692 GIT binary patch literal 1016 zcmY+C$xFjv5XHx??rq(7Q+pJGdJsWWq!uqiw3gbN1X`tFw6rRC^Wy*PMezN;CQ=6` z^SybqlXR+*HybmvS*z%alq?l{(hkEGY}_)kyrZ!D43Ux&fxoC1oQmm{wybPR0a?qr z_v=Tm;~%vBZWKOt#ATJ0lWlh&9^M8W7e}s(8-!8ssnZvfKdsJYgQ%x>-u3K0`|n}j zZ`4}VAgEvL4dZf(G>f@va23?|U4Gup_wx4Yl5U&#jr00tt>L)LzkR4bA^*q>e*<5t z3j1zJ5itG0STJ`O<=JmXN*+A8EJeWVHOhk%eo0j)g+1x6VtG$V%|6doH6{1O$IYpq z2pI8{Gd+B|*fm9QU;Hz%AG|C)D@!fr2Nz;YUE+(f)Wr{9k|mzK;pb%G@q_1O;ix;W zz6-Ktc@|}Puj|d7+2L66%*kyKF!ON>1WbQsp$C|L)K4(|m>u7ts?q}vq35@A zHQZrX56sLfQgXq}v?^sDFgIG0GEY-1bFWK@!GEVn_S}%-UzQ?)GN`>Ng+meMVwW$~ zg6DrBh8b?;dT_oVRrGpE{)`@sEZf+OiKa6!Izg&?s@L}+{j z8u}5`3rCfxpn9=Qo0(ef@W}d8x8?T2gV4+iTWYp^UBeX9Yjz+!Y?+`t>$_{E()Jq` z3TtX{y0ucVv@HcZbvXWAY5VPJG3Kem@y320zUSN?ZV1y`Z27>{b<3a_GgmOXgPwZ8 z>VL;(+|6(AGP9lDsi#kI{o01e)I&tpAzQ>*XakB^y7{nO>lnn9WI;T=snzEf+IHE zM1o@`aJdA>T;Qe?9J7I&OK{8wZdu%hrc7U{b3_^QpDibm%A2uxKzF`T*)ofq1ReJw ziRYcZboh$U?_b50G3keO$0jA2)mDM8O0aR__z`i$a^m8RisK{Rm`>u+%W?f4H++oI zU$c5@xur^|3!9|4oZN|zleo4X@47f*;Ga|68#?I+KHv$9@dMwqnEb$Q_Z_}1o*p>+ zoW;Z&)=PPvd09-FGmgQ0$bsCSD<(PdcLN6|Ct`M4OiuL0VRB->9LApAa+n<1D`F6j z9N8&{(X&qu=X7V6l9)XLFX^ScPIBX;jz2bxt#7EB-RNyryWpYBV@*V#|& zPQI&Rr*uA$P(Qnf4SjhifqyR>W;Y|@9X`j+>JCTUj(cP|^4(Gwc)uXQAA9ud;djMF z_gI3S_p)}6=X59Lx`f^RqMWF6UV_fqJ<;9Sq5ENTeX2V(qR%P^@?Vf(yCp%-?tha# uaTg`LgUwgVE$PnR6S@_3mwA#acVb8POavVH)x`)4H z@@&?(VCKw>&N=vA$)40Q{Hk%A_`(=#U)?QqM#L@d`jM={eCnSB|h_U zPU~^MpH8Cv(dh`M_n|nodG&Z4eN5ufP(FT{mduxB6>K+SrrQ)0Ij30L|M77U55kj3 z82$paUEf~xB}vDT-LL9cPN-)?v6c7EhA zALo1D?!2qDTn;lErHM`I9(?H4I?YDU`ey!{G4m^mxB9c@|30Fr>h!)LV}a=hW^Q2m zO#8W??I}OFBIE9eXD0Yr9^+?$nZdLl?EP=;^oTU3nr+5&=z&|5d5)fNWm!{S;_q}t zeJ(kkyj_P&I#1&TVQQ=@m%3#cv7DD=ERQc+^!@dk{L4BM!>qtp9L{FRtr;5wPi$E+ zE86LWZ(UR3O;H0q@P2_=-WB|s0ASdkG6M&q`OdSJexDnk#LneE8XbD-LM=S>+g@Q1n~ zzU!6@p4zOUcxvC4p|c^QPfazL&m9>v;Ej15cOC!D>AEKj_e(k4*RG6u@I@(wyDy_Y xK8$zB+oKP2e;}g|Z02#i5b~E4nxH zuW1xqjeU=59J{EJAd>*{^A9|g3-_^+fo0&SB;@5ip4c5_I>~to_z|>vG%zZ9LM;_dg zV_^PZJrBa-_P@sIF(D?Y;| zVcyY$d|8p*n4zY36~&gAsv`GO-T5bGxYbD?cE!NdXEzK?eP*NwIIB;OYrUiWZD-?MHg{*|EKYNbmV}5o zNynYrPG88;F$-p1Sow35^v`XakB5cL-cN?Z#0r+L@^ii_?Ds)b7SYHS-;&ERE%KS4 z+P5%4E?WMs%TEt8{xnUlWc%Fo2GmGB^V9cboFz7nM#Z>J?D$n~W`aK|Y#C)~9$nw& zX11C;NbUbzU24FMe^lHm??UJsr`L&WKM%J&t62<(d|)!`a!_k4Mfo=iY_i z|A{uw9a5hUn;JXLs%&P1kD(^K zw+*bxBQE4I1H2oF&jr@xfrUI~h4)+Hd0c4_98;T_#etew$yYTj+ zFk^1sY|8&YCt{d=OTU+-!Lac!OXF|XHhadVmmNjZ7o1Q$$7?uV;P#YvRhk^|u^&n^ z4{_LQ($u6E>_@eYe@)DF={-ekNOLA;Q<|Lg@=`W6*b5joH8@kp+tlzjHJKX>KQ-Au z_6wb;Lo6S4|0vs*^ee^E*JBC!z5PUIxbMWJx2F>NVOPY^=e7j=i(5<*xG2mESRlcN&*RtycT^)ni?j$`E4hsCCk6D|p8F?(S#Np|kU=&Zl;> z(TTK$|Ms!=8T{M~{|0Vyi~H{4n%I6~_ZHh{UU$EJ+;i&UDz1s$YhD*8`Z~Ag!4>?F zTJuFb|GoA;!AoFm1N}MC8fOqM$JpK_w(>pHomDO|u~y;C%3~VUmZ|bRN`Yur;LR$*Qe&9}(?&dyXsUnjnc`}>VFv3>m}n%KV1Zf~)D?UP{p zy1(2TZnu}3X78Vz-XMOU%Goz@?-M&~3HPkn*~+-{h~0e)cb;=p=ikPyk-wnQJ9cn+ z@7BIjEARh8%^s(4zQrCcZ_h6=S0R`8t-rzfZK`+$_q~5my-(DBF_&5mmvcY!-)wCz O_mTSKfB6UgE&dnWK0)dL literal 0 HcmV?d00001 diff --git a/shaders/spv/sprite.vert.spv b/shaders/spv/sprite.vert.spv new file mode 100644 index 0000000000000000000000000000000000000000..0da792038c96bac3bd60a317160e3032b4c1c488 GIT binary patch literal 2208 zcmZXT%}*0i6vZEu7C(>=5kW;P;0KCUR))l=C>mIhR0#`qO+%;27}{y311Kvt?){Ve zv)q_?esAWMXB~3;-Z}T4`|iE(Q5szxcW%TvH|aL?%Qxdj3#Q~T-YIu|u1@1(e+t{W+I???ttPwAt;qleF{Uq}`5E(bD98_Gd|Y+-hV=qn9RM zqoXWNx&uEoT+#&jX!*x|erg%$PvhuJ*m6@N)KKbypZbrQohWTKdP%=X?DctWdPCn! z(yY;myN&b9-1J;%TXFiomU&!io8NM6o|m}{eEs-561IM>hQ6fT?njw?bmZJMSsHa) zQQGjTil4IcH!x`H7DF!P z9(QY}&9tW35mWYWqTo(Wy{_WlNWob;MULwn=aQ4mCph?YxLvRBf8-rfKeIF6c73nD zF9$VHlfA(mVeTh?oz8)&X-UQh=KjIxz}z>OI50JY@thmRGshK~>A}k~KJ=U&`oZ{# z-&J+o8Q*HY{KIk9v}{*-EROn2M-FsbL)@^AxKKxL=q_ZI3vO5k7wVW5x?eKW!42!+ zLLGZ_G;KQW1#TkXm^IvVz>ynnG2oa5Ts7dBJKS2p@s{B>0*?8^ZHn8`?URc>sf&0% z{Cpu7_God|BUtIYZc8h9;mA9uNla+1%7|Gn@D1(xZYy?DYgLAi{gjN)FmJ%Qi+84- z5hB;T;%{n2LoEyXoz)5l#(zsI{!)SG3QTQF^3Xq;&`e`18ne9CG1Z;-hki-t(660c z6`n8r@Zbfl)Jz`modQ!U_^wuJG<>hX#LsGyi&~czabGKYH1>bWx!?y{>5Ck%g{hHu z0SBfg?%yyqu^*A)2UCM#YGjUvsgZX}4Dr;+n>CD|cLIK;Na{q(N8P`5T2<>CY3XZO z#`%U#J7qKZ^5S3ezk6TTOr& TlZ!p`WiITQEwO*p$)@Zt?^miC literal 0 HcmV?d00001 diff --git a/source/jsffi.c b/source/jsffi.c index b9853a6b..9474ae41 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -55,6 +55,7 @@ static JSAtom vertices_atom; static JSAtom dst_atom; static JSAtom src_atom; static JSAtom count_atom; +static JSAtom num_indices_atom; static JSAtom transform_atom; // GPU ATOMS @@ -1621,7 +1622,7 @@ JSValue make_quad_indices_buffer(JSContext *js, int quads) int count = quads*6; if (!JS_IsUndefined(idx_buffer) && idx_count >= count) return JS_DupValue(js,idx_buffer); - + int verts = quads*4; uint16_t *indices = malloc(sizeof(*indices)*count); for (int i = 0, v = 0; v < verts; i +=6, v += 4) { @@ -1637,6 +1638,7 @@ JSValue make_quad_indices_buffer(JSContext *js, int quads) JS_FreeValue(js,idx_buffer); idx_buffer = make_gpu_buffer(js,indices, sizeof(*indices)*count, JS_TYPED_ARRAY_UINT16, 1,0,1); + idx_count = count; return JS_DupValue(js,idx_buffer); } @@ -1650,7 +1652,7 @@ JSC_CCALL(os_make_text_buffer, int wrap = js2number(js,argv[4]); HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y }; text_vert *buffer = renderText(s, startpos, f, size, c, wrap); - size_t verts = arrlen(buffer); + size_t verts = arrlen(buffer); HMM_Vec2 *pos = malloc(arrlen(buffer)*sizeof(HMM_Vec2)); HMM_Vec2 *uv = malloc(arrlen(buffer)*sizeof(HMM_Vec2)); @@ -1662,16 +1664,14 @@ JSC_CCALL(os_make_text_buffer, color[i] = buffer[i].color; } - - JSValue jspos = make_gpu_buffer(js, pos, sizeof(HMM_Vec2)*arrlen(buffer), JS_TYPED_ARRAY_FLOAT32, 2,0,0); JSValue jsuv = make_gpu_buffer(js, uv, sizeof(HMM_Vec2)*arrlen(buffer), JS_TYPED_ARRAY_FLOAT32, 2,0,0); JSValue jscolor = make_gpu_buffer(js, color, sizeof(HMM_Vec4)*arrlen(buffer), JS_TYPED_ARRAY_FLOAT32, 4,0,0); size_t quads = verts/4; - size_t count = verts/2*3; + size_t count = verts/2*3; JSValue jsidx = make_quad_indices_buffer(js, quads); - + JS_FreeCString(js, s); arrfree(buffer); ret = JS_NewObject(js); @@ -1680,9 +1680,8 @@ JSC_CCALL(os_make_text_buffer, JS_SetProperty(js, ret, color_atom, jscolor); JS_SetProperty(js, ret, indices_atom, jsidx); JS_SetProperty(js, ret, vertices_atom, number2js(js, verts)); - JS_SetProperty(js, ret, count_atom, number2js(js, count)); - JS_SetPropertyStr(js,ret,"num_indices", number2js(js,count)); - + JS_SetProperty(js,ret,num_indices_atom, number2js(js,count)); + return ret; ) @@ -6706,6 +6705,7 @@ void ffi_load(JSContext *js) { vertex_atom = JS_NewAtom(js, "vertex"); index_atom = JS_NewAtom(js, "index"); indirect_atom = JS_NewAtom(js, "indirect"); + num_indices_atom = JS_NewAtom(js,"num_indices"); fill_event_atoms(js); diff --git a/source/qjs_imgui.cpp b/source/qjs_imgui.cpp index 6386cda9..606f3b34 100644 --- a/source/qjs_imgui.cpp +++ b/source/qjs_imgui.cpp @@ -4,12 +4,16 @@ #include "quickjs.h" #include +#include #include "imgui_impl_sdl3.h" -#include "imgui_impl_sdlrenderer3.h" +#include "imgui_impl_sdlgpu3.h" extern "C" { -SDL_Renderer *js2SDL_Renderer(JSContext *js, JSValue v); -SDL_Texture *js2SDL_Texture(JSContext *js, JSValue v); +SDL_GPUDevice *js2SDL_GPUDevice(JSContext *js, JSValue v); +SDL_GPURenderPass *js2SDL_GPURenderPass(JSContext *js, JSValue v); +SDL_GPUCommandBuffer *js2SDL_GPUCommandBuffer(JSContext *js, JSValue v); +SDL_GPUTexture *js2SDL_GPUTexture(JSContext *js, JSValue v); +SDL_Window *js2SDL_Window(JSContext *js, JSValue v); } static int START = 0; @@ -393,13 +397,13 @@ JSC_CCALL(imgui_pushid, JSC_CCALL(imgui_popid, ImGui::PopID(); ) JSC_CCALL(imgui_image, - SDL_Texture *tex = js2SDL_Texture(js,argv[0]); - ImGui::Image((ImTextureID)tex, ImVec2(tex->w, tex->h), ImVec2(0,0), ImVec2(1,1)); + SDL_GPUTexture *tex = js2SDL_GPUTexture(js,argv[0]); + ImGui::Image((ImTextureID)tex, ImVec2(100, 100), ImVec2(0,0), ImVec2(1,1)); ) JSC_SCALL(imgui_imagebutton, - SDL_Texture *tex = js2SDL_Texture(js,argv[1]); - if (ImGui::ImageButton(str, (ImTextureID)tex, ImVec2(tex->w, tex->h))) + SDL_GPUTexture *tex = js2SDL_GPUTexture(js,argv[1]); + if (ImGui::ImageButton(str, (ImTextureID)tex, ImVec2(100, 100))) JS_Call(js, argv[2], JS_UNDEFINED, 0, NULL); ) @@ -761,20 +765,20 @@ JSC_SCALL(imgui_setclipboard, ) JSC_CCALL(imgui_newframe, - ImGui_ImplSDLRenderer3_NewFrame(); + ImGui_ImplSDLGPU3_NewFrame(); ImGui_ImplSDL3_NewFrame(); ImGui::NewFrame(); ) JSC_CCALL(imgui_endframe, - SDL_Renderer *ren = js2SDL_Renderer(js,argv[0]); ImGui::Render(); - int w,h; - SDL_RendererLogicalPresentation mode; - SDL_GetRenderLogicalPresentation(ren, &w, &h, &mode); - SDL_SetRenderLogicalPresentation(ren, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED); - ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData(), ren); - SDL_SetRenderLogicalPresentation(ren,w,h,mode); + ImDrawData *draw_data = ImGui::GetDrawData(); + + SDL_GPUCommandBuffer *cmd = js2SDL_GPUCommandBuffer(js,argv[0]); + Imgui_ImplSDLGPU3_PrepareDrawData(draw_data,cmd); + SDL_GPURenderPass *pass = js2SDL_GPURenderPass(js,argv[1]); + + ImGui_ImplSDLGPU3_RenderDrawData(draw_data, cmd, pass); ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); ) @@ -794,19 +798,26 @@ JSC_CCALL(imgui_init, io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - printf("Has viewports? %d\n", ImGuiBackendFlags_PlatformHasViewports); ImGui::StyleColorsDark(); - SDL_Renderer *render = js2SDL_Renderer(js, argv[0]); - SDL_Window *win = SDL_GetRenderWindow(render); - ImGui_ImplSDL3_InitForSDLRenderer(win, render); - ImGui_ImplSDLRenderer3_Init(render); + SDL_GPUDevice *gpu = js2SDL_GPUDevice(js,argv[0]); + SDL_Window *window = js2SDL_Window(js,argv[1]); + + struct ImGui_ImplSDLGPU3_InitInfo info; + info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpu,window); + info.GpuDevice = gpu; + + ImGui_ImplSDL3_InitForSDLGPU(js2SDL_Window(js,argv[1])); + + ImGui_ImplSDLGPU3_Init(&info); io.IniFilename = ".prosperon/imgui.ini"; ImGui::LoadIniSettingsFromDisk(".prosperon/imgui.ini"); + ImPlot::CreateContext(); ImNodes::CreateContext(); + START = 1; ) @@ -900,11 +911,11 @@ static const JSCFunctionListEntry js_imgui_funcs[] = { MIST_FUNC_DEF(imgui, invisiblebutton, 2), MIST_FUNC_DEF(imgui, width, 1), MIST_FUNC_DEF(imgui, setclipboard, 1), - MIST_FUNC_DEF(imgui, newframe, 3), - MIST_FUNC_DEF(imgui, endframe, 1), + MIST_FUNC_DEF(imgui, newframe, 0), + MIST_FUNC_DEF(imgui, endframe, 2), MIST_FUNC_DEF(imgui, wantmouse, 0), MIST_FUNC_DEF(imgui, wantkeys, 0), - MIST_FUNC_DEF(imgui, init, 1), + MIST_FUNC_DEF(imgui, init, 2), }; extern "C" { diff --git a/source/thirdparty/imgui/imgui.cpp b/source/thirdparty/imgui/imgui.cpp index c7b84cc6..eca339f4 100644 --- a/source/thirdparty/imgui/imgui.cpp +++ b/source/thirdparty/imgui/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (main code and documentation) // Help: @@ -25,7 +25,7 @@ // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. // Everything else should be asked in 'Issues'! We are building a database of cross-linked knowledge there. -// Copyright (c) 2014-2024 Omar Cornut +// Copyright (c) 2014-2025 Omar Cornut // Developed by Omar Cornut and every direct or indirect contributors to the GitHub. // See LICENSE.txt for copyright and licensing details (standard MIT License). // This library is free but needs your support to sustain development and maintenance. @@ -85,6 +85,7 @@ CODE // [SECTION] SCROLLING // [SECTION] TOOLTIPS // [SECTION] POPUPS +// [SECTION] WINDOW FOCUS // [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] DRAG AND DROP // [SECTION] LOGGING/CAPTURING @@ -1106,7 +1107,7 @@ CODE #else #include #endif -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES) +#if defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)) // The UWP and GDK Win32 API subsets don't support clipboard nor IME functions #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS #define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS @@ -1155,12 +1156,14 @@ CODE #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size -#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*' #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif // Debug options @@ -1214,6 +1217,10 @@ namespace ImGui // Item static void ItemHandleShortcut(ImGuiID id); +// Window Focus +static int FindWindowFocusIndex(ImGuiWindow* window); +static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags); + // Navigation static void NavUpdate(); static void NavUpdateWindowing(); @@ -1234,7 +1241,6 @@ static ImVec2 NavCalcPreferredRefPos(); static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static void NavRestoreLayer(ImGuiNavLayer layer); -static int FindWindowFocusIndex(ImGuiWindow* window); // Error Checking and Debug Tools static void ErrorCheckNewFrameSanityChecks(); @@ -2336,7 +2342,7 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) ImFileHandle ImFileOpen(const char* filename, const char* mode) { -#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__) +#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && (defined(__MINGW32__) || (!defined(__CYGWIN__) && !defined(__GNUC__))) // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32! const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); @@ -3608,7 +3614,6 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) return "Unknown"; } - //----------------------------------------------------------------------------- // [SECTION] RENDER HELPERS // Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change, @@ -3954,7 +3959,8 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) Time = 0.0f; FrameCount = 0; FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1; - WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false; + WithinEndChildID = 0; + WithinFrameScope = WithinFrameScopeWithImplicitWindow = false; GcCompactAll = false; TestEngineHookItems = false; TestEngine = NULL; @@ -3999,6 +4005,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) ActiveIdPreviousFrameIsAlive = false; ActiveIdPreviousFrameHasBeenEditedBefore = false; ActiveIdPreviousFrameWindow = NULL; + memset(&ActiveIdValueOnActivation, 0, sizeof(ActiveIdValueOnActivation)); LastActiveId = 0; LastActiveIdTimer = 0.0f; @@ -4139,7 +4146,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas) StackSizesInBeginForCurrentWindow = NULL; DebugDrawIdConflictsCount = 0; - DebugLogFlags = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_OutputToTTY | ImGuiDebugLogFlags_EventFont; + DebugLogFlags = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_OutputToTTY; DebugLocateId = 0; DebugLogSkippedErrors = 0; DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None; @@ -4344,7 +4351,6 @@ void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type) hook.Callback(&g, &hook); } - //----------------------------------------------------------------------------- // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) //----------------------------------------------------------------------------- @@ -4456,7 +4462,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) // This could be written in a more general way (e.g associate a hook to ActiveId), // but since this is currently quite an exception we'll leave it as is. - // One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveId() + // One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveID() if (g.InputTextState.ID == g.ActiveId) InputTextDeactivateHook(g.ActiveId); } @@ -6320,9 +6326,12 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I } SetNextWindowSize(size); - // Forward child flags + // Forward child flags (we allow prior settings to merge but it'll only work for adding flags) + if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasChildFlags) + g.NextWindowData.ChildFlags |= child_flags; + else + g.NextWindowData.ChildFlags = child_flags; g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasChildFlags; - g.NextWindowData.ChildFlags = child_flags; // Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value. // FIXME: 2023/11/14: commented out shorted version. We had an issue with multiple ### in child window path names, which the trailing hash helped workaround. @@ -6380,10 +6389,10 @@ void ImGui::EndChild() ImGuiContext& g = *GImGui; ImGuiWindow* child_window = g.CurrentWindow; - IM_ASSERT(g.WithinEndChild == false); + const ImGuiID backup_within_end_child_id = g.WithinEndChildID; IM_ASSERT(child_window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() calls - g.WithinEndChild = true; + g.WithinEndChildID = child_window->ID; ImVec2 child_size = child_window->Size; End(); if (child_window->BeginCount == 1) @@ -6415,7 +6424,7 @@ void ImGui::EndChild() if (g.HoveredWindow == child_window) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; } - g.WithinEndChild = false; + g.WithinEndChildID = backup_within_end_child_id; g.LogLinePosY = -FLT_MAX; // To enforce a carriage return } @@ -6456,29 +6465,6 @@ static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settin window->DockOrder = settings->DockOrder; } -static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags) -{ - ImGuiContext& g = *GImGui; - - const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0 && ((new_flags & ImGuiWindowFlags_Popup) == 0 || (new_flags & ImGuiWindowFlags_ChildMenu) != 0); - const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild; - if ((just_created || child_flag_changed) && !new_is_explicit_child) - { - IM_ASSERT(!g.WindowsFocusOrder.contains(window)); - g.WindowsFocusOrder.push_back(window); - window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1); - } - else if (!just_created && child_flag_changed && new_is_explicit_child) - { - IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window); - for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++) - g.WindowsFocusOrder[n]->FocusOrder--; - g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder); - window->FocusOrder = -1; - } - window->IsExplicitChild = new_is_explicit_child; -} - static void InitOrLoadWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) { // Initial window state with e.g. default/arbitrary window position @@ -7048,9 +7034,10 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar ImGuiStyle& style = g.Style; ImGuiWindowFlags flags = window->Flags; - // Ensure that ScrollBar doesn't read last frame's SkipItems + // Ensure that Scrollbar() doesn't read last frame's SkipItems IM_ASSERT(window->BeginCount == 0); window->SkipItems = false; + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; // Draw window + handle manual resize // As we highlight the title bar when want_focus is set, multiple reappearing windows will have their title bar highlighted on their reappearing frame. @@ -7185,6 +7172,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar if (handle_borders_and_resize_grips && !window->DockNodeAsHost) RenderWindowOuterBorders(window); } + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; } // When inside a dock node, this is handled in DockNodeCalcTabBarLayout() instead. @@ -7335,42 +7323,6 @@ static void SetWindowActiveForSkipRefresh(ImGuiWindow* window) } } -// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) -// should be positioned behind that modal window, unless the window was created inside the modal begin-stack. -// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. -// - WindowA // FindBlockingModal() returns Modal1 -// - WindowB // .. returns Modal1 -// - Modal1 // .. returns Modal2 -// - WindowC // .. returns Modal2 -// - WindowD // .. returns Modal2 -// - Modal2 // .. returns Modal2 -// - WindowE // .. returns NULL -// Notes: -// - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL. -// Only difference is here we check for ->Active/WasActive but it may be unnecessary. -ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - if (g.OpenPopupStack.Size <= 0) - return NULL; - - // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. - for (ImGuiPopupData& popup_data : g.OpenPopupStack) - { - ImGuiWindow* popup_window = popup_data.Window; - if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal)) - continue; - if (!popup_window->Active && !popup_window->WasActive) // Check WasActive, because this code may run before popup renders on current frame, also check Active to handle newly created windows. - continue; - if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click. - return popup_window; - if (IsWindowWithinBeginStackOf(window, popup_window)) // Window may be over modal - continue; - return popup_window; // Place window right below first block modal - } - return NULL; -} - // Push a new Dear ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -7880,9 +7832,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { IM_ASSERT(window->IDStack.Size == 1); window->IDStack.Size = 0; // As window->IDStack[0] == window->ID here, make sure TestEngine doesn't erroneously see window as parent of itself. + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; IMGUI_TEST_ENGINE_ITEM_ADD(window->ID, window->Rect(), NULL); IMGUI_TEST_ENGINE_ITEM_INFO(window->ID, window->Name, (g.HoveredWindow == window) ? ImGuiItemStatusFlags_HoveredRect : 0); window->IDStack.Size = 1; + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + } #endif @@ -8189,7 +8144,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // [Test Engine] Register title bar / tab with MoveId. #ifdef IMGUI_ENABLE_TEST_ENGINE if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) + { + window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; IMGUI_TEST_ENGINE_ITEM_ADD(g.LastItemData.ID, g.LastItemData.Rect, &g.LastItemData); + window->DC.NavLayerCurrent = ImGuiNavLayer_Main; + } #endif } else @@ -8326,7 +8285,7 @@ void ImGui::End() // Error checking: verify that user doesn't directly call End() on a child window. if ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_DockNodeHost) && !window->DockIsActive) - IM_ASSERT_USER_ERROR(g.WithinEndChild, "Must call EndChild() and not End()!"); + IM_ASSERT_USER_ERROR(g.WithinEndChildID == window->ID, "Must call EndChild() and not End()!"); // Close anything that is open if (window->DC.CurrentColumns) @@ -8372,191 +8331,6 @@ void ImGui::End() SetCurrentViewport(g.CurrentWindow, g.CurrentWindow->Viewport); } -void ImGui::BringWindowToFocusFront(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(window == window->RootWindow); - - const int cur_order = window->FocusOrder; - IM_ASSERT(g.WindowsFocusOrder[cur_order] == window); - if (g.WindowsFocusOrder.back() == window) - return; - - const int new_order = g.WindowsFocusOrder.Size - 1; - for (int n = cur_order; n < new_order; n++) - { - g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1]; - g.WindowsFocusOrder[n]->FocusOrder--; - IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n); - } - g.WindowsFocusOrder[new_order] = window; - window->FocusOrder = (short)new_order; -} - -void ImGui::BringWindowToDisplayFront(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* current_front_window = g.Windows.back(); - if (current_front_window == window || current_front_window->RootWindowDockTree == window) // Cheap early out (could be better) - return; - for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window - if (g.Windows[i] == window) - { - memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*)); - g.Windows[g.Windows.Size - 1] = window; - break; - } -} - -void ImGui::BringWindowToDisplayBack(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - if (g.Windows[0] == window) - return; - for (int i = 0; i < g.Windows.Size; i++) - if (g.Windows[i] == window) - { - memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); - g.Windows[0] = window; - break; - } -} - -void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window) -{ - IM_ASSERT(window != NULL && behind_window != NULL); - ImGuiContext& g = *GImGui; - window = window->RootWindow; - behind_window = behind_window->RootWindow; - int pos_wnd = FindWindowDisplayIndex(window); - int pos_beh = FindWindowDisplayIndex(behind_window); - if (pos_wnd < pos_beh) - { - size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*); - memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes); - g.Windows[pos_beh - 1] = window; - } - else - { - size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*); - memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes); - g.Windows[pos_beh] = window; - } -} - -int ImGui::FindWindowDisplayIndex(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - return g.Windows.index_from_ptr(g.Windows.find(window)); -} - -// Moving window to front of display and set focus (which happens to be back of our sorted list) -void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) -{ - ImGuiContext& g = *GImGui; - - // Modal check? - if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. - if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) - { - // This block would typically be reached in two situations: - // - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag. - // - User clicking on void or anything behind a modal while a modal is open (window == NULL) - IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); - if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) - BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?) - ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals - return; - } - - // Find last focused child (if any) and focus it instead. - if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL) - window = NavRestoreLastChildNavWindow(window); - - // Apply focus - if (g.NavWindow != window) - { - SetNavWindow(window); - if (window && g.NavHighlightItemUnderNav) - g.NavMousePosDirty = true; - g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId - g.NavLayer = ImGuiNavLayer_Main; - SetNavFocusScope(window ? window->NavRootFocusScopeId : 0); - g.NavIdIsAlive = false; - g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid; - - // Close popups if any - ClosePopupsOverWindow(window, false); - } - - // Move the root window to the top of the pile - IM_ASSERT(window == NULL || window->RootWindowDockTree != NULL); - ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; - ImGuiWindow* display_front_window = window ? window->RootWindowDockTree : NULL; - ImGuiDockNode* dock_node = window ? window->DockNode : NULL; - bool active_id_window_is_dock_node_host = (g.ActiveIdWindow && dock_node && dock_node->HostWindow == g.ActiveIdWindow); - - // Steal active widgets. Some of the cases it triggers includes: - // - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run. - // - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId) - // - Using dock host items (tab, collapse button) can trigger this before we redirect the ActiveIdWindow toward the child window. - if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window) - if (!g.ActiveIdNoClearOnFocusLoss && !active_id_window_is_dock_node_host) - ClearActiveID(); - - // Passing NULL allow to disable keyboard focus - if (!window) - return; - window->LastFrameJustFocused = g.FrameCount; - - // Select in dock node - // For #2304 we avoid applying focus immediately before the tabbar is visible. - //if (dock_node && dock_node->TabBar) - // dock_node->TabBar->SelectedTabId = dock_node->TabBar->NextSelectedTabId = window->TabId; - - // Bring to front - BringWindowToFocusFront(focus_front_window); - if (((window->Flags | focus_front_window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) - BringWindowToDisplayFront(display_front_window); -} - -void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags) -{ - ImGuiContext& g = *GImGui; - int start_idx = g.WindowsFocusOrder.Size - 1; - if (under_this_window != NULL) - { - // Aim at root window behind us, if we are in a child window that's our own root (see #4640) - int offset = -1; - while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow) - { - under_this_window = under_this_window->ParentWindow; - offset = 0; - } - start_idx = FindWindowFocusIndex(under_this_window) + offset; - } - for (int i = start_idx; i >= 0; i--) - { - // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. - ImGuiWindow* window = g.WindowsFocusOrder[i]; - if (window == ignore_window || !window->WasActive) - continue; - if (filter_viewport != NULL && window->Viewport != filter_viewport) - continue; - if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) - { - // FIXME-DOCK: When ImGuiFocusRequestFlags_RestoreFocusedChild is set... - // This is failing (lagging by one frame) for docked windows. - // If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B. - // We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update) - // to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself? - FocusWindow(window, flags); - return; - } - } - FocusWindow(NULL, flags); -} - // Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only. void ImGui::SetCurrentFont(ImFont* font) { @@ -8829,29 +8603,6 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) return true; } -bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* ref_window = g.NavWindow; - ImGuiWindow* cur_window = g.CurrentWindow; - - if (ref_window == NULL) - return false; - if (flags & ImGuiFocusedFlags_AnyWindow) - return true; - - IM_ASSERT(cur_window); // Not inside a Begin()/End() - const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0; - const bool dock_hierarchy = (flags & ImGuiFocusedFlags_DockHierarchy) != 0; - if (flags & ImGuiHoveredFlags_RootWindow) - cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy, dock_hierarchy); - - if (flags & ImGuiHoveredFlags_ChildWindows) - return IsWindowChildOf(ref_window, cur_window, popup_hierarchy, dock_hierarchy); - else - return (ref_window == cur_window); -} - ImGuiID ImGui::GetWindowDockID() { ImGuiContext& g = *GImGui; @@ -8864,14 +8615,6 @@ bool ImGui::IsWindowDocked() return g.CurrentWindow->DockIsActive; } -// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) -// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically. -// If you want a window to never be focused, you may use the e.g. NoInputs flag. -bool ImGui::IsWindowNavFocusable(ImGuiWindow* window) -{ - return window->WasActive && window == window->RootWindow && !(window->Flags & ImGuiWindowFlags_NoNavFocus); -} - float ImGui::GetWindowWidth() { ImGuiWindow* window = GImGui->CurrentWindow; @@ -9020,24 +8763,6 @@ void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) SetWindowCollapsed(window, collapsed, cond); } -void ImGui::SetWindowFocus() -{ - FocusWindow(GImGui->CurrentWindow); -} - -void ImGui::SetWindowFocus(const char* name) -{ - if (name) - { - if (ImGuiWindow* window = FindWindowByName(name)) - FocusWindow(window); - } - else - { - FocusWindow(NULL); - } -} - void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; @@ -9096,12 +8821,6 @@ void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; } -void ImGui::SetNextWindowFocus() -{ - ImGuiContext& g = *GImGui; - g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus; -} - void ImGui::SetNextWindowBgAlpha(float alpha) { ImGuiContext& g = *GImGui; @@ -10944,7 +10663,6 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID own return true; } - //----------------------------------------------------------------------------- // [SECTION] ERROR CHECKING, STATE RECOVERY //----------------------------------------------------------------------------- @@ -11163,8 +10881,16 @@ void ImGui::ErrorRecoveryTryToRecoverState(const ImGuiErrorRecoveryState* state_ ImGuiWindow* window = g.CurrentWindow; if (window->Flags & ImGuiWindowFlags_ChildWindow) { - IM_ASSERT_USER_ERROR(0, "Missing EndChild()"); - EndChild(); + if (g.CurrentTable != NULL && g.CurrentTable->InnerWindow == g.CurrentWindow) + { + IM_ASSERT_USER_ERROR(0, "Missing EndTable()"); + EndTable(); + } + else + { + IM_ASSERT_USER_ERROR(0, "Missing EndChild()"); + EndChild(); + } } else { @@ -12323,6 +12049,43 @@ ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal() return NULL; } + +// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) +// should be positioned behind that modal window, unless the window was created inside the modal begin-stack. +// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. +// - WindowA // FindBlockingModal() returns Modal1 +// - WindowB // .. returns Modal1 +// - Modal1 // .. returns Modal2 +// - WindowC // .. returns Modal2 +// - WindowD // .. returns Modal2 +// - Modal2 // .. returns Modal2 +// - WindowE // .. returns NULL +// Notes: +// - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL. +// Only difference is here we check for ->Active/WasActive but it may be unnecessary. +ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= 0) + return NULL; + + // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. + for (ImGuiPopupData& popup_data : g.OpenPopupStack) + { + ImGuiWindow* popup_window = popup_data.Window; + if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal)) + continue; + if (!popup_window->Active && !popup_window->WasActive) // Check WasActive, because this code may run before popup renders on current frame, also check Active to handle newly created windows. + continue; + if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click. + return popup_window; + if (IsWindowWithinBeginStackOf(window, popup_window)) // Window may be over modal + continue; + return popup_window; // Place window right below first block modal + } + return NULL; +} + void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) { ImGuiContext& g = *GImGui; @@ -12601,11 +12364,11 @@ void ImGui::EndPopup() NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY); // Child-popups don't need to be laid out - IM_ASSERT(g.WithinEndChild == false); + const ImGuiID backup_within_end_child_id = g.WithinEndChildID; if (window->Flags & ImGuiWindowFlags_ChildWindow) - g.WithinEndChild = true; + g.WithinEndChildID = window->ID; End(); - g.WithinEndChild = false; + g.WithinEndChildID = backup_within_end_child_id; } // Helper to open a popup if mouse button is released over the item @@ -12837,6 +12600,289 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) return window->Pos; } +//----------------------------------------------------------------------------- +// [SECTION] WINDOW FOCUS +//---------------------------------------------------------------------------- +// - SetWindowFocus() +// - SetNextWindowFocus() +// - IsWindowFocused() +// - UpdateWindowInFocusOrderList() [Internal] +// - BringWindowToFocusFront() [Internal] +// - BringWindowToDisplayFront() [Internal] +// - BringWindowToDisplayBack() [Internal] +// - BringWindowToDisplayBehind() [Internal] +// - FindWindowDisplayIndex() [Internal] +// - FocusWindow() [Internal] +// - FocusTopMostWindowUnderOne() [Internal] +//----------------------------------------------------------------------------- + +void ImGui::SetWindowFocus() +{ + FocusWindow(GImGui->CurrentWindow); +} + +void ImGui::SetWindowFocus(const char* name) +{ + if (name) + { + if (ImGuiWindow* window = FindWindowByName(name)) + FocusWindow(window); + } + else + { + FocusWindow(NULL); + } +} + +void ImGui::SetNextWindowFocus() +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasFocus; +} + +// Similar to IsWindowHovered() +bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* ref_window = g.NavWindow; + ImGuiWindow* cur_window = g.CurrentWindow; + + if (ref_window == NULL) + return false; + if (flags & ImGuiFocusedFlags_AnyWindow) + return true; + + IM_ASSERT(cur_window); // Not inside a Begin()/End() + const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0; + const bool dock_hierarchy = (flags & ImGuiFocusedFlags_DockHierarchy) != 0; + if (flags & ImGuiHoveredFlags_RootWindow) + cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy, dock_hierarchy); + + if (flags & ImGuiHoveredFlags_ChildWindows) + return IsWindowChildOf(ref_window, cur_window, popup_hierarchy, dock_hierarchy); + else + return (ref_window == cur_window); +} + +static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_UNUSED(g); + int order = window->FocusOrder; + IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking) + IM_ASSERT(g.WindowsFocusOrder[order] == window); + return order; +} + +static void ImGui::UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags) +{ + ImGuiContext& g = *GImGui; + + const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0 && ((new_flags & ImGuiWindowFlags_Popup) == 0 || (new_flags & ImGuiWindowFlags_ChildMenu) != 0); + const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild; + if ((just_created || child_flag_changed) && !new_is_explicit_child) + { + IM_ASSERT(!g.WindowsFocusOrder.contains(window)); + g.WindowsFocusOrder.push_back(window); + window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1); + } + else if (!just_created && child_flag_changed && new_is_explicit_child) + { + IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window); + for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++) + g.WindowsFocusOrder[n]->FocusOrder--; + g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder); + window->FocusOrder = -1; + } + window->IsExplicitChild = new_is_explicit_child; +} + +void ImGui::BringWindowToFocusFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(window == window->RootWindow); + + const int cur_order = window->FocusOrder; + IM_ASSERT(g.WindowsFocusOrder[cur_order] == window); + if (g.WindowsFocusOrder.back() == window) + return; + + const int new_order = g.WindowsFocusOrder.Size - 1; + for (int n = cur_order; n < new_order; n++) + { + g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1]; + g.WindowsFocusOrder[n]->FocusOrder--; + IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n); + } + g.WindowsFocusOrder[new_order] = window; + window->FocusOrder = (short)new_order; +} + +// Note technically focus related but rather adjacent and close to BringWindowToFocusFront() +void ImGui::BringWindowToDisplayFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* current_front_window = g.Windows.back(); + if (current_front_window == window || current_front_window->RootWindowDockTree == window) // Cheap early out (could be better) + return; + for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window + if (g.Windows[i] == window) + { + memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*)); + g.Windows[g.Windows.Size - 1] = window; + break; + } +} + +void ImGui::BringWindowToDisplayBack(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows[0] == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); + g.Windows[0] = window; + break; + } +} + +void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window) +{ + IM_ASSERT(window != NULL && behind_window != NULL); + ImGuiContext& g = *GImGui; + window = window->RootWindow; + behind_window = behind_window->RootWindow; + int pos_wnd = FindWindowDisplayIndex(window); + int pos_beh = FindWindowDisplayIndex(behind_window); + if (pos_wnd < pos_beh) + { + size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes); + g.Windows[pos_beh - 1] = window; + } + else + { + size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes); + g.Windows[pos_beh] = window; + } +} + +int ImGui::FindWindowDisplayIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + return g.Windows.index_from_ptr(g.Windows.find(window)); +} + +// Moving window to front of display and set focus (which happens to be back of our sorted list) +void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) +{ + ImGuiContext& g = *GImGui; + + // Modal check? + if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. + if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) + { + // This block would typically be reached in two situations: + // - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag. + // - User clicking on void or anything behind a modal while a modal is open (window == NULL) + IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); + if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?) + ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals + return; + } + + // Find last focused child (if any) and focus it instead. + if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL) + window = NavRestoreLastChildNavWindow(window); + + // Apply focus + if (g.NavWindow != window) + { + SetNavWindow(window); + if (window && g.NavHighlightItemUnderNav) + g.NavMousePosDirty = true; + g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId + g.NavLayer = ImGuiNavLayer_Main; + SetNavFocusScope(window ? window->NavRootFocusScopeId : 0); + g.NavIdIsAlive = false; + g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid; + + // Close popups if any + ClosePopupsOverWindow(window, false); + } + + // Move the root window to the top of the pile + IM_ASSERT(window == NULL || window->RootWindowDockTree != NULL); + ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; + ImGuiWindow* display_front_window = window ? window->RootWindowDockTree : NULL; + ImGuiDockNode* dock_node = window ? window->DockNode : NULL; + bool active_id_window_is_dock_node_host = (g.ActiveIdWindow && dock_node && dock_node->HostWindow == g.ActiveIdWindow); + + // Steal active widgets. Some of the cases it triggers includes: + // - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run. + // - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId) + // - Using dock host items (tab, collapse button) can trigger this before we redirect the ActiveIdWindow toward the child window. + if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window) + if (!g.ActiveIdNoClearOnFocusLoss && !active_id_window_is_dock_node_host) + ClearActiveID(); + + // Passing NULL allow to disable keyboard focus + if (!window) + return; + window->LastFrameJustFocused = g.FrameCount; + + // Select in dock node + // For #2304 we avoid applying focus immediately before the tabbar is visible. + //if (dock_node && dock_node->TabBar) + // dock_node->TabBar->SelectedTabId = dock_node->TabBar->NextSelectedTabId = window->TabId; + + // Bring to front + BringWindowToFocusFront(focus_front_window); + if (((window->Flags | focus_front_window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayFront(display_front_window); +} + +void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags) +{ + ImGuiContext& g = *GImGui; + int start_idx = g.WindowsFocusOrder.Size - 1; + if (under_this_window != NULL) + { + // Aim at root window behind us, if we are in a child window that's our own root (see #4640) + int offset = -1; + while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow) + { + under_this_window = under_this_window->ParentWindow; + offset = 0; + } + start_idx = FindWindowFocusIndex(under_this_window) + offset; + } + for (int i = start_idx; i >= 0; i--) + { + // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. + ImGuiWindow* window = g.WindowsFocusOrder[i]; + if (window == ignore_window || !window->WasActive) + continue; + if (filter_viewport != NULL && window->Viewport != filter_viewport) + continue; + if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) + { + // FIXME-DOCK: When ImGuiFocusRequestFlags_RestoreFocusedChild is set... + // This is failing (lagging by one frame) for docked windows. + // If A and B are docked into window and B disappear, at the NewFrame() call site window->NavLastChildNavWindow will still point to B. + // We might leverage the tab order implicitly stored in window->DockNodeAsHost->TabBar (essentially the 'most_recently_selected_tab' code in tab bar will do that but on next update) + // to tell which is the "previous" window. Or we may leverage 'LastFrameFocused/LastFrameJustFocused' and have this function handle child window itself? + FocusWindow(window, flags); + return; + } + } + FocusWindow(NULL, flags); +} + //----------------------------------------------------------------------------- // [SECTION] KEYBOARD/GAMEPAD NAVIGATION //----------------------------------------------------------------------------- @@ -14197,14 +14243,12 @@ static void ImGui::NavUpdateCreateWrappingRequest() NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags); } -static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) +// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) +// Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmatically. +// If you want a window to never be focused, you may use the e.g. NoInputs flag. +bool ImGui::IsWindowNavFocusable(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - IM_UNUSED(g); - int order = window->FocusOrder; - IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking) - IM_ASSERT(g.WindowsFocusOrder[order] == window); - return order; + return window->WasActive && window == window->RootWindow && !(window->Flags & ImGuiWindowFlags_NoNavFocus); } static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // FIXME-OPT O(N) @@ -14328,15 +14372,16 @@ static void ImGui::NavUpdateWindowing() // Keyboard: Press and Release ALT to toggle menu layer const ImGuiKey windowing_toggle_keys[] = { ImGuiKey_LeftAlt, ImGuiKey_RightAlt }; bool windowing_toggle_layer_start = false; - for (ImGuiKey windowing_toggle_key : windowing_toggle_keys) - if (nav_keyboard_active && IsKeyPressed(windowing_toggle_key, 0, ImGuiKeyOwner_NoOwner)) - { - windowing_toggle_layer_start = true; - g.NavWindowingToggleLayer = true; - g.NavWindowingToggleKey = windowing_toggle_key; - g.NavInputSource = ImGuiInputSource_Keyboard; - break; - } + if (g.NavWindow != NULL && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) + for (ImGuiKey windowing_toggle_key : windowing_toggle_keys) + if (nav_keyboard_active && IsKeyPressed(windowing_toggle_key, 0, ImGuiKeyOwner_NoOwner)) + { + windowing_toggle_layer_start = true; + g.NavWindowingToggleLayer = true; + g.NavWindowingToggleKey = windowing_toggle_key; + g.NavInputSource = ImGuiInputSource_Keyboard; + break; + } if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard) { // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370) @@ -14493,7 +14538,6 @@ void ImGui::NavUpdateWindowingOverlay() PopStyleVar(); } - //----------------------------------------------------------------------------- // [SECTION] DRAG AND DROP //----------------------------------------------------------------------------- @@ -15102,7 +15146,6 @@ void ImGui::LogButtons() LogToClipboard(); } - //----------------------------------------------------------------------------- // [SECTION] SETTINGS //----------------------------------------------------------------------------- @@ -15493,7 +15536,6 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl } } - //----------------------------------------------------------------------------- // [SECTION] LOCALIZATION //----------------------------------------------------------------------------- @@ -15505,7 +15547,6 @@ void ImGui::LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count) g.LocalizationTable[entries[n].Key] = entries[n].Text; } - //----------------------------------------------------------------------------- // [SECTION] VIEWPORTS, PLATFORM WINDOWS //----------------------------------------------------------------------------- @@ -22371,7 +22412,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open) void ImGui::DebugTextUnformattedWithLocateItem(const char* line_begin, const char* line_end) { TextUnformatted(line_begin, line_end); - if (!IsItemHovered()) + if (!IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) return; ImGuiContext& g = *GImGui; ImRect text_rect = g.LastItemData.Rect; diff --git a/source/thirdparty/imgui/imgui.h b/source/thirdparty/imgui/imgui.h index 4a3d2f5f..e76157cf 100644 --- a/source/thirdparty/imgui/imgui.h +++ b/source/thirdparty/imgui/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (headers) // Help: @@ -28,8 +28,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.91.6" -#define IMGUI_VERSION_NUM 19160 +#define IMGUI_VERSION "1.91.7 WIP" +#define IMGUI_VERSION_NUM 19164 #define IMGUI_HAS_TABLE #define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch @@ -141,6 +141,7 @@ Index of this file: #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #endif @@ -700,6 +701,7 @@ namespace ImGui // Widgets: List Boxes // - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label. + // - If you don't need a label you can probably simply use BeginChild() with the ImGuiChildFlags_FrameStyle flag for the same result. // - You can submit contents and manage your selection state however you want it, by creating e.g. Selectable() or any other items. // - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created. // - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth @@ -1457,6 +1459,7 @@ enum ImGuiDataType_ ImGuiDataType_Float, // float ImGuiDataType_Double, // double ImGuiDataType_Bool, // bool (provided for user convenience, not supported by scalar widgets) + ImGuiDataType_String, // char* (provided for user convenience, not supported by scalar widgets) ImGuiDataType_COUNT }; @@ -1864,6 +1867,7 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max. Only supported by DragXXX() functions for now. ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it. + ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic. ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange, ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. }; @@ -2806,6 +2810,7 @@ struct ImGuiListClipper // - It is important that we are keeping those disabled by default so they don't leak in user space. // - This is in order to allow user enabling implicit cast operators between ImVec2/ImVec4 and their own types (using IM_VEC2_CLASS_EXTRA in imconfig.h) // - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including this file (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4. +// - We intentionally provide ImVec2*float but not float*ImVec2: this is rare enough and we want to reduce the surface for possible user mistake. #ifdef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED IM_MSVC_RUNTIME_CHECKS_OFF @@ -3007,7 +3012,7 @@ struct ImGuiSelectionBasicStorage IMGUI_API void Clear(); // Clear selection IMGUI_API void Swap(ImGuiSelectionBasicStorage& r); // Swap two selections IMGUI_API void SetItemSelected(ImGuiID id, bool selected); // Add/remove an item from selection (generally done by ApplyRequests() function) - IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiId id; while (selection.GetNextSelectedItem(&it, &id)) { ... }' + IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiID id; while (selection.GetNextSelectedItem(&it, &id)) { ... }' inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter. }; @@ -3359,7 +3364,7 @@ struct ImFontConfig unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure. float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future. float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered. - ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. + ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used. // [Internal] char Name[40]; // Name (strictly to ease debugging) diff --git a/source/thirdparty/imgui/imgui_draw.cpp b/source/thirdparty/imgui/imgui_draw.cpp index c8623729..09afefa1 100644 --- a/source/thirdparty/imgui/imgui_draw.cpp +++ b/source/thirdparty/imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (drawing and font code) /* @@ -67,13 +67,17 @@ Index of this file: #pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type +#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer +#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1 #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif //------------------------------------------------------------------------- @@ -105,13 +109,12 @@ namespace IMGUI_STB_NAMESPACE #pragma clang diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier #endif #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" // warning: this statement may fall through #endif #ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) @@ -2383,12 +2386,44 @@ ImFontConfig::ImFontConfig() GlyphMaxAdvanceX = FLT_MAX; RasterizerMultiply = 1.0f; RasterizerDensity = 1.0f; - EllipsisChar = (ImWchar)-1; + EllipsisChar = 0; } //----------------------------------------------------------------------------- // [SECTION] ImFontAtlas //----------------------------------------------------------------------------- +// - Default texture data encoded in ASCII +// - ImFontAtlas::ClearInputData() +// - ImFontAtlas::ClearTexData() +// - ImFontAtlas::ClearFonts() +// - ImFontAtlas::Clear() +// - ImFontAtlas::GetTexDataAsAlpha8() +// - ImFontAtlas::GetTexDataAsRGBA32() +// - ImFontAtlas::AddFont() +// - ImFontAtlas::AddFontDefault() +// - ImFontAtlas::AddFontFromFileTTF() +// - ImFontAtlas::AddFontFromMemoryTTF() +// - ImFontAtlas::AddFontFromMemoryCompressedTTF() +// - ImFontAtlas::AddFontFromMemoryCompressedBase85TTF() +// - ImFontAtlas::AddCustomRectRegular() +// - ImFontAtlas::AddCustomRectFontGlyph() +// - ImFontAtlas::CalcCustomRectUV() +// - ImFontAtlas::GetMouseCursorTexData() +// - ImFontAtlas::Build() +// - ImFontAtlasBuildMultiplyCalcLookupTable() +// - ImFontAtlasBuildMultiplyRectAlpha8() +// - ImFontAtlasBuildWithStbTruetype() +// - ImFontAtlasGetBuilderForStbTruetype() +// - ImFontAtlasUpdateConfigDataPointers() +// - ImFontAtlasBuildSetupFont() +// - ImFontAtlasBuildPackCustomRects() +// - ImFontAtlasBuildRender8bppRectFromString() +// - ImFontAtlasBuildRender32bppRectFromString() +// - ImFontAtlasBuildRenderDefaultTexData() +// - ImFontAtlasBuildRenderLinesTexData() +// - ImFontAtlasBuildInit() +// - ImFontAtlasBuildFinish() +//----------------------------------------------------------------------------- // A work of art lies ahead! (. = white layer, X = black layer, others are blank) // The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes. @@ -2570,9 +2605,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) // - We may support it better later and remove this rounding. new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels); - if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1) - new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar; - // Pointers to ConfigData and BuilderData are otherwise dangling ImFontAtlasUpdateConfigDataPointers(this); @@ -3333,6 +3365,16 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) //------------------------------------------------------------------------- // [SECTION] ImFontAtlas: glyph ranges helpers //------------------------------------------------------------------------- +// - GetGlyphRangesDefault() +// - GetGlyphRangesGreek() +// - GetGlyphRangesKorean() +// - GetGlyphRangesChineseFull() +// - GetGlyphRangesChineseSimplifiedCommon() +// - GetGlyphRangesJapanese() +// - GetGlyphRangesCyrillic() +// - GetGlyphRangesThai() +// - GetGlyphRangesVietnamese() +//----------------------------------------------------------------------------- // Retrieve list of range (2 int per range, values are inclusive) const ImWchar* ImFontAtlas::GetGlyphRangesDefault() @@ -3641,8 +3683,8 @@ ImFont::ImFont() { FontSize = 0.0f; FallbackAdvanceX = 0.0f; - FallbackChar = (ImWchar)-1; - EllipsisChar = (ImWchar)-1; + FallbackChar = 0; + EllipsisChar = 0; EllipsisWidth = EllipsisCharStep = 0.0f; EllipsisCharCount = 0; FallbackGlyph = NULL; @@ -3681,7 +3723,7 @@ static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_cha for (int n = 0; n < candidate_chars_count; n++) if (font->FindGlyphNoFallback(candidate_chars[n]) != NULL) return candidate_chars[n]; - return (ImWchar)-1; + return 0; } void ImFont::BuildLookupTable() @@ -3748,23 +3790,23 @@ void ImFont::BuildLookupTable() // Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. // FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots. - const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 }; + const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 }; const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E }; - if (EllipsisChar == (ImWchar)-1) + if (EllipsisChar == 0) EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars)); const ImWchar dot_char = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars)); - if (EllipsisChar != (ImWchar)-1) + if (EllipsisChar != 0) { EllipsisCharCount = 1; EllipsisWidth = EllipsisCharStep = FindGlyph(EllipsisChar)->X1; } - else if (dot_char != (ImWchar)-1) + else if (dot_char != 0) { - const ImFontGlyph* glyph = FindGlyph(dot_char); + const ImFontGlyph* dot_glyph = FindGlyph(dot_char); EllipsisChar = dot_char; EllipsisCharCount = 3; - EllipsisCharStep = (glyph->X1 - glyph->X0) + 1.0f; - EllipsisWidth = EllipsisCharStep * 3.0f - 1.0f; + EllipsisCharStep = (float)(int)(dot_glyph->X1 - dot_glyph->X0) + 1.0f; + EllipsisWidth = ImMax(dot_glyph->AdvanceX, dot_glyph->X0 + EllipsisCharStep * 3.0f - 1.0f); // FIXME: Slightly odd for normally mono-space fonts but since this is used for trailing contents. } } diff --git a/source/thirdparty/imgui/imgui_impl_sdl3.cpp b/source/thirdparty/imgui/imgui_impl_sdl3.cpp index 7e5a5b08..209738bd 100644 --- a/source/thirdparty/imgui/imgui_impl_sdl3.cpp +++ b/source/thirdparty/imgui/imgui_impl_sdl3.cpp @@ -25,7 +25,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-09-11: (Docking) Added support for viewport->ParentViewportId field to support parenting at OS level. (#7973) // 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten. // 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807) @@ -593,6 +593,11 @@ bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* rendere return ImGui_ImplSDL3_Init(window, renderer, nullptr); } +bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window) +{ + return ImGui_ImplSDL3_Init(window, nullptr, nullptr); +} + bool ImGui_ImplSDL3_InitForOther(SDL_Window* window) { return ImGui_ImplSDL3_Init(window, nullptr, nullptr); diff --git a/source/thirdparty/imgui/imgui_impl_sdl3.h b/source/thirdparty/imgui/imgui_impl_sdl3.h index 4303ced4..b7ca404a 100644 --- a/source/thirdparty/imgui/imgui_impl_sdl3.h +++ b/source/thirdparty/imgui/imgui_impl_sdl3.h @@ -38,6 +38,7 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer); +IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window); IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame(); diff --git a/source/thirdparty/imgui/imgui_impl_sdlgpu3.cpp b/source/thirdparty/imgui/imgui_impl_sdlgpu3.cpp new file mode 100644 index 00000000..643e6d93 --- /dev/null +++ b/source/thirdparty/imgui/imgui_impl_sdlgpu3.cpp @@ -0,0 +1,619 @@ +// dear imgui: Renderer Backend for SDL_GPU +// This needs to be used along with the SDL3 Platform Backend + +// Implemented features: +// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID. +// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification. +// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// Learn about Dear ImGui: +// - FAQ https://dearimgui.com/faq +// - Getting Started https://dearimgui.com/getting-started +// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). +// - Introduction, links and more at the top of imgui.cpp + +// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app. +// - Unlike other backends, the user must call the function Imgui_ImplSDLGPU3_PrepareDrawData() BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU3_RenderDrawData. +// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info. + +// CHANGELOG +// 2025-01-09: SDL_Gpu: Added the SDL_GPU3 backend. + +#include "imgui.h" +#ifndef IMGUI_DISABLE +#include "imgui_impl_sdlgpu3.h" +#include "imgui_impl_sdlgpu3_shaders.h" + +// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData() +struct ImGui_ImplSDLGPU3_FrameData +{ + SDL_GPUBuffer* VertexBuffer = nullptr; + SDL_GPUBuffer* IndexBuffer = nullptr; + uint32_t VertexBufferSize = 0; + uint32_t IndexBufferSize = 0; +}; + +// SDL_GPU Data +struct ImGui_ImplSDLGPU3_Data +{ + ImGui_ImplSDLGPU3_InitInfo GPUInitInfo; + + // Graphics pipeline & shaders + SDL_GPUShader* VertexShader = nullptr; + SDL_GPUShader* FragmentShader = nullptr; + SDL_GPUGraphicsPipeline* Pipeline = nullptr; + + // Font data + SDL_GPUSampler* FontSampler = nullptr; + SDL_GPUTexture* FontTexture = nullptr; + SDL_GPUTextureSamplerBinding FontBinding = { nullptr, nullptr }; + + // Frame data for main window + ImGui_ImplSDLGPU3_FrameData MainWindowFrameData; +}; + +// Forward Declarations +static bool ImGui_ImplSDLGPU3_CreateDeviceObjects(); +static void ImGui_ImplSDLGPU3_DestroyDeviceObjects(); +static void ImGui_ImplSDLGPU3_DestroyFrameData(); + +//----------------------------------------------------------------------------- +// FUNCTIONS +//----------------------------------------------------------------------------- + +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support has never been tested. +static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; +} + +static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height) +{ + //ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + + // Bind graphics pipeline + SDL_BindGPUGraphicsPipeline(render_pass,pipeline); + + // Bind Vertex And Index Buffers + if (draw_data->TotalVtxCount > 0) + { + SDL_GPUBufferBinding vertex_buffer_binding = {}; + vertex_buffer_binding.buffer = fd->VertexBuffer; + vertex_buffer_binding.offset = 0; + SDL_GPUBufferBinding index_buffer_binding = {}; + index_buffer_binding.buffer = fd->IndexBuffer; + index_buffer_binding.offset = 0; + SDL_BindGPUVertexBuffers(render_pass,0,&vertex_buffer_binding,1); + SDL_BindGPUIndexBuffer(render_pass,&index_buffer_binding,sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT); + } + + // Setup viewport + SDL_GPUViewport viewport = {}; + viewport.x = 0; + viewport.y = 0; + viewport.w = (float)fb_width; + viewport.h = (float)fb_height; + viewport.min_depth = 0.0f; + viewport.min_depth = 1.0f; + SDL_SetGPUViewport(render_pass,&viewport); + + // Setup scale and translation + // Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. + struct UBO { float scale[2]; float translation[2]; } ubo; + ubo.scale[0] = 2.0f / draw_data->DisplaySize.x; + ubo.scale[1] = 2.0f / draw_data->DisplaySize.y; + ubo.translation[0] = -1.0f - draw_data->DisplayPos.x * ubo.scale[0]; + ubo.translation[1] = -1.0f - draw_data->DisplayPos.y * ubo.scale[1]; + SDL_PushGPUVertexUniformData(command_buffer, 0, &ubo, sizeof(UBO)); +} + +static void CreateOrResizeBuffer(SDL_GPUBuffer** buffer, uint32_t* old_size, uint32_t new_size, SDL_GPUBufferUsageFlags usage) +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + SDL_WaitForGPUIdle(v->GpuDevice); + SDL_ReleaseGPUBuffer(v->GpuDevice, *buffer); + + SDL_GPUBufferCreateInfo buffer_info = {}; + buffer_info.usage = usage; + buffer_info.size = new_size; + buffer_info.props = 0; + *buffer = SDL_CreateGPUBuffer(v->GpuDevice, &buffer_info); + *old_size = new_size; + IM_ASSERT(*buffer != nullptr && "Failed to create GPU Buffer, call SDL_GetError() for more information"); +} + +// SDL_GPU doesn't allow copy passes to occur while a render or compute pass is bound! +// The only way to allow a user to supply their own RenderPass (to render to a texture instead of the window for example), +// is to split the upload part of ImGui_ImplSDLGPU3_RenderDrawData() to another function that needs to be called by the user before rendering. +void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0) + return; + + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData; + + uint32_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); + uint32_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); + if (fd->VertexBuffer == nullptr || fd->VertexBufferSize < vertex_size) + CreateOrResizeBuffer(&fd->VertexBuffer, &fd->VertexBufferSize, vertex_size, SDL_GPU_BUFFERUSAGE_VERTEX); + if (fd->IndexBuffer == nullptr || fd->IndexBufferSize < index_size) + CreateOrResizeBuffer(&fd->IndexBuffer, &fd->IndexBufferSize, index_size, SDL_GPU_BUFFERUSAGE_INDEX); + + // FIXME: It feels like more code could be shared there. + SDL_GPUTransferBufferCreateInfo vertex_transferbuffer_info = {}; + vertex_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; + vertex_transferbuffer_info.size = vertex_size; + SDL_GPUTransferBufferCreateInfo index_transferbuffer_info = {}; + index_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; + index_transferbuffer_info.size = index_size; + + SDL_GPUTransferBuffer* vertex_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &vertex_transferbuffer_info); + IM_ASSERT(vertex_transferbuffer != nullptr && "Failed to create the vertex transfer buffer, call SDL_GetError() for more information"); + SDL_GPUTransferBuffer* index_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &index_transferbuffer_info); + IM_ASSERT(index_transferbuffer != nullptr && "Failed to create the index transfer buffer, call SDL_GetError() for more information"); + + ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer, true); + ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->GpuDevice, index_transferbuffer, true); + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* draw_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert)); + memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + vtx_dst += draw_list->VtxBuffer.Size; + idx_dst += draw_list->IdxBuffer.Size; + } + SDL_UnmapGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer); + SDL_UnmapGPUTransferBuffer(v->GpuDevice, index_transferbuffer); + + SDL_GPUTransferBufferLocation vertex_buffer_location = {}; + vertex_buffer_location.offset = 0; + vertex_buffer_location.transfer_buffer = vertex_transferbuffer; + SDL_GPUTransferBufferLocation index_buffer_location = {}; + index_buffer_location.offset = 0; + index_buffer_location.transfer_buffer = index_transferbuffer; + + SDL_GPUBufferRegion vertex_buffer_region = {}; + vertex_buffer_region.buffer = fd->VertexBuffer; + vertex_buffer_region.offset = 0; + vertex_buffer_region.size = vertex_size; + + SDL_GPUBufferRegion index_buffer_region = {}; + index_buffer_region.buffer = fd->IndexBuffer; + index_buffer_region.offset = 0; + index_buffer_region.size = index_size; + + SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer); + SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region,true); + SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region,true); + SDL_EndGPUCopyPass(copy_pass); + SDL_ReleaseGPUTransferBuffer(v->GpuDevice, index_transferbuffer); + SDL_ReleaseGPUTransferBuffer(v->GpuDevice, vertex_transferbuffer); +} + +void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if (fb_width <= 0 || fb_height <= 0) + return; + + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData; + + if (pipeline == nullptr) + pipeline = bd->Pipeline; + + ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height); + + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + // (Because we merged all buffers into a single one, we maintain our own offset into them) + int global_vtx_offset = 0; + int global_idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* draw_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++) + { + const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback != nullptr) + { + pcmd->UserCallback(draw_list, pcmd); + } + else + { + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); + ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); + + // Clamp to viewport as SDL_SetGPUScissor() won't accept values that are off bounds + if (clip_min.x < 0.0f) { clip_min.x = 0.0f; } + if (clip_min.y < 0.0f) { clip_min.y = 0.0f; } + if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; } + if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; } + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; + + // Apply scissor/clipping rectangle + SDL_Rect scissor_rect = {}; + scissor_rect.x = (int)clip_min.x; + scissor_rect.y = (int)clip_min.y; + scissor_rect.w = (int)(clip_max.x - clip_min.x); + scissor_rect.h = (int)(clip_max.y - clip_min.y); + SDL_SetGPUScissor(render_pass,&scissor_rect); + + // Bind DescriptorSet with font or user texture + SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1); + + // Draw + SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); + } + } + global_idx_offset += draw_list->IdxBuffer.Size; + global_vtx_offset += draw_list->VtxBuffer.Size; + } + + // Note: at this point both SDL_SetGPUViewport() and SDL_SetGPUScissor() have been called. + // Our last values will leak into user/application rendering if you forgot to call SDL_SetGPUViewport() and SDL_SetGPUScissor() yourself to explicitly set that state + // In theory we should aim to backup/restore those values but I am not sure this is possible. + // We perform a call to SDL_SetGPUScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644) + SDL_Rect scissor_rect { 0, 0, fb_width, fb_height }; + SDL_SetGPUScissor(render_pass, &scissor_rect); +} + +bool ImGui_ImplSDLGPU3_CreateFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + // Destroy existing texture (if any) + if (bd->FontTexture) + { + SDL_WaitForGPUIdle(v->GpuDevice); + ImGui_ImplSDLGPU3_DestroyFontsTexture(); + } + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + uint32_t upload_size = width * height * 4 * sizeof(char); + + // Create the Image: + { + SDL_GPUTextureCreateInfo texture_info = {}; + texture_info.type = SDL_GPU_TEXTURETYPE_2D; + texture_info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM; + texture_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER; + texture_info.width = width; + texture_info.height = height; + texture_info.layer_count_or_depth = 1; + texture_info.num_levels = 1; + texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1; + + bd->FontTexture = SDL_CreateGPUTexture(v->GpuDevice, &texture_info); + IM_ASSERT(bd->FontTexture && "Failed to create font texture, call SDL_GetError() for more info"); + } + + // Assign the texture to the TextureSamplerBinding + bd->FontBinding.texture = bd->FontTexture; + + // Create all the upload structures and upload: + { + SDL_GPUTransferBufferCreateInfo font_transferbuffer_info = {}; + font_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; + font_transferbuffer_info.size = upload_size; + + SDL_GPUTransferBuffer* font_transferbuffer = SDL_CreateGPUTransferBuffer(v->GpuDevice, &font_transferbuffer_info); + IM_ASSERT(font_transferbuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information"); + + void* texture_ptr = SDL_MapGPUTransferBuffer(v->GpuDevice, font_transferbuffer, false); + memcpy(texture_ptr, pixels, upload_size); + SDL_UnmapGPUTransferBuffer(v->GpuDevice, font_transferbuffer); + + SDL_GPUTextureTransferInfo font_transfer_info = {}; + font_transfer_info.offset = 0; + font_transfer_info.transfer_buffer = font_transferbuffer; + + SDL_GPUTextureRegion font_texture_region = {}; + font_texture_region.texture = bd->FontTexture; + font_texture_region.w = width; + font_texture_region.h = height; + font_texture_region.d = 1; + + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->GpuDevice); + SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd); + SDL_UploadToGPUTexture(copy_pass, &font_transfer_info, &font_texture_region, false); + SDL_EndGPUCopyPass(copy_pass); + SDL_SubmitGPUCommandBuffer(cmd); + SDL_ReleaseGPUTransferBuffer(v->GpuDevice, font_transferbuffer); + } + + // Store our identifier + io.Fonts->SetTexID((ImTextureID)&bd->FontBinding); + + return true; +} + +// You probably never need to call this, as it is called by ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_Shutdown(). +void ImGui_ImplSDLGPU3_DestroyFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + if (bd->FontTexture) + { + SDL_ReleaseGPUTexture(v->GpuDevice, bd->FontTexture); + bd->FontBinding.texture = nullptr; + bd->FontTexture = nullptr; + } + io.Fonts->SetTexID(0); +} + +static void Imgui_ImplSDLGPU3_CreateShaders() +{ + // Create the shader modules + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + const char* driver = SDL_GetGPUDeviceDriver(v->GpuDevice); + + SDL_GPUShaderCreateInfo vertex_shader_info = {}; + vertex_shader_info.entrypoint = "main"; + vertex_shader_info.stage = SDL_GPU_SHADERSTAGE_VERTEX; + vertex_shader_info.num_uniform_buffers = 1; + vertex_shader_info.num_storage_buffers = 0; + vertex_shader_info.num_storage_textures = 0; + vertex_shader_info.num_samplers = 0; + + SDL_GPUShaderCreateInfo fragment_shader_info = {}; + fragment_shader_info.entrypoint = "main"; + fragment_shader_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT; + fragment_shader_info.num_samplers = 1; + fragment_shader_info.num_storage_buffers = 0; + fragment_shader_info.num_storage_textures = 0; + fragment_shader_info.num_uniform_buffers = 0; + + if (strcmp(driver, "vulkan") == 0) + { + vertex_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV; + vertex_shader_info.code = spirv_vertex; + vertex_shader_info.code_size = sizeof(spirv_vertex); + fragment_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV; + fragment_shader_info.code = spirv_fragment; + fragment_shader_info.code_size = sizeof(spirv_fragment); + } + else if (strcmp(driver, "direct3d12") == 0) + { + vertex_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC; + vertex_shader_info.code = dxbc_vertex; + vertex_shader_info.code_size = sizeof(dxbc_vertex); + fragment_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC; + fragment_shader_info.code = dxbc_fragment; + fragment_shader_info.code_size = sizeof(dxbc_fragment); + } +#ifdef __APPLE__ + else + { + vertex_shader_info.entrypoint = "main0"; + vertex_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB; + vertex_shader_info.code = metallib_vertex; + vertex_shader_info.code_size = sizeof(metallib_vertex); + fragment_shader_info.entrypoint = "main0"; + fragment_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB; + fragment_shader_info.code = metallib_fragment; + fragment_shader_info.code_size = sizeof(metallib_fragment); + } +#endif + bd->VertexShader = SDL_CreateGPUShader(v->GpuDevice, &vertex_shader_info); + bd->FragmentShader = SDL_CreateGPUShader(v->GpuDevice, &fragment_shader_info); + IM_ASSERT(bd->VertexShader != nullptr && "Failed to create vertex shader, call SDL_GetError() for more information"); + IM_ASSERT(bd->FragmentShader != nullptr && "Failed to create fragment shader, call SDL_GetError() for more information"); +} + +static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + Imgui_ImplSDLGPU3_CreateShaders(); + + SDL_GPUVertexBufferDescription vertex_buffer_desc[1]; + vertex_buffer_desc[0].slot = 0; + vertex_buffer_desc[0].input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX; + vertex_buffer_desc[0].instance_step_rate = 0; + vertex_buffer_desc[0].pitch = sizeof(ImDrawVert); + + SDL_GPUVertexAttribute vertex_attributes[3]; + vertex_attributes[0].buffer_slot = 0; + vertex_attributes[0].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2; + vertex_attributes[0].location = 0; + vertex_attributes[0].offset = offsetof(ImDrawVert,pos); + + vertex_attributes[1].buffer_slot = 0; + vertex_attributes[1].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2; + vertex_attributes[1].location = 1; + vertex_attributes[1].offset = offsetof(ImDrawVert, uv); + + vertex_attributes[2].buffer_slot = 0; + vertex_attributes[2].format = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM; + vertex_attributes[2].location = 2; + vertex_attributes[2].offset = offsetof(ImDrawVert, col); + + SDL_GPUVertexInputState vertex_input_state = {}; + vertex_input_state.num_vertex_attributes = 3; + vertex_input_state.vertex_attributes = vertex_attributes; + vertex_input_state.num_vertex_buffers = 1; + vertex_input_state.vertex_buffer_descriptions = vertex_buffer_desc; + + SDL_GPURasterizerState rasterizer_state = {}; + rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL; + rasterizer_state.cull_mode = SDL_GPU_CULLMODE_NONE; + rasterizer_state.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE; + rasterizer_state.enable_depth_bias = false; + rasterizer_state.enable_depth_clip = false; + + SDL_GPUMultisampleState multisample_state = {}; + multisample_state.sample_count = v->MSAASamples; + multisample_state.enable_mask = false; + + SDL_GPUDepthStencilState depth_stencil_state = {}; + depth_stencil_state.enable_depth_test = false; + depth_stencil_state.enable_depth_write = false; + depth_stencil_state.enable_stencil_test = false; + + SDL_GPUColorTargetBlendState blend_state = {}; + blend_state.enable_blend = true; + blend_state.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA; + blend_state.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA; + blend_state.color_blend_op = SDL_GPU_BLENDOP_ADD; + blend_state.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE; + blend_state.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA; + blend_state.alpha_blend_op = SDL_GPU_BLENDOP_ADD; + blend_state.color_write_mask = SDL_GPU_COLORCOMPONENT_R | SDL_GPU_COLORCOMPONENT_G | SDL_GPU_COLORCOMPONENT_B | SDL_GPU_COLORCOMPONENT_A; + + SDL_GPUColorTargetDescription color_target_desc[1]; + color_target_desc[0].format = v->ColorTargetFormat; + color_target_desc[0].blend_state = blend_state; + + SDL_GPUGraphicsPipelineTargetInfo target_info = {}; + target_info.num_color_targets = 1; + target_info.color_target_descriptions = color_target_desc; + target_info.has_depth_stencil_target = false; + + SDL_GPUGraphicsPipelineCreateInfo pipeline_info = {}; + pipeline_info.vertex_shader = bd->VertexShader; + pipeline_info.fragment_shader = bd->FragmentShader; + pipeline_info.vertex_input_state = vertex_input_state; + pipeline_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST; + pipeline_info.rasterizer_state = rasterizer_state; + pipeline_info.multisample_state = multisample_state; + pipeline_info.depth_stencil_state = depth_stencil_state; + pipeline_info.target_info = target_info; + + bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->GpuDevice, &pipeline_info); + IM_ASSERT(bd->Pipeline != nullptr && "Failed to create graphics pipeline, call SDL_GetError() for more information"); +} + +bool ImGui_ImplSDLGPU3_CreateDeviceObjects() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + if (!bd->FontSampler) + { + // Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling. + SDL_GPUSamplerCreateInfo sampler_info = {}; + sampler_info.min_filter = SDL_GPU_FILTER_LINEAR; + sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR; + sampler_info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR; + sampler_info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; + sampler_info.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; + sampler_info.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE; + sampler_info.mip_lod_bias = 0.0f; + sampler_info.min_lod = -1000.0f; + sampler_info.max_lod = 1000.0f; + sampler_info.enable_anisotropy = true; + sampler_info.max_anisotropy = 1.0f; + sampler_info.enable_compare = false; + + bd->FontSampler = SDL_CreateGPUSampler(v->GpuDevice, &sampler_info); + bd->FontBinding.sampler = bd->FontSampler; + IM_ASSERT(bd->FontSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information"); + } + + ImGui_ImplSDLGPU3_CreateGraphicsPipeline(); + + return true; +} + +void ImGui_ImplSDLGPU3_DestroyFrameData() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.VertexBuffer); + SDL_ReleaseGPUBuffer(v->GpuDevice, bd->MainWindowFrameData.IndexBuffer); + bd->MainWindowFrameData.VertexBuffer = nullptr; + bd->MainWindowFrameData.IndexBuffer = nullptr; + bd->MainWindowFrameData.VertexBufferSize = 0; + bd->MainWindowFrameData.IndexBufferSize = 0; +} + +void ImGui_ImplSDLGPU3_DestroyDeviceObjects() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + ImGui_ImplSDLGPU3_InitInfo* v = &bd->GPUInitInfo; + + ImGui_ImplSDLGPU3_DestroyFrameData(); + ImGui_ImplSDLGPU3_DestroyFontsTexture(); + + if (bd->VertexShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->VertexShader); bd->VertexShader = nullptr;} + if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->GpuDevice, bd->FragmentShader); bd->FragmentShader = nullptr;} + if (bd->FontSampler) { SDL_ReleaseGPUSampler(v->GpuDevice, bd->FontSampler); bd->FontSampler = nullptr;} + if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->GpuDevice, bd->Pipeline); bd->Pipeline = nullptr;} +} + +bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info) +{ + ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); + IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); + + // Setup backend capabilities flags + ImGui_ImplSDLGPU3_Data* bd = IM_NEW(ImGui_ImplSDLGPU3_Data)(); + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_sdlgpu3"; + io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. + + IM_ASSERT(info->GpuDevice != nullptr); + IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID); + + bd->GPUInitInfo = *info; + + ImGui_ImplSDLGPU3_CreateDeviceObjects(); + + return true; +} + +void ImGui_ImplSDLGPU3_Shutdown() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); + ImGuiIO& io = ImGui::GetIO(); + + ImGui_ImplSDLGPU3_DestroyDeviceObjects(); + io.BackendRendererName = nullptr; + io.BackendRendererUserData = nullptr; + io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset; + IM_DELETE(bd); +} + +void ImGui_ImplSDLGPU3_NewFrame() +{ + ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData(); + IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLGPU3_Init()?"); + + if (!bd->FontTexture) + ImGui_ImplSDLGPU3_CreateFontsTexture(); +} + +#endif // #ifndef IMGUI_DISABLE diff --git a/source/thirdparty/imgui/imgui_impl_sdlgpu3.h b/source/thirdparty/imgui/imgui_impl_sdlgpu3.h new file mode 100644 index 00000000..72713fb5 --- /dev/null +++ b/source/thirdparty/imgui/imgui_impl_sdlgpu3.h @@ -0,0 +1,48 @@ +// dear imgui: Renderer Backend for SDL_GPU +// This needs to be used along with the SDL3 Platform Backend + +// Implemented features: +// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID. +// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// Missing features: +// [ ] Renderer: Multi-viewport support (multiple windows). + +// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification. +// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ + +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. +// Learn about Dear ImGui: +// - FAQ https://dearimgui.com/faq +// - Getting Started https://dearimgui.com/getting-started +// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). +// - Introduction, links and more at the top of imgui.cpp + +// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app. +// - Unline other backends, the user must call the function Imgui_ImplSDLGPU_PrepareDrawData BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData. +// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info. + +#pragma once +#include "imgui.h" // IMGUI_IMPL_API +#ifndef IMGUI_DISABLE +#include + +// Initialization data, for ImGui_ImplSDLGPU_Init() +// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value +struct ImGui_ImplSDLGPU3_InitInfo +{ + SDL_GPUDevice* GpuDevice = nullptr; + SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID; + SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1; +}; + +// Follow "Getting Started" link and check examples/ folder to learn about using backends! +IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info); +IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame(); +IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer); +IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr); +IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_CreateFontsTexture(); +IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture(); + +#endif // #ifndef IMGUI_DISABLE diff --git a/source/thirdparty/imgui/imgui_impl_sdlgpu3_shaders.h b/source/thirdparty/imgui/imgui_impl_sdlgpu3_shaders.h new file mode 100644 index 00000000..f792aa6a --- /dev/null +++ b/source/thirdparty/imgui/imgui_impl_sdlgpu3_shaders.h @@ -0,0 +1,372 @@ +#pragma once +#ifndef IMGUI_DISABLE +#include + +// Data exported using +// misc/fonts/binary_to_compressed_c.exe -u8 -nocompress filename symbolname >filename.h +// With some manual pasting. + +// Check sdlgpu3/ folder for the shaders' source code and instruction on how to build them +const uint8_t spirv_vertex[1732] = { + 3,2,35,7,0,0,1,0,11,0,13,0,55,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,10,0,0,0,0,0,4,0,0,0,109, + 97,105,110,0,0,0,0,11,0,0,0,15,0,0,0,21,0,0,0,30,0,0,0,31,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101, + 95,100,105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0, + 0,0,0,5,0,3,0,9,0,0,0,0,0,0,0,6,0,5,0,9,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,9,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,11,0,0,0,79,117,116,0,5,0,4,0,15,0,0,0,97,67,111,108,111,114, + 0,0,5,0,3,0,21,0,0,0,97,85,86,0,5,0,6,0,28,0,0,0,103,108,95,80,101,114,86,101,114,116,101,120,0,0,0,0,6,0,6,0,28,0,0,0,0,0,0,0,103,108,95,80,111,115,105,116,105,111,110,0,6,0,7,0,28, + 0,0,0,1,0,0,0,103,108,95,80,111,105,110,116,83,105,122,101,0,0,0,0,6,0,7,0,28,0,0,0,2,0,0,0,103,108,95,67,108,105,112,68,105,115,116,97,110,99,101,0,6,0,7,0,28,0,0,0,3,0,0,0,103,108, + 95,67,117,108,108,68,105,115,116,97,110,99,101,0,5,0,3,0,30,0,0,0,0,0,0,0,5,0,4,0,31,0,0,0,97,80,111,115,0,0,0,0,5,0,6,0,33,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0, + 0,0,6,0,5,0,33,0,0,0,0,0,0,0,117,83,99,97,108,101,0,0,6,0,6,0,33,0,0,0,1,0,0,0,117,84,114,97,110,115,108,97,116,101,0,0,5,0,3,0,35,0,0,0,112,99,0,0,71,0,4,0,11,0,0,0,30,0,0,0,0,0,0, + 0,71,0,4,0,15,0,0,0,30,0,0,0,2,0,0,0,71,0,4,0,21,0,0,0,30,0,0,0,1,0,0,0,71,0,3,0,28,0,0,0,2,0,0,0,72,0,5,0,28,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,72,0,5,0,28,0,0,0,1,0,0,0,11,0,0,0,1,0, + 0,0,72,0,5,0,28,0,0,0,2,0,0,0,11,0,0,0,3,0,0,0,72,0,5,0,28,0,0,0,3,0,0,0,11,0,0,0,4,0,0,0,71,0,4,0,31,0,0,0,30,0,0,0,0,0,0,0,71,0,3,0,33,0,0,0,2,0,0,0,72,0,5,0,33,0,0,0,0,0,0,0,35, + 0,0,0,0,0,0,0,72,0,5,0,33,0,0,0,1,0,0,0,35,0,0,0,8,0,0,0,71,0,4,0,35,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,35,0,0,0,34,0,0,0,1,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6, + 0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,23,0,4,0,8,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,9,0,0,0,7,0,0,0,8,0,0,0,32,0,4,0,10,0,0,0,3,0,0,0,9,0,0,0,59,0,4,0,10,0,0,0,11,0,0,0,3,0,0, + 0,21,0,4,0,12,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,12,0,0,0,13,0,0,0,0,0,0,0,32,0,4,0,14,0,0,0,1,0,0,0,7,0,0,0,59,0,4,0,14,0,0,0,15,0,0,0,1,0,0,0,32,0,4,0,17,0,0,0,3,0,0,0,7,0,0,0,43,0, + 4,0,12,0,0,0,19,0,0,0,1,0,0,0,32,0,4,0,20,0,0,0,1,0,0,0,8,0,0,0,59,0,4,0,20,0,0,0,21,0,0,0,1,0,0,0,32,0,4,0,23,0,0,0,3,0,0,0,8,0,0,0,21,0,4,0,25,0,0,0,32,0,0,0,0,0,0,0,43,0,4,0,25, + 0,0,0,26,0,0,0,1,0,0,0,28,0,4,0,27,0,0,0,6,0,0,0,26,0,0,0,30,0,6,0,28,0,0,0,7,0,0,0,6,0,0,0,27,0,0,0,27,0,0,0,32,0,4,0,29,0,0,0,3,0,0,0,28,0,0,0,59,0,4,0,29,0,0,0,30,0,0,0,3,0,0,0, + 59,0,4,0,20,0,0,0,31,0,0,0,1,0,0,0,30,0,4,0,33,0,0,0,8,0,0,0,8,0,0,0,32,0,4,0,34,0,0,0,2,0,0,0,33,0,0,0,59,0,4,0,34,0,0,0,35,0,0,0,2,0,0,0,32,0,4,0,36,0,0,0,2,0,0,0,8,0,0,0,43,0,4, + 0,6,0,0,0,43,0,0,0,0,0,0,0,43,0,4,0,6,0,0,0,44,0,0,0,0,0,128,63,43,0,4,0,6,0,0,0,49,0,0,0,0,0,128,191,32,0,4,0,50,0,0,0,3,0,0,0,6,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248, + 0,2,0,5,0,0,0,61,0,4,0,7,0,0,0,16,0,0,0,15,0,0,0,65,0,5,0,17,0,0,0,18,0,0,0,11,0,0,0,13,0,0,0,62,0,3,0,18,0,0,0,16,0,0,0,61,0,4,0,8,0,0,0,22,0,0,0,21,0,0,0,65,0,5,0,23,0,0,0,24,0,0, + 0,11,0,0,0,19,0,0,0,62,0,3,0,24,0,0,0,22,0,0,0,61,0,4,0,8,0,0,0,32,0,0,0,31,0,0,0,65,0,5,0,36,0,0,0,37,0,0,0,35,0,0,0,13,0,0,0,61,0,4,0,8,0,0,0,38,0,0,0,37,0,0,0,133,0,5,0,8,0,0,0, + 39,0,0,0,32,0,0,0,38,0,0,0,65,0,5,0,36,0,0,0,40,0,0,0,35,0,0,0,19,0,0,0,61,0,4,0,8,0,0,0,41,0,0,0,40,0,0,0,129,0,5,0,8,0,0,0,42,0,0,0,39,0,0,0,41,0,0,0,81,0,5,0,6,0,0,0,45,0,0,0,42, + 0,0,0,0,0,0,0,81,0,5,0,6,0,0,0,46,0,0,0,42,0,0,0,1,0,0,0,80,0,7,0,7,0,0,0,47,0,0,0,45,0,0,0,46,0,0,0,43,0,0,0,44,0,0,0,65,0,5,0,17,0,0,0,48,0,0,0,30,0,0,0,13,0,0,0,62,0,3,0,48,0,0, + 0,47,0,0,0,65,0,6,0,50,0,0,0,51,0,0,0,30,0,0,0,13,0,0,0,26,0,0,0,61,0,4,0,6,0,0,0,52,0,0,0,51,0,0,0,133,0,5,0,6,0,0,0,53,0,0,0,52,0,0,0,49,0,0,0,65,0,6,0,50,0,0,0,54,0,0,0,30,0,0,0, + 13,0,0,0,26,0,0,0,62,0,3,0,54,0,0,0,53,0,0,0,253,0,1,0,56,0,1,0, +}; +const uint8_t spirv_fragment[844] = { + 3,2,35,7,0,0,1,0,11,0,13,0,30,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,7,0,4,0,0,0,4,0,0,0,109,97, + 105,110,0,0,0,0,9,0,0,0,13,0,0,0,16,0,3,0,4,0,0,0,7,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,95,100, + 105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,0,0,0,5, + 0,4,0,9,0,0,0,102,67,111,108,111,114,0,0,5,0,3,0,11,0,0,0,0,0,0,0,6,0,5,0,11,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,11,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,13,0,0,0,73,110,0,0,5, + 0,5,0,22,0,0,0,115,84,101,120,116,117,114,101,0,0,0,0,71,0,4,0,9,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,13,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,34,0, + 0,0,2,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,32,0,4,0,8,0,0,0,3,0,0,0,7,0,0,0,59,0,4,0,8,0,0,0,9,0,0,0,3,0,0,0,23, + 0,4,0,10,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,11,0,0,0,7,0,0,0,10,0,0,0,32,0,4,0,12,0,0,0,1,0,0,0,11,0,0,0,59,0,4,0,12,0,0,0,13,0,0,0,1,0,0,0,21,0,4,0,14,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0, + 14,0,0,0,15,0,0,0,0,0,0,0,32,0,4,0,16,0,0,0,1,0,0,0,7,0,0,0,25,0,9,0,19,0,0,0,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,27,0,3,0,20,0,0,0,19,0,0,0,32,0,4,0,21,0,0,0,0, + 0,0,0,20,0,0,0,59,0,4,0,21,0,0,0,22,0,0,0,0,0,0,0,43,0,4,0,14,0,0,0,24,0,0,0,1,0,0,0,32,0,4,0,25,0,0,0,1,0,0,0,10,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,0,2,0,5,0,0,0,65, + 0,5,0,16,0,0,0,17,0,0,0,13,0,0,0,15,0,0,0,61,0,4,0,7,0,0,0,18,0,0,0,17,0,0,0,61,0,4,0,20,0,0,0,23,0,0,0,22,0,0,0,65,0,5,0,25,0,0,0,26,0,0,0,13,0,0,0,24,0,0,0,61,0,4,0,10,0,0,0,27,0, + 0,0,26,0,0,0,87,0,5,0,7,0,0,0,28,0,0,0,23,0,0,0,27,0,0,0,133,0,5,0,7,0,0,0,29,0,0,0,18,0,0,0,28,0,0,0,62,0,3,0,9,0,0,0,29,0,0,0,253,0,1,0,56,0,1,0, +}; + +const uint8_t dxbc_vertex[1064] = { + 68,88,66,67,32,50,127,204,241,196,165,104,216,114,216,116,220,164,29,45,1,0,0,0,40,4,0,0,5,0,0,0,52,0,0,0,136,1,0,0,236,1,0,0,92,2,0,0,140,3,0,0,82,68,69,70,76,1,0,0,1,0,0,0,116,0, + 0,0,1,0,0,0,60,0,0,0,1,5,254,255,0,5,0,0,34,1,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,1,0,0,0,1,0,0,0,0,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,171,171,100,0,0,0,2,0,0,0,140,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,8,0,0,0,2,0,0,0,240,0,0, + 0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,20,1,0,0,8,0,0,0,8,0,0,0,2,0,0,0,240,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,112,99,95,117,83,99,97, + 108,101,0,102,108,111,97,116,50,0,171,171,171,1,0,3,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,112,99,95,117,84,114,97,110,115,108,97,116,101,0,77,105,99,114, + 111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,171,73,83,71,78,92,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,3,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,80,0,0,0,2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,15,15,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83, + 71,78,104,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,12,0,0,89,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,15,0,0, + 0,84,69,88,67,79,79,82,68,0,83,86,95,80,111,115,105,116,105,111,110,0,171,171,171,83,72,69,88,40,1,0,0,81,0,1,0,74,0,0,0,106,8,0,1,89,0,0,7,70,142,48,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,1,0,0,0,95,0,0,3,50,16,16,0,0,0,0,0,95,0,0,3,50,16,16,0,1,0,0,0,95,0,0,3,242,16,16,0,2,0,0,0,101,0,0,3,242,32,16,0,0,0,0,0,101,0,0,3,50,32,16,0,1,0,0,0,103,0,0,4,242,32,16,0,2, + 0,0,0,1,0,0,0,104,0,0,2,1,0,0,0,50,0,0,13,50,0,16,0,0,0,0,0,70,16,16,0,0,0,0,0,70,128,48,0,0,0,0,0,0,0,0,0,0,0,0,0,230,138,48,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,6,34,32,16,0,2,0,0,0, + 26,0,16,128,65,0,0,0,0,0,0,0,54,0,0,5,242,32,16,0,0,0,0,0,70,30,16,0,2,0,0,0,54,0,0,5,18,32,16,0,2,0,0,0,10,0,16,0,0,0,0,0,54,0,0,8,194,32,16,0,2,0,0,0,2,64,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,128,63,54,0,0,5,50,32,16,0,1,0,0,0,70,16,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,6,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +const uint8_t dxbc_fragment[744] = { + 68,88,66,67,235,219,43,109,38,151,39,223,98,41,193,28,215,98,67,110,1,0,0,0,232,2,0,0,5,0,0,0,52,0,0,0,12,1,0,0,88,1,0,0,140,1,0,0,76,2,0,0,82,68,69,70,208,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,60,0,0,0,1,5,255,255,0,5,0,0,167,0,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,140,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, + 0,0,2,0,0,0,0,0,0,0,158,0,0,0,2,0,0,0,5,0,0,0,4,0,0,0,255,255,255,255,0,0,0,0,1,0,0,0,12,0,0,0,2,0,0,0,0,0,0,0,95,115,84,101,120,116,117,114,101,95,115,97,109,112,108,101,114,0,115, + 84,101,120,116,117,114,101,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,73,83,71,78, + 68,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,15,0,0,56,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,71,78,44,0, + 0,0,1,0,0,0,8,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,83,86,95,84,97,114,103,101,116,0,171,171,83,72,69,88,184,0,0,0,81,0,0,0,46,0,0,0,106,8,0,1,90,0,0,6,70,110,48, + 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,88,24,0,7,70,126,48,0,0,0,0,0,0,0,0,0,0,0,0,0,85,85,0,0,2,0,0,0,98,16,0,3,242,16,16,0,0,0,0,0,98,16,0,3,50,16,16,0,1,0,0,0,101,0,0,3,242,32,16,0,0, + 0,0,0,104,0,0,2,1,0,0,0,69,0,0,11,242,0,16,0,0,0,0,0,70,16,16,0,1,0,0,0,70,126,32,0,0,0,0,0,0,0,0,0,0,96,32,0,0,0,0,0,0,0,0,0,56,0,0,7,242,32,16,0,0,0,0,0,70,14,16,0,0,0,0,0,70,30, + 16,0,0,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +#ifdef __APPLE__ +#include +#if TARGET_OS_MAC +const uint8_t metallib_vertex[3892] = { + 77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,52,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,32, + 14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,62,81,190,157,8,240,236,158,164,213,65,62,170,226,96,136,231,243,238,160,100, + 26,13,254,254,64,19,129,180,3,149,75,77,68,83,90,8,0,32,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,84, + 69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23, + 11,0,0,0,0,20,0,0,0,8,14,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,74,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73, + 6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136, + 32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,32, + 36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,34, + 8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218, + 192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29, + 202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135, + 119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160, + 7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161, + 13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104, + 3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8, + 4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,176,112,72, + 7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116, + 208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116, + 160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32, + 7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6, + 246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208, + 6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112, + 32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,160,48,0,0,8,0,0,0,4,0,0,0,0,0,10,64,98,131,64,81,166,1,0,128,44,16,0,11,0,0,0,50,30,152,16,25,17, + 76,144,140,9,38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,98,24,1,40,3,218,17,0,210,177,132,39,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136, + 67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204, + 120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194, + 97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120, + 135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129, + 29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104, + 7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225, + 29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1, + 30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152, + 129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59, + 212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224, + 14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120, + 7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119, + 248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,26,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152, + 6,100,208,82,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104, + 97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120, + 95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109, + 97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109, + 112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54, + 56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115, + 116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101, + 97,105,114,46,118,101,114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97, + 116,52,97,105,114,46,97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112, + 111,115,105,116,105,111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105, + 110,100,101,120,97,80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100, + 97,105,114,46,97,100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115, + 108,97,116,101,97,105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104, + 67,111,110,115,116,97,110,116,112,99,0,0,0,166,119,0,0,0,0,0,0,48,130,144,4,35,8,74,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130, + 144,40,35,8,201,50,130,112,0,51,12,106,16,172,193,12,3,27,8,109,48,195,224,6,131,26,204,48,184,1,241,6,51,12,110,80,188,193,12,131,27,24,111,48,195,224,6,7,28,204,48,184,1,18,7,51, + 12,110,144,200,193,12,129,50,195,160,6,115,64,7,51,16,75,29,176,1,29,204,16,48,51,4,205,12,129,51,131,241,64,145,52,81,51,24,79,21,89,211,53,67,129,69,210,148,205,48,152,194,41,160, + 194,12,9,29,104,27,29,176,65,100,77,220,12,9,27,104,27,27,176,65,100,77,221,12,137,26,104,155,26,176,65,36,77,222,12,10,29,196,1,29,88,100,16,7,113,64,7,86,25,204,64,213,193,7,6,114, + 176,209,1,27,132,129,24,168,193,24,180,130,25,200,193,25,196,65,132,6,83,26,204,64,168,194,42,176,130,43,204,48,216,65,42,188,194,157,1,192,113,28,199,113,28,199,113,28,199,185,129, + 27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,22,29,208,129,27,208,1,46,224,2,46,240,3,122,128,130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179, + 185,81,18,59,184,3,60,200,3,61,216,3,62,232,3,63,72,133,141,205,174,205,37,141,172,204,141,110,148,224,15,114,9,75,147,115,177,43,147,155,75,123,115,27,37,0,133,164,194,210,228,92, + 216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,66,33,167,176,52,57,151,177,183,54,184,52,182,178,175,55,56,186,180,55,183,185,81,6,81,24,5,82,72,37,44,77,206, + 197,174,76,142,174,12,111,148,224,21,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193, + 29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156, + 195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80, + 15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,180,37, + 64,61,7,161,72,146,52,7,161,72,9,65,48,26,48,2,48,70,0,130,32,136,127,20,115,16,150,117,97,36,163,1,52,51,0,0,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89, + 0,111,109,110,105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105, + 110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,133,89,33,216,194,44,172,24,110,193,22,104,97,67,32,11,27,134,88,192,133,90,216,48,228, + 66,46,212,194,134,224,22,0,0,157,134,5,146,40,16,130,1,36,254,157,6,103,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,204,5,204,54,4,89, + 48,219,16,12,194,6,1,49,0,4,0,0,0,91,138,32,200,133,67,23,182,20,68,144,11,135,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,134,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148, + 240,0,0,0,0,3,0,0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,13,0,0,0,18,3,148,102,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54, + 52,45,97,112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0, +}; +const uint8_t metallib_fragment[3787] = { + 77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,203,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0, + 224,13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,201,103,233,140,10,95,185,107,79,93,85,82,78,218,248,8,95,184,8,139,191, + 155,174,56,51,95,203,135,255,117,44,62,77,68,83,90,8,0,224,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68, + 84,69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,196,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33, + 12,0,0,44,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112, + 196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33, + 43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140, + 0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111, + 32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28, + 224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225, + 28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104, + 131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121, + 168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232, + 65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113, + 168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192, + 2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144, + 128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,176,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192, + 135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7, + 118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230, + 96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208, + 6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16, + 7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160, + 7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42, + 160,64,0,0,8,0,0,0,4,0,0,0,0,0,10,96,72,85,108,15,16,0,2,0,0,128,0,0,0,0,0,64,1,72,108,16,40,234,50,0,0,144,5,2,0,0,0,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69, + 80,2,133,80,14,229,83,128,2,5,81,32,197,48,2,80,6,36,199,18,158,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12, + 230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122, + 112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60, + 188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121, + 152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67, + 57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238, + 0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80, + 36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195, + 59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210, + 65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88, + 135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225, + 23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16, + 14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121, + 32,0,0,252,0,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71, + 6,81,100,48,134,180,40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114, + 97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114, + 46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114, + 101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101, + 114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100, + 101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109, + 112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114, + 46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110, + 116,95,105,110,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108, + 111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110, + 100,101,120,97,105,114,46,115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114, + 46,115,97,109,112,108,101,114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,198,96,0,0,0,0,0,0,48,130,208,8,35,8,82,51,130,208,12,35,8,13,49,130,208, + 20,35,8,141,49,130,208,28,35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,13,51,130,144,0,51,12,100,16,148,193,12,131,25,8,103,48,195,128,6,3,25,204,48,160,1,145,6,51,12,104,80,164, + 193,12,3,26,24,105,48,195,128,6,135,26,204,48,160,1,178,6,51,12,104,144,176,193,12,129,50,195,64,6,109,224,6,51,16,203,27,152,129,27,204,16,48,51,4,205,12,129,51,195,241,184,129,27, + 64,145,52,205,16,128,194,12,137,27,80,149,117,65,145,132,205,144,152,1,149,89,23,164,73,219,12,10,25,112,157,27,152,129,7,125,18,24,204,144,188,65,24,116,110,96,6,144,24,72,99,48,3, + 33,10,163,64,10,165,48,195,0,7,161,96,10,71,6,0,199,113,28,199,113,28,199,113,28,231,6,110,224,6,110,224,6,110,224,6,110,224,6,22,29,232,129,101,89,166,192,177,2,43,144,131,58,128, + 130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,185,81,18,56,136,3,57,152,3,58,168,3,59,184,3,60,72,133,141,205,174,205,37,141,172,204,141,110,148,32,15, + 114,9,75,147,115,177,43,147,155,75,123,115,27,37,208,131,164,194,210,228,92,216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,246,32,167,176,52,57,151,177,183,54, + 184,52,182,178,175,55,56,186,180,55,183,185,81,6,62,232,3,63,72,38,44,77,206,197,76,46,236,172,173,204,141,110,148,192,20,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122, + 88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231, + 80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32, + 28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148, + 67,56,144,195,1,0,0,0,97,32,0,0,49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0, + 97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114, + 45,97,108,105,97,115,45,115,99,111,112,101,45,116,101,120,116,117,114,101,115,0,43,132,85,64,133,21,3,43,172,66,42,172,24,90,97,21,84,97,131,208,10,172,0,0,35,6,205,16,130,96,240,88, + 135,129,20,3,33,8,204,104,66,0,96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,104,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,251,5,0,0,0,0,0,0,0,0,101,12,0,0,37, + 0,0,0,18,3,148,40,1,0,0,0,3,0,0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,20,0,0,0,18,3, + 148,161,0,0,0,0,109,97,105,110,48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97, + 112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +#elif TARGET_OS_IPHONE +const uint8_t metallib_vertex[3876] = { + 77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,36,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,16, + 14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,240,54,230,217,232,66,102,78,35,5,77,235,101,252,229,192,148,96,126,162,111, + 77,253,247,211,52,17,198,182,137,68,244,77,68,83,90,8,0,16,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68, + 84,69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192, + 23,11,0,0,0,0,20,0,0,0,252,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,72,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200, + 4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70, + 136,32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92, + 32,36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12, + 34,8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28, + 218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128, + 29,202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135, + 119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160, + 7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161, + 13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104, + 3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8, + 4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,170,112,72, + 7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14, + 113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122, + 96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64, + 7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15, + 121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114, + 80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109, + 224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,3,0,128,0,0,0,64,0,0,0,0,0,160,0,36,54,8,20,85,26,0,0,200,2,1,0,11,0,0,0,50,30,152,16,25,17,76,144,140,9, + 38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,17,128,50,160,29,1,32,29,75,144,2,0,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195, + 140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112, + 7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137, + 59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95, + 8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144, + 67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24, + 135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24, + 81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33, + 29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236, + 192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180, + 113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48, + 35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135, + 119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135, + 119,168,7,120,152,7,0,0,0,0,121,32,0,0,25,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,6,100,208,82,0,0,0,139, + 210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122, + 101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116, + 97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120, + 116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115, + 65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97, + 108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104, + 95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,118,101, + 114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46, + 97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,111,115,105,116,105, + 111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97, + 80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,97,105,114,46,97, + 100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,108,97,116,101,97, + 105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,67,111,110,115,116, + 97,110,116,112,99,0,0,0,230,117,0,0,0,0,0,0,48,130,144,4,35,8,10,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,144,40,35,8,7,48,195, + 160,6,193,26,204,48,176,129,208,6,51,12,110,48,168,193,12,131,27,16,111,48,195,224,6,197,27,204,48,184,129,241,6,51,12,110,112,192,193,12,131,27,32,113,48,195,224,6,137,28,204,16,40, + 51,12,106,224,6,115,48,3,177,208,129,26,204,193,12,1,51,67,208,204,16,56,51,24,15,20,73,19,53,131,241,84,145,53,93,51,20,88,36,77,217,12,67,41,152,194,41,204,144,204,129,182,205,1, + 27,68,214,196,205,144,176,129,182,177,1,27,68,214,212,205,144,168,129,182,169,1,27,68,210,228,205,160,204,65,28,204,129,69,6,113,16,7,115,96,149,193,12,20,29,124,96,32,7,219,28,176, + 65,24,136,129,26,140,1,43,152,129,28,156,65,28,68,104,48,165,193,12,68,42,168,194,42,180,194,12,67,29,160,130,43,156,25,0,28,199,113,28,199,113,28,199,113,110,224,6,110,224,6,110,224, + 6,110,224,6,110,96,209,129,30,88,150,69,7,116,224,6,116,128,11,184,128,11,252,128,30,160,32,35,129,9,202,136,141,205,174,205,165,237,141,172,142,173,204,197,140,45,236,108,110,148, + 164,14,236,224,14,240,32,15,244,96,15,248,160,15,82,97,99,179,107,115,73,35,43,115,163,27,37,240,131,92,194,210,228,92,236,202,228,230,210,222,220,70,9,254,32,169,176,52,57,23,182, + 48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,80,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,205,109,110,148,33,20,68,97,20,82,9,75,147,115,177, + 43,147,163,43,195,27,37,112,5,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230, + 33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56, + 180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244, + 128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,197,64,91,2,212, + 115,16,73,20,69,115,16,73,36,17,4,163,1,35,0,99,4,32,8,130,248,71,49,7,97,89,23,70,50,26,64,51,3,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,0,111,109,110, + 105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97, + 105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,101,89,33,212,130,44,172,24,108,161,22,102,97,67,16,11,27,6,88,184,5,90,216,48,224,2,46,208,194,134, + 192,22,0,0,157,6,38,154,40,16,130,65,36,254,157,134,135,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,12,6,204,54,4,90,48,219,16,12,194, + 6,1,49,0,4,0,0,0,91,138,32,192,133,35,23,182,20,68,128,11,71,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,132,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,240,0,0,0,0,3,0, + 0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,12,0,0,0,18,3,148,99,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112, + 108,101,45,105,111,115,49,56,46,49,46,48,0,0,0,0,0, +}; +const uint8_t metallib_fragment[3771] = { + 77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,187,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,208, + 13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,167,26,51,31,140,153,203,226,66,149,243,47,185,58,96,202,28,176,71,121,86,159, + 244,234,235,69,155,58,121,67,241,212,77,68,83,90,8,0,208,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,84, + 69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,180,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12, + 0,0,41,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112, + 196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33, + 43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140, + 0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111, + 32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28, + 224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225, + 28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104, + 131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121, + 168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232, + 65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113, + 168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192, + 2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144, + 128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,170,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131, + 56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7, + 118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7, + 122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116, + 128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120, + 160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32, + 7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,4,0,128, + 0,0,0,64,0,0,0,0,0,160,0,134,84,197,246,0,1,32,0,0,0,8,0,0,0,0,0,20,128,196,6,129,162,43,3,0,0,89,32,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,80,2,133,80,14,229, + 83,128,2,5,81,32,35,0,101,64,114,44,65,10,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244, + 128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32, + 135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204, + 240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14, + 238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67, + 56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228, + 144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104, + 7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67, + 57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216, + 225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236, + 96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33, + 29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192, + 14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,251,0,0,0,114, + 30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,81,100,48,134,180, + 40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109, + 97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116, + 104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114, + 105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32, + 51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115, + 95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114, + 97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,46,97,114,103,95,116,121, + 112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,116,95,105,110,112,117,116, + 117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,111,114,117,115,101,114,40, + 108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,105,114,46, + 115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,46,115,97,109,112,108,101, + 114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,6,95,0,0,0,0,0,0,48,130,208,8,35,8,18,51,130,208,12,35,8,13,49,130,208,20,35,8,141,49,130,208,28, + 35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,9,48,195,64,6,65,25,204,48,152,129,112,6,51,12,104,48,144,193,12,3,26,16,105,48,195,128,6,69,26,204,48,160,129,145,6,51,12,104,112, + 168,193,12,3,26,32,107,48,195,128,6,9,27,204,16,40,51,12,100,128,6,109,48,3,177,184,1,25,180,193,12,1,51,67,208,204,16,56,51,28,79,27,180,1,20,73,211,12,193,31,204,144,180,1,85,89, + 23,20,73,216,12,137,25,80,153,117,65,154,180,205,160,144,1,215,181,129,25,120,208,39,129,193,12,137,27,132,65,215,6,102,0,137,129,52,6,51,16,161,32,10,163,64,10,51,12,111,0,10,165, + 112,99,0,112,28,199,113,28,199,113,28,199,185,129,27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,150,41,112,172,192,10,228,160,14,160,32,35,129,9,202,136,141,205,174,205, + 165,237,141,172,142,173,204,197,140,45,236,108,110,148,228,13,224,32,14,228,96,14,232,160,14,236,224,14,82,97,99,179,107,115,73,35,43,115,163,27,37,192,131,92,194,210,228,92,236,202, + 228,230,210,222,220,70,9,242,32,169,176,52,57,23,182,48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,61,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237, + 205,109,110,148,97,15,248,160,15,146,9,75,147,115,49,147,11,59,107,43,115,163,27,37,40,5,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176, + 67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135, + 112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28, + 200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0, + 49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,97,105,114,45,97,108,105,97,115, + 45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,45,97,108,105,97,115,45,115,99, + 111,112,101,45,116,101,120,116,117,114,101,115,0,43,4,85,56,133,21,195,42,168,2,42,172,24,88,65,21,82,97,131,192,10,171,0,0,35,6,205,16,130,96,240,84,135,129,20,3,33,8,204,104,66,0, + 96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,96,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,248,5,0,0,0,0,0,0,0,0,101,12,0,0,37,0,0,0,18,3,148,40,1,0,0,0,3,0, + 0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,19,0,0,0,18,3,148,126,0,0,0,0,109,97,105,110, + 48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,108,101,45,105,111,115, + 49,56,46,49,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; +#elif TARGET_IPHONE_SIMULATOR +#error "SDL_GPU does not support the iphone simulator" +#endif +#endif + +#endif // #ifndef IMGUI_DISABLE diff --git a/source/thirdparty/imgui/imgui_internal.h b/source/thirdparty/imgui/imgui_internal.h index 86aed947..81266cfb 100644 --- a/source/thirdparty/imgui/imgui_internal.h +++ b/source/thirdparty/imgui/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -101,6 +101,7 @@ Index of this file: #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #endif @@ -471,7 +472,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); } template static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } template static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } template static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -template static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } +template static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); } template static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; } template static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; } @@ -837,8 +838,7 @@ struct ImGuiDataTypeInfo // Extend ImGuiDataType_ enum ImGuiDataTypePrivate_ { - ImGuiDataType_String = ImGuiDataType_COUNT + 1, - ImGuiDataType_Pointer, + ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1, ImGuiDataType_ID, }; @@ -924,7 +924,7 @@ enum ImGuiButtonFlagsPrivate_ ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release) ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release) ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) - //ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat + //ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat -> use ImGuiItemFlags_ButtonRepeat instead. ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable. //ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press @@ -1132,8 +1132,10 @@ struct IMGUI_API ImGuiInputTextState { ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent). ImStbTexteditState* Stb; // State for stb_textedit.h + ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set. ImGuiID ID; // widget id owning the text state int TextLen; // UTF-8 length of the string in TextA (in bytes) + const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). Field only set and valid _inside_ the call InputText() call. ImVector TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1). ImVector TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered) ImVector CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack @@ -1143,9 +1145,8 @@ struct IMGUI_API ImGuiInputTextState bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection bool Edited; // edited this frame - ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set. - bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version. - int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet. + bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version. + int ReloadSelectionStart; int ReloadSelectionEnd; ImGuiInputTextState(); @@ -2239,9 +2240,9 @@ struct ImGuiContext int FrameCountEnded; int FrameCountPlatformEnded; int FrameCountRendered; + ImGuiID WithinEndChildID; // Set within EndChild() bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame() bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed - bool WithinEndChild; // Set within EndChild() bool GcCompactAll; // Request full GC bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() void* TestEngine; // Test engine user data @@ -2304,6 +2305,7 @@ struct ImGuiContext bool ActiveIdPreviousFrameIsAlive; bool ActiveIdPreviousFrameHasBeenEditedBefore; ImGuiWindow* ActiveIdPreviousFrameWindow; + ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX. ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. diff --git a/source/thirdparty/imgui/imgui_tables.cpp b/source/thirdparty/imgui/imgui_tables.cpp index f4e76225..1ab9c703 100644 --- a/source/thirdparty/imgui/imgui_tables.cpp +++ b/source/thirdparty/imgui/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (tables and columns code) /* @@ -232,7 +232,11 @@ Index of this file: #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*' +#pragma GCC diagnostic ignored "-Wstrict-overflow" #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #endif @@ -3295,7 +3299,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label const ImVec2 align = g.Style.TableAngledHeadersTextAlign; // Draw background and labels in first pass, then all borders. - float max_x = 0.0f; + float max_x = -FLT_MAX; for (int pass = 0; pass < 2; pass++) for (int order_n = 0; order_n < data_count; order_n++) { diff --git a/source/thirdparty/imgui/imgui_widgets.cpp b/source/thirdparty/imgui/imgui_widgets.cpp index d39a949d..c88efc1d 100644 --- a/source/thirdparty/imgui/imgui_widgets.cpp +++ b/source/thirdparty/imgui/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.91.6 +// dear imgui, v1.91.7 WIP // (widgets code) /* @@ -82,9 +82,14 @@ Index of this file: #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*' #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked -#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1 +#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif //------------------------------------------------------------------------- @@ -472,7 +477,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) // - PressedOnDragDropHold can generally be associated with any flag. // - PressedOnDoubleClick can be associated by PressedOnClickRelease/PressedOnRelease, in which case the second release event won't be reported. //------------------------------------------------------------------------------------------------------------------------------------------------ -// The behavior of the return-value changes when ImGuiButtonFlags_Repeat is set: +// The behavior of the return-value changes when ImGuiItemFlags_ButtonRepeat is set: // Repeat+ Repeat+ Repeat+ Repeat+ // PressedOnClickRelease PressedOnClick PressedOnRelease PressedOnDoubleClick //------------------------------------------------------------------------------------------------------------------------------------------------- @@ -2172,6 +2177,7 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] = { sizeof(float), "float", "%.3f","%f" }, // ImGuiDataType_Float (float are promoted to double in va_arg) { sizeof(double), "double","%f", "%lf" }, // ImGuiDataType_Double { sizeof(bool), "bool", "%d", "%d" }, // ImGuiDataType_Bool + { 0, "char*","%s", "%s" }, // ImGuiDataType_String }; IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT); @@ -2440,9 +2446,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) { adjust_delta = g.IO.MouseDelta[axis]; - if (g.IO.KeyAlt) + if (g.IO.KeyAlt && !(flags & ImGuiSliderFlags_NoSpeedTweaks)) adjust_delta *= 1.0f / 100.0f; - if (g.IO.KeyShift) + if (g.IO.KeyShift && !(flags & ImGuiSliderFlags_NoSpeedTweaks)) adjust_delta *= 10.0f; } else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) @@ -2450,7 +2456,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); - const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f; + const float tweak_factor = (flags & ImGuiSliderFlags_NoSpeedTweaks) ? 1.0f : tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f; adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } @@ -2638,6 +2644,10 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, temp_input_is_active = true; } + // Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert) + if (make_active) + memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size); + if (make_active && !temp_input_is_active) { SetActiveID(id, window); @@ -3228,6 +3238,10 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat if ((clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))) temp_input_is_active = true; + // Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert) + if (make_active) + memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size); + if (make_active && !temp_input_is_active) { SetActiveID(id, window); @@ -3936,12 +3950,12 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c namespace ImStb { static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; } -static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextA[idx]; } -static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextA.Data + line_start_idx + char_idx, obj->TextA.Data + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; } +static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextSrc[idx]; } +static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextSrc + line_start_idx + char_idx, obj->TextSrc + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; } static char STB_TEXTEDIT_NEWLINE = '\n'; static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx) { - const char* text = obj->TextA.Data; + const char* text = obj->TextSrc; const char* text_remaining = NULL; const ImVec2 size = InputTextCalcTextSize(obj->Ctx, text + line_start_idx, text + obj->TextLen, &text_remaining, NULL, true); r->x0 = 0.0f; @@ -3960,15 +3974,15 @@ static int IMSTB_TEXTEDIT_GETNEXTCHARINDEX_IMPL(ImGuiInputTextState* obj, int id if (idx >= obj->TextLen) return obj->TextLen + 1; unsigned int c; - return idx + ImTextCharFromUtf8(&c, obj->TextA.Data + idx, obj->TextA.Data + obj->TextLen); + return idx + ImTextCharFromUtf8(&c, obj->TextSrc + idx, obj->TextSrc + obj->TextLen); } static int IMSTB_TEXTEDIT_GETPREVCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx) { if (idx <= 0) return -1; - const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, obj->TextA.Data + idx); - return (int)(p - obj->TextA.Data); + const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, obj->TextSrc + idx); + return (int)(p - obj->TextSrc); } static bool ImCharIsSeparatorW(unsigned int c) @@ -3991,10 +4005,10 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx) if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0) return 0; - const char* curr_p = obj->TextA.Data + idx; - const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p); - unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextA.Data + obj->TextLen); - unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextA.Data + obj->TextLen); + const char* curr_p = obj->TextSrc + idx; + const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p); + unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextSrc + obj->TextLen); + unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextSrc + obj->TextLen); bool prev_white = ImCharIsBlankW(prev_c); bool prev_separ = ImCharIsSeparatorW(prev_c); @@ -4007,10 +4021,10 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0) return 0; - const char* curr_p = obj->TextA.Data + idx; - const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p); - unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextA.Data + obj->TextLen); - unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextA.Data + obj->TextLen); + const char* curr_p = obj->TextSrc + idx; + const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p); + unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextSrc + obj->TextLen); + unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextSrc + obj->TextLen); bool prev_white = ImCharIsBlankW(prev_c); bool prev_separ = ImCharIsSeparatorW(prev_c); @@ -4047,16 +4061,13 @@ static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n) { + // Offset remaining text (+ copy zero terminator) + IM_ASSERT(obj->TextSrc == obj->TextA.Data); char* dst = obj->TextA.Data + pos; - + char* src = obj->TextA.Data + pos + n; + memmove(dst, src, obj->TextLen - n - pos + 1); obj->Edited = true; obj->TextLen -= n; - - // Offset remaining text (FIXME-OPT: Use memmove) - const char* src = obj->TextA.Data + pos + n; - while (char c = *src++) - *dst++ = c; - *dst = '\0'; } static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len) @@ -4069,11 +4080,13 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch return false; // Grow internal buffer if needed + IM_ASSERT(obj->TextSrc == obj->TextA.Data); if (new_text_len + text_len + 1 > obj->TextA.Size) { if (!is_resizable) return false; obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1); + obj->TextSrc = obj->TextA.Data; } char* text = obj->TextA.Data; @@ -4171,26 +4184,25 @@ int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; } int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; } void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; } -void ImGuiInputTextState::ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; } -void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; } -void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; } +void ImGuiInputTextState::ReloadUserBufAndSelectAll() { WantReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; } +void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { WantReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; } +void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { WantReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; } ImGuiInputTextCallbackData::ImGuiInputTextCallbackData() { memset(this, 0, sizeof(*this)); } -// Public API to manipulate UTF-8 text -// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar) +// Public API to manipulate UTF-8 text from within a callback. // FIXME: The existence of this rarely exercised code path is a bit of a nuisance. +// Historically they existed because STB_TEXTEDIT_INSERTCHARS() etc. worked on our ImWchar +// buffer, but nowadays they both work on UTF-8 data. Should aim to merge both. void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count) { IM_ASSERT(pos + bytes_count <= BufTextLen); char* dst = Buf + pos; const char* src = Buf + pos + bytes_count; - while (char c = *src++) - *dst++ = c; - *dst = '\0'; + memmove(dst, src, BufTextLen - bytes_count - pos + 1); if (CursorPos >= pos + bytes_count) CursorPos -= bytes_count; @@ -4215,13 +4227,13 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons if (!is_resizable) return; - // Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!) ImGuiContext& g = *Ctx; ImGuiInputTextState* edit_state = &g.InputTextState; IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID); IM_ASSERT(Buf == edit_state->TextA.Data); int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1; edit_state->TextA.resize(new_buf_size + 1); + edit_state->TextSrc = edit_state->TextA.Data; Buf = edit_state->TextA.Data; BufSize = edit_state->BufCapacity = new_buf_size; } @@ -4339,26 +4351,23 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im return true; } -// Find the shortest single replacement we can make to get the new text from the old text. -// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end. +// Find the shortest single replacement we can make to get from old_buf to new_buf +// Note that this doesn't directly alter state->TextA, state->TextLen. They are expected to be made valid separately. // FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly. -static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* state, const char* new_buf_a, int new_length_a) +static void InputTextReconcileUndoState(ImGuiInputTextState* state, const char* old_buf, int old_length, const char* new_buf, int new_length) { - const char* old_buf = state->CallbackTextBackup.Data; - const int old_length = state->CallbackTextBackup.Size - 1; - - const int shorter_length = ImMin(old_length, new_length_a); + const int shorter_length = ImMin(old_length, new_length); int first_diff; for (first_diff = 0; first_diff < shorter_length; first_diff++) - if (old_buf[first_diff] != new_buf_a[first_diff]) + if (old_buf[first_diff] != new_buf[first_diff]) break; - if (first_diff == old_length && first_diff == new_length_a) + if (first_diff == old_length && first_diff == new_length) return; int old_last_diff = old_length - 1; - int new_last_diff = new_length_a - 1; + int new_last_diff = new_length - 1; for (; old_last_diff >= first_diff && new_last_diff >= first_diff; old_last_diff--, new_last_diff--) - if (old_buf[old_last_diff] != new_buf_a[new_last_diff]) + if (old_buf[old_last_diff] != new_buf[new_last_diff]) break; const int insert_len = new_last_diff - first_diff + 1; @@ -4387,6 +4396,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id) else { IM_ASSERT(state->TextA.Data != 0); + IM_ASSERT(state->TextA[state->TextLen] == 0); g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1); memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1); } @@ -4510,64 +4520,67 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX; - const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf); + const bool init_reload_from_user_buf = (state != NULL && state->WantReloadUserBuf); const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state. const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav); const bool init_state = (init_make_active || user_scroll_active); - if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf) + if (init_reload_from_user_buf) + { + int new_len = (int)strlen(buf); + IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); + state->WantReloadUserBuf = false; + InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len); + state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string. + state->TextLen = new_len; + memcpy(state->TextA.Data, buf, state->TextLen + 1); + state->Stb->select_start = state->ReloadSelectionStart; + state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; + state->CursorClamp(); + } + else if ((init_state && g.ActiveId != id) || init_changed_specs) { // Access state even if we don't own it yet. state = &g.InputTextState; state->CursorAnimReset(); - state->ReloadUserBuf = false; // Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714) InputTextDeactivateHook(state->ID); + // Take a copy of the initial buffer value. // From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode) const int buf_len = (int)strlen(buf); - if (!init_reload_from_user_buf) - { - // Take a copy of the initial buffer value. - state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. - memcpy(state->TextToRevertTo.Data, buf, buf_len + 1); - } + IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?"); + state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. + memcpy(state->TextToRevertTo.Data, buf, buf_len + 1); // Preserve cursor position and undo/redo stack if we come back to same widget // FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate? - bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf); - if (recycle_state && (state->TextLen != buf_len || (strncmp(state->TextA.Data, buf, buf_len) != 0))) + bool recycle_state = (state->ID == id && !init_changed_specs); + if (recycle_state && (state->TextLen != buf_len || (state->TextA.Data == NULL || strncmp(state->TextA.Data, buf, buf_len) != 0))) recycle_state = false; // Start edition state->ID = id; - state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string. - state->TextLen = (int)strlen(buf); - memcpy(state->TextA.Data, buf, state->TextLen + 1); + state->TextLen = buf_len; + if (!is_readonly) + { + state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string. + memcpy(state->TextA.Data, buf, state->TextLen + 1); + } // Find initial scroll position for right alignment state->Scroll = ImVec2(0.0f, 0.0f); if (flags & ImGuiInputTextFlags_ElideLeft) state->Scroll.x += ImMax(0.0f, CalcTextSize(buf).x - frame_size.x + style.FramePadding.x * 2.0f); + // Recycle existing cursor/selection/undo stack but clamp position + // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. if (recycle_state) - { - // Recycle existing cursor/selection/undo stack but clamp position - // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. state->CursorClamp(); - } else - { stb_textedit_initialize_state(state->Stb, !is_multiline); - } - if (init_reload_from_user_buf) - { - state->Stb->select_start = state->ReloadSelectionStart; - state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; - state->CursorClamp(); - } - else if (!is_multiline) + if (!is_multiline) { if (flags & ImGuiInputTextFlags_AutoSelectAll) select_all = true; @@ -4617,7 +4630,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Expose scroll in a manner that is agnostic to us using a child window if (is_multiline && state != NULL) state->Scroll.y = draw_window->Scroll.y; + + // Read-only mode always ever read from source buffer. Refresh TextLen when active. + if (is_readonly && state != NULL) + state->TextLen = (int)strlen(buf); + //if (is_readonly && state != NULL) + // state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation. } + if (state != NULL) + state->TextSrc = is_readonly ? buf : state->TextA.Data; // We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function) if (g.ActiveId == id && state == NULL) @@ -4882,13 +4903,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Cut, Copy if (g.PlatformIO.Platform_SetClipboardTextFn != NULL) { + // SetClipboardText() only takes null terminated strings + state->TextSrc may point to read-only user buffer, so we need to make a copy. const int ib = state->HasSelection() ? ImMin(state->Stb->select_start, state->Stb->select_end) : 0; const int ie = state->HasSelection() ? ImMax(state->Stb->select_start, state->Stb->select_end) : state->TextLen; - - char backup = state->TextA.Data[ie]; - state->TextA.Data[ie] = 0; // A bit of a hack since SetClipboardText only takes null terminated strings - SetClipboardText(state->TextA.Data + ib); - state->TextA.Data[ie] = backup; + g.TempBuffer.reserve(ie - ib + 1); + memcpy(g.TempBuffer.Data, state->TextSrc + ib, ie - ib); + g.TempBuffer.Data[ie - ib] = 0; + SetClipboardText(g.TempBuffer.Data); } if (is_cut) { @@ -4904,25 +4925,27 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Filter pasted buffer const int clipboard_len = (int)strlen(clipboard); - char* clipboard_filtered = (char*)IM_ALLOC(clipboard_len + 1); - int clipboard_filtered_len = 0; + ImVector clipboard_filtered; + clipboard_filtered.reserve(clipboard_len + 1); for (const char* s = clipboard; *s != 0; ) { unsigned int c; - int len = ImTextCharFromUtf8(&c, s, NULL); - s += len; + int in_len = ImTextCharFromUtf8(&c, s, NULL); + s += in_len; if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true)) continue; - memcpy(clipboard_filtered + clipboard_filtered_len, s - len, len); - clipboard_filtered_len += len; + char c_utf8[5]; + ImTextCharToUtf8(c_utf8, c); + int out_len = (int)strlen(c_utf8); + clipboard_filtered.resize(clipboard_filtered.Size + out_len); + memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len); } - clipboard_filtered[clipboard_filtered_len] = 0; - if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + if (clipboard_filtered.Size > 0) // If everything was filtered, ignore the pasting operation { - stb_textedit_paste(state, state->Stb, clipboard_filtered, clipboard_filtered_len); + clipboard_filtered.push_back(0); + stb_textedit_paste(state, state->Stb, clipboard_filtered.Data, clipboard_filtered.Size - 1); state->CursorFollow = true; } - MemFree(clipboard_filtered); } } @@ -5015,10 +5038,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ callback_data.UserData = callback_user_data; // FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925 - state->CallbackTextBackup.resize(state->TextLen + 1); - memcpy(state->CallbackTextBackup.Data, state->TextA.Data, state->TextLen + 1); - char* callback_buf = is_readonly ? buf : state->TextA.Data; + IM_ASSERT(callback_buf == state->TextSrc); + state->CallbackTextBackup.resize(state->TextLen + 1); + memcpy(state->CallbackTextBackup.Data, callback_buf, state->TextLen + 1); + callback_data.EventKey = event_key; callback_data.Buf = callback_buf; callback_data.BufTextLen = state->TextLen; @@ -5045,7 +5069,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Callback may update buffer and thus set buf_dirty even in read-only mode. IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! - InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ? + InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen); state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() state->CursorAnimReset(); } @@ -5053,9 +5077,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } // Will copy result string if modified - if (!is_readonly && strcmp(state->TextA.Data, buf) != 0) + if (!is_readonly && strcmp(state->TextSrc, buf) != 0) { - apply_new_text = state->TextA.Data; + apply_new_text = state->TextSrc; apply_new_text_length = state->TextLen; value_changed = true; } @@ -5149,7 +5173,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // - Measure text height (for scrollbar) // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. - const char* text_begin = state->TextA.Data; + const char* text_begin = buf_display; const char* text_end = text_begin + state->TextLen; ImVec2 cursor_offset, select_start_offset; @@ -5330,6 +5354,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ g.LastItemData.StatusFlags = item_data_backup.StatusFlags; } } + if (state) + state->TextSrc = NULL; // Log as text if (g.LogEnabled && (!is_password || is_displaying_hint)) @@ -7500,6 +7526,12 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel if (flags & ImGuiMultiSelectFlags_BoxSelect2d) flags &= ~ImGuiMultiSelectFlags_BoxSelect1d; + // FIXME: Workaround to the fact we override CursorMaxPos, meaning size measurement are lost. (#8250) + // They should perhaps be stacked properly? + if (ImGuiTable* table = g.CurrentTable) + if (table->CurrentColumn != -1) + TableEndCell(table); // This is currently safe to call multiple time. If that properly is lost we can extract the "save measurement" part of it. + // FIXME: BeginFocusScope() const ImGuiID id = window->IDStack.back(); ms->Clear(); @@ -8213,15 +8245,10 @@ void ImGuiSelectionExternalStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io) //------------------------------------------------------------------------- // This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label. -// This handle some subtleties with capturing info from the label, but for 99% uses it could essentially be rewritten as: -// if (ImGui::BeginChild("...", ImVec2(ImGui::CalcItemWidth(), ImGui::GetTextLineHeight() * 7.5f), ImGuiChildFlags_FrameStyle)) -// { .... } -// ImGui::EndChild(); -// ImGui::SameLine(); -// ImGui::AlignTextToFramePadding(); -// ImGui::Text("Label"); +// This handle some subtleties with capturing info from the label. +// If you don't need a label you can pretty much directly use ImGui::BeginChild() with ImGuiChildFlags_FrameStyle. // Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty" -// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height). +// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.5f * item_height). bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) { ImGuiContext& g = *GImGui;