summaryrefslogtreecommitdiff
path: root/src/imgui_ui_stable_diffusion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imgui_ui_stable_diffusion.cpp')
-rw-r--r--src/imgui_ui_stable_diffusion.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/imgui_ui_stable_diffusion.cpp b/src/imgui_ui_stable_diffusion.cpp
new file mode 100644
index 0000000..a5c93c6
--- /dev/null
+++ b/src/imgui_ui_stable_diffusion.cpp
@@ -0,0 +1,175 @@
+static void
+ImGui_SD_Thumbnail(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io,
+ sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 *SourceArray, uint16 SourceCount)
+{
+ ImGui::Begin("SD gallery");
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
+ ImVec2 ViewportMin = ImGui::GetCursorScreenPos();
+ ImVec2 ViewportScale = ImGui::GetContentRegionAvail();
+ ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y);
+ if (!SourceCount || ViewportScale.x < 50) {
+ ImGui::End();
+ return;
+ }
+ int test[16];
+ int count = 0;
+ // draw_list->AddImage((void *)(intptr_t)textureID, ViewportMin, ViewportMax);
+ uint32 T_Height = 128;
+ real32 RowPercent = (real32)ViewportScale.x / T_Height;
+ uint32 PerRow = (uint32)RowPercent;
+ uint32 UI_Size = T_Height;
+ bool32 Active = false;
+ for (int i = 0; i < SourceCount; i++) {
+ int32 Y = i / PerRow;
+ int32 X = i % PerRow;
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, SourceArray[i]);
+ // ImGui::Text("Count: %i", Source->RelativeTimestamp);
+ real32 Ratio = (real32)Source->Width / Source->Height;
+ uint32 T_Width = (uint32)(Ratio * T_Height);
+ if (Source->ThumbnailTex == 0) {
+ Source_DumpThumbnail(Memory, Source, T_Width, T_Height);
+ }
+ // draw_list->AddRect(ImgMin, ImgMax, IM_COL32(255, 255, 255, 64));
+ ImVec2 ImgMin = ViewportMin + ImVec2(X * UI_Size, Y * UI_Size);
+ ImGui::SetCursorScreenPos(ImgMin);
+ real32 ClosestSpacing = 0.2;
+ bool32 Wide = (Source->Width > Source->Height);
+ // ImVec2 Min = (Wide) ? ImVec2(0,ClosestSpacing) : ImVec2(ClosestSpacing,0);
+ // ImVec2 Max = (Wide) ? ImVec2(1-ClosestSpacing,1) : ImVec2(1,1-ClosestSpacing);
+ ImVec2 Min(0.2, 0.2);
+ ImVec2 Max(0.8, 0.8);
+ ImGui::ImageButton((void *)(intptr_t)Source->ThumbnailTex, ImVec2(UI_Size, UI_Size), Min, Max, 12);
+ // ImGui::ImageButton(user_texture_id, & sizeconst ImVec2& = ImVec2(0, 0), = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
+ // ImVec2 ImgMax = ImgMin + ImVec2(UI_Size * Ratio, UI_Size);
+ // ImGui::Button("##thumbnail", ImVec2(UI_Size, UI_Size));
+ // draw_list->AddImage((void *)(intptr_t)Source->ThumbnailTex, ImgMin, ImgMax);
+
+ if (ImGui::IsItemHovered()) {
+ State->PreviewSource = SourceArray[i];
+ State->UpdateFrame = true;
+ Active = true;
+ block_source *Source1 = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, 1);
+ block_source *Source2 = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, 2);
+ block_source *Source0 = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, 0);
+ real32 a = 0;
+ }
+
+ if (ImGui::IsItemClicked() || ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
+ if (!io.KeyShift && !Source->IsSelected) {
+ Source_DeselectAll(File, Memory);
+ }
+ Source->IsSelected = 1;
+ }
+ ImGui::OpenPopupOnItemClick("temptosource", ImGuiPopupFlags_MouseButtonRight);
+ }
+ if (State->PreviewSource != -1 && !Active) {
+ State->PreviewSource = -1;
+ State->UpdateFrame = true;
+ }
+ if (ImGui::BeginPopup("temptosource")) {
+ if (ImGui::MenuItem("Create layer from source")) {
+ State->HotkeyInput = hotkey_newlayerfromsource;
+ }
+ ImGui::EndPopup();
+ }
+
+ ImGui::End();
+}
+
+static void
+ImGui_SD_Prompt(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io,
+ sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray)
+{
+ sorted_comp_array *SortedCompStart = &SortedCompArray[File->PrincipalCompIndex];
+ sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray,File->PrincipalCompIndex);
+ ImGui::Begin("SD prompt input");
+ sd_state *SD = &File->UI.SD;
+ int Size = ImGui::GetFontSize();
+ ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(200, 80, 0, 255));
+ if (ImGui::Button("Generate!", ImVec2(Size*8, Size*2))) {
+ if (!State->CurlActive) {
+ if (SD->Mode) {
+ block_layer *Layer = NULL;
+ for (int i = SortedCompStart->LayerCount - 1; i >= 0; i--) {
+ sorted_layer_array SortEntry = SortedLayerStart[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ if (TestLayer->IsSelected) {
+ Layer = TestLayer;
+ break;
+ }
+ }
+ if (Layer) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ void *BitmapAddress;
+ if (Source->Type == source_type_principal) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0);
+ }
+ else if (Source->Type == source_type_file) {
+ cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, 0);
+ Assert(Entry->IsCached);
+ BitmapAddress = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry->Block_StartIndex);
+ }
+ uint64 Size = Source->Width * Source->Height * Source->BytesPerPixel;
+
+ int32 len = 0;
+ uint8 *PNGBitmap = stbi_write_png_to_mem((uint8 *)BitmapAddress, Source->Width * Source->BytesPerPixel,
+ Source->Width, Source->Height, Source->BytesPerPixel, &len);
+ Assert(PNGBitmap);
+
+ uint64 EncodedEstimateSize = base64_encode_size((size_t)Size);
+ uint8 *EncodedOutput = (uint8 *)Memory_PushScratch(Memory, EncodedEstimateSize);
+ uint64 EncodedTrueSize = 0;
+
+ base64_encode((uint8 *)PNGBitmap, len, EncodedOutput, (size_t *)&EncodedTrueSize);
+ Assert(EncodedOutput[EncodedTrueSize] == '\0');
+ // printf("%s", EncodedOutput);
+
+ STBIW_FREE(PNGBitmap);
+
+ SD_AssembleJSON(SD, (char *)State->JSONPayload, EncodedOutput);
+ Memory_PopScratch(Memory, EncodedEstimateSize);
+ State->CurlActive = -1;
+ }
+ } else {
+ SD_AssembleJSON(SD, State->JSONPayload);
+ // SD_AssembleJSON(SD, (char *)State->Dump2);
+ State->CurlActive = -1;
+ }
+ }
+ }
+ ImGui::PopStyleColor();
+ if (State->CurlActive) {
+ ImGui::SameLine();
+ ImGui::Text("Est. time: %.1f sec, %.2f", State->SDTimeEstimate, State->SDPercentDone*100);
+ }
+ ImGui::InputText("Address", SD->ServerAddress, SD_LEN_ADDRESS);
+ if (SD->ServerAddress[0] == '\0' && SD->Prompt[0] == '\0') {
+ sprintf(SD->Prompt, "%s", "highres");
+ sprintf(SD->NegPrompt, "%s", "nsfw, \ntext, \ncropped, \nworst quality, \nlow quality, \nnormal quality, \njpeg artifacts, \nsignature, \nwatermark");
+ sprintf(SD->ServerAddress, "%s", "http://127.0.0.1:7860");
+ }
+ if (ImGui::Selectable("txt2img", !SD->Mode))
+ SD->Mode = 0;
+ if (ImGui::Selectable("img2img", SD->Mode))
+ SD->Mode = 1;
+ ImGui::InputTextMultiline("Prompt", SD->Prompt, SD_LEN_PROMPT);
+ ImGui::InputTextMultiline("Negative prompt", SD->NegPrompt, SD_LEN_PROMPT);
+ ImGui::SliderInt("Steps", &SD->Steps, 0, 150);
+ ImGui::SliderInt("Width", &SD->Width, 64, 2048, "%i px");
+ if (ImGui::IsItemDeactivatedAfterEdit()) {
+ SD->Width = SD->Width + (64 - (SD->Width % 64));
+ }
+ ImGui::SliderInt("Height", &SD->Height, 64, 2048, "%i px");
+ if (ImGui::IsItemDeactivatedAfterEdit()) {
+ SD->Height = SD->Height + (64 - (SD->Height % 64));
+ }
+ ImGui::SliderFloat("CFG scale", &SD->CFG, 1, 30, "%.2f");
+ if (SD->Mode) {
+ ImGui::SliderFloat("Denoising strength", &SD->DenoisingStrength, 0, 1, "%.2f");
+ }
+ ImGui::SliderInt("Batch size", &SD->BatchSize, 1, 8, "%i");
+ ImGui::InputInt("Seed", &SD->Seed);
+ ImGui::End();
+}