From 09c6cb9e3be2655b842e13dd68879cb10cf52acf Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Mon, 21 Nov 2022 13:56:37 -0500 Subject: things --- createcalls.cpp | 160 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 137 insertions(+), 23 deletions(-) (limited to 'createcalls.cpp') diff --git a/createcalls.cpp b/createcalls.cpp index e88e39f..4c72c4e 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -38,6 +38,22 @@ Source_Delete(project_data *File, memory *Memory, uint32 Index) File->Source_Count--; } +// These thumbnail textures aren't needed for anything else, so I'm just gonna +// count on GL to retain them in GPU memory. +static void +Source_DumpThumbnail(memory *Memory, block_source *Source, uint32 T_Width, uint32 T_Height) +{ + Assert(Source->Type == source_type_principal_temp); + void *BitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index); + uint32 Size = T_Height*T_Width*4; + uint8 *Output = (uint8 *)Memory_PushScratch(Memory, Size); + stbir_resize_uint8((uint8 *)BitmapAddress, Source->Width, Source->Height, 0, Output, T_Height, T_Width, 0, 4); + + GL_GenAndBindTexture(&Source->ThumbnailTex, T_Height, T_Width, 4, Output); + + Memory_PopScratch(Memory, Size); +} + static int16 Source_Generate(project_data *File, project_state *State, memory *Memory, void *TempString) { @@ -67,10 +83,10 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void * } static bezier_point * -Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index) +Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index, bool32 AssertExists) { Assert(Index < MAX_KEYFRAMES_PER_BLOCK); - block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0]); + block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], AssertExists); return &Bezier->Point[Index]; } @@ -100,7 +116,7 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData) { if (!Property->Block_Bezier_Count) { Property->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 *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], 0); Bezier->Occupied = true; // NOTE(fox): Effects will change this! History_Action_Swap(Memory, F_Layers, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count); @@ -108,7 +124,7 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData) } int k = 0; for (;;) { - bezier_point *Point = Bezier_LookupAddress(Memory, Property, k); + bezier_point *Point = Bezier_LookupAddress(Memory, Property, k, 0); if (!Point->Occupied) { History_Action_Swap(Memory, F_Bezier, sizeof(*Point), Point); *Point = PointData; @@ -181,6 +197,18 @@ Layer_Interact_Evaluate(memory *Memory, project_state *State, uint16 Layer_Index } } +static void +Layer_ToggleChannel(project_data *File, memory *Memory, int32 a) +{ + 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->IsSelected) + Layer->Property[a].IsToggled ^= 1; + } +} + static void Layer_Select(memory *Memory, project_state *State, int32 i) { @@ -208,23 +236,47 @@ void Source_DeselectAll(project_data *File, memory *Memory) } } -void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, sorted_layer *SortedLayerArray) +// NOTE(fox): This won't work with precomps! + +void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo) { clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer; + if (Contents->Type == selection_none) + return; uint64 ClipboardPos = sizeof(clipboard_contents); ClipboardPos = sizeof(clipboard_contents); - int h = 0, c = 0, i = 0; - block_layer *Layer; + int i = SortedCompInfo->LayerCount - 1; + block_layer *Layer = NULL; clipboard_channel *Channel; int b = 0; - while (b < Contents->ChannelCount) { + int LayerCount = 0; + + int NumberOfLayersFromClipboard = 1; + int LastOffset = 0; + for (int a = 0; a < Contents->ChannelCount; a++) { + Channel = &Contents->Channel[a]; + if (a != 0) { + if (Channel->LayerOffset != LastOffset) + NumberOfLayersFromClipboard++; + } + LastOffset = Channel->LayerOffset; + } + + for (;;) { Channel = &Contents->Channel[b]; - while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) + while (i >= 0) { - Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); - if (Layer->IsSelected) + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (TestLayer->IsSelected) { + Layer = TestLayer; break; + } + i--; } + if (Layer == NULL) + break; // NOTE(fox): This loop assumes all layers and the clipboard have // channels laid out in the same way! for (int h = 0; h < AmountOf(Layer->Property); h++) { @@ -232,6 +284,7 @@ void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, s if (Property->Name == Channel->Name) { for (int p = 0; p < Channel->KeyframeCount; p++) { bezier_point PointData = *(bezier_point *)((uint8 *)State->ClipboardBuffer + ClipboardPos); + PointData.Pos[0].x += State->Frame_Current; Bezier_Add(Memory, Property, PointData); ClipboardPos += sizeof(bezier_point); } @@ -239,22 +292,26 @@ void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, s Channel = &Contents->Channel[b]; } } + Layer = NULL; + if (b < Contents->ChannelCount) { + if (NumberOfLayersFromClipboard != 1) + break; + else + b = 0; + } } } -void Clipboard_Store(project_data *File, project_state *State, memory *Memory, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) +void Clipboard_Store(project_data *File, project_state *State, memory *Memory, sorted_comp_info *SortedCompInfo, sorted_layer *SortedLayerInfo, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { - // TODO(fox): Multi-precomp support! int LocalOffset = 0; clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer; *Contents = {}; uint64 ClipboardPos = sizeof(clipboard_contents); - // for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) - Assert(0); - for (int i = 10; i >= 0; i--) + for (int i = SortedCompInfo->LayerCount - 1; i >= 0; i--) { - sorted_layer SortEntry = {}; // SortedLayerInfo[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); for (int h = 0; h < AmountOf(Layer->Property); h++) { @@ -263,10 +320,18 @@ void Clipboard_Store(project_data *File, project_state *State, memory *Memory, s sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h; uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK); clipboard_channel *Channel = &Contents->Channel[Contents->ChannelCount]; + bezier_point *FirstPoint = NULL; + int TimeOffset = 0; for (int p = 0; p < Property->Keyframe_Count; p++) { bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]); if (PointAddress->IsSelected) { - Memory_Copy((uint8 *)State->ClipboardBuffer + ClipboardPos, (uint8 *)PointAddress, sizeof(bezier_point)); + if (!FirstPoint) { + FirstPoint = PointAddress; + TimeOffset = FirstPoint->Pos[0].x; + } + bezier_point PointToCopy = *PointAddress; + PointToCopy.Pos[0].x -= TimeOffset; + Memory_Copy((uint8 *)State->ClipboardBuffer + ClipboardPos, (uint8 *)&PointToCopy, sizeof(bezier_point)); ClipboardPos += sizeof(bezier_point); Channel->KeyframeCount++; } @@ -486,6 +551,35 @@ void Layer_Evaluate_Display(block_layer *Layer, sorted_layer *LayerArrayStart, s */ } +void TempSource_SortAll(project_data *File, project_state *State, memory *Memory, uint16 *SourceArrayStart, uint16 *TempSourceCount) +{ + int count = 0; + int h = 0, c = 0, i = 0; + 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->Type == source_type_principal_temp) { + uint32 Playhead = 0; + while (Playhead < count) { + block_source *TestSource = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, SourceArrayStart[Playhead]); + Assert(TestSource->Type == source_type_principal_temp); + if (TestSource->RelativeTimestamp > Source->RelativeTimestamp) { + break; + } else { + Playhead++; + } + } + if (Playhead != count) { + uint8 *Address_Start = (uint8 *)(SourceArrayStart + Playhead); + uint8 *Address_End = (uint8 *)(SourceArrayStart + count) - 1; + Arbitrary_ShiftData(Address_Start, Address_End, sizeof(uint16), 1); + } + SourceArrayStart[Playhead] = i; + count++; + } + } + *TempSourceCount = count; +} + // The first loop is for counting how many layers are in each precomp, the // second is for sorting the layers by offset, and the third is for applying // interactivity if the user is moving any layers. @@ -591,12 +685,20 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray; Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize); + uint64 SourceArraySize = sizeof(uint16) * File->Source_Count; + Sorted.Source_SortSize = SourceArraySize; + void *Source_SortedArray = Memory_PushScratch(Memory, Sorted.Source_SortSize); + Arbitrary_Zero((uint8 *)Source_SortedArray, Sorted.Source_SortSize); + Sorted.SourceArray = (uint16 *)Source_SortedArray; + + TempSource_SortAll(File, State, Memory, Sorted.SourceArray, &Sorted.TempSourceCount); Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyInfo, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count); return Sorted; } -void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize) +void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSize, uint64 Source_SortSize) { + Memory_PopScratch(Memory, Source_SortSize); Memory_PopScratch(Memory, Property_SortSize); Memory_PopScratch(Memory, Layer_SortSize); } @@ -844,6 +946,7 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, } B->BrushBuffer = Brush->PaintBuffer; + B->EraseMode = Brush->EraseMode; // ImGui's color picker works in sRGB, so we need to convert to linear. // real32 R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92; @@ -890,11 +993,22 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion) real32 BrushAlpha = Brush_BitmapAlpha * B.A_Brush; real32 LayerAlpha = A_Layer; - real32 A_Blend = LayerAlpha + BrushAlpha; + real32 A_Blend = 0; + real32 R_Blend = 0; + real32 G_Blend = 0; + real32 B_Blend = 0; - real32 R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha); - real32 G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha); - real32 B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha); + if (!B.EraseMode) { + A_Blend = LayerAlpha + BrushAlpha; + R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha); + G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha); + B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha); + } else { + A_Blend = A_Layer * (1.0f - BrushAlpha); + R_Blend = R_Layer; + G_Blend = G_Layer; + B_Blend = B_Layer; + } /* R_Blend = (R_Brush * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha); -- cgit v1.2.3