#if SPECIAL #include "main.h" #endif 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_newlayer_source; } 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 & 0x01) { 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(); }