From 17bee519ece8fc2bc356956841fed97286d24139 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Thu, 24 Nov 2022 01:16:54 -0500 Subject: legwork --- createcalls.cpp | 37 +++++++++++- defines.h | 2 +- effects.h | 70 ----------------------- effects_constructors.cpp | 4 ++ effects_gl.cpp | 101 --------------------------------- effects_software.cpp | 143 +++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 95 ++++++++++++++----------------- memory.cpp | 4 +- my_imgui_widgets.cpp | 48 ++++++++++++---- stable_diffusion.cpp | 2 +- stable_diffusion.h | 6 +- 11 files changed, 267 insertions(+), 245 deletions(-) delete mode 100644 effects.h delete mode 100644 effects_gl.cpp diff --git a/createcalls.cpp b/createcalls.cpp index 4d9ea1e..d1d423b 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -360,7 +360,7 @@ Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memor gl_effect_layer TestL = {}; gl_effect_layer TestM = {}; - GL_UpdateTexture(&TestL, EffectBitmapAddress, Width, Height, BytesPerPixel, 0); + GL_UpdateTexture(&TestL, EffectBitmapAddress, Width, Height, BytesPerPixel, 0); GL_UpdateTexture(&TestM, EffectBitmapAddress, Width, Height, BytesPerPixel, 1); for (int i = 0; i < Layer->Block_Effect_Count; i++) @@ -888,8 +888,8 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem Sorted.CompArray = (sorted_comp_info *)Layer_SortedArray; Sorted.LayerArray = (sorted_layer *)((uint8 *)Layer_SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count)); - uint64 PropertyArraySize = sizeof(uint16) * 7 * MAX_KEYFRAMES_PER_BLOCK * File->Layer_Count; - uint64 PropertyInfoSize = sizeof(sorted_property_info) * 7 * File->Layer_Count; + uint64 PropertyArraySize = sizeof(uint16) * 8 * MAX_KEYFRAMES_PER_BLOCK * File->Layer_Count; + uint64 PropertyInfoSize = sizeof(sorted_property_info) * 8 * File->Layer_Count; Sorted.Property_SortSize = PropertyArraySize + PropertyInfoSize; void *Property_SortedArray = Memory_PushScratch(Memory, Sorted.Property_SortSize); Arbitrary_Zero((uint8 *)Property_SortedArray, Sorted.Property_SortSize); @@ -1001,6 +1001,37 @@ void Source_UICreateButton(project_data *File, project_state *State, memory *Mem Source_DeselectAll(File, Memory); } +void Precomp_UIDuplicate(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, + sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) +{ + block_layer *Layer = NULL; + for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) + { + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + if (Layer->IsSelected) { + break; + } + } + if (Layer) { + block_layer *DupeLayer = Layer_Init(File, Memory); + *DupeLayer = *Layer; + DupeLayer->Vertical_Offset += 1; + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + if (Property->Block_Bezier_Count) { + property_channel *DupeProperty = &DupeLayer->Property[h]; + DupeProperty->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier); + block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]); + block_bezier *DupeBezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, DupeProperty->Block_Bezier_Index[0], 0); + Bezier->Occupied = true; + *DupeBezier = *Bezier; + } + } + } +} + void Precomp_UICreateButton(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) { diff --git a/defines.h b/defines.h index 49a1426..f77f68e 100644 --- a/defines.h +++ b/defines.h @@ -33,7 +33,7 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like #define MAX_SOURCES 1024 #define MAX_COMPS 1024 #define MAX_MASKS 8 -#define MAX_PROPERTIES_PER_EFFECT 16 +#define MAX_PROPERTIES_PER_EFFECT 80 // Kinda high since we want to support 8 xy points of Curves data across 5 channels. #define MAX_KEYFRAME_BLOCKS 64 #define MAX_KEYFRAMES_PER_BLOCK 32 // max keyframes on a single channel is 2048 diff --git a/effects.h b/effects.h deleted file mode 100644 index 793cadf..0000000 --- a/effects.h +++ /dev/null @@ -1,70 +0,0 @@ -enum effect_display_type -{ - standard, - levels -}; - -struct effect_supported_renderers -{ - bool32 renderer_effect_gpu; -#if ARM - bool32 renderer_effect_neon; -#else - bool32 renderer_effect_avx; - bool32 renderer_effect_sse; -#endif - bool32 renderer_effect_scalar; -}; - -struct effect_header -{ - char *Name; - void (*func)(source *, layer_bitmap_info *, memory *, property_channel []); - uint16 NumberOfProperties; - effect_display_type DisplayType; - // effect_supported_renderers SupportedRenderers; - property_header PropertyHeader[MAX_PROPERTIES_PER_EFFECT]; -}; - -struct effect { - char *Name; - void (*func)(source *, layer_bitmap_info *, memory *, property_channel []); - uint16 NumberOfProperties; - effect_display_type DisplayType; - property_channel Property[MAX_PROPERTIES_PER_EFFECT]; - bool32 IsSelected = 0; - bool32 UIIsCollapsed = 0; - bool32 IsActive = 1; - uint32 ImGuiID; -}; - - -// TODO(fox): It'd probably be easier if we just switched to constructors at some point. - -static effect_header EffectList[] { - { - "Solid Color", - &Effect_DrawColor, 2, standard, { - {"Color", { V4(0.0f, 0.0f, 0.0f, 1.0f) }, type_color, { NORMALIZED_COL_MIN }, { NORMALIZED_COL_MAX} }, - {"Blend mode", { blend_normal }, type_blendmode}, - } - }, - { - "Levels", - &Effect_Levels, 6, levels, { - {"Start point", {0.0f}, type_real}, - {"Mid point", {1.0f}, type_real}, - {"End point", {1.0f}, type_real}, - {"Start Col", { V4(0.0f)}, type_color}, - {"Mid Col", { V4(1.0f)}, type_color}, - {"End Col", { V4(1.0f)}, type_color}, - } - }, - { - "Gaussian Blur", - &Effect_GaussianBlur, 1, standard, { - {"Radius", {0.0f}, type_real, 0.0f, 500.0f}, - } - } -}; - diff --git a/effects_constructors.cpp b/effects_constructors.cpp index 7f7038d..04594b6 100644 --- a/effects_constructors.cpp +++ b/effects_constructors.cpp @@ -95,6 +95,10 @@ Effect_InitEntries(project_state *State) Effect_AddProperty_Blendmode(State, "Blend mode", blend_softlight); Effect_EndEntry(State); /* + Effect_AddEntry(State, "Curves", "REALCRVS", &Effect_Curves, NULL, effect_display_type_curves); + for (int i = 0; i < MAX_PROPERTIES_PER_EFFECT; i++) { + Effect_AddProperty_Real(State, "point", 0.0f); + } // Gaussian blur Effect_AddEntry(State, "Gaussian blur", "REALGBLR", &Effect_GaussianBlur, GLShader_GaussianBlur); Effect_AddProperty_Real(State, "Radius", 1.0f, 0.0f, 200.0f); diff --git a/effects_gl.cpp b/effects_gl.cpp deleted file mode 100644 index 2c1435b..0000000 --- a/effects_gl.cpp +++ /dev/null @@ -1,101 +0,0 @@ -static uint16 Effect_GL_InitShader(int EffectIndex); -static uint16 GL_EffectShaderProgram[512]; -static void GL_BindDefaultVertexArrays(); -static void GL_InitTexture(gl_effect_layer *Test); - -void Effect_GL_Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]) -{ - real32 All_Start = Property[0].CurrentValue.f; - real32 All_Mid = Property[1].CurrentValue.f; - real32 All_End = Property[2].CurrentValue.f; - v4 Start = Property[3].CurrentValue.col; - v4 Mid = Property[4].CurrentValue.col; - v4 End = Property[5].CurrentValue.col; - - if (!BitmapInfo->Test.Initialized) { - GL_InitTexture(&BitmapInfo->Test); - } - - gl_effect_layer Test = BitmapInfo->Test; - uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer; - uint16 Width = Source->Info.Width; - uint16 Height = Source->Info.Height; - - glBindTexture(GL_TEXTURE_2D, Test.Texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, Data); - - glBindFramebuffer(GL_FRAMEBUFFER, Test.FramebufferObject); - glBindRenderbuffer(GL_RENDERBUFFER, Test.Color_Renderbuffer); - - uint16 ShaderProgram = Effect_GL_InitShader(1); - - GL_BindDefaultVertexArrays(); - - int vertexColorLocation = glGetUniformLocation(ShaderProgram, "Start"); - glUniform1f(vertexColorLocation, All_Start); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "Mid"); - glUniform1f(vertexColorLocation, All_Mid); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "End"); - glUniform1f(vertexColorLocation, All_End); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "StartCol"); - glUniform4f(vertexColorLocation, Start.r, Start.g, Start.b, Start.a); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "MidCol"); - glUniform4f(vertexColorLocation, Mid.r, Mid.g, Mid.b, Mid.a); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "EndCol"); - glUniform4f(vertexColorLocation, End.r, End.g, End.b, End.a); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - - glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - -} - -void Effect_GL_GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]) -{ - real32 Radius = Property[0].CurrentValue.f; - - if (!BitmapInfo->Test.Initialized) { - GL_InitTexture(&BitmapInfo->Test); - } - - gl_effect_layer Test = BitmapInfo->Test; - uint8 *Data = (uint8 *)BitmapInfo->BitmapBuffer; - uint16 Width = Source->Info.Width; - uint16 Height = Source->Info.Height; - - glBindTexture(GL_TEXTURE_2D, Test.Texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, Data); - - glBindFramebuffer(GL_FRAMEBUFFER, Test.FramebufferObject); - glBindRenderbuffer(GL_RENDERBUFFER, Test.Color_Renderbuffer); - - uint16 ShaderProgram = Effect_GL_InitShader(2); - - GL_BindDefaultVertexArrays(); - - int vertexColorLocation = glGetUniformLocation(ShaderProgram, "Radius"); - glUniform1f(vertexColorLocation, Radius + 1.60f); - vertexColorLocation = glGetUniformLocation(ShaderProgram, "Direction"); - glUniform2f(vertexColorLocation, 1.0f, 0.0f); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]); - - // This blur works in two passes. - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, Data); - - vertexColorLocation = glGetUniformLocation(ShaderProgram, "Direction"); - glUniform2f(vertexColorLocation, 0.0f, 1.0f); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, &Data[0]); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - -} diff --git a/effects_software.cpp b/effects_software.cpp index 27023e6..71023e0 100644 --- a/effects_software.cpp +++ b/effects_software.cpp @@ -47,3 +47,146 @@ Effect_Software_DrawColor(int Width, int Height, int BytesPerPixel, void *Effect } } } +static void +CurvesSolver(real32 *LUT, v2 Point_P1, v2 Point_P2, v2 m1, v2 m2, int i) +{ + + real32 Precision = ((real32)1 / 256) * 0.1; + real32 Point_Span = Point_P2.x - Point_P1.x; + v2 Cache[256]; + + if (i == 0) { + // Don't know how to fix this, so I'm just gonna linear interpolate + // until I try quadratic solving. + real32 Count_Start = (Point_P1.x * 256); + real32 Count_End = (Point_P2.x * 256); + real32 Count_Total = Count_End - Count_Start; + real32 Width = Point_P2.x - Point_P1.x; + real32 Height = Point_P2.y - Point_P1.y; + real32 Count = Count_Start; + real32 t = 1; + while (Count < Count_End) { + LUT[(uint32)Count] = Normalize(Point_P1.y + (Height*((Count-Count_Start)/(Count_End - (Count_End - 256)))/Width)); + Count++; + } + } else { + real32 Count_Start = (Point_P1.x * 256); + real32 Count_End = (Point_P2.x * 256); + real32 Count_Total = Count_End - Count_Start; + real32 Count = Count_Start; + real32 t = 0; + while (Count < Count_End) { + + real32 c = 2*t*t*t - 3*t*t; + real32 c0 = c + 1; + real32 c1 = t*t*t - 2*t*t + t; + real32 c2 = -c; + real32 c3 = t*t*t - t*t; + + v2 Point = (c0 * Point_P1) + (c1 * m1) + (c2 * Point_P2) + (c3 * m2); + + real32 TargetX = Count / 256; + + // Only record the value if it's within a certain precision. + + if (Point.x <= TargetX - Precision || + Point.x >= TargetX + Precision) { + t = t * TargetX / Point.x; + } else { + if (Point.y > 1.0f) { + LUT[(uint32)Count] = 1.0f; + } else if (Point.y < 0.0f) + LUT[(uint32)Count] = 0.0f; + else { + LUT[(uint32)Count] = Point.y; + } + t += (Point_Span / Count_Total); + Count++; + } + } + } +} + +/* +static void +Effect_Curves(file_source *Source, void *BitmapAddress, uint16 ShaderProgram, uint8 *FileEffectAddress) +{ + uint32 ChannelIndex = *(uint32 *)(real32 *)FileEffectAddress; + FileEffectAddress += sizeof(real32); + real32 NumberOfPoints_Main = *(real32 *)FileEffectAddress; + FileEffectAddress += sizeof(real32); + v4 NumberOfPoints_Col = *(v4 *)FileEffectAddress; + FileEffectAddress += sizeof(v4); + + real32 LUT[5][256] = {}; + + for (int a = 0; a < 5; a++) { + + int Num = (a == 0) ? NumberOfPoints_Main : NumberOfPoints_Col.E[a-1]; + v2 *CurvePoint = (v2 *)(FileEffectAddress + (a * (sizeof(v2) * 10))); + + for (int i = 0; i < Num; i++) { + v2 Point_P1 = CurvePoint[i]; + v2 Point_P2 = CurvePoint[i + 1]; + v2 Point_P0 = (i != 0) ? CurvePoint[i - 1] : V2(0, 0); + v2 Point_P3 = (i != (Num - 2)) ? CurvePoint[i + 2] : V2(1, 1); + + v2 m1 = (Point_P2 - Point_P0) / (2 * Tau); + v2 m2 = (Point_P3 - Point_P1) / (2 * Tau); + + CurvesSolver(LUT[a], Point_P1, Point_P2, m1, m2, i); + } + + if (CurvePoint[0].x > 0.0f) { + real32 Count_Start = 0; + real32 Count_End = (CurvePoint[0].x * 255); + real32 Count = Count_Start; + while (Count < Count_End) { + LUT[a][(uint32)Count] = LUT[a][(uint32)Count_End]; + Count++; + } + } + + if (CurvePoint[Num-1].x < 1.0f) { + real32 Count_Start = (CurvePoint[Num-1].x * 255) - 0.5; + real32 Count_End = 255; + real32 Count = Count_Start; + while (Count < Count_End) { + LUT[a][(uint32)Count] = LUT[a][(uint32)Count_Start]; + Count++; + } + } + + for (int i = 0; i < Num; i++) { + if (CurvePoint[i].y == 1.0f) + LUT[a][255] = 1.0f; + } + } + + + uint64 Size = Source->Width*Source->Height; + int i = 0; + Assert(BytesPerPixel == 4); + while (i < Size) { + uint32 *Pixel = (uint32 *)BitmapAddress + i; + v4 t = Uint32ToCol8(*Pixel); + + real32 R_Lookup = LUT[1][(uint32)(t.r)]; + real32 G_Lookup = LUT[2][(uint32)(t.g)]; + real32 B_Lookup = LUT[3][(uint32)(t.b)]; + real32 A_Lookup = LUT[4][(uint32)(t.a)]; + + real32 R_Lookup_All = LUT[0][(uint32)(R_Lookup*255)]; + real32 G_Lookup_All = LUT[0][(uint32)(G_Lookup*255)]; + real32 B_Lookup_All = LUT[0][(uint32)(B_Lookup*255)]; + + uint32 Result = (((uint32)((A_Lookup * 255.0f) + 0.5) << 24) | + ((uint32)((B_Lookup_All * 255.0f) + 0.5) << 16) | + ((uint32)((G_Lookup_All * 255.0f) + 0.5) << 8) | + ((uint32)((R_Lookup_All * 255.0f) + 0.5) << 0)); + + *Pixel = Result; + i++; + } +} +*/ diff --git a/main.cpp b/main.cpp index ddf1560..950d548 100644 --- a/main.cpp +++ b/main.cpp @@ -184,13 +184,13 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui_DebugUndoTree(Memory, State); } +#if 0 if (State->Initializing == 3) { Source_UICreateButton(File, State, Memory, Sorted.CompArray, Sorted.LayerArray); block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0); Layer->Block_Effect_Index[0] = Effect_Init(State, Memory, 0, Layer->Block_Effect_Count); Layer->Block_Effect_Count = 1; } -#if 0 // Layera->x.IsToggled = true; // Layera->y.IsToggled = true; // block_layer *Layerb = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 1); @@ -388,33 +388,18 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io layer_bitmap_state *BitmapState = &State->Render.Bitmap[Index_Physical]; void *BitmapAddress = NULL; - void *SecondSourceBitmap = NULL; // If there are effects or we're in interact_type_brush, we need to redirect to another scratch bitmap. + void *RenderAddress = NULL; // result of masking, effects, and intermediate paint stroke int Width = 0, Height = 0, BytesPerPixel = 0; - uint64 ScratchActive = 0; + if (!Layer->IsPrecomp) { - block_source *Source; + block_source *Source = NULL; if ((State->PreviewSource != -1) && Layer->IsSelected) { Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, State->PreviewSource); } else { Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); } if (Source->Type == source_type_principal || Source->Type == source_type_principal_temp) { - if (State->Interact_Active == interact_type_brush && State->Brush.LayerToPaint_Index == Index_Physical) { - Assert(Source->Type == source_type_principal); - void *SourceBitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); - ScratchActive = Source->Width * Source->Height * Source->BytesPerPixel; - SecondSourceBitmap = Memory_PushScratch(Memory, ScratchActive); - Memory_Copy((uint8 *)SecondSourceBitmap, (uint8 *)SourceBitmapAddress, ScratchActive); - // TODO(fox): Do all these extra precomputes really make a difference in the renderer? - rectangle RenderRegion = { 0, 0, Source->Width, Source->Height }; - direct_info Info = { (real32)Source->Width, (real32)Source->Height, (real32)Source->BytesPerPixel, (real32)Source->Width * Source->BytesPerPixel, - Bitmap_ByteInfo(Source->BytesPerPixel), blend_normal, - RenderRegion, State->Brush.TransientBitmap}; - Render_Main((void *)&Info, SecondSourceBitmap, render_type_notransform, State->Brush.CacheBounds); - BitmapAddress = SecondSourceBitmap; - } else { - BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); - } + BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); } else { cache_entry *Entry = Memory_Cache_Search(State, Memory, cache_entry_type_source, Layer->Block_Source_Index, 0); if (!Entry->IsCached) { @@ -449,24 +434,24 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io Height = Precomp->Height; BytesPerPixel = Precomp->BytesPerPixel; } + Assert(BitmapAddress); - if (Layer->Block_Effect_Count && !SecondSourceBitmap) { - block_source *Source; - if ((State->PreviewSource != -1) && Layer->IsSelected) { - Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, State->PreviewSource); - } else { - Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - } - void *SourceBitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index, 0); - ScratchActive = Source->Width * Source->Height * Source->BytesPerPixel; - SecondSourceBitmap = Memory_PushScratch(Memory, ScratchActive); - Memory_Copy((uint8 *)SecondSourceBitmap, (uint8 *)SourceBitmapAddress, ScratchActive); - BitmapAddress = SecondSourceBitmap; + uint64 ScratchSize = Width * Height * BytesPerPixel; + RenderAddress = Memory_PushScratch(Memory, ScratchSize); + // Memory_Copy((uint8 *)RenderAddress, (uint8 *)BitmapAddress, ScratchSize); + + if (State->Interact_Active == interact_type_brush && State->Brush.LayerToPaint_Index == Index_Physical) { + // TODO(fox): Do all these extra precomputes really make a difference in the renderer? + rectangle RenderRegion = { 0, 0, Width, Height }; + direct_info Info = { (real32)Width, (real32)Height, (real32)BytesPerPixel, (real32)Width * BytesPerPixel, + Bitmap_ByteInfo(BytesPerPixel), blend_normal, + RenderRegion, State->Brush.TransientBitmap}; + Render_Main((void *)&Info, RenderAddress, render_type_notransform, State->Brush.CacheBounds); + } else if (Layer->Block_Effect_Count || Layer->Block_Mask_Count) { + Layer_UpdateMasksEffects(State, Layer, Memory, RenderAddress, Width, Height, BytesPerPixel); } - Layer_UpdateMasksEffects(State, Layer, Memory, BitmapAddress, Width, Height, BytesPerPixel); - Assert(Width); Assert(Height); transform_info T = Transform_Calculate(State, Memory, File, Layer, Comp, Width, Height, BytesPerPixel); @@ -474,8 +459,7 @@ Render_Comp(project_data *File, project_state *State, memory *Memory, ImGuiIO io rectangle RenderRegion = {0, 0, Comp->Width, Comp->Height}; Render_Main((void *)&T, CompBuffer, render_type_main, RenderRegion); - if (ScratchActive) - Memory_PopScratch(Memory, ScratchActive); + Memory_PopScratch(Memory, ScratchSize); } } Entry_Main->CycleTime = GetCPUTime() - Comp_TimeStart; @@ -545,11 +529,11 @@ int main(int argc, char *argv[]) { Memory_InitTable(&GlobalMemory, &Memory, 2 * 1024 * 1024, F_Properties, "Properties", sizeof(property_channel)); Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Bezier, "Bezier paths (keyframes, masks)", sizeof(block_bezier)); Memory_InitTable(&GlobalMemory, &Memory, 4 * 1024 * 1024, F_Strings, "Strings", sizeof(block_string)); - Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, F_PrincipalBitmaps, "Principal bitmap data", BitmapBlockSize); + Memory_InitTable(&GlobalMemory, &Memory, (uint64)100 * 1024 * 1024, F_PrincipalBitmaps, "Principal bitmap data", BitmapBlockSize); Memory_InitTable(&GlobalMemory, &Memory, (uint64)5 * 1024 * 1024, B_Thumbnails, "Thumbnails"); Memory_InitTable(&GlobalMemory, &Memory, (uint64)64 * 1024 * 1024, B_ScratchSpace, "Scratch"); - Memory_InitTable(&GlobalMemory, &Memory, (uint64)50 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer"); + Memory_InitTable(&GlobalMemory, &Memory, (uint64)200 * 1024 * 1024, B_CachedBitmaps, "Cached bitmap buffer"); #if ARM @@ -603,27 +587,25 @@ int main(int argc, char *argv[]) { File->Comp_Count = 1; - { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/a.jpg"); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 0); - Source->IsSelected = true; - } #if 0 - { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/b.jpg"); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 1); + const char *myb[] = { "../asset/hand/IMG_4239.jpg", "../asset/hand/IMG_4242.jpg", "../asset/hand/IMG_4243.jpg", + "../asset/hand/IMG_4244.jpg", "../asset/hand/IMG_4248.jpg", "../asset/hand/IMG_4249.jpg" }; + + for (int i = 0; i < 6; i++) { + uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)myb[i]); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); Source->IsSelected = true; } - { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/c.png"); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2); + uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/a.png"); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); Source->IsSelected = true; } + { - uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/d.png"); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, 2); + uint16 SourceIndex = Source_Generate(File, State, &Memory, (void *)"../asset/hand/c.png"); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, File->Source_Count - 1); Source->IsSelected = true; } #endif @@ -735,7 +717,16 @@ int main(int argc, char *argv[]) { Brush_CalcBitmapAlphaFromSize(&Memory, &State->Brush, 4); State_BindBrushTexture(&Memory, &State->Brush, 4); - // File_Open(File, State, &Memory, "test"); + File_Open(File, State, &Memory, "test"); + int h = 0, c = 0, i = 0; + int Count = File->Source_Count; + while (Block_Loop(&Memory, F_Sources, Count, &h, &c, &i)) { + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(&Memory, F_Sources, i); + if (Source->Type == source_type_principal_temp) { + Source->Occupied = 0; + File->Source_Count--; + } + } #if STABLE curl_global_init(CURL_GLOBAL_ALL); diff --git a/memory.cpp b/memory.cpp index 3a7697d..28f1797 100644 --- a/memory.cpp +++ b/memory.cpp @@ -106,10 +106,10 @@ static uint32 Memory_Block_PrincipalBitmap_AllocateNew(project_data *File, project_state *State, memory *Memory) { int h = 0, c = 0, i = 0; - int MaxBlockIndex = 0; + int MaxBlockIndex = -1; while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) { block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i); - if (Source->Bitmap_Index > MaxBlockIndex) + if (Source->Bitmap_Index > MaxBlockIndex && Source->Type == source_type_principal) MaxBlockIndex = i; } diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index eaa7eb9..70d4ffc 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -307,7 +307,7 @@ ImGui_SD_Thumbnail(project_data *File, project_state *State, ui *UI, memory *Mem ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y); - if (!SourceCount) { + if (!SourceCount || ViewportScale.x < 50) { ImGui::End(); return; } @@ -435,7 +435,7 @@ ImGui_SD_Prompt(project_data *File, project_state *State, ui *UI, memory *Memory } ImGui::InputText("Address", SD->ServerAddress, SD_LEN_ADDRESS); if (State->Initializing && (SD->ServerAddress[0] == '\0')) { - sprintf(SD->Prompt, "%s", "1girl, looking at viewer, smile, hakurei reimu, cowboy shot"); + sprintf(SD->Prompt, "%s", "scan, highres, monochrome, traditional medium, (sketch:1.2), flat shading, earth, globe, effects, clouds, lightning, fire"); sprintf(SD->NegPrompt, "%s", "nsfw, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark"); sprintf(SD->ServerAddress, "%s", "http://127.0.0.1:7860"); } @@ -1055,16 +1055,18 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; if (!io.KeyCtrl) { - for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) { - sorted_layer SortEntry = SortedLayerInfo[i]; - uint32 Index_Physical = SortEntry.Block_Layer_Index; - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); - if (Layer->IsSelected && Source->Type == source_type_principal) { - Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); - State->Interact_Active = interact_type_brush; - State->Brush.LayerToPaint_Index = Index_Physical; - break; + int h = 0, c = 0, i = 0; + while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) + { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (!Layer->IsPrecomp) { + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + if (Layer->IsSelected && Source->Type == source_type_principal) { + Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); + State->Interact_Active = interact_type_brush; + State->Brush.LayerToPaint_Index = i; + break; + } } } } @@ -1715,10 +1717,32 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::OpenPopupOnItemClick("layerpopup", ImGuiPopupFlags_MouseButtonRight); if (ImGui::BeginPopup("layerpopup")) { + if (ImGui::Selectable("Visible")) { + bool32 Commit = false; + int h = 0, z = 0, i = 0; + while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (Layer->IsSelected) { + if (!Commit) { + History_Entry_Commit(Memory, "Toggle visibility"); + Commit = true; + } + History_Action_Swap(Memory, F_File, sizeof(Layer->IsVisible), &Layer->IsVisible); + Layer->IsVisible ^= 1; + } + } + if (Commit) { + History_Entry_End(Memory); + State->UpdateFrame = true; + } + } if (ImGui::MenuItem("Pre-compose layer")) { Precomp_UICreateButton(File, State, Memory, CompIndex, SortedCompInfo, SortedLayerInfo); State->UpdateKeyframes = true; } + if (ImGui::MenuItem("Duplicate layer")) { + Precomp_UIDuplicate(File, State, Memory, CompIndex, SortedCompInfo, SortedLayerInfo); + } if (ImGui::BeginMenu("Layer color")) { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); diff --git a/stable_diffusion.cpp b/stable_diffusion.cpp index 469a85a..022c3c2 100644 --- a/stable_diffusion.cpp +++ b/stable_diffusion.cpp @@ -147,7 +147,7 @@ SD_AssembleJSON(sd_state *SD, char *JSONPayload, void *Base64Bitmap = NULL) } if (SD->Mode) sprintf(JSONPayload, "%s\"%s\": %.2f,\n", JSONPayload, "denoising_strength", SD->DenoisingStrength); - sprintf(JSONPayload, "%s%s\n", JSONPayload, "\"sampler_index\": \"DDIM\""); + sprintf(JSONPayload, "%s%s\n", JSONPayload, "\"sampler_index\": \"DPM++ 2S a Karras\""); sprintf(JSONPayload, "%s}\n", JSONPayload); printf("%s\n", JSONPayload); // sprintf(CurlCommand, "curl -X POST -H 'Content-Type: application/json' -i '%s/sdapi/v1/txt2img' --data '%s'", SD->ServerAddress, JSONPayload); diff --git a/stable_diffusion.h b/stable_diffusion.h index b498a7c..887b469 100644 --- a/stable_diffusion.h +++ b/stable_diffusion.h @@ -22,11 +22,11 @@ struct sd_state char NegPrompt[256]; char ServerAddress[128]; int32 Steps = 10; - int32 Width = 384; - int32 Height = 512; + int32 Width = 960; + int32 Height = 640; int32 SamplerIndex = 0; real32 CFG = 7; - int32 BatchSize = 4; + int32 BatchSize = 1; real32 DenoisingStrength = 0.4; int32 Seed = -1; }; -- cgit v1.2.3