From bc5e89a834954767075e7c7b2c3ad1fdc344b682 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Wed, 19 Jun 2019 09:40:14 +0200 Subject: [PATCH] 16/32bit exr texture export --- Sources/arm/Exporter.hx | 278 ++++++++---------------------------- Sources/arm/LayerSlot.hx | 68 +++------ Sources/arm/Layers.hx | 9 +- Sources/arm/Project.hx | 4 +- Sources/arm/io/ExportArm.hx | 16 +++ Sources/arm/io/ExportObj.hx | 48 +++++++ Sources/arm/ui/UITrait.hx | 15 +- 7 files changed, 155 insertions(+), 283 deletions(-) create mode 100644 Sources/arm/io/ExportArm.hx create mode 100644 Sources/arm/io/ExportObj.hx diff --git a/Sources/arm/Exporter.hx b/Sources/arm/Exporter.hx index b3c8f5e9..5a3506b1 100644 --- a/Sources/arm/Exporter.hx +++ b/Sources/arm/Exporter.hx @@ -6,13 +6,45 @@ import arm.ui.UIBox; class Exporter { + static inline var gamma = 1.0 / 2.2; + + static function writeTexture(file:String, pixels:haxe.io.Bytes, type = 1, off = 0) { + var out = new haxe.io.BytesOutput(); + var res = Config.getTextureRes(); + var bitsHandle = UITrait.inst.bitsHandle.position; + var bits = bitsHandle == 0 ? 8 : bitsHandle == 1 ? 16 : 32; + if (bits > 8) { // 16/32bit + var writer = new iron.format.exr.Writer(out, res, res, pixels, bits, type, off); + } + else if (UITrait.inst.formatType == 0) { + var writer = new iron.format.jpg.Writer(out); + writer.write({ + width: res, + height: res, + quality: UITrait.inst.formatQuality, + pixels: pixels + }, type, off); + } + else { + var writer = new iron.format.png.Writer(out); + var data = type == 1 ? + iron.format.png.Tools.build32RGBA(res, res, pixels) : + iron.format.png.Tools.build32RGBA_(res, res, pixels, off); + writer.write(data); + } + #if kha_krom + Krom.fileSaveBytes(file, out.getBytes().getData()); + #end + } + public static function exportTextures(path:String) { var textureSize = Config.getTextureRes(); var formatQuality = UITrait.inst.formatQuality; var f = arm.App.filenameHandle.text; if (f == "") f = "untitled"; var formatType = UITrait.inst.formatType; - var ext = formatType == 0 ? ".jpg" : formatType == 1 ? ".png" : ".tga"; + var bits = UITrait.inst.bitsHandle.position == 0 ? 8 : 16; + var ext = bits == 16 ? ".exr" : formatType == 0 ? ".jpg" : ".png"; if (StringTools.endsWith(f, ext)) f = f.substr(0, f.length - 4); var texpaint:kha.Image = null; var texpaint_nor:kha.Image = null; @@ -115,227 +147,76 @@ class Exporter { } } - var bo = new haxe.io.BytesOutput(); var pixels:haxe.io.Bytes = null; if (UITrait.inst.isBase || UITrait.inst.isOpac) { pixels = texpaint.getPixels(); // bgra if (UITrait.inst.isBase && UITrait.inst.isBaseSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, 1.0 / 2.2) * 255)); - pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, 1.0 / 2.2) * 255)); - pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, gamma) * 255)); + pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, gamma) * 255)); + pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, gamma) * 255)); } } if (UITrait.inst.isOpac && UITrait.inst.isOpacSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 + 3, Std.int(Math.pow(pixels.get(i * 4 + 3) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 + 3, Std.int(Math.pow(pixels.get(i * 4 + 3) / 255, gamma) * 255)); } } - if (UITrait.inst.isBase) { - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 1); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA(textureSize, textureSize, pixels)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_base" + ext, bo.getBytes().getData()); - #end - } - if (UITrait.inst.isOpac) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 2, 3); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA(textureSize, textureSize, pixels, 3)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_opac" + ext, bo.getBytes().getData()); - #end - } + if (UITrait.inst.isBase) writeTexture(path + "/" + f + "_base" + ext, pixels); + if (UITrait.inst.isOpac) writeTexture(path + "/" + f + "_opac" + ext, pixels, 2, 3); } + + if (UITrait.inst.isNor) { pixels = texpaint_nor.getPixels(); if (UITrait.inst.isNorSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, 1.0 / 2.2) * 255)); - pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, 1.0 / 2.2) * 255)); - pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, gamma) * 255)); + pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, gamma) * 255)); + pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, gamma) * 255)); } } - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 1); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA(textureSize, textureSize, pixels)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_nor" + ext, bo.getBytes().getData()); - #end + writeTexture(path + "/" + f + "_nor" + ext, pixels); } if (UITrait.inst.isOcc || UITrait.inst.isRough || UITrait.inst.isMet || UITrait.inst.isHeight) { - pixels = texpaint_pack.getPixels(); // occ, rough, met, height - if (UITrait.inst.isOcc && UITrait.inst.isOccSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 + 2, Std.int(Math.pow(pixels.get(i * 4 + 2) / 255, gamma) * 255)); } } if (UITrait.inst.isRough && UITrait.inst.isRoughSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 + 1, Std.int(Math.pow(pixels.get(i * 4 + 1) / 255, gamma) * 255)); } } if (UITrait.inst.isMet && UITrait.inst.isMetSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 , Std.int(Math.pow(pixels.get(i * 4 ) / 255, gamma) * 255)); } } if (UITrait.inst.isHeight && UITrait.inst.isHeightSpace == 1) { for (i in 0...Std.int(pixels.length / 4)) { - pixels.set(i * 4 + 3, Std.int(Math.pow(pixels.get(i * 4 + 3) / 255, 1.0 / 2.2) * 255)); + pixels.set(i * 4 + 3, Std.int(Math.pow(pixels.get(i * 4 + 3) / 255, gamma) * 255)); } } if (UITrait.inst.outputType == 0) { - - if (UITrait.inst.isOcc) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 2, 0); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA_(textureSize, textureSize, pixels, 0)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_occ" + ext, bo.getBytes().getData()); - #end - } - - if (UITrait.inst.isRough) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 2, 1); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA_(textureSize, textureSize, pixels, 1)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_rough" + ext, bo.getBytes().getData()); - #end - } - - if (UITrait.inst.isMet) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 2, 2); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA_(textureSize, textureSize, pixels, 2)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_met" + ext, bo.getBytes().getData()); - #end - } + if (UITrait.inst.isOcc) writeTexture(path + "/" + f + "_occ" + ext, pixels, 2, 0); + if (UITrait.inst.isRough) writeTexture(path + "/" + f + "_rough" + ext, pixels, 2, 1); + if (UITrait.inst.isMet) writeTexture(path + "/" + f + "_met" + ext, pixels, 2, 2); } else { // UE4 if (UITrait.inst.isOcc || UITrait.inst.isRough || UITrait.inst.isMet) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 1); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA(textureSize, textureSize, pixels)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_orm" + ext, bo.getBytes().getData()); - #end + writeTexture(path + "/" + f + "_orm" + ext, pixels); } } - if (UITrait.inst.isHeight) { - bo = new haxe.io.BytesOutput(); - if (formatType == 0) { - var jpgdata:iron.format.jpg.Data.Data = { - width: textureSize, - height: textureSize, - quality: formatQuality, - pixels: pixels - }; - var jpgwriter = new iron.format.jpg.Writer(bo); - jpgwriter.write(jpgdata, 2, 3); - } - else { - var pngwriter = new iron.format.png.Writer(bo); - pngwriter.write(iron.format.png.Tools.build32RGBA(textureSize, textureSize, pixels, 3)); - } - #if kha_krom - Krom.fileSaveBytes(path + "/" + f + "_height" + ext, bo.getBytes().getData()); - #end - } + if (UITrait.inst.isHeight) writeTexture(path + "/" + f + "_height" + ext, pixels, 2, 3); } // if (UITrait.inst.isEmis) Krom.fileSaveBytes(path + "/tex_emis" + ext, bo.getBytes().getData()); @@ -343,54 +224,7 @@ class Exporter { } public static function exportMesh(path:String) { - if (UITrait.inst.exportMeshFormat == 0) { // .obj - var s = ""; - var off = 0; - for (p in UITrait.inst.paintObjects) { - var mesh = p.data.raw; - var sc = p.data.scalePos; - var posa = mesh.vertex_arrays[0].values; - var nora = mesh.vertex_arrays[1].values; - var texa = mesh.vertex_arrays[2].values; - var len = Std.int(posa.length / 4); - s += "o " + p.name + "\n"; - for (i in 0...len) { - s += "v " + posa[i * 4 ] * sc + " " + - posa[i * 4 + 2] * sc + " " + - (-posa[i * 4 + 1] * sc) + "\n"; - } - for (i in 0...len) { - s += "vn " + nora[i * 2 ] + " " + - posa[i * 4 + 3] + " " + - (-nora[i * 2 + 1]) + "\n"; - } - for (i in 0...len) { - s += "vt " + texa[i * 2 ] + " " + - (1.0 - texa[i * 2 + 1]) + "\n"; - } - var inda = mesh.index_arrays[0].values; - for (i in 0...Std.int(inda.length / 3)) { - var i1 = inda[i * 3 ] + 1 + off; - var i2 = inda[i * 3 + 1] + 1 + off; - var i3 = inda[i * 3 + 2] + 1 + off; - s += "f " + i1 + "/" + i1 + "/" + i1 + " " + - i2 + "/" + i2 + "/" + i2 + " " + - i3 + "/" + i3 + "/" + i3 + "\n"; - } - off += inda.length; - } - if (!StringTools.endsWith(path, ".obj")) path += ".obj"; - #if kha_krom - Krom.fileSaveBytes(path, haxe.io.Bytes.ofString(s).getData()); - #end - } - else { // .arm - var raw:TSceneFormat = { mesh_datas: [ UITrait.inst.paintObject.data.raw ] }; - var b = iron.system.ArmPack.encode(raw); - if (!StringTools.endsWith(path, ".arm")) path += ".arm"; - #if kha_krom - Krom.fileSaveBytes(path, b.getData()); - #end - } + if (UITrait.inst.exportMeshFormat == 0) arm.io.ExportObj.run(path); + else arm.io.ExportArm.run(path); } } diff --git a/Sources/arm/LayerSlot.hx b/Sources/arm/LayerSlot.hx index 9946d0c3..ae728e3b 100644 --- a/Sources/arm/LayerSlot.hx +++ b/Sources/arm/LayerSlot.hx @@ -72,7 +72,8 @@ class LayerSlot { } this.ext = ext; name = "Layer " + (id + 1); - var format = UITrait.inst.bitsHandle.position == 0 ? 'RGBA32' : 'RGBA64'; + var format = UITrait.inst.bitsHandle.position == 0 ? 'RGBA32' : + UITrait.inst.bitsHandle.position == 1 ? 'RGBA64' : 'RGBA128'; { var t = new RenderTargetRaw(); @@ -274,7 +275,10 @@ class LayerSlot { return l; } - public function resize() { + public function resizeAndSetBits() { + var format = UITrait.inst.bitsHandle.position == 0 ? TextureFormat.RGBA32 : + UITrait.inst.bitsHandle.position == 1 ? TextureFormat.RGBA64 : TextureFormat.RGBA128; + var res = Config.getTextureRes(); var rts = RenderPath.active.renderTargets; @@ -282,53 +286,6 @@ class LayerSlot { var texpaint_nor = this.texpaint_nor; var texpaint_pack = this.texpaint_pack; - this.texpaint = kha.Image.createRenderTarget(res, res, TextureFormat.RGBA32); - this.texpaint_nor = kha.Image.createRenderTarget(res, res, TextureFormat.RGBA32); - this.texpaint_pack = kha.Image.createRenderTarget(res, res, TextureFormat.RGBA32); - - this.texpaint.g2.begin(false); - this.texpaint.g2.drawScaledImage(texpaint, 0, 0, res, res); - this.texpaint.g2.end(); - - this.texpaint_nor.g2.begin(false); - this.texpaint_nor.g2.drawScaledImage(texpaint_nor, 0, 0, res, res); - this.texpaint_nor.g2.end(); - - this.texpaint_pack.g2.begin(false); - this.texpaint_pack.g2.drawScaledImage(texpaint_pack, 0, 0, res, res); - this.texpaint_pack.g2.end(); - - texpaint.unload(); - texpaint_nor.unload(); - texpaint_pack.unload(); - - rts.get("texpaint" + this.ext).image = this.texpaint; - rts.get("texpaint_nor" + this.ext).image = this.texpaint_nor; - rts.get("texpaint_pack" + this.ext).image = this.texpaint_pack; - - if (this.texpaint_mask != null) { - var texpaint_mask = this.texpaint_mask; - this.texpaint_mask = kha.Image.createRenderTarget(res, res, TextureFormat.L8); - - this.texpaint_mask.g2.begin(false); - this.texpaint_mask.g2.drawScaledImage(texpaint_mask, 0, 0, res, res); - this.texpaint_mask.g2.end(); - - texpaint_mask.unload(); - - rts.get("texpaint_mask" + this.ext).image = this.texpaint_mask; - } - } - - public function setBits(formatName:String) { - var format = formatName == "RGBA32" ? TextureFormat.RGBA32 : TextureFormat.RGBA64; - var res = this.texpaint.width; - var rts = RenderPath.active.renderTargets; - - var texpaint = this.texpaint; - var texpaint_nor = this.texpaint_nor; - var texpaint_pack = this.texpaint_pack; - this.texpaint = kha.Image.createRenderTarget(res, res, format); this.texpaint_nor = kha.Image.createRenderTarget(res, res, format); this.texpaint_pack = kha.Image.createRenderTarget(res, res, format); @@ -352,5 +309,18 @@ class LayerSlot { rts.get("texpaint" + this.ext).image = this.texpaint; rts.get("texpaint_nor" + this.ext).image = this.texpaint_nor; rts.get("texpaint_pack" + this.ext).image = this.texpaint_pack; + + if (this.texpaint_mask != null && this.texpaint_mask.width != res) { + var texpaint_mask = this.texpaint_mask; + this.texpaint_mask = kha.Image.createRenderTarget(res, res, TextureFormat.L8); + + this.texpaint_mask.g2.begin(false); + this.texpaint_mask.g2.drawScaledImage(texpaint_mask, 0, 0, res, res); + this.texpaint_mask.g2.end(); + + texpaint_mask.unload(); + + rts.get("texpaint_mask" + this.ext).image = this.texpaint_mask; + } } } diff --git a/Sources/arm/Layers.hx b/Sources/arm/Layers.hx index 606d4419..ac4e175f 100644 --- a/Sources/arm/Layers.hx +++ b/Sources/arm/Layers.hx @@ -90,8 +90,8 @@ class Layers { while (UITrait.inst.undoLayers.length > C.undo_steps) { var l = UITrait.inst.undoLayers.pop(); l.unload(); } } g.end(); - for (l in UITrait.inst.layers) l.resize(); - for (l in UITrait.inst.undoLayers) l.resize(); + for (l in UITrait.inst.layers) l.resizeAndSetBits(); + for (l in UITrait.inst.undoLayers) l.resizeAndSetBits(); var rts = RenderPath.active.renderTargets; rts.get("texpaint_blend0").image.unload(); rts.get("texpaint_blend0").raw.width = Config.getTextureRes(); @@ -109,9 +109,8 @@ class Layers { public static function setLayerBits(g:kha.graphics4.Graphics) { g.end(); - var format = UITrait.inst.bitsHandle.position == 0 ? 'RGBA32' : 'RGBA64'; - for (l in UITrait.inst.layers) l.setBits(format); - for (l in UITrait.inst.undoLayers) l.setBits(format); + for (l in UITrait.inst.layers) l.resizeAndSetBits(); + for (l in UITrait.inst.undoLayers) l.resizeAndSetBits(); g.begin(); iron.App.removeRender(setLayerBits); } diff --git a/Sources/arm/Project.hx b/Sources/arm/Project.hx index 2eda0671..e5c45465 100644 --- a/Sources/arm/Project.hx +++ b/Sources/arm/Project.hx @@ -360,8 +360,8 @@ class Project { UITrait.inst.resHandle.position = Config.getTextureResPos(project.layer_datas[0].res); if (UITrait.inst.layers[0].texpaint.width != Config.getTextureRes()) { - for (l in UITrait.inst.layers) l.resize(); - if (UITrait.inst.undoLayers != null) for (l in UITrait.inst.undoLayers) l.resize(); + for (l in UITrait.inst.layers) l.resizeAndSetBits(); + if (UITrait.inst.undoLayers != null) for (l in UITrait.inst.undoLayers) l.resizeAndSetBits(); var rts = iron.RenderPath.active.renderTargets; rts.get("texpaint_blend0").image.unload(); rts.get("texpaint_blend0").raw.width = Config.getTextureRes(); diff --git a/Sources/arm/io/ExportArm.hx b/Sources/arm/io/ExportArm.hx new file mode 100644 index 00000000..13a4970f --- /dev/null +++ b/Sources/arm/io/ExportArm.hx @@ -0,0 +1,16 @@ +package arm.io; + +import iron.data.SceneFormat; +import arm.ui.UITrait; + +class ExportArm { + + public static function run(path:String) { + var raw:TSceneFormat = { mesh_datas: [ UITrait.inst.paintObject.data.raw ] }; + var b = iron.system.ArmPack.encode(raw); + if (!StringTools.endsWith(path, ".arm")) path += ".arm"; + #if kha_krom + Krom.fileSaveBytes(path, b.getData()); + #end + } +} diff --git a/Sources/arm/io/ExportObj.hx b/Sources/arm/io/ExportObj.hx new file mode 100644 index 00000000..bc42f582 --- /dev/null +++ b/Sources/arm/io/ExportObj.hx @@ -0,0 +1,48 @@ +package arm.io; + +import arm.ui.UITrait; + +class ExportObj { + + public static function run(path:String) { + var s = ""; + var off = 0; + for (p in UITrait.inst.paintObjects) { + var mesh = p.data.raw; + var sc = p.data.scalePos; + var posa = mesh.vertex_arrays[0].values; + var nora = mesh.vertex_arrays[1].values; + var texa = mesh.vertex_arrays[2].values; + var len = Std.int(posa.length / 4); + s += "o " + p.name + "\n"; + for (i in 0...len) { + s += "v " + posa[i * 4 ] * sc + " " + + posa[i * 4 + 2] * sc + " " + + (-posa[i * 4 + 1] * sc) + "\n"; + } + for (i in 0...len) { + s += "vn " + nora[i * 2 ] + " " + + posa[i * 4 + 3] + " " + + (-nora[i * 2 + 1]) + "\n"; + } + for (i in 0...len) { + s += "vt " + texa[i * 2 ] + " " + + (1.0 - texa[i * 2 + 1]) + "\n"; + } + var inda = mesh.index_arrays[0].values; + for (i in 0...Std.int(inda.length / 3)) { + var i1 = inda[i * 3 ] + 1 + off; + var i2 = inda[i * 3 + 1] + 1 + off; + var i3 = inda[i * 3 + 2] + 1 + off; + s += "f " + i1 + "/" + i1 + "/" + i1 + " " + + i2 + "/" + i2 + "/" + i2 + " " + + i3 + "/" + i3 + "/" + i3 + "\n"; + } + off += inda.length; + } + if (!StringTools.endsWith(path, ".obj")) path += ".obj"; + #if kha_krom + Krom.fileSaveBytes(path, haxe.io.Bytes.ofString(s).getData()); + #end + } +} diff --git a/Sources/arm/ui/UITrait.hx b/Sources/arm/ui/UITrait.hx index 666064c7..f8c74977 100644 --- a/Sources/arm/ui/UITrait.hx +++ b/Sources/arm/ui/UITrait.hx @@ -485,7 +485,7 @@ class UITrait extends iron.Trait { arm.App.whandle.redraws = 2; arm.App.foldersOnly = true; arm.App.showFilename = true; - UIFiles.filters = formatType == 0 ? "jpg" : "png"; + UIFiles.filters = bitsHandle.position > 0 ? "exr" : formatType == 0 ? "jpg" : "png"; arm.App.filesDone = function(path:String) { textureExport = true; textureExportPath = path; @@ -2268,7 +2268,7 @@ class UITrait extends iron.Trait { arm.App.foldersOnly = true; arm.App.showFilename = true; // var path = 'C:\\Users\\lubos\\Documents\\'; - UIFiles.filters = formatType == 0 ? "jpg" : "png"; + UIFiles.filters = bitsHandle.position > 0 ? "exr" : formatType == 0 ? "jpg" : "png"; arm.App.filesDone = function(path:String) { textureExport = true; textureExportPath = path; @@ -2285,14 +2285,19 @@ class UITrait extends iron.Trait { UVUtil.trianglemap = null; UVUtil.trianglemapCached = false; } - ui.combo(bitsHandle, ["8bit", "16bit"], "Color", true); + ui.combo(bitsHandle, ["8bit", "16bit", "32bit"], "Color", true); if (bitsHandle.changed) { iron.App.notifyOnRender(Layers.setLayerBits); } ui.row([1/2, 1/2]); - formatType = ui.combo(Id.handle({position: formatType}), ["jpg", "png"], "Format", true); - ui.enabled = formatType == 0; + if (bitsHandle.position == 0) { + formatType = ui.combo(Id.handle({position: formatType}), ["jpg", "png"], "Format", true); + } + else { + ui.combo(Id.handle({position: formatType}), ["exr"], "Format", true); + } + ui.enabled = formatType == 0 && bitsHandle.position == 0; formatQuality = ui.slider(Id.handle({value: formatQuality}), "Quality", 0.0, 100.0, true, 1); ui.enabled = true; ui.row([1/2, 1/2]);