summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dependencies/src/imgui/imgui_impl_sdl.cpp130
-rw-r--r--src/createcalls.cpp10
-rw-r--r--src/gl_calls.cpp36
-rw-r--r--src/imgui_ui.cpp41
-rw-r--r--src/imgui_ui_viewport.cpp30
-rw-r--r--src/include/all.h4
-rw-r--r--src/include/layer.h2
-rw-r--r--src/include/main.h16
-rw-r--r--src/layer.cpp21
-rw-r--r--src/main.cpp65
-rw-r--r--src/sorted.cpp22
11 files changed, 311 insertions, 66 deletions
diff --git a/dependencies/src/imgui/imgui_impl_sdl.cpp b/dependencies/src/imgui/imgui_impl_sdl.cpp
index 34e1abb..9a68de7 100644
--- a/dependencies/src/imgui/imgui_impl_sdl.cpp
+++ b/dependencies/src/imgui/imgui_impl_sdl.cpp
@@ -366,6 +366,130 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
return false;
}
+#if 0
+/* XPM */
+static const char *arrow[] = {
+ /* width height num_colors chars_per_pixel */
+ " 32 32 3 1",
+ /* colors */
+ "X c #000000",
+ ". c #ffffff",
+ " c None",
+ /* pixels */
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "X..............................X",
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "0,0"
+};
+#endif
+
+/* XPM */
+static const char *arrow[] = {
+ /* width height num_colors chars_per_pixel */
+ " 32 32 3 1",
+ /* colors */
+ "X c #000000",
+ ". c #ffffff",
+ " c None",
+ /* pixels */
+ " ",
+ " ",
+ " XX ",
+ " X... ",
+ " ...X ",
+ " ...X ",
+ " ...X ",
+ " ... ",
+ " ...X ",
+ " ... ",
+ "X..X ",
+ "X..X ",
+ "...X ",
+ "...X ",
+ "...X ",
+ "X..X ",
+ "X..X ",
+ " ... XX ",
+ " ... X....XX ",
+ " X... X........X ",
+ " ...X XX.......X ",
+ " X... .....X ",
+ " X...X ......X ",
+ " X...X X....... ",
+ " X....XX X.....X... ",
+ " X...... ........X X..X ",
+ " X.... ......X ... ",
+ " XX XXXX ... ",
+ " X..X ",
+ " X..X ",
+ " XX ",
+ " ",
+ "0,0"
+};
+
+static SDL_Cursor *cursor_test(const char *image[])
+{
+ int i, row, col;
+ Uint8 data[4*32];
+ Uint8 mask[4*32];
+ int hot_x, hot_y;
+
+ i = -1;
+ for (row=0; row<32; ++row) {
+ for (col=0; col<32; ++col) {
+ if (col % 8) {
+ data[i] <<= 1;
+ mask[i] <<= 1;
+ } else {
+ ++i;
+ data[i] = mask[i] = 0;
+ }
+ switch (image[4+row][col]) {
+ case 'X':
+ data[i] |= 0x01;
+ mask[i] |= 0x01;
+ break;
+ case '.':
+ mask[i] |= 0x01;
+ break;
+ case ' ':
+ break;
+ }
+ }
+ }
+ sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+ return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+}
+
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
{
ImGuiIO& io = ImGui::GetIO();
@@ -408,13 +532,15 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
// Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
bd->MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
- bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
+ bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = cursor_test(arrow);
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
- bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
+ bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
+ // bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
+ // bd->MouseCursors[ImGuiMouseCursor_Test] = SDL_CreateCursor();
// Set platform dependent data in viewport
// Our mouse update function expect PlatformHandle to be filled for the main viewport
diff --git a/src/createcalls.cpp b/src/createcalls.cpp
index bf9eea2..09bcea5 100644
--- a/src/createcalls.cpp
+++ b/src/createcalls.cpp
@@ -688,9 +688,9 @@ Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *Arr
}
// TODO(fox): Add different modes (all dupes on top, each dupe above its layer, two for bottom)
-void
-SortUnionTest(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer *StartLayer,
- int i, int FauxIncrement, int LayerCount, int Mode)
+static void
+Sort_OffsetDupes(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer *StartLayer,
+ int i, int FauxIncrement, int LayerCount, int Mode)
{
block_layer *PrevLayer = StartLayer;
for (int a = i+1; a < LayerCount; a++) {
@@ -698,7 +698,7 @@ SortUnionTest(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer
uint32 NextIndex_Physical = NextSortEntry->Block_Layer_Index;
block_layer *NextLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, NextIndex_Physical);
if (NextLayer->Vertical_Offset == PrevLayer->Vertical_Offset) {
- if (Mode == 0) {
+ if (Mode == 0 && !NextSortEntry->IsFake) {
History_Action_Swap(Memory, F_Layers, sizeof(NextLayer->Vertical_Offset), &NextLayer->Vertical_Offset);
NextLayer->Vertical_Offset -= 1;
} else {
@@ -792,7 +792,7 @@ Project_Layer_Duplicate(project_data *File, project_state *State, memory *Memory
Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, NewLayer));
NewLayer->Vertical_Offset--;
- SortUnionTest(Memory, SortedLayerStart, NewLayer, i, 0, LayerCount, 0);
+ Sort_OffsetDupes(Memory, SortedLayerStart, NewLayer, i, 0, LayerCount, 0);
Assert(!NewLayer->x.Keyframe_Count);
Assert(!NewLayer->y.Keyframe_Count);
diff --git a/src/gl_calls.cpp b/src/gl_calls.cpp
index 8bdd7f1..1203c2f 100644
--- a/src/gl_calls.cpp
+++ b/src/gl_calls.cpp
@@ -260,7 +260,11 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
Uniform = glGetUniformLocation(DefaultShaderProgram, "Scale");
glUniform1f(Uniform, T.scale);
- if (RenderMode == 0 || RenderMode == 1)
+ // Concave shapes are fairly more costly than convex: we have to write to
+ // the stencil buffer, but since we also are using it to mask out precomps,
+ // every shape has to be drawn a second time to "clean up" the buffer.
+
+ if (RenderMode & gl_renderflag_fill && RenderMode & gl_renderflag_concave)
{
// disable color component writing and allow stencil writing using the shape layer's vertices
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -309,8 +313,6 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
// ---
- // NOTE(fox): We need to clean up the mask after we draw the colors if
- // precomps are involved.
// TODO(fox): If this is the final method, add this optimization: shapes with
// no precomps below them don't have to be drawn twice and can instead
// get cleaned by setting StencilOp to GL_DECR.
@@ -335,14 +337,38 @@ GL_RasterizeShape2(gl_effect_layer *TestM, void *StrokeData, void *FillData, uin
glDrawArrays(GL_TRIANGLE_FAN, 0, FillCount);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- } else {
+ }
+ else if (RenderMode & gl_renderflag_fill)
+ {
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glBindVertexArray(0);
+ glStencilFunc(GL_EQUAL, StencilLayer, 0xFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
+ glUniform1i(Uniform, 1);
+ Uniform = glGetUniformLocation(DefaultShaderProgram, "InputCol");
+ glUniform3f(Uniform, FillCol.r, FillCol.g, FillCol.b);
+
+ 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)));
+
+ glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_INT, 0);
+ }
+ else {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
glBindVertexArray(0);
// stroke component
- if (RenderMode == 0 || RenderMode == 2) {
+ if (RenderMode & gl_renderflag_stroke)
+ {
Uniform = glGetUniformLocation(DefaultShaderProgram, "VertexMode");
glUniform1i(Uniform, 1);
Uniform = glGetUniformLocation(DefaultShaderProgram, "FragmentMode");
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 84e2b91..5d0f65d 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -9,7 +9,6 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
{
ImGui::Begin("Files");
ImGui::Text("%s: %hu", "Layers", File->Layer_Count);
- ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) {
@@ -90,18 +89,6 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
// if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
// Source_DeselectAll(File, Memory);
-#if DEBUG
-
- for (int i = 0; i < Debug.Temp.WatchedProperties; i++) {
- if (Debug.Temp.DebugPropertyType[i] == d_float) {
- ImGui::Text("%s: %f", Debug.Temp.String[i], Debug.Temp.Val[i].f);
- } else if (Debug.Temp.DebugPropertyType[i] == d_int) {
- ImGui::Text("%s: %i", Debug.Temp.String[i], Debug.Temp.Val[i].i);
- } else if (Debug.Temp.DebugPropertyType[i] == d_uint) {
- ImGui::Text("%s: %u", Debug.Temp.String[i], Debug.Temp.Val[i].u);
- }
- }
-#endif
ImGui::End();
}
@@ -144,6 +131,15 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor
UI->AltColor = Temp;
}
+ if (State->Tool == tool_default) {
+ if (ImGui::MenuItem("All", NULL, (State->SelectionMode == 0))) {
+ State->SelectionMode = 0;
+ }
+ if (ImGui::MenuItem("Exclude precomps", NULL, (State->SelectionMode == 1))) {
+ State->SelectionMode = 1;
+ }
+ }
+
if (State->Tool == tool_brush) {
real32 BrushSizeMin = 0;
real32 BrushSizeMax = 1024;
@@ -167,6 +163,20 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor
// ImGui_Opt_Shape(&State->Pen.Opt);
}
+#if DEBUG
+
+ for (int i = 0; i < Debug.Temp.WatchedProperties; i++) {
+ if (Debug.Temp.DebugPropertyType[i] == d_float) {
+ ImGui::Text("%s: %f", Debug.Temp.String[i], Debug.Temp.Val[i].f);
+ } else if (Debug.Temp.DebugPropertyType[i] == d_int) {
+ ImGui::Text("%s: %i", Debug.Temp.String[i], Debug.Temp.Val[i].i);
+ } else if (Debug.Temp.DebugPropertyType[i] == d_uint) {
+ ImGui::Text("%s: %u", Debug.Temp.String[i], Debug.Temp.Val[i].u);
+ }
+ }
+ ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
+#endif
+
ImGui::End();
}
@@ -395,6 +405,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
}
// if (ImGui::IsKeyPressed(ImGuiKey_RightBracket)) {
// }
+ if (ImGui::IsKeyPressed(ImGuiKey_GraveAccent)) {
+ Layer_ApplyPreviousSelection(File, State, Memory);
+ }
if (ImGui::IsKeyPressed(ImGuiKey_X)) {
if (State->TimelineMode == timeline_mode_graph && State->Interact_Active == interact_type_keyframe_move) {
@@ -683,6 +696,8 @@ ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImG
UI->Mode = 0;
if (ImGui::Selectable("Vector view", UI->Mode == 1))
UI->Mode = 1;
+ if (ImGui::MenuItem("Clip viewport canvas", NULL, State->ViewportEnabled == 0))
+ State->ViewportEnabled ^= 1;
#if STABLE
if (ImGui::Selectable("Stable Diffusion tools", UI->StableEnabled))
UI->StableEnabled ^= 1;
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index ed26ce7..dc37225 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -676,7 +676,7 @@ ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Me
Layer_DeselectAll(File, State, Memory, 1);
State->Interact_Transform = {};
}
- if (Selection != -1)
+ if (Selection > 0)
Layer_Select(Memory, State, Selection);
}
State->Interact_Active = interact_type_none;
@@ -1108,6 +1108,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
bool open = true;
ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
+ DebugWatchVar("Count: ", &State->PreviousSelectionCount, d_int);
if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) {
State->FocusedWindow = focus_viewport;
@@ -1144,16 +1145,8 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
// BGCOL = IM_COL32(0, 0, 0, 255);
OUTLINE = IM_COL32(255,255,255, 255);
}
- draw_list->AddRectFilled(ViewportMin, ViewportMax, BGCOL);
- draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255,255,255, 255));
-
- real32 FontSize = ImGui::GetFontSize();
- ImGui::SetCursorScreenPos(ImVec2(ViewportMax.x - FontSize*2, ViewportMin.y + ViewportScale.y - FontSize*3.0));
- ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 80));
- if (ImGui::Button("?"))
- State->ImGuiPopups = popup_keybinds;
- ImGui::PopStyleColor();
+ draw_list->AddRectFilled(ViewportMin, ViewportMax, BGCOL);
// Actual composition texture
draw_list->PushClipRect(ViewportMin, ViewportMax, true);
@@ -1167,7 +1160,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
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,
+ *RenderData = { ViewportMin, ViewportMax, ImGui::GetMainViewport()->Size, State->ViewportEnabled,
Comp->Width, Comp->Height, Comp->BytesPerPixel,
UI->CompPos, UI->CompZoom, UI->CompZoom.x / Comp->Width, {} };
layer_transforms ExtraT = {};
@@ -1180,6 +1173,15 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
draw_list->PopClipRect();
+ draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255,255,255, 255));
+
+ real32 FontSize = ImGui::GetFontSize();
+ ImGui::SetCursorScreenPos(ImVec2(ViewportMax.x - FontSize*2, ViewportMin.y + ViewportScale.y - FontSize*3.0));
+ ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 80));
+ if (ImGui::Button("?"))
+ State->ImGuiPopups = popup_keybinds;
+ ImGui::PopStyleColor();
+
// UI+interaction for layer
if (State->MostRecentlySelectedLayer > -1)
@@ -1275,7 +1277,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
v2 CompPoint = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos) * V2(MainComp->Width, MainComp->Height);
int32 Selection = LayerIterate_TestSelection(State, Memory, File->PrincipalCompIndex, T, CompPoint,
SortedCompArray, SortedLayerArray, io.KeyShift);
- if (!io.KeyShift && !State->InteractTransformMode && Selection != -1) {
+ if (!io.KeyShift && !State->InteractTransformMode && Selection > 0) {
Layer_DeselectAll(File, State, Memory);
Layer_Select(Memory, State, Selection);
State->Interact_Active = interact_type_viewport_transform_gizmo;
@@ -1323,10 +1325,10 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
SortedCompArray, SortedLayerArray, 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);
+ Layer_DeselectAll(File, State, Memory, 0, 1);
State->Interact_Transform = {};
}
- if (Selection != -1)
+ if (Selection > 0)
Layer_Select(Memory, State, Selection);
}
}
diff --git a/src/include/all.h b/src/include/all.h
index cdd14a8..b5b1d77 100644
--- a/src/include/all.h
+++ b/src/include/all.h
@@ -224,6 +224,10 @@ static void
Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray,
uint16 PrincipalIndex, layer_transforms ExtraT, v2 MinPos, v2 MaxPos);
+static void
+Sort_OffsetDupes(memory *Memory, sorted_layer_array *SortedLayerStart, block_layer *StartLayer, sorted_layer_array *StartSortEntry,
+ int i, int FauxIncrement, int LayerCount, int Mode);
+
void AV_IsFileSupported(char *filename, bool32 *IsVideo, bool32 *HasAudio);
void AV_Dealloc(av_info *AV);
diff --git a/src/include/layer.h b/src/include/layer.h
index 074a274..bbea0e6 100644
--- a/src/include/layer.h
+++ b/src/include/layer.h
@@ -24,7 +24,7 @@ static void
Layer_Select_RecurseUp(memory *Memory, project_state *State, int32 i, int16 RecursionIdx[MAX_PRECOMP_RECURSIONS], uint32 Recursions);
static void
-Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp = 0);
+Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp = 0, bool32 RecordSelection = 0);
static bool32
Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_array **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer,
diff --git a/src/include/main.h b/src/include/main.h
index 9c1da89..3b4843e 100644
--- a/src/include/main.h
+++ b/src/include/main.h
@@ -398,6 +398,13 @@ struct gl_effect_layer {
uint32 Stencil_Renderbuffer;
};
+enum gl_shape_renderflags
+{
+ gl_renderflag_fill = 1 << 0,
+ gl_renderflag_stroke = 1 << 1,
+ gl_renderflag_concave = 1 << 2
+};
+
struct gl_data
{
int Type;
@@ -415,7 +422,10 @@ struct gl_data
struct gl_viewport_data
{
+ ImVec2 ViewportMin;
+ ImVec2 ViewportMax;
ImVec2 ViewportSize;
+ int ViewportDisplay;
int Width;
int Height;
int BytesPerPixel;
@@ -468,6 +478,12 @@ struct project_state
bool32 UpdateScreen = 1; // refreshes entire UI; influenced by raw key/mouse input
bool32 DebugDisableCache = 1;
+ bool32 ViewportEnabled = 0;
+ bool32 SelectionMode = 1;
+
+ uint16 PreviousSelection[MAX_LAYERS];
+ uint16 PreviousSelectionCount = 0;
+
// bad
uint32 CachedFrameCount;
int32 LastCachedFrame = -10000;
diff --git a/src/layer.cpp b/src/layer.cpp
index 9a3a0a4..0b278e5 100644
--- a/src/layer.cpp
+++ b/src/layer.cpp
@@ -230,7 +230,22 @@ Interact_BoxSelect_End(project_data *File, project_state *State, memory *Memory)
}
static void
-Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp) {
+Layer_ApplyPreviousSelection(project_data *File, project_state *State, memory *Memory)
+{
+ if (State->PreviousSelectionCount) {
+ for (int a = 0; a < State->PreviousSelectionCount; a++) {
+ int Idx = State->PreviousSelection[a];
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Idx);
+ Layer->IsSelected = 0x01;
+ }
+ State->MostRecentlySelectedLayer = State->PreviousSelection[0];
+ }
+}
+
+static void
+Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool32 AllowComp, bool32 RecordSelection) {
+ if (RecordSelection && State->PreviousSelectionCount)
+ State->PreviousSelectionCount = 0;
int h = 0, c = 0, i = 0;
bool32 ShiftLayers = false;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
@@ -239,6 +254,10 @@ Layer_DeselectAll(project_data *File, project_state *State, memory *Memory, bool
ShiftLayers = 1;
} else {
if (!(AllowComp && Layer->IsSelected & 0x02)) {
+ if (Layer->IsSelected & 0x01 && RecordSelection) {
+ State->PreviousSelection[State->PreviousSelectionCount] = i;
+ State->PreviousSelectionCount++;
+ }
Layer->IsSelected = 0x00;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 77a405a..f5ffbea 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -74,6 +74,7 @@ Main_RenderUI(ImGuiIO io, ImVec4 clear_color, SDL_Window *window)
static bool32
Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_file Sorted, ui *UI, SDL_Window *window, GLuint textureID)
{
+ uint64 InputStart = SDL_GetPerformanceCounter();
ImGuiIO& io = ImGui::GetIO();
SDL_Event event = {};
int test = 0;
@@ -171,6 +172,10 @@ Main_InputTest(project_data *File, project_state *State, memory *Memory, sorted_
test += 1;
if (State->UpdateScreen)
test = 0;
+
+ uint64 InputTime = SDL_GetPerformanceCounter() - InputStart;
+ printf("OURUI: %.2lu\n", InputTime);
+
return test;
}
@@ -291,6 +296,7 @@ Render_SortKeyframes(project_data *File, project_state *State, memory *Memory,
static void
GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
+ uint64 PerfStart = SDL_GetPerformanceCounter();
gl_viewport_data *RenderData = (gl_viewport_data *)cmd->UserCallbackData;
gl_effect_layer MSBuffer = {};
@@ -350,13 +356,22 @@ GL_Test(const ImDrawList* parent_list, const ImDrawCmd* cmd)
glBindFramebuffer(GL_READ_FRAMEBUFFER, MSBuffer.FramebufferObject);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// The multisample framebuffer allows us to conveniently clip to the comp bounds.
- ImVec2 MinPos(RenderData->UIPos.x, A[3] - RenderData->UIPos.y - RenderData->UIZoom.y);
- ImVec2 MaxPos = MinPos + RenderData->UIZoom;
- glBlitFramebuffer(MinPos.x, MinPos.y, MaxPos.x, MaxPos.y,
- MinPos.x, MinPos.y, MaxPos.x, MaxPos.y,
- GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ if (RenderData->ViewportDisplay == 1) {
+ ImVec2 MinPos(RenderData->UIPos.x, A[3] - RenderData->UIPos.y - RenderData->UIZoom.y);
+ ImVec2 MaxPos = MinPos + RenderData->UIZoom;
+ glBlitFramebuffer(MinPos.x, MinPos.y, MaxPos.x, MaxPos.y,
+ MinPos.x, MinPos.y, MaxPos.x, MaxPos.y,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ } else {
+ // TODO(fox): fix this?
+ glBlitFramebuffer(RenderData->ViewportMin.x, RenderData->ViewportMin.y - 50, RenderData->ViewportMax.x, RenderData->ViewportMax.y,
+ RenderData->ViewportMin.x, RenderData->ViewportMin.y - 50, RenderData->ViewportMax.x, RenderData->ViewportMax.y,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ }
GL_DeleteHWBuffer(&MSBuffer);
+ uint64 PerfEnd = SDL_GetPerformanceCounter() - PerfStart;
+ printf("OPENGL: %.2lu\n", PerfEnd);
}
// TODO(fox): We have five functions that essentially do this same precomp loop
@@ -465,17 +480,19 @@ LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex
Assert(Layer->Block_Composition_Index == CompIndex);
int Width = 0, Height = 0;
Layer_GetDimensions(Memory, Layer, &Width, &Height);
- if (Layer->IsPrecomp && (Layer->IsSelected & 0x03)) {
+ if (Layer->IsPrecomp && (Layer->IsSelected & 0x03 || State->SelectionMode == 1)) {
// only like 20% sure how this works...
layer_transforms NewExtraT = Layer_GetTransforms(Layer);
v2 NewCenter = T_CompPosToLayerPos(NewExtraT, Comp->Width, Comp->Height, Width, Height, Center.x, Center.y);
NewExtraT.rotation = ExtraT.rotation - NewExtraT.rotation;
NewExtraT.scale = ExtraT.scale / NewExtraT.scale;
LayerIndex = LayerIterate_SelectionAct(State, Memory, Layer->Block_Source_Index, NewExtraT, NewCenter, SortedCompArray, SortedLayerArray, SelectionCount, SelectedLayerIndex, SelectedPrecompIndex, BelowOnly);
- if (LayerIndex != -1) {
+ if (LayerIndex == -2) {
+ return -2;
+ } else if (LayerIndex != -1) {
Layer->IsSelected = 0x02;
return LayerIndex;
- }
+ }
}
v2 Position = State->Interact_Transform.Position;
real32 Rad = (ExtraT.rotation * (PI / 180));
@@ -484,16 +501,22 @@ LayerIterate_SelectionAct(project_state *State, memory *Memory, uint32 CompIndex
Position = XAxis + YAxis;
layer_transforms T = Layer_GetTransforms(Layer);
v2 UV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, Center / V2(Comp->Width, Comp->Height));
- if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !(Layer->IsSelected & 0x01) && !Layer->IsLocked)
+ if (UV.x <= 1.0f && UV.x >= 0.0f && UV.y <= 1.0f && UV.y >= 0.0f && !Layer->IsLocked)
{
- if (!BelowOnly && SelectionCount == 1) {
- if (i < SelectedLayerIndex || SelectedPrecompIndex != CompIndex) {
+ if (!(Layer->IsSelected & 0x01)) {
+ if (!BelowOnly && SelectionCount == 1) {
+ if (i < SelectedLayerIndex || SelectedPrecompIndex != CompIndex) {
+ LayerIndex = Index_Physical;
+ break;
+ }
+ } else {
LayerIndex = Index_Physical;
break;
}
- } else {
- LayerIndex = Index_Physical;
- break;
+ } else if (Layer->IsSelected & 0x01 && BelowOnly) {
+ Layer->IsSelected = 0x00;
+ State->Interact_Transform = {};
+ return -2;
}
}
}
@@ -621,10 +644,16 @@ Render_UI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDr
RenderData->LayerCount++;
PointBuffer += sizeof(gl_data);
+ int RenderFlags = 0;
int Visibility = ShapeOpt.Visibility;
+ if (Visibility == 0 || Visibility == 2)
+ RenderFlags |= gl_renderflag_fill;
+ if (Visibility == 1 || Visibility == 2)
+ RenderFlags |= gl_renderflag_stroke;
+
*GL_Data = { 0, Data_Stroke, StrokeCount, ShapeOpt.StrokeCol,
Data_Fill, NumberOfVerts, ShapeOpt.FillCol,
- T, Shape->Width, Shape->Height, Visibility };
+ T, Shape->Width, Shape->Height, RenderFlags };
} else if (Layer->IsPrecomp) {
layer_transforms NewExtraT = Layer_GetTransforms(Layer);
@@ -1322,7 +1351,9 @@ int main(int argc, char *argv[]) {
// TODO(fox): Do the same thing with the timeline and viewport to
// reduce wasted rendering further; for now I am at least pausing all
// UI when no inputs happen.
+ uint64 InputStart = SDL_GetPerformanceCounter();
State->UpdateScreen += Main_InputTest(File, State, &Memory, Sorted, &File->UI, window, textureID);
+ uint64 InputTime = SDL_GetPerformanceCounter() - InputStart;
if (State->IsPlaying) {
block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(&Memory, F_Precomps, File->PrincipalCompIndex);
@@ -1423,6 +1454,7 @@ int main(int argc, char *argv[]) {
// frames, but we'd have to make sure the pop order stays the same in all scenarios.
Assert(Debug.ScratchState == 0);
+ uint64 RenderStart = SDL_GetPerformanceCounter();
bool32 UpdateScreen = 0;
if (State->IsPlaying && State->HotFramePerf > 1 && FullyCached) {
uint64 RenderTime = SDL_GetPerformanceCounter() - State->HotFramePerf;
@@ -1439,6 +1471,7 @@ int main(int argc, char *argv[]) {
UpdateScreen = 1;
}
}
+ uint64 RenderTime = SDL_GetPerformanceCounter() - RenderStart;
if (State->HotFramePerf == 1) {
State->HotFramePerf = SDL_GetPerformanceCounter();
@@ -1459,6 +1492,8 @@ int main(int argc, char *argv[]) {
if (TargetMS > FrameMS)
SDL_Delay((uint64)(TargetMS - FrameMS));
}
+ printf("TOTAL: %.2lu, (%.2f ms) - INPUTS: %.2lu - RENDERING: %.2lu\n", PerfTime, FrameMS, InputTime, RenderTime);
+ // printf("TOTAL: %.2lu, (%.2f ms) - RENDERING: %.2lu\n", PerfTime, FrameMS, PerfTime);
}
for (int i = 0; i < 7; i++) {
diff --git a/src/sorted.cpp b/src/sorted.cpp
index 1553bf9..948c6f6 100644
--- a/src/sorted.cpp
+++ b/src/sorted.cpp
@@ -299,16 +299,7 @@ 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 & 0x01) {
- 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;
- }
+ // Sort_OffsetDupes(Memory, SortedLayerStart, Layer, LayerEntry, i, FauxIncrement, SortedCompStart->LayerCount, 1);
uint8 *Address_Start = (uint8 *)(LayerEntry);
uint8 *Address_End = (uint8 *)(&SortedLayerStart[SortedCompStart->LayerCount + FauxIncrement]) - 1;
Assert(SortedCompStart->CurrentSortIndex != (SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount));
@@ -318,6 +309,17 @@ Layer_SortAll(project_state *State, memory *Memory,
Assert(FakeLayerEntry->Block_Layer_Index == LayerEntry->Block_Layer_Index);
FakeLayerEntry->IsFake = true;
FauxIncrement++;
+
+ sorted_layer_array *PrevLayerEntry = FakeLayerEntry;
+ for (int a = i+1; a < SortedCompStart->LayerCount; a++) {
+ int NextIdx = a + FauxIncrement;
+ sorted_layer_array *NextLayerEntry = &SortedLayerStart[NextIdx];
+ if (NextLayerEntry->SortedOffset == PrevLayerEntry->SortedOffset)
+ NextLayerEntry->SortedOffset -= 1;
+ else
+ break;
+ PrevLayerEntry = NextLayerEntry;
+ }
}
i++;
}