From a2c1ceedc6c6b3756f8d9b3b9c29798b5d925447 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 1 Feb 2023 13:11:05 -0500 Subject: sorting and shape updates --- src/createcalls.cpp | 54 ++++++++++-- src/gl_calls.cpp | 172 +++++++++++-------------------------- src/imgui_ui.cpp | 179 ++------------------------------------ src/imgui_ui_timeline.cpp | 37 ++++++-- src/imgui_ui_viewport.cpp | 215 ++++++++++++++++++++++++++++------------------ src/include/all.h | 11 ++- src/include/layer.h | 4 +- src/include/main.h | 50 ++++++++--- src/layer.cpp | 18 ++-- src/main.cpp | 215 +++++++++++++++++++++++----------------------- src/prenderer.cpp | 13 +++ src/sorted.cpp | 11 +++ 12 files changed, 449 insertions(+), 530 deletions(-) diff --git a/src/createcalls.cpp b/src/createcalls.cpp index fd60b4e..54dd376 100644 --- a/src/createcalls.cpp +++ b/src/createcalls.cpp @@ -473,7 +473,7 @@ void Slide_Test(project_data *File, project_state *State, memory *Memory, sorted { block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); v2 CompDimensions = V2(MainComp->Width, MainComp->Height); - real32 Threshold = 5; + real32 Threshold = 10; uint8 *InteractBuffer = (uint8 *)State->Brush.TransientBitmap; for (int i = 0; i < State->Interact_Count; i++) { interact_slide_layer *Interact_Layer = (interact_slide_layer *)InteractBuffer; @@ -481,11 +481,14 @@ void Slide_Test(project_data *File, project_state *State, memory *Memory, sorted block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Interact_Layer->Index); v2 CompUV = V2(State->Interact_Offset[0], State->Interact_Offset[1]); v2 CompPos = CompUV * CompDimensions; - v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, CompUV, SortedCompArray, SortedLayerArray); + // v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, CompUV, SortedCompArray, SortedLayerArray, Interact_Layer->Index); + v2 LayerPos = V2(Layer->x.CurrentValue, Layer->y.CurrentValue); int Width, Height; Layer_GetDimensions(Memory, Layer, &Width, &Height); - if (abs(CompPos.x - LayerPos.x) > Threshold && - abs(CompPos.y - LayerPos.y) > Threshold) + v2 Difference = V2(abs(CompPos.x - LayerPos.x), abs(CompPos.y - LayerPos.y)); + printf("Diff: %.1f, %.1f\n", Difference.x, Difference.y); + if (Difference.x < Threshold && + Difference.y < Threshold) Assert(0); } } @@ -571,6 +574,33 @@ void Effect_Curves_Sort(memory *Memory, block_effect *Effect, uint16 *SortedPoin } } +static void +Layer_Nudge(project_data *File, project_state *State, memory *Memory, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray) +{ + sorted_comp_array SortedCompStart = SortedCompArray[File->PrincipalCompIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); + State->Interact_Active = interact_type_layer_move; + State->Interact_Offset[0] = 1; + History_Entry_Commit(Memory, "Move layer stack down"); + for (int i = 0; i < SortedCompStart.LayerCount; i++) + { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + // NOTE(fox): Some data on the tree could be saved here. + History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + Layer->Vertical_Offset = SortEntry.SortedOffset; + if (Layer->IsSelected) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->Frame_Offset), &Layer->Frame_Offset); + Interact_Evaluate_Layer(Memory, State, Index_Physical, SortedCompStart, SortedLayerStart, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Frame_Offset); + } + } + State->Interact_Active = interact_type_none; + State->Interact_Modifier = 0; + History_Entry_End(Memory); +} + static void Interact_Evaluate_Layer(memory *Memory, project_state *State, uint16 Layer_Index_Physical, sorted_comp_array SortedCompStart, sorted_layer_array *SortedLayerStart, int32 *Frame_Start, int32 *Frame_End, int *Frame_Offset) @@ -678,14 +708,20 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory Assert(Layer->Block_Effect_Count == 0); - NewLayer->IsSelected = true; + Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer)); NewLayer->Vertical_Offset--; - for (int a = i+2; a < LayerCount; a++) { + for (int a = i+1; a < LayerCount; a++) { + sorted_layer_array PrevSortEntry = SortedLayerStart[a-1]; + uint32 PrevIndex_Physical = PrevSortEntry.Block_Layer_Index; + block_layer *PrevLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, PrevIndex_Physical); sorted_layer_array NextSortEntry = SortedLayerStart[a]; uint32 NextIndex_Physical = NextSortEntry.Block_Layer_Index; block_layer *NextLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, NextIndex_Physical); - NextLayer->Vertical_Offset--; + if (NextLayer->Vertical_Offset == PrevLayer->Vertical_Offset) + NextLayer->Vertical_Offset -= 1; + else + break; } Assert(!NewLayer->x.Keyframe_Count); @@ -704,8 +740,8 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory Increment++; } else { - // History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); - Layer->IsSelected = false; + // History_Action_Swap(Memory, F_Layers, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset); + Layer->IsSelected = false; } } } diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp index 0fe2a31..91dba4f 100644 --- a/src/gl_calls.cpp +++ b/src/gl_calls.cpp @@ -177,21 +177,21 @@ GL_DeleteHWBuffer(gl_effect_layer *Test) } static void -GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, +GL_BlitStencil(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, layer_transforms T, int Width, int Height, int BytesPerPixel, int L_Width, int L_Height,v4 StrokeCol, v4 FillCol, int RenderMode, int Vector, ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom) { - int Uniform = 0; - // stencil buffer - glEnable(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 0, 0xFF); glStencilMask(0xff); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + int Uniform = 0; Uniform = glGetUniformLocation(DefaultShaderProgram, "CompDimensions"); glUniform2f(Uniform, Width, Height); @@ -213,131 +213,63 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale"); glUniform1f(Uniform, T.scale); - if (RenderMode == 0 || RenderMode == 1) - { - - Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode"); - glUniform1i(Uniform, 1); - Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode"); - glUniform1i(Uniform, 1); - - // fill - // vertices - glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject); - glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * FillCount, FillData, GL_STATIC_DRAW); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); - - // stencil buffer - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP); - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP); - glDisable(GL_CULL_FACE); - - glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount); - // - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glBindVertexArray(0); - - Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode"); - glUniform1i(Uniform, 0); - Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode"); - glUniform1i(Uniform, 1); - Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol"); - glUniform3f(Uniform, FillCol.r, FillCol.g, FillCol.b); - - // stencil for fill - // - // vertices - glBindBuffer(GL_ARRAY_BUFFER, DefaultVerts.VertexBufferObject); - glBufferData(GL_ARRAY_BUFFER, sizeof(GL_DefaultVertices), GL_DefaultVertices, GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); - glEnableVertexAttribArray(1); - - // stencil buffer - glStencilFunc(GL_NOTEQUAL, 0, 0xFF); - glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); - - glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0); - // - } else { - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - } - - // stencil buffer not needed - glDisable(GL_STENCIL_TEST); - glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 0, 0xFF); - + Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode"); + glUniform1i(Uniform, 1); + Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode"); + glUniform1i(Uniform, 1); + Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol"); + glUniform3f(Uniform, 0, 0, 0); + + // fill + // vertices + glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject); + glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * FillCount, FillData, GL_STATIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); + + // stencil buffer + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP); + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP); + glDisable(GL_CULL_FACE); + + glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0); + // + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glBindVertexArray(0); - if (RenderMode == 0 || RenderMode == 2) { - Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode"); - glUniform1i(Uniform, 1); - Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode"); - glUniform1i(Uniform, 1); - Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol"); - glUniform3f(Uniform, StrokeCol.r, StrokeCol.g, StrokeCol.b); - - // stroke - // - glBindBuffer(GL_ARRAY_BUFFER, ShapeVerts.VertexBufferObject); - glBufferData(GL_ARRAY_BUFFER, sizeof(real32) * 4 * StrokeCount, StrokeData, GL_STATIC_DRAW); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); - glEnableVertexAttribArray(1); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, StrokeCount); - // - } } static void -GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, - layer_transforms T, int Width, int Height, int BytesPerPixel, void *EffectBitmapAddress, int L_Width, int L_Height, v4 StrokeCol, v4 FillCol, int RenderMode, int Vector, - ImVec2 ViewportSize, ImVec2 UIZoom, ImVec2 UIPos) +GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uint32 StrokeCount, uint32 FillCount, + layer_transforms T, int Width, int Height, int BytesPerPixel, + int L_Width, int L_Height,v4 StrokeCol, v4 FillCol, int RenderMode, int Vector, + ImVec2 ViewportSize, ImVec2 UIPos, ImVec2 UIZoom, bool32 KeepStencil) { -#if 0 - int Uniform = 0; - glBindTexture(GL_TEXTURE_2D, TestL->Texture); - int ByteFlag = (BytesPerPixel == 4) ? GL_RGBA : GL_RGBA16; - int ByteFlag2 = (BytesPerPixel == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; - glTexImage2D(GL_TEXTURE_2D, 0, ByteFlag, Width, Height, 0, GL_RGBA, - ByteFlag2, EffectBitmapAddress); - - if (!Vector) - GL_UpdateTexture(TestL, EffectBitmapAddress, Width, Height, BytesPerPixel, 0); - GL_UpdateTexture(TestM, EffectBitmapAddress, Width, Height, BytesPerPixel, 1); - - glBindFramebuffer(GL_FRAMEBUFFER, TestM->FramebufferObject); - // stencil buffer - glEnable(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glEnable(GL_STENCIL_TEST); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + if (!KeepStencil) + glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS, 0, 0xFF); glStencilMask(0xff); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glUseProgram(DefaultShaderProgram); + int Uniform = 0; Uniform = glGetUniformLocation(DefaultShaderProgram, "CompDimensions"); - glUniform3f(Uniform, Width, Height, 0); + glUniform2f(Uniform, Width, Height); Uniform = glGetUniformLocation(DefaultShaderProgram, "LayerDimensions"); glUniform2f(Uniform, L_Width, L_Height); Uniform = glGetUniformLocation(DefaultShaderProgram, "ScreenDimensions"); glUniform2f(Uniform, ViewportSize.x, ViewportSize.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "Pos"); - glUniform2f(Uniform, T.x, T.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "CompOffset"); + Uniform = glGetUniformLocation(DefaultShaderProgram, "UIOffset"); glUniform2f(Uniform, UIPos.x, UIPos.y); - Uniform = glGetUniformLocation(DefaultShaderProgram, "CompZoom"); + Uniform = glGetUniformLocation(DefaultShaderProgram, "UIZoom"); glUniform2f(Uniform, UIZoom.x, UIZoom.y); + Uniform = glGetUniformLocation(DefaultShaderProgram, "Pos"); + glUniform2f(Uniform, T.x, T.y); Uniform = glGetUniformLocation(DefaultShaderProgram, "Anchor"); glUniform2f(Uniform, T.ax, T.ay); real32 Rad = (T.rotation * (PI / 180)); @@ -364,7 +296,7 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeDa // stencil buffer glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP); - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP); + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP); glDisable(GL_CULL_FACE); glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount); @@ -427,17 +359,6 @@ GL_RasterizeShape(gl_effect_layer *TestL, gl_effect_layer *TestM, void *StrokeDa glDrawArrays(GL_TRIANGLE_STRIP, 0, StrokeCount); // } - - glBindFramebuffer(GL_READ_FRAMEBUFFER, TestM->FramebufferObject); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TestL->FramebufferObject); - glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - glBindFramebuffer(GL_FRAMEBUFFER, TestL->FramebufferObject); - - glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, EffectBitmapAddress); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); -#endif } void @@ -445,6 +366,9 @@ GL_UpdateTexture(gl_effect_layer *Test, void *Data, uint16 Width, uint16 Height, { glViewport(0, 0, Width, Height); + // int err; + // err = glGetError(); Assert(err == 0); + if (!Test->Initialized) { GL_InitHWBuffer(Test); } diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp index 871c69d..e77195c 100644 --- a/src/imgui_ui.cpp +++ b/src/imgui_ui.cpp @@ -390,6 +390,12 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me } } } + if (ImGui::IsKeyPressed(ImGuiKey_LeftBracket)) { + Layer_Nudge(File, State, Memory, Sorted.CompArray, Sorted.LayerArray); + } + // if (ImGui::IsKeyPressed(ImGuiKey_RightBracket)) { + // } + if (ImGui::IsKeyPressed(ImGuiKey_X)) { if (State->TimelineMode == timeline_mode_graph && State->Interact_Active == interact_type_keyframe_move) { if (State->Interact_Modifier != 1) @@ -750,176 +756,3 @@ ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui } ImGui::End(); } - -static char ImGuiPrefs[] = "[Window][DockSpaceViewport_11111111]\n" -"Pos=0,0\n" -"Size=3840,2160\n" -"Collapsed=0\n" -"\n" -"[Window][Debug##Default]\n" -"Pos=122,442\n" -"Size=400,400\n" -"Collapsed=0\n" -"\n" -"[Window][Viewport]\n" -"Pos=443,34\n" -"Size=2872,1565\n" -"Collapsed=0\n" -"DockId=0x00000010,0\n" -"\n" -"[Window][###Properties]\n" -"Pos=0,34\n" -"Size=441,1565\n" -"Collapsed=0\n" -"DockId=0x0000000B,0\n" -"\n" -"[Window][Timeline]\n" -"Pos=0,1601\n" -"Size=3840,559\n" -"Collapsed=0\n" -"DockId=0x0000000A,0\n" -"\n" -"[Window][Dear ImGui Demo]\n" -"Pos=2677,34\n" -"Size=523,437\n" -"Collapsed=0\n" -"DockId=0x00000011,1\n" -"\n" -"[Window][Files]\n" -"Pos=3317,604\n" -"Size=523,743\n" -"Collapsed=0\n" -"DockId=0x00000007,0\n" -"\n" -"[Window][Effects list]\n" -"Pos=3317,1349\n" -"Size=523,250\n" -"Collapsed=0\n" -"DockId=0x00000008,0\n" -"\n" -"[Window][Graph editor]\n" -"Pos=0,949\n" -"Size=3200,526\n" -"Collapsed=0\n" -"DockId=0x00000009,0\n" -"\n" -"[Window][undotree]\n" -"Pos=2677,473\n" -"Size=523,572\n" -"Collapsed=0\n" -"DockId=0x00000007,2\n" -"\n" -"[Window][memoryviewer]\n" -"Pos=50,273\n" -"Size=800,200\n" -"Collapsed=0\n" -"\n" -"[Window][Example: Custom rendering]\n" -"Pos=758,789\n" -"Size=485,414\n" -"Collapsed=0\n" -"\n" -"[Window][Memory viewer]\n" -"Pos=2677,473\n" -"Size=523,572\n" -"Collapsed=0\n" -"DockId=0x00000007,1\n" -"\n" -"[Window][Graph info]\n" -"Pos=2838,1265\n" -"Size=235,353\n" -"Collapsed=0\n" -"\n" -"[Window][Properties]\n" -"Pos=0,34\n" -"Size=495,1056\n" -"Collapsed=0\n" -"DockId=0x0000000F,0\n" -"\n" -"[Window][Colors]\n" -"Pos=3317,34\n" -"Size=523,568\n" -"Collapsed=0\n" -"DockId=0x00000011,0\n" -"\n" -"[Window][Menu]\n" -"Pos=0,0\n" -"Size=3840,32\n" -"Collapsed=0\n" -"DockId=0x0000000D,0\n" -"\n" -"[Window][Stable Diffusion]\n" -"Pos=2206,684\n" -"Size=421,462\n" -"Collapsed=0\n" -"\n" -"[Window][SD prompt input]\n" -"Pos=2677,473\n" -"Size=523,541\n" -"Collapsed=0\n" -"DockId=0x00000007,2\n" -"\n" -"[Window][Example: Console]\n" -"Pos=747,851\n" -"Size=520,600\n" -"Collapsed=0\n" -"\n" -"[Window][SD gallery]\n" -"Pos=0,718\n" -"Size=441,557\n" -"Collapsed=0\n" -"DockId=0x0000000C,0\n" -"\n" -"[Window][Save as]\n" -"Pos=1782,1058\n" -"Size=300,116\n" -"Collapsed=0\n" -"\n" -"[Window][Keybinds]\n" -"Pos=1573,769\n" -"Size=750,639\n" -"Collapsed=0\n" -"\n" -"[Table][0x861D378E,3]\n" -"Column 0 Weight=1.0000\n" -"Column 1 Weight=1.0000\n" -"Column 2 Weight=1.0000\n" -"\n" -"[Table][0x1F146634,3]\n" -"RefScale=13\n" -"Column 0 Width=63\n" -"Column 1 Width=63\n" -"Column 2 Width=63\n" -"\n" -"[Table][0x64418101,3]\n" -"RefScale=13\n" -"Column 0 Width=63\n" -"Column 1 Width=63\n" -"Column 2 Width=63\n" -"\n" -"[Table][0xC9935533,3]\n" -"Column 0 Weight=1.0000\n" -"Column 1 Weight=1.0000\n" -"Column 2 Weight=1.0000\n" -"\n" -"[Docking][Data]\n" -"DockSpace ID=0x8B93E3BD Window=0xA787BDB4 Pos=0,0 Size=3840,2160 Split=Y Selected=0x13926F0B\n" -" DockNode ID=0x0000000D Parent=0x8B93E3BD SizeRef=3200,32 HiddenTabBar=1 Selected=0xA57AB2C6\n" -" DockNode ID=0x0000000E Parent=0x8B93E3BD SizeRef=3200,1299 Split=Y\n" -" DockNode ID=0x00000001 Parent=0x0000000E SizeRef=3200,1205 Split=X Selected=0x13926F0B\n" -" DockNode ID=0x00000003 Parent=0x00000001 SizeRef=441,1171 Split=Y Selected=0xDBB8CEFA\n" -" DockNode ID=0x0000000B Parent=0x00000003 SizeRef=521,425 Selected=0xDBB8CEFA\n" -" DockNode ID=0x0000000C Parent=0x00000003 SizeRef=521,347 Selected=0x56290987\n" -" DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1690,1171 Split=X Selected=0x13926F0B\n" -" DockNode ID=0x00000005 Parent=0x00000004 SizeRef=1165,1171 Split=X Selected=0x13926F0B\n" -" DockNode ID=0x0000000F Parent=0x00000005 SizeRef=495,856 Selected=0x199AB496\n" -" DockNode ID=0x00000010 Parent=0x00000005 SizeRef=2199,856 CentralNode=1 Selected=0x13926F0B\n" -" DockNode ID=0x00000006 Parent=0x00000004 SizeRef=523,1171 Split=Y Selected=0x86FA2F90\n" -" DockNode ID=0x00000011 Parent=0x00000006 SizeRef=483,437 Selected=0xBF7DFDC9\n" -" DockNode ID=0x00000012 Parent=0x00000006 SizeRef=483,766 Split=Y Selected=0x59A2A092\n" -" DockNode ID=0x00000007 Parent=0x00000012 SizeRef=523,572 Selected=0x86FA2F90\n" -" DockNode ID=0x00000008 Parent=0x00000012 SizeRef=523,192 Selected=0x812F222D\n" -" DockNode ID=0x00000002 Parent=0x0000000E SizeRef=3200,559 Split=Y Selected=0x0F18B61B\n" -" DockNode ID=0x00000009 Parent=0x00000002 SizeRef=3250,526 Selected=0xA1F22F4D\n" -" DockNode ID=0x0000000A Parent=0x00000002 SizeRef=3250,323 HiddenTabBar=1 Selected=0x0F18B61B\n" -"\0"; diff --git a/src/imgui_ui_timeline.cpp b/src/imgui_ui_timeline.cpp index 29b2835..6c111f1 100644 --- a/src/imgui_ui_timeline.cpp +++ b/src/imgui_ui_timeline.cpp @@ -1,3 +1,4 @@ +#include "imgui.h" #if SPECIAL #include "main.h" #endif @@ -427,8 +428,11 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem // NOTE(fox): Layer sorting pre-calculates UI positioning, so the order layers are drawn could be arbitrary. real32 DisplayOffset = 0; - for (int i = SortedCompStart.LayerCount - 1; i >= 0; i--) + int LayerCount = SortedCompStart.LayerCount + SortedCompStart.FakeLayerCount; + for (int i = 0; i < LayerCount; i++) { + if (i != 0) + int a = 0; sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); @@ -458,11 +462,13 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f); draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, LayerColor); + if (SortEntry.IsFake) + draw_list->AddRectFilled(Layer_ScreenPos_Min, Layer_ScreenPos_Max, IM_COL32(129, 50, 180, 90)); 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[128]; #if DEBUG - sprintf(buf, "%s, %i", String->Char, Index_Physical); + sprintf(buf, "%s, (idx: %i so: %.1f di: %.1f", String->Char, Index_Physical, SortEntry.SortedOffset, SortEntry. DisplayOffset); #else sprintf(buf, "%s", String->Char); #endif @@ -499,7 +505,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem Test &= (Layer_ScreenPos_Min.x <= io.MouseClickedPos[0].x && Layer_ScreenPos_Max.x >= io.MousePos.x); if (Test) { - if (!Layer->IsSelected) { + if (!Layer->IsSelected && !Layer->IsLocked) { Layer_Select(Memory, State, Index_Physical); } } else if (!io.KeyShift) { @@ -519,7 +525,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); } if (ImGui::IsItemActivated()) { - if (!Layer->IsSelected) { + if (!Layer->IsSelected && !Layer->IsLocked) { if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); } @@ -563,7 +569,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::InvisibleButton("##layer_mid", Layer_ScreenSize, ImGuiMouseButton_Left); if (ImGui::IsItemActivated()) { - if (!Layer->IsSelected) { + if (!Layer->IsSelected && !Layer->IsLocked) { if (!io.KeyShift) Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Index_Physical); Layer_Select_RecurseUp(Memory, State, Index_Physical, RecursionIdx, Recursions); @@ -572,7 +578,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem ImGui::OpenPopupOnItemClick("layerpopup", ImGuiPopupFlags_MouseButtonRight); if (ImGui::BeginPopup("layerpopup")) { - if (ImGui::Selectable("Visible")) { + if (ImGui::MenuItem("Visible", NULL, Layer->IsVisible)) { bool32 Commit = false; int h = 0, z = 0, i = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &z, &i)) { @@ -591,6 +597,25 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem State->UpdateFrame = true; } } + if (ImGui::MenuItem("Lock", NULL, Layer->IsLocked)) { + 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 lock"); + Commit = true; + } + History_Action_Swap(Memory, F_Layers, sizeof(Layer->IsLocked), &Layer->IsLocked); + Layer->IsLocked ^= 1; + } + } + if (Commit) { + History_Entry_End(Memory); + State->UpdateFrame = true; + } + } if (ImGui::MenuItem("Pre-compose layer")) { Precomp_UICreateButton(File, State, Memory, CompIndex, SortedCompStart, SortedLayerStart); State->UpdateKeyframes = true; diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp index 749999d..6503e6f 100644 --- a/src/imgui_ui_viewport.cpp +++ b/src/imgui_ui_viewport.cpp @@ -38,6 +38,7 @@ ImGui_Viewport_Toolbar(project_state *State, ImDrawList *draw_list) static void ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io, block_layer *Layer, int Width, int Height, shape_layer *Shape, block_composition *MainComp, ImDrawList *draw_list) { + memory_table_list TableName = (Layer == NULL) ? F_File : F_Layers; if (Shape->Point_Count) { uint32 wcol = IM_COL32(00, 00, 80, 255); v2 CompUV = State->LastClickedPoint; @@ -132,9 +133,7 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io if (IsItemDeactivated) { if (Layer == NULL && a == 0 && i == 0 && Shape->IsClosed == false) { History_Entry_Commit(Memory, "Close shape"); - Assert(0); - // which one?? - History_Action_Swap(Memory, F_File, sizeof(Shape->IsClosed), &Shape->IsClosed); + History_Action_Swap(Memory, TableName, sizeof(Shape->IsClosed), &Shape->IsClosed); Shape->IsClosed = true; History_Entry_End(Memory); } else if (Layer != NULL) { @@ -388,33 +387,26 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me layer_transforms BoxTransforms = { NewCenter.x, NewCenter.y, 0.5, 0.5, (real32)(Rad / (PI / 180)), Scale }; v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos); - - // for (int i = 0; i < 4; i++) { - // v2 Anchor = TransformPoint(BoxTransforms, BoxLength.x, BoxLength.y, BoxLength * Mid_Local[i]); - // Mid_P[i] = IV2(Anchor)*CompScale + UI->CompPos; - // } - real32 U = LayerPoint.x / BoxLength.x; real32 V = LayerPoint.y / BoxLength.y; - // DebugWatchVar("U", &U, d_float); - // DebugWatchVar("V", &V, d_float); - ImVec2 ScaleHandleSize(50, 50); + real32 HandleSize = ImGui::GetFontSize() * 2; + ImVec2 ScaleHandleSize(HandleSize, HandleSize); bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z); - // First do the halfway scale points, since they don't need UVs considered: + uint32 Col[4] = { IM_COL32(255, 0, 0, 255), IM_COL32(0, 255, 0, 255), IM_COL32(0, 0, 255, 255), IM_COL32(255, 255, 255, 255) }; + + // TODO(fox): Combine halfway and corner scale code? for (int i = 0; i < 4; i++) { ImGui::SetCursorScreenPos(Mid_P[i] - ScaleHandleSize/2); ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f))); ImGui::InvisibleButton("##ScaleMids", ScaleHandleSize); - ImGui::PopStyleColor(); ImGui_DrawCenteredRect(draw_list, Mid_P[i], 12, IM_COL32(20, 20, 20, 255)); ImGui_DrawCenteredRect(draw_list, Mid_P[i], 10, IM_COL32(20, 20, 220, 255)); - ImGui_DrawCenteredRect(draw_list, Mid_P[i], 6, IM_COL32(255, 255, 225, 50)); + ImGui_DrawCenteredRect(draw_list, Mid_P[i], 6, Col[i]); if (ImGui::GetMouseCursor() != ImGuiMouseCursor_None && ImGui::IsItemHovered() && !OtherActions) { @@ -428,59 +420,58 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me if (State->InteractTransformMode == 1 && ImGui::IsItemActive()) { - uint32 side = i; - v2 Dir = {}; - if (i == 0) { - Dir = V2(1, -1); - } else if (i == 1) { - Dir = V2(-1, -1); - } else if (i == 2) { - Dir = V2(-1, 0); - } else if (i == 3) { - Dir = V2(1, 0); - } else { - Assert(0); - } - - // InteractMin + V2(BoxLength.x * 0.5, 0), InteractMin + V2(0, BoxLength.y * 0.5), - // InteractMax - V2(BoxLength.x * 0.5, 0), InteractMax - V2(0, BoxLength.y * 0.5) }; - + // real32 NegRad = Rad - (90 * (PI / 180)); ImVec2 LengthVec = (io.MousePos - io.MouseClickedPos[0]) / CompScale; real32 NegRad = -Rad; - v2 UnrotatedLengthVec = {}; - { - v2 XAxis = (LengthVec.x * 1.0f)*V2(cos(NegRad), sin(NegRad)); - v2 YAxis = (LengthVec.y * -1.0f)*V2(sin(NegRad), -cos(NegRad)); - UnrotatedLengthVec = XAxis + YAxis; - } - - real32 Length = UnrotatedLengthVec.x * Dir.x; - real32 BoxAxis = BoxLength.x; - Interact->Scale = 1.0f + Length / BoxAxis; - v2 MovePos = V2((Length / 2), -(Length / 2) * (BoxLength.y / BoxLength.x)); - v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); - v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); - v2 Pos = XAxis + YAxis; + v2 XAxis = (LengthVec.x * 1.0f)*V2(cos(NegRad), sin(NegRad)); + v2 YAxis = (LengthVec.y * -1.0f)*V2(sin(NegRad), -cos(NegRad)); + v2 UnrotatedLengthVec = XAxis + YAxis; - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; -#if 0 + v2 Dir = {}; if (i == 0) { - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + Dir = V2(-1, 1); } else if (i == 1) { - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + Dir = V2(1, 1); } else if (i == 2) { - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + Dir = V2(1, -1); } else if (i == 3) { - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + Dir = V2(-1, -1); + } else { + Assert(0); } -#endif + if (i == 1 || i == 3) { + real32 Length = UnrotatedLengthVec.x * Dir.x; + real32 BoxAxis = BoxLength.x; + Interact->Scale = 1.0f + -Length / BoxAxis; + v2 MovePos = V2((Length / 2), 0); + v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); + v2 Pos = XAxis + YAxis; + if (!io.KeyCtrl) { + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; + } else { + Interact->Position.x = 0; + Interact->Position.y = 0; + } + } else { + real32 Length = UnrotatedLengthVec.y * Dir.x; + real32 BoxAxis = BoxLength.y; + Interact->Scale = 1.0f + -Length / BoxAxis; + v2 MovePos = V2(0, (Length / 2)); + v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); + v2 Pos = XAxis + YAxis; + if (!io.KeyCtrl) { + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; + } else { + Interact->Position.x = 0; + Interact->Position.y = 0; + } + } } ImGui::PopID(); @@ -494,7 +485,6 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me InBounds = true; } - uint32 Col[4] = { IM_COL32(255, 0, 0, 255), IM_COL32(0, 255, 0, 255), IM_COL32(0, 0, 255, 255), IM_COL32(255, 255, 255, 255) }; for (int i = 0; i < 4; i++) { ImGui::SetCursorScreenPos(P[i] - ScaleHandleSize/2); ImGui::PushID(i); @@ -542,6 +532,8 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me Assert(0); } + // Determine whether to use the unrotated X or Y axis based on + // where the mouse is. Makes the box corner always 'stick' to the mouse. v2 Vector0 = V2(BoxLength.x, BoxLength.y); real32 Dot = Inner(V2(-Vector0.y * Dir.x, Vector0.x * Dir.y), UnrotatedLengthVec); bool32 Test = (Dot < 0.0f) ? 0 : 1; @@ -554,8 +546,13 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); v2 Pos = XAxis + YAxis; - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + if (!io.KeyCtrl) { + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; + } else { + Interact->Position.x = 0; + Interact->Position.y = 0; + } } else { real32 Mult = (i == 1 || i == 3) ? -1 : 1; real32 Length = UnrotatedLengthVec.y * Mult * Dir.x; @@ -565,8 +562,13 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me v2 XAxis = (MovePos.x * Dir.x)*V2(cos(Rad), sin(Rad)); v2 YAxis = (MovePos.y * Dir.y)*V2(sin(Rad), -cos(Rad)); v2 Pos = XAxis + YAxis; - Interact->Position.x = Pos.x; - Interact->Position.y = Pos.y; + if (!io.KeyCtrl) { + Interact->Position.x = Pos.x; + Interact->Position.y = Pos.y; + } else { + Interact->Position.x = 0; + Interact->Position.y = 0; + } } } @@ -623,27 +625,40 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me State->UpdateFrame = true; if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - Assert(State->Interact_Active == interact_type_viewport_transform_gizmo); - int h = 0, c = 0, i = 0; - History_Entry_Commit(Memory, "Transform layers"); - 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 == 1) { - History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue); - History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue); - History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue); - History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue); - Transform_ApplyInteractive(State->Interact_Transform, &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue); + // A mouse release without any delta usually means the user wants + // to initiate a layer seelect. + ImVec2 LengthVec = (io.MousePos - io.MouseClickedPos[0]); + if (fabsf(LengthVec.x) + fabsf(LengthVec.y) > 2) { + Assert(State->Interact_Active == interact_type_viewport_transform_gizmo); + int h = 0, c = 0, i = 0; + History_Entry_Commit(Memory, "Transform layers"); + 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 == 1) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue); + History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue); + History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue); + History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue); + Transform_ApplyInteractive(State->Interact_Transform, &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue); + } } + History_Entry_End(Memory); + State->UpdateFrame = true; + State->UncommitedKeyframe = 1; + } else { + int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, io.KeyShift); + Assert(State->Tool == tool_default); + if (!io.KeyShift) { + Layer_DeselectAll(File, State, Memory); + State->Interact_Transform = {}; + } + if (Selection != -1) + Layer_Select(Memory, State, Selection); } - History_Entry_End(Memory); State->Interact_Active = interact_type_none; State->Interact_Transform = {}; - State->UpdateFrame = true; State->InteractTransformMode = 0; State->Interact_Modifier = 0; - State->UncommitedKeyframe = 1; - State->UpdateFrame = true; } } @@ -1077,6 +1092,10 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) { State->FocusedWindow = focus_viewport; + // normal people won't use this... + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + Layer_DeselectAll(File, State, Memory); + } } block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); @@ -1123,9 +1142,21 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, draw_list->AddRect(CompPosMin, CompPosMax, OUTLINE); draw_list->AddImage((void *)(intptr_t)textureID, CompPosMin, CompPosMax); } else { - Render_UI(File, State, Memory, UI, draw_list, - SortedCompArray, SortedLayerArray, + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); + uint8 *StartAddress = (uint8 *)Memory->Slot[B_PointData].Address; + uint8 *Data = StartAddress; + Arbitrary_Zero(Data, Memory->Slot[B_PointData].Size); + gl_viewport_data *RenderData = (gl_viewport_data *)Data; + Data += sizeof(gl_viewport_data); + *RenderData = { ImGui::GetMainViewport()->Size, + Comp->Width, Comp->Height, Comp->BytesPerPixel, + UI->CompPos, UI->CompZoom, UI->CompZoom.x / Comp->Width, {} }; + layer_transforms ExtraT = {}; + Render_UI(File, State, Memory, UI, draw_list, Data, RenderData, + SortedCompArray, SortedLayerArray, &ExtraT, SortedPropertyStart, SortedKeyframeArray, File->PrincipalCompIndex, State->Frame_Current); + draw_list->AddCallback(GL_Test, (void *)StartAddress); + draw_list->AddCallback(ImDrawCallback_ResetRenderState, NULL); draw_list->AddRect(CompPosMin, CompPosMax, OUTLINE); } draw_list->PopClipRect(); @@ -1200,6 +1231,12 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z) || ImGui::IsMouseDown(ImGuiMouseButton_Right); + // If there's any sort of drag before the user lets go of the mouse, they + // either want to use the bounding box or drag an object that isn't + // currently selected, so we need to select it now instead of on mouse + // release. This requires a state override (Interact_OutOfDrag) to force + // the deselection code to not be called on mouse release. + if (IsActive && !OtherActions && !io.KeyCtrl && !io.KeyAlt) { ImVec2 ClickedPos = io.MouseClickedPos[0]; @@ -1215,9 +1252,10 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, BoxMax.y = (MousePos.y > ClickedPos.y) ? MousePos.y : ClickedPos.y; if (io.MouseDelta.x || io.MouseDelta.y) { if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { - int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); + int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, io.KeyShift); if (!State->InteractTransformMode && Selection != -1) { - Layer_DeselectAll(File, State, Memory); + if (!io.KeyShift) + Layer_DeselectAll(File, State, Memory); Layer_Select(Memory, State, Selection); State->Interact_Active = interact_type_viewport_transform_gizmo; State->Interact_OutOfDrag = true; @@ -1252,7 +1290,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, State->Interact_OutOfDrag = 0; } else { // Layer selection - int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex); + int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex, io.KeyShift); if (State->Tool == tool_default && State->Interact_Active == interact_type_none) { if (!io.KeyShift && State->Interact_Active == interact_type_none) { Layer_DeselectAll(File, State, Memory); @@ -1295,7 +1333,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImVec2 MouseDelta = io.MouseDelta; real32 Delta = MouseDelta.x + MouseDelta.y; v2 PrincipalCompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); - v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, PrincipalCompUV, SortedCompArray, SortedLayerArray); + v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, PrincipalCompUV, SortedCompArray, SortedLayerArray, State->Brush.LayerToPaint_Index); if (IsActivated) { RenderQueue_AddBrush(State, LayerPos); } else if (Delta != 0.0f) { @@ -1423,6 +1461,13 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, if (State->Interact_Active == interact_type_viewport_duplicate) { if (IsDeactivated) { + // NOTE(fox): Normally calling functions that add/delete things + // shouldn't be done here since they affect sorting and can lead to + // access of invalid data, but since the duplicate state already + // pre-modifies the sort data to be correct, it's safe to call it + // here. + // UI bugs can form if code prior to this and code after this + // depend on the IsFake flag! History_Entry_Commit(Memory, "Duplicate layers"); State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; diff --git a/src/include/all.h b/src/include/all.h index 08a96e6..da7de64 100644 --- a/src/include/all.h +++ b/src/include/all.h @@ -351,11 +351,11 @@ static void Layer_GetDimensions(memory *Memory, block_layer *Layer, int *Width, int *Height); static v2 -Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); +Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 LayerIndex); // TODO(fox);: Precomps? static int32 -Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex); +Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex, bool32 BelowOnly); static bool32 Shape_TestBoxSelect(v2 Min, v2 Max, bezier_point *BezierPointData, uint32 BezierCount); @@ -488,10 +488,13 @@ static v2 T_CompPosToLayerPos(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, real32 X, real32 Y); static void -Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, +Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, uint8 *PointBuffer, gl_viewport_data *RenderData, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, layer_transforms *ExtraT, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current); +static layer_transforms +Transform_Add(layer_transforms T, layer_transforms ExtraT); + static v2 Transform_ScreenSpaceToLocal(layer_transforms T, uint32 FileWidth, uint32 FileHeight, uint32 SourceWidth, uint32 SourceHeight, ImVec2 CompPos, ImVec2 CompZoom, ImVec2 ViewportMin, ImVec2 Point); diff --git a/src/include/layer.h b/src/include/layer.h index 2b83a79..d059bb6 100644 --- a/src/include/layer.h +++ b/src/include/layer.h @@ -40,10 +40,10 @@ Layer_Select_Traverse(uint16 PrincipalCompIndex, memory *Memory, project_state * int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], int32 *Recursions); static v2 -Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray); +Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 LayerIndex); static int32 -Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex); +Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex, bool32 BelowOnly); static void Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex); diff --git a/src/include/main.h b/src/include/main.h index e1d1787..1f04d41 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -192,6 +192,16 @@ struct render_queue_item v2 Pos; }; +struct layer_transforms +{ + real32 x; + real32 y; + real32 ax; + real32 ay; + real32 rotation; + real32 scale; +}; + struct render_queue { uint16 Playhead; @@ -387,6 +397,33 @@ struct gl_effect_layer { uint32 Stencil_Renderbuffer; }; +struct gl_data +{ + int Type; + void *StrokeData; + uint32 StrokeCount; + v4 StrokeCol; + void *FillData; + uint32 FillCount; + v4 FillCol; + layer_transforms T; + real32 Width; + real32 Height; + int RenderMode; +}; + +struct gl_viewport_data +{ + ImVec2 ViewportSize; + int Width; + int Height; + int BytesPerPixel; + ImVec2 UIPos; + ImVec2 UIZoom; + real32 UIScale; + gl_data *LayerEntry[MAX_LAYERS]; + int LayerCount; +}; enum effect_display_type { @@ -610,16 +647,6 @@ struct block_composition int32 Frame_End; }; -struct layer_transforms -{ - real32 x; - real32 y; - real32 ax; - real32 ay; - real32 rotation; - real32 scale; -}; - enum source_type { source_type_none, source_type_principal, @@ -710,8 +737,9 @@ struct block_layer { }; }; - bool32 IsSelected; bool32 IsVisible; + bool32 IsLocked; + bool32 IsSelected; bool32 IsAdjustment; // NOTE(fox): I use these in some places without calling diff --git a/src/layer.cpp b/src/layer.cpp index 3686d75..dfe91a4 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -340,7 +340,7 @@ Layer_GetDimensions(memory *Memory, block_layer *Layer, int *Width, int *Height) } static v2 -Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray) +Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, v2 PrincipalCompUV, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 LayerIndex) { int16 RecursionIdx[MAX_PRECOMP_RECURSIONS] = {}; RecursionIdx[0] = -1; @@ -348,12 +348,12 @@ Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); sorted_comp_array SortedCompStart = 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); + Layer_Select_Traverse(File->PrincipalCompIndex, Memory, State, LayerIndex, SortedCompArray, SortedLayerArray, RecursionIdx, &Recursions); v2 PointUV = {0, 0}; int OuterWidth = Comp->Width, OuterHeight = Comp->Height; int InnerWidth = 0, InnerHeight = 0; if (Recursions == 0) { - block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index); + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerIndex); layer_transforms T = Layer_GetTransforms(Layer); Layer_GetDimensions(Memory, Layer, &InnerWidth, &InnerHeight); PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV); @@ -393,9 +393,11 @@ Layer_TestForPoint(memory *Memory, project_state *State, ui *UI, sorted_comp_arr return 0; } +// NOTE(fox): We loop twice to allow for convenient down-travelling when only +// one layer is selected, toggleable by the BelowOnly bool (i.e. shift held). // TODO(fox): Precomps? static int32 -Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex) +Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex, bool32 BelowOnly) { block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); sorted_comp_array SortedCompStart = SortedCompArray[PrincipalIndex]; @@ -425,9 +427,9 @@ Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_ar Layer_GetDimensions(Memory, Layer, &Width, &Height); layer_transforms T = Layer_GetTransforms(Layer); v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, State->LastClickedPoint); - if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected) + if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsSelected && !Layer->IsLocked) { - if (SelectionCount == 1) { + if (!BelowOnly && SelectionCount == 1) { if (i < SelectedLayerIndex) { LayerIndex = Index_Physical; break; @@ -566,6 +568,8 @@ Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_ar sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + if (Layer->IsLocked) + continue; if (Layer->IsShapeLayer) { shape_layer *Shape = &Layer->Shape; int Width = Shape->Width, Height = Shape->Height; @@ -585,7 +589,7 @@ Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_ar int Width, Height; Layer_GetDimensions(Memory, Layer, &Width, &Height); if (Transform_TestBox(Layer, Width, Height, MinPos, MaxPos)) - Layer->IsSelected = true; + Layer_Select(Memory, State, Index_Physical); } } } diff --git a/src/main.cpp b/src/main.cpp index fd56316..534460e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -128,15 +128,15 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_ } #endif - ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); ImGui_Timeline(File, State, Memory, UI, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); + ImGui_Viewport(File, State, UI, Memory, io, textureID, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); if (File->UI.Mode == 0) { ImGui_EffectsPanel(File, State, Memory, UI, io); } else { } ImGui_PropertiesPanel(File, State, UI, Memory, io, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); - ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); + // ImGui_File(File, State, Memory, io, Sorted.CompArray, Sorted.LayerArray); ImGui_ColorPanel(File, State, UI, Memory, io); #if STABLE @@ -274,61 +274,6 @@ Render_SortKeyframes(project_data *File, project_state *State, memory *Memory, } } -/* -struct render_entry_data -{ - int LayerCount; - int Width; - int Height; - int BytesPerPixel; - blend_mode BlendMode; -}; - -struct render_layer_data -{ - layer_transforms T; - int Width; - int Height; - // AV-specific - int BytesPerPixel; - void *Buffer; - // shape-specific - void *Stroke_Data; - uint32 Stroke_Count; - v4 Stroke_Col; - void *Fill_Data; - uint32 Fill_Count; - v4 Fill_Col; -}; -*/ - -struct gl_data -{ - void *StrokeData; - uint32 StrokeCount; - v4 StrokeCol; - void *FillData; - uint32 FillCount; - v4 FillCol; - layer_transforms T; - real32 Width; - real32 Height; - int RenderMode; -}; - -struct gl_viewport_data -{ - ImVec2 ViewportSize; - int Width; - int Height; - int BytesPerPixel; - ImVec2 UIPos; - ImVec2 UIZoom; - real32 UIScale; - gl_data *LayerEntry[MAX_LAYERS]; - int LayerCount; -}; - static void GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd) { @@ -346,13 +291,23 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd) glUseProgram(DefaultShaderProgram); - // for (int i = 0; i < 1; i++) { + bool32 KeepStencil = false; + for (int i = 0; i < RenderData->LayerCount; i++) { gl_data *Data = RenderData->LayerEntry[i]; - GL_RasterizeShape2(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount, - Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel, - Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0, - RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom); + + if (Data->Type == 0) { + GL_RasterizeShape2(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount, + Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel, + Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0, + RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom, KeepStencil); + } else { + // GL_BlitStencil(&MSBuffer, Data->StrokeData, Data->FillData, Data->StrokeCount, Data->FillCount, + // Data->T, RenderData->Width, RenderData->Height, RenderData->BytesPerPixel, + // Data->Width, Data->Height, Data->StrokeCol, Data->FillCol, Data->RenderMode, 0, + // RenderData->ViewportSize, RenderData->UIPos, RenderData->UIZoom); + // KeepStencil = true; + } } glBindFramebuffer(GL_READ_FRAMEBUFFER, MSBuffer.FramebufferObject); @@ -368,14 +323,12 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd) } static void -Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, - sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, +Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, uint8 *PointBuffer, gl_viewport_data *RenderData, + sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, layer_transforms *ExtraT, sorted_property_array *SortedPropertyStart, uint16 *SortedKeyframeArray, uint32 CompIndex, int32 Frame_Current) { - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex); cache_entry *Entry_Main = Memory_Cache_Search(State, Memory, cache_entry_type_comp, CompIndex, Frame_Current); - void *CompBuffer = Memory_Block_Bitmap_AddressAtIndex(Memory, Entry_Main->Block_StartIndex); uint64 Size = Comp->Width * Comp->Height * Comp->BytesPerPixel; sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; @@ -383,24 +336,51 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr Render_SortKeyframes(File, State, Memory, SortedCompStart, SortedLayerStart, SortedCompArray, SortedLayerArray, SortedPropertyStart, SortedKeyframeArray, Frame_Current); - uint8 *StartAddress = (uint8 *)Memory->Slot[B_PointData].Address; - Arbitrary_Zero(StartAddress, Memory->Slot[B_PointData].Size); - - - gl_viewport_data *RenderData = (gl_viewport_data *)StartAddress; - StartAddress += sizeof(gl_viewport_data); - *RenderData = { ImGui::GetMainViewport()->Size, - Comp->Width, Comp->Height, Comp->BytesPerPixel, - UI->CompPos, UI->CompZoom, UI->CompZoom.x / Comp->Width, {} }; - int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount; for (int i = 0; i < LayerCount; i++) { sorted_layer_array SortEntry = SortedLayerStart[i]; uint32 Index_Physical = SortEntry.Block_Layer_Index; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); - if (!Layer->IsShapeLayer) { - continue; + if (Layer->IsPrecomp) { + *ExtraT = Layer_GetTransforms(Layer); + if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) { + Transform_ApplyInteractive(State->Interact_Transform, &ExtraT->x, &ExtraT->y, &ExtraT->rotation, &ExtraT->scale); + } + if (State->Interact_Active == interact_type_viewport_transform_gizmo && Layer->IsSelected == 1) { + Transform_ApplyInteractive(State->Interact_Transform, &ExtraT->x, &ExtraT->y, &ExtraT->rotation, &ExtraT->scale); + } + if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected == 1) { + Assert(0); + // Transform_ApplySlide((v2 *)&State->Interact_Offset[0], &T); + } + if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) { + Assert(Layer->IsSelected); + ExtraT->x += State->Interact_Offset[0]; + ExtraT->y += State->Interact_Offset[1]; + } + gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)PointBuffer; + RenderData->LayerCount++; + PointBuffer += sizeof(gl_data); + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + GL_Data->Type = 1; + GL_Data->T = *ExtraT; + GL_Data->Width = Width; + GL_Data->Height = Height; + GL_Data->FillData = PointBuffer; + real32 CompVerts[16] = { 0.f, 0.f, 0.f, 0.f, + 0.f, (real32)Height, 0.f, 0.f, + (real32)Width, (real32)Height, 0.f, 0.f, + (real32)Width, 0.f, 0.f, 0.f }; + for (int a = 0; a < 16; a++) { + *(real32 *)PointBuffer = CompVerts[a]; + PointBuffer += sizeof(real32); + } + GL_Data->FillCount = 4; + Render_UI(File, State, Memory, UI, draw_list, PointBuffer, RenderData, + SortedCompArray, SortedLayerArray, ExtraT, + SortedPropertyStart, SortedKeyframeArray, Layer->Block_Source_Index, Frame_Current); } int32 Frame_Start = Layer->Frame_Start; int32 Frame_End = Layer->Frame_End; @@ -414,9 +394,7 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr if (Frame_Start_Abs <= Frame_Current && Frame_End_Abs > Frame_Current && Layer->IsVisible) { - shape_layer *Shape = &Layer->Shape; - shape_options ShapeOpt = Layer->ShapeOpt; - void *Data = StartAddress; + void *Data = PointBuffer; layer_transforms T = Layer_GetTransforms(Layer); if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) { @@ -426,6 +404,7 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr Transform_ApplyInteractive(State->Interact_Transform, &T.x, &T.y, &T.rotation, &T.scale); } if (State->Interact_Active == interact_type_viewport_slide && Layer->IsSelected == 1) { + Assert(0); // Transform_ApplySlide((v2 *)&State->Interact_Offset[0], &T); } if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) { @@ -433,39 +412,57 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr T.x += State->Interact_Offset[0]; T.y += State->Interact_Offset[1]; } + if (ExtraT->scale != 0) { + T = Transform_Add(T, *ExtraT, Comp->Width, Comp->Height); + } - v2 Min = {}, Max = {}; - uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data, - State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &Min, &Max); - StartAddress += NumberOfVerts * sizeof(nvg_point); - void *Data_Stroke = StartAddress; - uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke); - StartAddress += StrokeCount * sizeof(real32) * 4; - void *Data_Fill = StartAddress; - NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill); - StartAddress += NumberOfVerts * sizeof(real32) * 4; - - // zero to set the framebuffer to main - gl_effect_layer TestL = {}; - void *EffectBitmapAddress = NULL; - - gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)StartAddress; - RenderData->LayerCount++; - StartAddress += sizeof(gl_data); - - int Visibility = (ShapeOpt.StrokeWidth > 0.0f) ? ShapeOpt.Visibility : 1; - *GL_Data = { Data_Stroke, StrokeCount, ShapeOpt.StrokeCol, - Data_Fill, NumberOfVerts, ShapeOpt.FillCol, - T, Shape->Width, Shape->Height, Visibility }; + if (Layer->IsShapeLayer) { + shape_layer *Shape = &Layer->Shape; + shape_options ShapeOpt = Layer->ShapeOpt; + if (ShapeOpt.Visibility == 1 && ShapeOpt.StrokeWidth <= 0.0f) + continue; + v2 Min = {}, Max = {}; + uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, ShapeOpt, (nvg_point *)Data, + State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &Min, &Max); + PointBuffer += NumberOfVerts * sizeof(nvg_point); + void *Data_Stroke = PointBuffer; + uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, ShapeOpt.StrokeWidth, ShapeOpt.LineCapType, ShapeOpt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke); + PointBuffer += StrokeCount * sizeof(real32) * 4; + void *Data_Fill = PointBuffer; + NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill); + PointBuffer += NumberOfVerts * sizeof(real32) * 4; + + // zero to set the framebuffer to main + gl_effect_layer TestL = {}; + void *EffectBitmapAddress = NULL; + + gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)PointBuffer; + RenderData->LayerCount++; + PointBuffer += sizeof(gl_data); + + int Visibility = ShapeOpt.Visibility; + *GL_Data = { 0, Data_Stroke, StrokeCount, ShapeOpt.StrokeCol, + Data_Fill, NumberOfVerts, ShapeOpt.FillCol, + T, Shape->Width, Shape->Height, Visibility }; + } else if (!Layer->IsPrecomp) { + int Width = 0, Height = 0; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + + gl_data *GL_Data = RenderData->LayerEntry[RenderData->LayerCount] = (gl_data *)PointBuffer; + RenderData->LayerCount++; + PointBuffer += sizeof(gl_data); + + GL_Data->Type = 1; + GL_Data->Width = Width; + GL_Data->Height = Height; + GL_Data->T = T; + } else { + } } } - Assert((StartAddress - (uint8 *)Memory->Slot[B_PointData].Address) < Memory->Slot[B_PointData].Size); - - ImDrawCallback CustomRenderer = GL_Test; - draw_list->AddCallback(CustomRenderer, (void *)RenderData); + Assert((PointBuffer - (uint8 *)Memory->Slot[B_PointData].Address) < Memory->Slot[B_PointData].Size); - draw_list->AddCallback(ImDrawCallback_ResetRenderState, NULL); } static void * diff --git a/src/prenderer.cpp b/src/prenderer.cpp index 53025b2..76ac4ab 100644 --- a/src/prenderer.cpp +++ b/src/prenderer.cpp @@ -279,6 +279,19 @@ Transform_Inverse(layer_transforms T) return T; } +static layer_transforms +Transform_Add(layer_transforms T, layer_transforms ExtraT, real32 Width, real32 Height) +{ + v2 NewPos = TransformPoint(ExtraT, Width, Height, V2(T.x, T.y)); + T.x = NewPos.x; + T.y = NewPos.y; + T.ax = T.ax; + T.ay = T.ay; + T.rotation = T.rotation + ExtraT.rotation; + T.scale = T.scale * ExtraT.scale; + return T; +} + static ImVec2 Layer_LocalToScreenSpace(project_state *State, memory *Memory, block_layer *Layer, ui *UI, uint32 PrincipalCompIndex, v2 Point) { diff --git a/src/sorted.cpp b/src/sorted.cpp index 08d9d3b..03f5b0a 100644 --- a/src/sorted.cpp +++ b/src/sorted.cpp @@ -242,11 +242,22 @@ Layer_SortAll(project_state *State, memory *Memory, sorted_layer_array *LayerEntry = &SortedLayerStart[Idx]; block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry->Block_Layer_Index); if (Layer->IsSelected) { + for (int a = i+1; a < SortedCompStart->LayerCount; a++) { + int PrevIdx = a + FauxIncrement - 1; + sorted_layer_array *PrevLayerEntry = &SortedLayerStart[PrevIdx]; + int NextIdx = a + FauxIncrement; + sorted_layer_array *NextLayerEntry = &SortedLayerStart[NextIdx]; + if (NextLayerEntry->SortedOffset == PrevLayerEntry->SortedOffset) + NextLayerEntry->SortedOffset -= 1; + else + break; + } uint8 *Address_Start = (uint8 *)(LayerEntry); uint8 *Address_End = (uint8 *)(&SortedLayerStart[SortedCompStart->LayerCount + FauxIncrement]) - 1; Assert(SortedCompStart->CurrentSortIndex != (SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount)); Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer_array), 1); sorted_layer_array *FakeLayerEntry = LayerEntry + 1; + FakeLayerEntry->SortedOffset -= 1; Assert(FakeLayerEntry->Block_Layer_Index == LayerEntry->Block_Layer_Index); FakeLayerEntry->IsFake = true; FauxIncrement++; -- cgit v1.2.3