diff options
-rw-r--r-- | createcalls.cpp | 429 | ||||
-rw-r--r-- | defines.h | 1 | ||||
-rw-r--r-- | functions.h | 75 | ||||
-rw-r--r-- | main.cpp | 16 | ||||
-rw-r--r-- | main.h | 2 | ||||
-rw-r--r-- | my_imgui_widgets.cpp | 86 | ||||
-rw-r--r-- | prenderer.cpp | 50 |
7 files changed, 190 insertions, 469 deletions
diff --git a/createcalls.cpp b/createcalls.cpp index 1e96c74..d1f6448 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -413,6 +413,15 @@ Layer_Select(memory *Memory, project_state *State, int32 i) State->RecentSelectionType = selection_type_layer; } +static void +Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions) +{ + for (int a = 1; a <= Recursions; a++) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[a]); + Layer->IsSelected = 2; + } +} + void Layer_DeselectAll(project_data *File, project_state *State, memory *Memory) { int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { @@ -608,6 +617,59 @@ Layer_GetSortedArray(sorted_layer *LayerArrayStart, sorted_comp_info *SortedComp return LayerArrayStart + LayerOffset; } +static void +Layer_Select_Traverse(uint16 PrincipalCompIndex, memory *Memory, project_state *State, int32 IndexToFind, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, + int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], int32 *Recursions) +{ + uint16 CompIndex = 0; + if (RecursionIdx[*Recursions] == -1) { + CompIndex = PrincipalCompIndex; + } else { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[*Recursions]); + CompIndex = Layer->Block_Source_Index; + } + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); + sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex]; + uint32 RecursionsCurrent = *Recursions; + 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); + if (Layer->IsPrecomp && Layer->IsSelected == 2) { + *Recursions = RecursionsCurrent + 1; + RecursionIdx[*Recursions] = Index_Physical; + Layer_Select_Traverse(PrincipalCompIndex, Memory, State, IndexToFind, SortedCompArray, SortedLayerArray, RecursionIdx, Recursions); + } else if (Index_Physical == IndexToFind) { + return; + } + } +} + +static v2 +Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) +{ + int16 RecursionIdx[MAX_PRECOMP_RECURSIONS] = {}; + RecursionIdx[0] = -1; + int32 Recursions = 0; + sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); + sorted_comp_info SortedCompInfo = SortedCompArray[File->PrincipalCompIndex]; + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); + Layer_Select_Traverse(File->PrincipalCompIndex, Memory, State, State->Brush.LayerToPaint_Index, SortedCompArray, SortedLayerArray, RecursionIdx, &Recursions); + v2 PointUV = {0, 0}; + int OuterWidth = Comp->Width, OuterHeight = Comp->Height; + int InnerWidth = 0, InnerHeight = 0; + for (int i = 1; i <= Recursions; i++) { + block_layer *InnerLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[i]); + layer_transforms T = Layer_GetTransforms(InnerLayer); + Layer_GetDimensions(Memory, InnerLayer, &InnerWidth, &InnerHeight); + PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, State->TempZoomRatio); + OuterWidth = InnerWidth; + OuterHeight = InnerHeight; + } + return PointUV * V2(InnerWidth, InnerHeight); +} + int32 Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, uint16 PrincipalIndex) { block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); @@ -1452,10 +1514,9 @@ PaintTest_AVX2(brush_info B, void *Buffer, rectangle RenderRegion) #endif static void -Brush_Render(project_state *State, ui *UI, layer_transforms T_Layer, block_composition *MainComp, block_source *Source, void *BitmapAddress, ImVec2 ViewportMin, ImVec2 MousePos) +Brush_Render(project_state *State, ui *UI, layer_transforms T_Layer, block_composition *MainComp, block_source *Source, void *BitmapAddress, ImVec2 ViewportMin, v2 LayerPos) { brush_info B; - v2 LayerPos = Transform_ScreenSpaceToLocal(T_Layer, MainComp->Width, MainComp->Height, Source->Width, Source->Height, UI->CompPos, UI->CompZoom, ViewportMin, MousePos); Brush_Info(&B, &State->Brush, Source, LayerPos, UI->Color); if (State->Brush.Size >= 128) { Render_Main((void *)&B, BitmapAddress, render_type_brush, B.LayerBounds); @@ -1463,367 +1524,3 @@ Brush_Render(project_state *State, ui *UI, layer_transforms T_Layer, block_compo PaintTest(B, BitmapAddress, B.LayerBounds); } } - - -#if 0 -static void -IncrementFrame(project_data *File, int16 Amount) { - if ((File->CurrentFrame <= 0 && Amount < File->StartFrame) || (File->CurrentFrame >= File->EndFrame)) { - File->CurrentFrame = 0; - } else { - File->CurrentFrame += Amount; - } -} - -static void -CreateKeyframeBlock(property_channel *Property, memory *Memory) -{ - int16 a = Property->NumberOfKeyframeBlocks++; - Assert(a < MAX_KEYFRAME_BLOCKS); - - Property->KeyframeBlock[a] = (keyframe_block *)AllocateMemory(Memory, sizeof(keyframe_block), F_Keyframes); -} - -// Note we use total bytes here so we can use this memory for both packed and unpacked bitmaps. -void * Layer_AllocateBitmap(memory *Memory, uint16 Width, uint16 Height, uint16 BytesPerPixel) -{ - uint64 TotalBytes = Bitmap_CalcTotalBytes(Width, Height, BytesPerPixel); - void *Address = AllocateMemory(Memory, TotalBytes, B_LayerBitmaps); - return Address; -} - -static cached_bitmap * -Cache_CheckBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame) -{ - if (!Source || !BitmapInfo) - return 0; - memory_table *Table = &Memory->Slot[B_LoadedBitmaps]; - int32 FrameToSeek = TimelineFrame - BitmapInfo->FrameOffset; - if (FrameToSeek < 0) { - FrameToSeek = 0; - } - // Stills have a frame index of one. - if (Source->SourceType == source_type_image) { - FrameToSeek = 0; - } - for (int i = 0; i < Table->NumberOfPointers; i++) { - cached_bitmap *Bitmap = &Memory->Bitmap[i]; - if (Bitmap->Frame == FrameToSeek && Bitmap->SourceOwner == Source) { - return Bitmap; - } - } - return 0; -} - -static cached_bitmap * -STB_LoadStill(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory) -{ - int n = 0; - int h, w; - void *temp = stbi_load(Source->Path, &w, &h, &n, 4); - Assert(temp); - cached_bitmap *Bitmap = Memory_RollingBitmap(Memory, Source, 0); - // Note the use of Unpacked since we haven't packed the bitmap and don't have any padding. - uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); - Bitmap_CopyToPointer(temp, Bitmap->Data, Source->Info.BytesPerPixel, Size); - return Bitmap; -} - -static void -Layer_InitSource(project_layer *Layer, source *Source, memory *Memory) -{ - uint16 Width = Source->Info.Width; - uint16 Height = Source->Info.Height; - uint16 BytesPerPixel = Source->Info.BytesPerPixel; - Layer->BitmapInfo.BitmapBuffer = Layer_AllocateBitmap(Memory, Width, Height, BytesPerPixel); -} - -static void -Layer_PositionCenter(project_layer *Layer, uint16 Width, uint16 Height) { - Layer->x.CurrentValue.f = Width/2; - Layer->y.CurrentValue.f = Height/2; -} - -static void -Layer_CreateFromSource(project_data *File, project_state *State, memory *Memory, source *Source) -{ - if (File->NumberOfLayers + 1 > MAX_LAYERS) { - // TODO(fox): Output! - } - project_layer *Layer = Layer_Init(File, Memory); - Layer->Source = Source; - State->UpdateFrame = true; -} - - -static void -Layer_UpdateBitmap(project_data *File, project_layer *Layer, memory *Memory, int32 CurrentFrame) { - source *Source = Layer->Source; - layer_bitmap_info *BitmapInfo = &Layer->BitmapInfo; - - // AVInfo is created here instead of on layer creation so we can save - // having to keep some state in the undo/delete commands. - if (!BitmapInfo->AVInfo) { - BitmapInfo->AVInfo = AllocateMemory(Memory, sizeof(av_info), P_AVInfo); - AV_Init(Source, (av_info *)BitmapInfo->AVInfo, Memory); - Layer_InitSource(Layer, Source, Memory); - Layer_PositionCenter(Layer, File->Width, File->Height); - } - - cached_bitmap *Bitmap = Cache_CheckBitmap(Source, BitmapInfo, Memory, CurrentFrame); - if (!Bitmap) { - if (Source->SourceType == source_type_image) { - Bitmap = STB_LoadStill(Source, BitmapInfo, Memory); - } else { - Bitmap = AV_LoadVideoFrame(Source, BitmapInfo, Memory, CurrentFrame); - } - } - uint16 Width = Source->Info.Width; - uint16 Height = Source->Info.Height; - uint16 BytesPerPixel = Source->Info.BytesPerPixel; - void *DestBuffer = BitmapInfo->BitmapBuffer; - uint64 UnpackedSize = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); -#if PACKEDRGB - uint64 PackedSize = Bitmap_CalcTotalBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel); - - if (Layer->NumberOfMasks == 0 && Layer->NumberOfEffects == 0) { - Bitmap_ConvertPacking(Bitmap->Data, Memory->Scratch, Width, Height, BytesPerPixel, 0); - Bitmap_CopyToPointer(Memory->Scratch, DestBuffer, BytesPerPixel, PackedSize); - } else { - Bitmap_CopyToPointer(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize); - // GL_InitTexture(&BitmapInfo->Test, DestBuffer, Width, Height); - // GL_MaskTexture(&BitmapInfo->TestM, DestBuffer, Width, Height); - - if (Layer->NumberOfMasks) { - for (int i = 0; i < Layer->NumberOfMasks; i++) { - mask *Mask = &Layer->Mask[i]; - if (Mask->IsClosed) - Mask_TriangulateAndRasterize(Memory, Layer, Mask); - } - } - - for (int i = 0; i < Layer->NumberOfEffects; i++) - { - if (Layer->Effect[i]->IsActive) - Layer->Effect[i]->func(Source, BitmapInfo, Memory, Layer->Effect[i]->Property); - } - Bitmap_ConvertPacking(DestBuffer, Memory->Scratch, Width, Height, BytesPerPixel, 0); - Bitmap_CopyToPointer(Memory->Scratch, DestBuffer, BytesPerPixel, PackedSize); - } -#else - Bitmap_CopyToPointer(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize); - GL_UpdateTexture(&BitmapInfo->Test, DestBuffer, Width, Height, 0); - GL_UpdateTexture(&BitmapInfo->TestM, DestBuffer, Width, Height, 1); - - if (Layer->NumberOfMasks) { - for (int i = 0; i < Layer->NumberOfMasks; i++) { - mask *Mask = &Layer->Mask[i]; - if (Mask->IsClosed) - Mask_TriangulateAndRasterize(Memory, Layer, Mask); - } - Bitmap_StencilAlpha(Bitmap->Data, DestBuffer, BytesPerPixel, UnpackedSize); - } - - if (Layer->NumberOfEffects) { - for (int i = 0; i < Layer->NumberOfEffects; i++) - { - if (Layer->Effect[i]->IsActive) - Layer->Effect[i]->func(Source, BitmapInfo, Memory, Layer->Effect[i]->Property); - } - } -#endif -} - -static ImVec2 -Layer_LocalToScreenSpace(project_layer *Layer, ui *UI, comp_buffer CompBuffer, v2 Point) -{ - real32 Rad = (Layer->rotation.CurrentValue.f * (PI / 180)); - real32 s = Layer->scale.CurrentValue.f; - real32 AX = Layer->ax.CurrentValue.f; - real32 AY = Layer->ay.CurrentValue.f; - source *Source = Layer->Source; - - v2 XAxis = (Point.x - AX*Source->Info.Width) * s * V2(cos(Rad), sin(Rad)); - v2 YAxis = (Point.y - AY*Source->Info.Height) * -s * V2(sin(Rad), -cos(Rad)); - v2 LocalPoint = XAxis + YAxis; - v2 CompUV = V2((Layer->x.CurrentValue.f + LocalPoint.x) / CompBuffer.Width, - (Layer->y.CurrentValue.f + LocalPoint.y) / CompBuffer.Height); - v2 ScreenPoint = V2(UI->CompPos.x + CompUV.x * UI->CompZoom.x, - UI->CompPos.y + CompUV.y * UI->CompZoom.y); - - return ImVec2(ScreenPoint.x, ScreenPoint.y); -} - -static v2 -Layer_ScreenSpaceToLocal(project_layer *Layer, ImVec2 CompPos, ImVec2 CompZoom, comp_buffer CompBuffer, ImVec2 ViewportMin, ImVec2 Point) -{ - source *Source = Layer->Source; - v2 CompUV = ImGui_ScreenPointToCompUV(ViewportMin, CompPos, CompZoom, Point); - v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, CompUV); - return V2(LayerUV.x * Source->Info.Width, LayerUV.y * Source->Info.Height); -} -static void -LoadTestFootage(project_data *File, project_state *State, memory *Memory) -{ - void *SourceString = String_GenerateFromChar(Memory, "../asset/a.jpg"); - Source_Generate(File, State, Memory, SourceString); - SourceString = String_GenerateFromChar(Memory, "../asset/24.mp4"); - Source_Generate(File, State, Memory, SourceString); - SourceString = String_GenerateFromChar(Memory, "../asset/b.jpg"); - Source_Generate(File, State, Memory, SourceString); - SourceString = String_GenerateFromChar(Memory, "../asset/c.jpg"); - Source_Generate(File, State, Memory, SourceString); - SourceString = String_GenerateFromChar(Memory, "../asset/p.mp4"); - Source_Generate(File, State, Memory, SourceString); - - Layer_CreateFromSource(File, State, Memory, &File->Source[0]); - Keyframe_Insert(&File->Layer[0]->x, Memory, 01, -10); - Keyframe_Insert(&File->Layer[0]->x, Memory, 10, -5); - Keyframe_Insert(&File->Layer[0]->x, Memory, 23, 0); - Keyframe_Insert(&File->Layer[0]->x, Memory, 34, 5); - - for (int i = 0; i < 5; i++) { - keyframe *Keyframe = KeyframeLookup(&File->Layer[0]->x, i); - Keyframe->TangentLeft = V2(-3, 0); - Keyframe->TangentRight = V2(1.5, 0); - Keyframe->Type = bezier; - } - - File->Layer[0]->x.IsToggled = true; - SelectLayer(File->Layer[0], State, 0); - // AddEffect(File->Layer[0], Memory, 1); - // property_channel *Property = &File->Layer[0]->x; - // for (int i = 0; i < 16; i++) - // Keyframe_Insert(Property, Memory, i*2, i*2*100); - // Keyframe_Insert(Property, Memory, 1, 100); - // Keyframe_Insert(Property, Memory, 15, 1500); - // Keyframe_Insert(Property, Memory, 16, 1600); - // Keyframe_Insert(Property, Memory, 31, 3100); - - // Keyframe_Delete(Property, Memory, 1); - // History_Undo(Memory); - // History_Redo(Memory); - - // Property->IsToggled = true; - - - /* - mask *Mask = &File->Layer[0]->Mask[0]; - File->Layer[0]->NumberOfMasks = 1; - Mask->Point[0].Pos = V2(200, 200); - Mask->Point[1].Pos = V2(210, 400); - Mask->Point[2].Pos = V2(220, 520); - Mask->Point[3].Pos = V2(1380, 520); - Mask->Point[4].Pos = V2(1480, 200); - - Mask->Point[0].TangentLeft = V2(-50, 0); - Mask->Point[1].TangentLeft = V2(-50, 0); - Mask->Point[2].TangentLeft = V2(-50, 0); - Mask->Point[3].TangentLeft = V2(-50, 0); - Mask->Point[4].TangentLeft = V2(-50, 0); - - Mask->Point[0].TangentRight = V2(50, 0); - Mask->Point[1].TangentRight = V2(50, 0); - Mask->Point[2].TangentRight = V2(50, 0); - Mask->Point[3].TangentRight = V2(50, 0); - Mask->Point[4].TangentRight = V2(50, 0); - - Mask->Point[0].HandleBezier = true; - Mask->Point[1].HandleBezier = true; - Mask->Point[2].HandleBezier = true; - Mask->Point[3].HandleBezier = true; - Mask->Point[4].HandleBezier = true; - - Mask->NumberOfPoints = 5; - Mask->IsClosed = true; - */ - - /* - Mask_DeletePoint(Memory, Mask, 1); - - History_Undo(Memory); - // History_Redo(Memory); - - Mask_AddPointToCurve(Memory, Mask, 1, 0.5); - - History_Undo(Memory); - History_Redo(Memory); - */ - - // if (!Source_Generate(File, Memory, "../asset/test.png")) - // PostMsg(State, "File open fail..."); - // if (!Source_Generate(File, Memory, "../asset/debug.png")) - // PostMsg(State, "File open fail..."); - - // property_channel *Property = &File->Layer[0]->x; - // Keyframe_Insert(Property, Memory, 1, 500); - // Keyframe_Insert(Property, Memory, 30, 800); - // Keyframe_Insert(Property, Memory, 15, 400); - // Keyframe_Insert(Property, Memory, 20, 100); - // Property->IsToggled = true; - // Property->IsGraphToggled = true; - // Property->GraphLength = 150; - // Property->GraphYOffset = (Property->GraphWindowHeight - Property->GraphLength)/2; - - // Layer_CreateFromSource(File, State, Memory, Source); - - // if (!Source_Generate(File, Memory, "../asset/p.mp4")) - // PostMsg(State, "File open fail..."); - // source *Source2 = &File->Source[1]; - // project_layer *Layer2 = Layer_Init(File, Memory); - // AV_Init(Source2, &Layer2->BitmapInfo, Memory); - // Layer_InitSource(Layer2, Source2, Memory); - // Layer2->StartFrame = 11; - // Layer2->EndFrame = 23; - - // void *SourceString1 = String_GenerateFromChar(Memory, "../asset/b.jpg"); - // if (!Source_Generate(File, Memory, SourceString1)) - // PostMsg(State, "File open fail..."); - // source *Source1 = &File->Source[1]; - // for (int i = 0; i < 25; i++) - // Layer_CreateFromSource(File, State, Memory, Source1); - // project_layer *Layer2 = Layer_Init(File, Memory); - // Layer_InitSource(Layer2, Source2, Memory); - - // AddEffect(File->Layer[0], Memory, 2); - // project_layer *Layer1 = CreateDebugLayer(&File, &Memory, 9, 14); - // project_layer *Layer1 = CreateSolidLayer(&File, &Memory, 9, 13, V4(1.0, 1.0, 1.0, 1.0)); - // Layer1->x.CurrentValue.f = 7; - // Layer1->y.CurrentValue.f = 4; - // Layer1->StartFrame = 0; - // Layer1->EndFrame = File.EndFrame; -} - -static void -CreateDemoScene(project_data *File, project_state *State, memory *Memory) -{ - Layer_CreateFromSource(File, State, Memory, &File->Source[1]); - project_layer *Layer1 = File->Layer[0]; - Layer1->x.CurrentValue.f = 1920/2; - Layer1->y.CurrentValue.f = 1080/2; - Layer1->StartFrame = 0; - Layer1->EndFrame = File->EndFrame; - Layer_CreateFromSource(File, State, Memory, &File->Source[2]); - project_layer *Layer2 = File->Layer[1]; - Layer2->x.CurrentValue.f = 1920/2; - Layer2->y.CurrentValue.f = 1080/2; - Layer2->StartFrame = 0; - Layer2->EndFrame = File->EndFrame; - Keyframe_Insert(&Layer2->rotation, Memory, 2, 0); - Keyframe_Insert(&Layer2->rotation, Memory, 50, 360); - Layer2->rotation.IsToggled = true; - Layer2->scale.IsToggled = true; - Layer_CreateFromSource(File, State, Memory, &File->Source[3]); - project_layer *Layer3 = File->Layer[2]; - Layer3->x.CurrentValue.f = 1920/4; - Layer3->y.CurrentValue.f = 1080/4; - Layer3->opacity.CurrentValue.f = 0.5f; - Layer3->StartFrame = 0; - Layer3->EndFrame = File->EndFrame; - Keyframe_Insert(&Layer3->x, Memory, 2, Layer3->x.CurrentValue.f); - Keyframe_Insert(&Layer3->x, Memory, 30, Layer3->x.CurrentValue.f+(1280/2)); - Keyframe_Insert(&Layer3->x, Memory, 60, Layer3->x.CurrentValue.f+(1280/3)); - Layer3->x.IsToggled = true; - Layer3->y.IsToggled = true; -} -#endif @@ -32,6 +32,7 @@ typedef uint64 ptrsize; // is there a compiler variable for 32 vs 64 bit like #define MAX_EFFECTS 32 #define MAX_SOURCES 1024 #define MAX_COMPS 1024 +#define MAX_PRECOMP_RECURSIONS 4 #define MAX_MASKS 8 #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 diff --git a/functions.h b/functions.h index 9cd6c6a..2825f85 100644 --- a/functions.h +++ b/functions.h @@ -1,5 +1,3 @@ -// static bool32 AV_IsFileSupported(char *filename, bool32 *IsVideo); - static void Memory_Copy(uint8 *Address_Write, uint8 *Address_Read, uint64 Size); static void Arbitrary_Zero(uint8 *Address_Write, uint64 Size); static void Arbitrary_SwapData(memory *Memory, uint8 *Address_0, uint8 *Address_1, uint64 Size); @@ -17,6 +15,8 @@ static ImVec2 Layer_LocalToScreenSpace(project_state *State, memory *Memory, blo static v2 TransformPoint(layer_transforms T, real32 Width, real32 Height, v2 Point); +static void Layer_GetDimensions(memory *Memory, block_layer *Layer, int *Width, int *Height); + static void * Memory_PushScratch(memory *Memory, uint64 Size); static void Memory_PopScratch(memory *Memory, uint64 Size); @@ -35,75 +35,4 @@ static layer_transforms Layer_GetTransforms(block_layer *Layer); void GL_GenAndBindTexture(GLuint *GLTexture, int Width, int Height, int BytesPerPixel, void *BufferAddress); static real32 Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 X); -# if 0 - -// Buffer management - -static void * Layer_AllocateBitmap(memory *Memory, uint16 Width, uint16 Height, uint16 BytesPerPixel); // -static project_layer * Layer_Init(project_data *File, memory *Memory); // Initializes a layer's name and properties. Add a source manually. - - -static void Bitmap_CalcPackedDimensions(uint16 Width, uint16 Height, uint16 *WidthP, uint16 *HeightP); // Returns the dimensions a packed bitmap should be in memory. -static void Bitmap_ConvertPacking(void *Buffer, void *DestBuffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, uint16 Which); -static void Bitmap_CalcHistogram(void *Data, void *Input, uint16 BytesPerPixel, uint64 TotalBytes); -static uint16 Bitmap_CalcByteOffset(uint16 BytesPerPixel); // Returns the amount of bytes a loop goes through depending on the InstructionMode. -static uint64 Bitmap_CalcTotalBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel); // Returns the total amount of bytes a bitmap takes up. -static uint64 Bitmap_CalcUnpackedBytes(uint16 Width, uint16 Height, uint16 BytesPerPixel); - -static bool32 Source_Generate(project_data *File, project_state *State, memory *Memory, void *Path); // Fills out source info if the source is a supported file. - -// Libav (ffmpeg) backend for decoding video - -static void AV_Init(char *filename, source *Source, memory *Memory); // Initializes all internal structs and calculates average PTS. -static cached_bitmap * AV_LoadVideoFrame(source *Source, memory *Memory, int32 TimelineFrame); // Loads video frame at TimelineFrame. - -static cached_bitmap * Cache_CheckBitmap(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, int32 TimelineFrame); - -// OpenGL - -static void GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, bool32 Multisample); -static void GL_RasterizeShape(project_layer *Layer, mask *Mask); - -static v2 Line_RatioToPoint(v2 a, v2 b, float ratio); -static v2 ImGui_ScreenPointToCompUV(ImVec2 ViewportMin, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 MousePos); - -void Bezier_CubicCalcPoints(v2 p1, v2 p2, v2 p3, v2 p4, void *Data, uint32 *Increment); - -static void Mask_TriangulateAndRasterize(memory *Memory, project_layer *Layer, mask *Mask); - - -static void History_Undo(memory *Memory); -static void History_Redo(memory *Memory); - -static void History_Entry_Commit(memory *Memory, action_entry_type Type, char *Name); -static void History_Entry_End(memory *Memory); -static void History_Entry_SetPointer(memory *Memory, void *Data); - -static void History_Action_Change(memory *Memory, void *DataLocation, void *OriginalData, void *NewData, action_type ActionChange); -static void History_Action_Change_SwapBool(memory *Memory, bool32 *Bool); -static void History_Action_Change_V2(memory *Memory, v2 *DataAddress, v2 *OriginalData, v2 *NewData); -static void History_Action_Change_Increment(memory *Memory, void *Data, action_type); -static void History_Action_Change_Decrement(memory *Memory, void *Data, action_type); -static void History_Action_Shift(memory *Memory, action_type ActionChange, void *DataAddress, int16 Direction, int16 Index); -static void History_Action_Shift_2(memory *Memory, void *StartingAddress, uint32 Size, uint16 NumberOf, int16 Direction, int16 Index); -static void History_Action_StoreData(memory *Memory, void *DataAddress, uint64 ByteSize); -static void History_Action_Undo(memory *Memory); -static void History_Action_Redo(memory *Memory); - -#if ARM -static void NEON_RenderLayer(transform_info T, comp_buffer *Buffer, rectangle RenderRegion); -#else -static void AVX2_RenderLayer(transform_info TransformInfo, comp_buffer *Buffer, rectangle RenderRegion); -static void SSE2_RenderLayer(transform_info TransformInfo, comp_buffer *Buffer, rectangle RenderRegion); -#endif -static void Fallback_RenderLayer(transform_info TransformInfo, comp_buffer *Buffer, rectangle RenderRegion); -static void PushRect(rectangle RenderRegion); -static bool32 CheckQueue(render_queue RenderInfo, uint16 Index); - -// Effects - -static void Effect_DrawColor(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]); -static void Effect_Levels(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]); -static void Effect_GaussianBlur(source *Source, layer_bitmap_info *BitmapInfo, memory *Memory, property_channel Property[]); -#endif @@ -176,15 +176,15 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, ui *UI, } #endif - if (State->FocusedWindow == focus_viewport && State->SetFocus) { - ImGui::SetNextWindowFocus(); - State->SetFocus = false; - } + // if (State->FocusedWindow == focus_viewport && State->SetFocus) { + // ImGui::SetNextWindowFocus(); + // State->SetFocus = false; + // } ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray); - if (State->FocusedWindow == focus_timeline && State->SetFocus) { - ImGui::SetNextWindowFocus(); - State->SetFocus = false; - } + // if (State->FocusedWindow == focus_timeline && State->SetFocus) { + // ImGui::SetNextWindowFocus(); + // State->SetFocus = false; + // } ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyInfo, Sorted.PropertyArray); ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.PropertyArray); @@ -196,7 +196,7 @@ char *BrushNames[brush_amount] = { struct brush_state { ImVec2 UIPos; // Initial position when ctrl is held - real32 Size = 64; // Maxes at 1024 for now + real32 Size = 256; // Maxes at 1024 for now real32 Hardness = 1.0f; // From 1 to 100 real32 Spacing = 1.0f; bool32 EraseMode = 0; diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 163a15f..3264e89 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -96,12 +96,37 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * property_channel *Property2 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[c+2]); property_channel *Property3 = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect.Block_Property_Index[c+3]); real32 Color[4] = { Property->CurrentValue, Property1->CurrentValue, Property2->CurrentValue, Property3->CurrentValue }; - if (ImGui::ColorEdit4("color", (real32 *)Color, ImGuiColorEditFlags_Float)) { + if (ImGui::ColorEdit4("color", (real32 *)Color, ImGuiColorEditFlags_Float | ImGuiColorEditFlags_NoInputs)) { + } + if (ImGui::IsItemActivated()) { + // State->Interact_Offset[0] = Property->CurrentValue; + // State->Interact_Offset[1] = Property1->CurrentValue; + // State->Interact_Offset[2] = Property2->CurrentValue; + // State->Interact_Offset[3] = Property3->CurrentValue; + State->Interact_Active = interact_type_slider_scrub; + } + if (ImGui::IsItemActive()) { + State->UpdateFrame = true; Property->CurrentValue = Color[0]; Property1->CurrentValue = Color[1]; Property2->CurrentValue = Color[2]; Property3->CurrentValue = Color[3]; } + + if (ImGui::IsItemDeactivatedAfterEdit()) { + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + Property->CurrentValue = State->Interact_Offset[0]; + } else if (!Property->Keyframe_Count) { + // History_Entry_Commit(Memory, "Property interact"); + // real32 Temp = Property->CurrentValue; + // Property->CurrentValue = State->Interact_Offset[0]; + // History_Action_Swap(Memory, Table, sizeof(Property->CurrentValue), &Property->CurrentValue); + // Property->CurrentValue = Temp; + // History_Entry_End(Memory); + } + State->Interact_Active = interact_type_none; + State->UpdateFrame = true; + } c += 3; } else if (ChannelHeader.DisplayType == property_display_type_blendmode) { uint32 *item_current_idx = (uint32 *)&(Property->CurrentValue); // Here we store our selection data as an index. @@ -1049,7 +1074,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImDrawList* draw_list = ImGui::GetWindowDrawList(); draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255)); draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255, 255, 255, 255)); - // draw_list->AddRect(CompPosMin, CompPosMax, IM_COL32(255, 255, 255, 55)); + draw_list->AddRect(CompPosMin, CompPosMax, IM_COL32(255, 255, 255, 55)); // Actual composition texture draw_list->PushClipRect(ViewportMin, ViewportMax, true); @@ -1073,7 +1098,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); bool32 IsHovered = ImGui::IsItemHovered(); -#if 1 +#if 0 bool32 IsActive = ImGui::IsItemActive(); bool32 IsActivated = ImGui::IsItemActivated(); bool32 IsDeactivated = ImGui::IsItemDeactivated(); @@ -1177,17 +1202,20 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, real32 DeltaSlope = MouseDelta.y / MouseDelta.x; for (real32 i = 0; i < DeltaDistance; i += State->Brush.Spacing) { ImVec2 MousePos = ImGui_Brush_CalcMousePos(State, io, MouseDelta, i, DeltaDistance, DeltaSlope); - Brush_Render(State, UI, T_Layer, MainComp, Source, State->Brush.TransientBitmap, ViewportMin, MousePos); + v2 PrincipalCompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); + v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, PrincipalCompUV, SortedCompArray, SortedLayerArray); + Brush_Render(State, UI, T_Layer, MainComp, Source, State->Brush.TransientBitmap, ViewportMin, LayerPos); } } else if (IsActivated) { ImVec2 MousePos = io.MousePos; - Brush_Render(State, UI, T_Layer, MainComp, Source, State->Brush.TransientBitmap, ViewportMin, MousePos); + v2 PrincipalCompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); + v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, PrincipalCompUV, SortedCompArray, SortedLayerArray); + Brush_Render(State, UI, T_Layer, MainComp, Source, State->Brush.TransientBitmap, ViewportMin, LayerPos); } State->UpdateFrame = true; } if (IsDeactivated) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index); block_source *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); @@ -1632,19 +1660,25 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor static void -ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, uint16 CompIndex, +ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, ImDrawList *draw_list, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions, ImVec2 Increment, ImVec2 TimelineAbsolutePos, ImVec2 TimelineMoveSize, ImVec2 TimelineZoomSize, ImVec2 TimelineSize, ImVec2 TimelineSizeWithBorder, real32 LayerIncrement, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray) { + uint16 CompIndex = 0; + if (RecursionIdx[Recursions] == -1) { + CompIndex = File->PrincipalCompIndex; + } else { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[Recursions]); + CompIndex = Layer->Block_Source_Index; + } block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); sorted_comp_info SortedCompInfo = SortedCompArray[CompIndex]; sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, CompIndex); ImGui::PushID(CompIndex); - // Layers are drawn from top to bottom, so we can account for opened precomps/keyframes - // without needing another loop. + // NOTE(fox): Layer sorting pre-calculates UI positioning, so the order layers are drawn is arbitrary. real32 DisplayOffset = 0; for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) { @@ -1680,15 +1714,21 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, LayerColor); draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, BorderColor, 2); block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index); - char buf[21]; - sprintf(buf, "%.2f, %.2f", Layer->Vertical_Offset, SortEntry.SortedOffset); - // draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf); + char buf[128]; +#if DEBUG + sprintf(buf, "%s, %i", String->Char, Index_Physical); +#else + sprintf(buf, "%s", String->Char); +#endif if (UI->TimelinePercentZoomed.y <= 1.0f) - draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, String->Char); + draw_list->AddText(Layer_ScreenPos_Min, 0xFFFFFFFF, buf); - if (Layer->IsSelected) { + if (Layer->IsSelected == 1) { draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(1.0f, 1.0f, 1.0f, 0.5f), 2); + } else if (Layer->IsSelected == 2) { + // draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.25f, 0.25f, 0.25f, 0.5f), 2); + draw_list->AddRect(Layer_ScreenPos_Min, Layer_ScreenPos_Max, ImColor(0.0f, 0.9f, 0.0f, 0.9f), 4); } // @@ -1778,6 +1818,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem if (!Layer->IsSelected) { if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); + Layer_Select_RecurseUp(Memory, State, Index_Physical, RecursionIdx, Recursions); } } @@ -1942,7 +1983,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::PushClipRect(MinClipPos, MaxClipPos, true); draw_list->PushClipRect(MinClipPos, MaxClipPos, true); - ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, Layer->Block_Source_Index, + uint32 RecursionsCount = Recursions+1; + RecursionIdx[RecursionsCount] = Index_Physical; + ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, RecursionIdx, RecursionsCount, Increment, NestedTimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray); @@ -2044,7 +2087,10 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGui_Timeline_BGElements(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize); - ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex, + int16 RecursionIdx[MAX_PRECOMP_RECURSIONS] = {}; + int32 Recursions = 0; + RecursionIdx[0] = -1; + ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, RecursionIdx, Recursions, Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement, SortedCompArray, SortedLayerArray, SortedPropertyInfo, SortedPropertyArray); @@ -2715,10 +2761,10 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me } #if DEBUG - if (ImGui::IsKeyPressed(ImGuiKey_3)) - { - State->ImGuiPopups = popup_keybinds; - } + // if (ImGui::IsKeyPressed(ImGuiKey_3)) + // { + // State->ImGuiPopups = popup_keybinds; + // } if (ImGui::IsKeyPressed(ImGuiKey_F)) { sprintf(State->DummyName, "test2"); diff --git a/prenderer.cpp b/prenderer.cpp index 929fd9b..76e76cf 100644 --- a/prenderer.cpp +++ b/prenderer.cpp @@ -37,6 +37,55 @@ Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHe return V2(LayerUV.x * SourceWidth, LayerUV.y * SourceHeight); } +static void +Layer_GetDimensions(memory *Memory, block_layer *Layer, int *Width, int *Height) +{ + if (!Layer->IsPrecomp) { + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + *Width = Source->Width; + *Height = Source->Height; + } else { + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index); + *Width = Comp->Width; + *Height = Comp->Height; + } +} + +// static v2 +// Layer_SlowTreeTraverse(project_data *File, memory *Memory, block_layer *Layer, v2 Point) +// { +// } + +/* +static v2 +Layer_Transform_ScreenSpaceToLocal_Recurse(project_data *File, memory *Memory, block_layer *Layer, v2 Point) +{ + uint32 Recurse[4]; + real32 Idx = 0; + Recurse[0] = Idx = Layer->Block_Composition_Index; + v2 LayerUV = Point; + int i = 1; + do { + // block_layer *OuterLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Idx); + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Idx); + Recurse[i++] = Idx; + Idx = OuterLayer->Block_Composition_Index; + } while (Idx != File->PrincipalCompIndex); + for (int a = i-2; a >= 0; a--) { + block_layer *OuterLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Recurse[a-1]); + int OuterWidth = 0, OuterHeight = 0; + Layer_GetDimensions(Memory, OuterLayer, &OuterWidth, &OuterHeight); + layer_transforms T = Layer_GetTransforms(OuterLayer); + block_layer *InnerLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Recurse[a]); + int InnerWidth = 0, InnerHeight = 0; + Layer_GetDimensions(Memory, InnerLayer, &InnerWidth, &InnerHeight); + LayerUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, LayerUV); + } + // return V2(LayerUV.x * SourceWidth, LayerUV.y * SourceHeight); + return V2(LayerUV.x, LayerUV.y); +} +*/ + // Transform given data based on state's Interact data. static void Transform_ApplyInteractive(interact_transform Interact, real32 *OutputX, real32 *OutputY, real32 *OutputRotation, real32 *OutputScale) @@ -88,7 +137,6 @@ Transform_IterateOuterBounds(block_layer *Layer, uint32 Width, uint32 Height, re if (Points[i].y > *MaxY) { *MaxY = Points[i].y; } } } - static void Transform_Recurse(project_state *State, memory *Memory, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray, |