summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-11-24 01:16:54 -0500
committerFox Caminiti <fox@foxcam.net>2022-11-24 01:16:54 -0500
commit17bee519ece8fc2bc356956841fed97286d24139 (patch)
treedd09d56fdd7e1d1fca58cbc345414bdfba9c19a6
parentfd315f15828b8537a48530c094ced845edc3a1d3 (diff)
legwork
-rw-r--r--createcalls.cpp37
-rw-r--r--defines.h2
-rw-r--r--effects.h70
-rw-r--r--effects_constructors.cpp4
-rw-r--r--effects_gl.cpp101
-rw-r--r--effects_software.cpp143
-rw-r--r--main.cpp95
-rw-r--r--memory.cpp4
-rw-r--r--my_imgui_widgets.cpp48
-rw-r--r--stable_diffusion.cpp2
-rw-r--r--stable_diffusion.h6
11 files changed, 267 insertions, 245 deletions
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;
};