diff --git a/Sources/arm/App.hx b/Sources/arm/App.hx index 784c75ca..be66f57f 100644 --- a/Sources/arm/App.hx +++ b/Sources/arm/App.hx @@ -490,6 +490,9 @@ class App extends iron.Trait { else { arm.App.showMessageBox("You are up to date!"); } + // explorer "https://armorpaint.org/download" + // open "https://armorpaint.org/download" + // xdg-open "https://armorpaint.org/download" } }); #end diff --git a/Sources/arm/MaterialBuilder.hx b/Sources/arm/MaterialBuilder.hx index 6fbf887c..a77dbdbe 100644 --- a/Sources/arm/MaterialBuilder.hx +++ b/Sources/arm/MaterialBuilder.hx @@ -119,7 +119,7 @@ class MaterialBuilder { frag.add_uniform('float brushOpacity', '_brushOpacity'); frag.add_uniform('float brushHardness', '_brushHardness'); - if (UITrait.inst.brushType == 0 || UITrait.inst.brushType == 1 || decal || UITrait.inst.brushType == 8) { // Draw / Erase + if (UITrait.inst.brushType == 0 || UITrait.inst.brushType == 1 || decal || UITrait.inst.brushType == 8 || UITrait.inst.brushType == 9) { // Draw / Erase #if (kha_opengl || kha_webgl) frag.write('if (sp.z > textureLod(paintdb, vec2(sp.x, 1.0 - bsp.y), 0).r) { discard; }'); @@ -237,35 +237,74 @@ class MaterialBuilder { } } - var clone = UITrait.inst.brushType == 8; - if (clone) { + if (UITrait.inst.brushType == 8 || UITrait.inst.brushType == 9) { // Clone, Blur + frag.add_uniform('sampler2D gbuffer2'); frag.add_uniform('vec2 gbufferSize', '_gbufferSize'); - frag.add_uniform('vec2 cloneDelta', '_cloneDelta'); - #if (kha_opengl || kha_webgl) - frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (1.0 - (sp.y + cloneDelta.y)) * gbufferSize.y), 0).ba;'); - #else - frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (sp.y + cloneDelta.y) * gbufferSize.y), 0).ba;'); - #end frag.add_uniform('sampler2D texpaint_undo', '_texpaint_undo'); frag.add_uniform('sampler2D texpaint_nor_undo', '_texpaint_nor_undo'); frag.add_uniform('sampler2D texpaint_pack_undo', '_texpaint_pack_undo'); - frag.write('vec3 texpaint_pack_sample = textureLod(texpaint_pack_undo, texCoordInp, 0).rgb;'); - - var base = 'textureLod(texpaint_undo, texCoordInp, 0).rgb;'; - var rough = 'texpaint_pack_sample.g;'; - var met = 'texpaint_pack_sample.b;'; - var occ = 'texpaint_pack_sample.r;'; - var nortan = 'textureLod(texpaint_nor_undo, texCoordInp, 0).rgb;'; - var height = '0.0'; - var opac = '1.0'; - frag.write('vec3 basecol = $base;'); - frag.write('float roughness = $rough;'); - frag.write('float metallic = $met;'); - frag.write('float occlusion = $occ;'); - frag.write('vec3 nortan = $nortan;'); - frag.write('float height = $height;'); - frag.write('float opacity = $opac * brushOpacity;'); + + if (UITrait.inst.brushType == 8) { // Clone + frag.add_uniform('vec2 cloneDelta', '_cloneDelta'); + #if (kha_opengl || kha_webgl) + frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (1.0 - (sp.y + cloneDelta.y)) * gbufferSize.y), 0).ba;'); + #else + frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2((sp.x + cloneDelta.x) * gbufferSize.x, (sp.y + cloneDelta.y) * gbufferSize.y), 0).ba;'); + #end + + frag.write('vec3 texpaint_pack_sample = textureLod(texpaint_pack_undo, texCoordInp, 0).rgb;'); + var base = 'textureLod(texpaint_undo, texCoordInp, 0).rgb'; + var rough = 'texpaint_pack_sample.g'; + var met = 'texpaint_pack_sample.b'; + var occ = 'texpaint_pack_sample.r'; + var nortan = 'textureLod(texpaint_nor_undo, texCoordInp, 0).rgb'; + var height = '0.0'; + var opac = '1.0'; + frag.write('vec3 basecol = $base;'); + frag.write('float roughness = $rough;'); + frag.write('float metallic = $met;'); + frag.write('float occlusion = $occ;'); + frag.write('vec3 nortan = $nortan;'); + frag.write('float height = $height;'); + frag.write('float opacity = $opac * brushOpacity;'); + } + else { // Blur + #if (kha_opengl || kha_webgl) + frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2(sp.x * gbufferSize.x, (1.0 - sp.y) * gbufferSize.y), 0).ba;'); + #else + frag.write('vec2 texCoordInp = texelFetch(gbuffer2, ivec2(sp.x * gbufferSize.x, sp.y * gbufferSize.y), 0).ba;'); + #end + + frag.write('vec3 basecol = vec3(0.0, 0.0, 0.0);'); + frag.write('float roughness = 0.0;'); + frag.write('float metallic = 0.0;'); + frag.write('float occlusion = 0.0;'); + frag.write('vec3 nortan = vec3(0.0, 0.0, 0.0);'); + frag.write('float height = 1.0;'); + frag.write('float opacity = 1.0 * brushOpacity;'); + frag.write('for (int i = -7; i <= 7; i++) {'); + frag.write(' basecol += textureOffset(texpaint_undo, texCoordInp, ivec2(i, 0)).rgb;'); + frag.write(' vec3 texpaint_pack_sample = textureOffset(texpaint_pack_undo, texCoordInp, ivec2(i, 0)).rgb;'); + frag.write(' roughness += texpaint_pack_sample.g;'); + frag.write(' metallic += texpaint_pack_sample.b;'); + frag.write(' occlusion += texpaint_pack_sample.r;'); + frag.write(' nortan += textureOffset(texpaint_nor_undo, texCoordInp, ivec2(i, 0)).rgb;'); + frag.write('}'); + frag.write('for (int i = -7; i <= 7; i++) {'); + frag.write(' basecol += textureOffset(texpaint_undo, texCoordInp, ivec2(0, i)).rgb;'); + frag.write(' vec3 texpaint_pack_sample = textureOffset(texpaint_pack_undo, texCoordInp, ivec2(0, i)).rgb;'); + frag.write(' roughness += texpaint_pack_sample.g;'); + frag.write(' metallic += texpaint_pack_sample.b;'); + frag.write(' occlusion += texpaint_pack_sample.r;'); + frag.write(' nortan += textureOffset(texpaint_nor_undo, texCoordInp, ivec2(0, i)).rgb;'); + frag.write('}'); + frag.write('basecol /= 30.0;'); + frag.write('roughness /= 30.0;'); + frag.write('metallic /= 30.0;'); + frag.write('occlusion /= 30.0;'); + frag.write('nortan /= 30.0;'); + } } else { Cycles.parse_height_as_channel = true; @@ -706,7 +745,8 @@ class MaterialBuilder { var writeTC = (UITrait.inst.brushType == 2 && UITrait.inst.fillTypeHandle.position == 1) || // Face fill UITrait.inst.brushType == 4 || // Colorid pick - UITrait.inst.brushType == 8; // Clone + UITrait.inst.brushType == 8 || // Clone + UITrait.inst.brushType == 9; // Blur if (writeTC) { frag.write('fragColor[2] = vec4(posa - posb, texCoord.xy);'); diff --git a/Sources/arm/renderpath/RenderPathDeferred.hx b/Sources/arm/renderpath/RenderPathDeferred.hx index 0109f089..b33899e2 100644 --- a/Sources/arm/renderpath/RenderPathDeferred.hx +++ b/Sources/arm/renderpath/RenderPathDeferred.hx @@ -247,7 +247,8 @@ class RenderPathDeferred { // Read texcoords from gbuffer var readTC = (UITrait.inst.brushType == 2 && UITrait.inst.fillTypeHandle.position == 1) || // Face fill - UITrait.inst.brushType == 8; // Clone + UITrait.inst.brushType == 8 || // Clone + UITrait.inst.brushType == 9; // Blur if (readTC) { path.bindTarget("gbuffer2", "gbuffer2"); } diff --git a/Sources/arm/ui/UITrait.hx b/Sources/arm/ui/UITrait.hx index b7c1a452..a4e1abb2 100644 --- a/Sources/arm/ui/UITrait.hx +++ b/Sources/arm/ui/UITrait.hx @@ -510,12 +510,13 @@ class UITrait extends iron.Trait { else if (kb.started("t")) selectTool(6); // Text else if (kb.started("s")) selectTool(7); // Shape else if (kb.started("l")) selectTool(8); // Clone - // else if (kb.started("p")) selectTool(8); // Particle + else if (kb.started("u")) selectTool(9); // Blur + // else if (kb.started("p")) selectTool(10); // Particle } // Radius if (!ctrl && !shift) { - if (brushType == 0 || brushType == 1 || brushType == 5 || brushType == 6 || brushType == 7) { // Draw, erase, decal, text + if (brushType == 0 || brushType == 1 || brushType == 5 || brushType == 6 || brushType == 7 || brushType == 8 || brushType == 9) { // Draw, erase, decal, text, shape, clone, blur if (kb.started("f")) { brushCanLock = true; mouse.lock(); @@ -905,6 +906,13 @@ class UITrait extends iron.Trait { g.color = 0xffffffff; } + var kb = iron.system.Input.getKeyboard(); + if (brushType == 8 && !kb.down("alt") && (mouse.down() || pen.down())) { // Clone source cursor + g.color = 0x66ffffff; + g.drawScaledImage(cursorImg, mx + cloneDeltaX * iron.App.w() - psize / 2, my + cloneDeltaY * iron.App.h() - psize / 2, psize, psize); + g.color = 0xffffffff; + } + if (showGrid) { // Separator line var x1 = iron.App.x() + iron.App.w() / 3; @@ -1108,9 +1116,16 @@ class UITrait extends iron.Trait { ui._x -= 2; ui._y += 2; + ui._x += 2; + if (brushType == 9) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2); + if (ui.image(img9) == State.Started) selectTool(9); + if (ui.isHovered) ui.tooltip("Blur (U)"); + ui._x -= 2; + ui._y += 2; + // ui._x += 2; - // if (brushType == 8) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2); - // if (ui.image(img9) == State.Started) selectTool(8); + // if (brushType == 10) ui.rect(-1, -1, img1.width + 2, img1.height + 2, ui.t.HIGHLIGHT_COL, 2); + // if (ui.image(img11) == State.Started) selectTool(10); // if (ui.isHovered) ui.tooltip("Particle (P)"); // ui._x -= 2; // ui._y += 2;