1 /* 2 Copyright © 2022, Inochi2D Project 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module creator.windows.imgexport; 8 import creator.windows; 9 import creator.widgets; 10 import creator.core; 11 import creator.core.i18n; 12 import creator; 13 import std.string; 14 import creator.utils.link; 15 import creator.ext; 16 import creator.io; 17 import i18n; 18 import inmath; 19 import inochi2d; 20 21 /** 22 Settings window 23 */ 24 class ImageExportWindow : Window { 25 private: 26 string outFile; 27 ExCamera selectedCamera; 28 ExCamera[] cameras; 29 bool transparency; 30 bool postprocessing; 31 32 void export_() { 33 Camera cam = selectedCamera.getCamera(); 34 vec2 vp = selectedCamera.getViewport(); 35 36 Camera oc; 37 float or, og, ob, oa; 38 int ow, oh; 39 inGetViewport(ow, oh); 40 oc = inGetCamera(); 41 42 // Set state for dumping viewport 43 inSetCamera(cam); 44 inSetViewport(cast(int)vp.x, cast(int)vp.y); 45 if (transparency) { 46 inGetClearColor(or, og, ob, oa); 47 inSetClearColor(0, 0, 0, 0); 48 } 49 50 // Render viewport 51 inBeginScene(); 52 incActivePuppet().draw(); 53 inEndScene(); 54 if (postprocessing) inPostProcessScene(); 55 56 // Dump to file 57 ubyte[] data = new ubyte[inViewportDataLength()]; 58 inDumpViewport(data); 59 incExportImage(outFile, data, cast(int)vp.x, cast(int)vp.y); 60 61 // Reset state 62 if (transparency) inSetClearColor(or, og, ob, oa); 63 inSetViewport(ow, oh); 64 inSetCamera(oc); 65 } 66 67 protected: 68 override 69 void onBeginUpdate() { 70 flags |= ImGuiWindowFlags.NoSavedSettings; 71 72 ImVec2 wpos = ImVec2( 73 igGetMainViewport().Pos.x+(igGetMainViewport().Size.x/2), 74 igGetMainViewport().Pos.y+(igGetMainViewport().Size.y/2), 75 ); 76 77 ImVec2 uiSize = ImVec2( 78 512, 79 256 80 ); 81 82 igSetNextWindowPos(wpos, ImGuiCond.Appearing, ImVec2(0.5, 0.5)); 83 igSetNextWindowSize(uiSize, ImGuiCond.Appearing); 84 igSetNextWindowSizeConstraints(uiSize, ImVec2(float.max, float.max)); 85 super.onBeginUpdate(); 86 } 87 88 override 89 void onUpdate() { 90 91 // Contents 92 if (igBeginChild("ExportContent", ImVec2(0, -28), true)) { 93 incText(_("Export Settings")); 94 95 igSpacing(); 96 97 if (incBeginCategory(__("Camera"))) { 98 if (igBeginCombo("###CAMERA", selectedCamera.name.toStringz)) { 99 100 foreach(ref camera; cameras) { 101 if (igMenuItem(camera.cName)) { 102 selectedCamera = camera; 103 } 104 } 105 106 igEndCombo(); 107 } 108 109 igSpacing(); 110 igCheckbox(__("Allow Transparency"), &transparency); 111 igCheckbox(__("Use Post Processing"), &postprocessing); 112 } 113 incEndCategory(); 114 } 115 igEndChild(); 116 117 // Bottom buttons 118 if (igBeginChild("ExportButtons", ImVec2(0, 0), false, ImGuiWindowFlags.NoScrollbar)) { 119 incDummy(ImVec2(-64, 0)); 120 igSameLine(0, 0); 121 122 if (igButton(__("Save"), ImVec2(64, 24))) { 123 this.export_(); 124 this.close(); 125 } 126 } 127 igEndChild(); 128 } 129 130 public: 131 this(string outFile) { 132 super(_("Export Image...")); 133 134 this.outFile = outFile; 135 136 // Search for cameras 137 cameras = incActivePuppet().findNodesType!ExCamera(incActivePuppet().root); 138 if (cameras.length == 0) { 139 incDialog("Error", "No cameras to export from in Scene, please add a Camera."); 140 this.close(); 141 return; 142 } 143 144 selectedCamera = cameras[0]; 145 } 146 }