summaryrefslogtreecommitdiff
path: root/createcalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'createcalls.cpp')
-rw-r--r--createcalls.cpp539
1 files changed, 408 insertions, 131 deletions
diff --git a/createcalls.cpp b/createcalls.cpp
index 01f1caa..85faa3c 100644
--- a/createcalls.cpp
+++ b/createcalls.cpp
@@ -10,7 +10,7 @@ Source_Generate_Blank(project_data *File, project_state *State, memory *Memory,
{
Assert(File->Source_Count < MAX_SOURCES);
uint16 Index = Memory_Block_AllocateNew(Memory, F_Sources);
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index);
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index, 0);
Source->Occupied = 1;
Source->Width = Width;
Source->Height = Height;
@@ -46,7 +46,7 @@ Source_Generate(project_data *File, project_state *State, memory *Memory, void *
bool32 IsVideo = 0;
if (Source_IsFileSupported((char *)TempString, &IsVideo)) {
uint16 Index = Memory_Block_AllocateNew(Memory, F_Sources);
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index);
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Index, 0);
History_Entry_Commit(Memory, "Add source");
History_Action_Block_Swap(Memory, F_Sources, Source);
@@ -74,27 +74,24 @@ Bezier_LookupAddress(memory *Memory, property_channel *Property, uint16 Index)
return &Bezier->Point[Index];
}
-/*
-if (State->Interact_Active == interact_type_keyframe_rotate) {
- ImVec2 Keyframe_LocalPos_Ratio = (V2(Keyframe_LocalPos_[0]) - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment);
- ImVec2 Keyframe_ScreenPos = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2);
- real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]);
- real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x);
- State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New));
- DebugWatchVar("Rotation: ", &State->Interact_Offset[0], d_float);
-}
-*/
-// Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_);
-
-
+// NOTE(fox): It's not required for the Y to be set correctly in i.e. sorting.
static void
-Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos)
+Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos, real32 GraphZoomHeight = 1, real32 Y_Increment = 1)
{
Pos[0] = PointAddress->Pos[0];
Pos[1] = PointAddress->Pos[1];
Pos[2] = PointAddress->Pos[2];
- if (State->Interact_Active == interact_type_keyframe_move && PointAddress->IsSelected) {
- Pos[0].x += (int32)State->Interact_Offset[0];
+ if (PointAddress->IsSelected) {
+ if (State->Interact_Active == interact_type_keyframe_move) {
+ Pos[PointAddress->IsSelected - 1].x += (int32)State->Interact_Offset[0];
+ Pos[PointAddress->IsSelected - 1].y -= (State->Interact_Offset[1] / GraphZoomHeight / Y_Increment);
+ } else if (State->Interact_Active == interact_type_keyframe_scale) {
+ Pos[1].x += State->Interact_Offset[0];
+ Pos[2].x -= State->Interact_Offset[0];
+ } else if (State->Interact_Active == interact_type_keyframe_rotate) {
+ // how do I do this??
+ Assert(0);
+ }
}
}
@@ -125,36 +122,17 @@ Bezier_Add(memory *Memory, property_channel *Property, bezier_point PointData)
static property_channel
-Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX) { property_channel Property = {};
+Property_InitFloat(char *Name, real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX, bool32 AlwaysInteger = 0) {
+ property_channel Property = {};
Property.Name = Name;
Property.CurrentValue = Val;
Property.MinVal = MinVal;
Property.MaxVal = MaxVal;
+ Property.AlwaysInteger = AlwaysInteger;
Property.ScrubVal = ScrubVal;
return Property;
}
-static void
-Keyframe_Interact_Evaluate(memory *Memory, project_state *State, uint8 IsSelected, v2 Pos_Initial[3], v2 Pos_New[3])
-{
- /*
- Assert(Pos_New[0].y == Pos_Initial[0].y);
- if (State->Interact_Active == interact_type_keyframe_move) {
- Pos_New[0].x = Pos_New[0].x + Offset.x;
- Pos_New[0].y = Pos_New[0].y + Offset.y;
- } else if (State->Interact_Active == interact_type_keyframe_scale) {
- Pos_New[1].x += (IsSelected - 1 == 0 || IsSelected - 1 == 1) ? Offset.x : 0;
- Pos_New[2].x -= (IsSelected - 1 == 0 || IsSelected - 1 == 2) ? Offset.x : 0;
- } else if (State->Interact_Active == interact_type_keyframe_rotate) {
- real32 Rad = State->Interact_Offset[0];
- v2 XAxis = V2(8, 8) * V2(cos(Rad), sin(Rad));
- v2 YAxis = V2(sin(Rad), -cos(Rad));
- Pos_New[2].x += XAxis.x + XAxis.y;
- Pos_New[2].y += YAxis.x + YAxis.y;
- }
- */
-}
-
static block_composition *
Precomp_Init(project_data *File, memory *Memory)
{
@@ -212,13 +190,13 @@ Layer_Select(memory *Memory, project_state *State, int32 i)
// State->RecentSelectionType = selection_layer;
}
-// TODO(fox): Precomps!
-void Layer_DeselectAll(memory *Memory, uint32 LayerCount) {
- for (uint32 i = 0; i < LayerCount; i++) {
+void Layer_DeselectAll(project_data *File, project_state *State, memory *Memory) {
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Sources, File->Layer_Count, &h, &c, &i)) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
- if (Layer->IsSelected)
- Layer->IsSelected = false;
+ Layer->IsSelected = false;
}
+ State->MostRecentlySelectedLayer = -1;
}
void Source_DeselectAll(project_data *File, memory *Memory)
@@ -230,6 +208,81 @@ void Source_DeselectAll(project_data *File, memory *Memory)
}
}
+void Clipboard_Paste(project_data *File, project_state *State, memory *Memory, sorted_layer *SortedLayerArray)
+{
+ clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer;
+ uint64 ClipboardPos = sizeof(clipboard_contents);
+ ClipboardPos = sizeof(clipboard_contents);
+ int h = 0, c = 0, i = 0;
+ block_layer *Layer;
+ clipboard_channel *Channel;
+ int b = 0;
+ while (b < Contents->ChannelCount) {
+ Channel = &Contents->Channel[b];
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
+ {
+ Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected)
+ break;
+ }
+ // NOTE(fox): This loop assumes all layers and the clipboard have
+ // channels laid out in the same way!
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->Name == Channel->Name) {
+ for (int p = 0; p < Channel->KeyframeCount; p++) {
+ bezier_point PointData = *(bezier_point *)((uint8 *)State->ClipboardBuffer + ClipboardPos);
+ Bezier_Add(Memory, Property, PointData);
+ ClipboardPos += sizeof(bezier_point);
+ }
+ b++;
+ Channel = &Contents->Channel[b];
+ }
+ }
+ }
+}
+
+
+void Clipboard_Store(project_data *File, project_state *State, memory *Memory, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray)
+{
+ // TODO(fox): Multi-precomp support!
+ int LocalOffset = 0;
+ clipboard_contents *Contents = (clipboard_contents *)State->ClipboardBuffer;
+ *Contents = {};
+ uint64 ClipboardPos = sizeof(clipboard_contents);
+ // for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--)
+ Assert(0);
+ for (int i = 10; i >= 0; i--)
+ {
+ sorted_layer SortEntry = {}; // SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->IsToggled || Layer->IsSelected) {
+ sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h;
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
+ clipboard_channel *Channel = &Contents->Channel[Contents->ChannelCount];
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]);
+ if (PointAddress->IsSelected) {
+ Arbitrary_WriteInto((uint8 *)PointAddress, (uint8 *)State->ClipboardBuffer + ClipboardPos, sizeof(bezier_point));
+ ClipboardPos += sizeof(bezier_point);
+ Channel->KeyframeCount++;
+ }
+ }
+ if (Channel->KeyframeCount) {
+ if (!LocalOffset)
+ LocalOffset = i;
+ Contents->ChannelCount++;
+ Channel->LayerOffset = LocalOffset - i;
+ Channel->Name = Property->Name;
+ }
+ }
+ }
+ }
+}
+
static sorted_layer *
Layer_GetSortedArray(sorted_layer *LayerArrayStart, sorted_comp_info *SortedCompStart, uint32 TargetComp)
{
@@ -288,41 +341,67 @@ void Layer_RecursiveDeselect(memory *Memory, sorted_comp_info *SortedCompArray,
}
}
-void Property_MinMax(memory *Memory, project_state *State, property_channel *Property, uint16 *ArrayLocation, v2 *Min, v2 *Max)
+void Property_MinMax_X(memory *Memory, project_state *State, property_channel *Property,
+ uint16 *ArrayLocation, real32 *Min, real32 *Max)
{
v2 FirstPointPos[3];
bezier_point *FirstPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[0]);
Bezier_EvaluateValue(State, FirstPointAddress, FirstPointPos);
- Min->x = FirstPointPos[0].x;
+ *Min = FirstPointPos[0].x;
v2 LastPointPos[3];
bezier_point *LastPointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[Property->Keyframe_Count - 1]);
Bezier_EvaluateValue(State, LastPointAddress, LastPointPos);
- Max->x = LastPointPos[0].x;
- int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
- real32 MinY = FLT_MAX;
- real32 MaxY = FLT_MIN;
- for (int p = 0; p < Property->Keyframe_Count; p++) {
- bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, ArrayLocation[p]);
- MinY = (MinY < PointAddress->Pos[0].y) ? MinY : PointAddress->Pos[0].y;
- MaxY = (MaxY > PointAddress->Pos[0].y) ? MaxY : PointAddress->Pos[0].y;
+ *Max = LastPointPos[0].x;
+}
+void Property_MinMax_Y(memory *Memory, project_state *State, property_channel *Property,
+ sorted_property_info *PropertyInfo, real32 *Min, real32 *Max, bool32 Evaluate = 1)
+{
+ if (Evaluate) {
+ v2 MinYPointPos[3];
+ bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MinYIndex);
+ Bezier_EvaluateValue(State, MinYPointAddress, MinYPointPos);
+ *Min = MinYPointPos[0].y;
+ v2 MaxYPointPos[3];
+ bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MaxYIndex);
+ Bezier_EvaluateValue(State, MaxYPointAddress, MaxYPointPos);
+ *Max = MaxYPointPos[0].y;
+ } else {
+ bezier_point *MinYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MinYIndex);
+ *Min = MinYPointAddress->Pos[0].y;
+ bezier_point *MaxYPointAddress = Bezier_LookupAddress(Memory, Property, PropertyInfo->MaxYIndex);
+ *Max = MaxYPointAddress->Pos[0].y;
}
- Min->y = MinY;
- Max->y = MaxY;
}
// The sorting algorithm is straightforward: read every point, evaluate it if
// it's currently being interacted with by the user, record index in a sorted
// list, and repeat, shiftig the list as necessary.
-void Property_SortAll(memory *Memory, project_state *State, property_channel *Property, uint16 *PropertyArrayStart)
+void Property_SortAll(memory *Memory, project_state *State, property_channel *Property, sorted_property_info *PropertyInfo, uint16 *PropertyArrayStart)
{
int h = 0, c = 0, i = 0;
uint32 CurrentSortIndex = 0;
+ real32 MinY = FLT_MAX;
+ real32 MaxY = FLT_MIN;
int32 Offset = (State->Interact_Active == interact_type_keyframe_move) ? (int32)State->Interact_Offset[0] : 0;
while (Block_Loop(Memory, Property, Property->Keyframe_Count, &h, &c, &i)) {
v2 PointPos[3];
bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, i);
+
+ if (PointAddress->IsSelected)
+ PropertyInfo->IsGraphSelected = true;
+
Bezier_EvaluateValue(State, PointAddress, PointPos);
+
+ if (MinY > PointAddress->Pos[0].y) {
+ MinY = PointAddress->Pos[0].y;
+ PropertyInfo->MinYIndex = i;
+ }
+ if (MaxY < PointAddress->Pos[0].y) {
+ MaxY = PointAddress->Pos[0].y;
+ PropertyInfo->MaxYIndex = i;
+ }
+
uint32 SortedIndex_Playhead = 0;
while (SortedIndex_Playhead < CurrentSortIndex) {
uint16 TestPointEntry = PropertyArrayStart[SortedIndex_Playhead];
@@ -347,7 +426,26 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr
}
}
-void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *SortedLayerInfo, sorted_comp_info SortedCompInfo, int *EntriesPassed, sorted_layer *LayerEntry)
+void Property_DeselectAll(project_data *File, memory *Memory, uint16 *SortedPropertyArray)
+{
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (!Layer->IsSelected)
+ continue;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
+ for (int p = 0; p < Property->Keyframe_Count; p++) {
+ int k = ArrayLocation[p];
+ bezier_point *PointAddress = Bezier_LookupAddress(Memory, Property, k);
+ PointAddress->IsSelected = 0;
+ }
+ }
+ }
+}
+
+void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *SortedLayerInfo, sorted_comp_info SortedCompInfo, int *EntriesPassed, sorted_layer *LayerEntry, bool32 AltMethod)
{
int PrevOffsetIndex = i + Direction + (*EntriesPassed * Direction);
bool32 OutOfBounds = (Direction > 0) ? (PrevOffsetIndex > (SortedCompInfo.LayerCount - 1)) : (PrevOffsetIndex < 0);
@@ -355,18 +453,46 @@ void Layer_Sort_CheckPrev(memory *Memory, int i, int Direction, sorted_layer *So
sorted_layer *PrevLayerEntry = &SortedLayerInfo[PrevOffsetIndex];
real32 PrevOffset = PrevLayerEntry->SortedOffset;
if (PrevOffset == (LayerEntry->SortedOffset - Direction)) {
- LayerEntry->SortedOffset -= Direction;
(*EntriesPassed)++;
- Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, SortedCompInfo, EntriesPassed, LayerEntry);
+ if (!AltMethod) {
+ PrevLayerEntry->SortedOffset += Direction;
+ } else {
+ LayerEntry->SortedOffset -= Direction;
+ Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, SortedCompInfo, EntriesPassed, LayerEntry, AltMethod);
+ }
}
}
}
+void Layer_Evaluate_Display(block_layer *Layer, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, sorted_layer *SortedLayerInfo, int i, real32 *Offset)
+{
+ int ExtraPad = 1;
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ if (Property->IsToggled) {
+ *Offset += 1 + ExtraPad;
+ ExtraPad = 0;
+ }
+ }
+ /*
+ if (Layer->Precomp_Toggled) {
+ Assert(Layer->IsPrecomp);
+ sorted_comp_info *Layer_SortedCompInfo = &CompStart[Layer->Block_Source_Index];
+ sorted_layer *Layer_SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Source_Index);
+ sorted_layer *TopLayerEntry = &Layer_SortedLayerInfo[0];
+ sorted_layer *BottomLayerEntry = &Layer_SortedLayerInfo[Layer_SortedCompInfo->LayerCount - 1];
+ *Offset += TopLayerEntry->SortedOffset - BottomLayerEntry->SortedOffset + 2;
+ }
+ */
+}
+
// The first loop is for counting how many layers are in each precomp, the
// second is for sorting the layers by offset, and the third is for applying
// interactivity if the user is moving any layers.
-void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart, sorted_comp_info *CompStart, uint16 *SortedPropertyArray, uint32 LayerCount, uint32 CompCount)
+void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sorted_layer *LayerArrayStart,
+ sorted_comp_info *CompStart, sorted_property_info *SortedPropertyInfo, uint16 *SortedPropertyArray,
+ uint32 LayerCount, uint32 CompCount)
{
int h = 0, c = 0, i = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
@@ -376,19 +502,19 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
for (int h = 0; h < AmountOf(Layer->Property); h++) {
property_channel *Property = &Layer->Property[h];
if (Property->Block_Bezier_Count) {
+ sorted_property_info *InfoLocation = SortedPropertyInfo + (i * 7) + h;
uint16 *ArrayLocation = SortedPropertyArray + (i * 7 * MAX_KEYFRAMES_PER_BLOCK) + (h * MAX_KEYFRAMES_PER_BLOCK);
- Property_SortAll(Memory, State, Property, ArrayLocation);
+ Property_SortAll(Memory, State, Property, InfoLocation, ArrayLocation);
}
}
}
h = 0, c = 0, i = 0;
- uint32 CurrentSortIndex = 0;
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
sorted_comp_info *SortedCompInfo = &CompStart[Layer->Block_Composition_Index];
sorted_layer *SortedLayerInfo = Layer_GetSortedArray(LayerArrayStart, CompStart, Layer->Block_Composition_Index);
uint32 SortedIndex_Playhead = 0;
- while (SortedIndex_Playhead < CurrentSortIndex) {
+ while (SortedIndex_Playhead < SortedCompInfo->CurrentSortIndex) {
sorted_layer LayerEntry = SortedLayerInfo[SortedIndex_Playhead];
block_layer *TestLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, LayerEntry.Block_Layer_Index);
if (-Layer->Vertical_Offset < -TestLayer->Vertical_Offset) {
@@ -397,16 +523,16 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
SortedIndex_Playhead++;
}
}
- if (SortedIndex_Playhead != CurrentSortIndex) {
+ if (SortedIndex_Playhead != SortedCompInfo->CurrentSortIndex) {
uint8 *Address_Start = (uint8 *)(SortedLayerInfo + SortedIndex_Playhead);
- uint8 *Address_End = (uint8 *)(SortedLayerInfo + CurrentSortIndex) - 1;
- Assert(CurrentSortIndex != SortedCompInfo->LayerCount);
+ uint8 *Address_End = (uint8 *)(SortedLayerInfo + SortedCompInfo->CurrentSortIndex) - 1;
+ Assert(SortedCompInfo->CurrentSortIndex != SortedCompInfo->LayerCount);
Arbitrary_ShiftData(Address_Start, Address_End, sizeof(sorted_layer), 1);
}
sorted_layer *LayerEntry = SortedLayerInfo + SortedIndex_Playhead;
LayerEntry->Block_Layer_Index = i;
LayerEntry->SortedOffset = Layer->Vertical_Offset;
- CurrentSortIndex++;
+ SortedCompInfo->CurrentSortIndex++;
}
if (State->Interact_Active == interact_type_layer_move) {
int32 Offset = (int32)State->Interact_Offset[1];
@@ -426,7 +552,7 @@ void Layer_SortAll(project_data *File, project_state *State, memory *Memory, sor
if (Layer->IsSelected) {
int32 SpacesToMove = Offset * Direction;
while (SpacesToMove) {
- Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, *SortedCompInfo, &EntriesPassed, LayerEntry);
+ Layer_Sort_CheckPrev(Memory, i, Direction, SortedLayerInfo, *SortedCompInfo, &EntriesPassed, LayerEntry, 0);
LayerEntry->SortedOffset -= Direction;
SpacesToMove--;
}
@@ -465,7 +591,7 @@ sorted_file File_Sort_Push(project_data *File, project_state *State, memory *Mem
Sorted.PropertyInfo = (sorted_property_info *)Property_SortedArray;
Sorted.PropertyArray = (uint16 *)((uint8 *)Property_SortedArray + PropertyInfoSize);
- Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
+ Layer_SortAll(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyInfo, Sorted.PropertyArray, File->Layer_Count, File->Comp_Count);
return Sorted;
}
@@ -486,6 +612,7 @@ Layer_Delete(project_data *File, memory *Memory, uint32 Index)
File->Layer_Count--;
}
+
block_layer * Layer_Init(project_data *File, memory *Memory)
{
if (File->Layer_Count + 1 > MAX_LAYERS) {
@@ -498,7 +625,7 @@ block_layer * Layer_Init(project_data *File, memory *Memory)
Layer->Occupied = 1;
Layer->Block_String_Index = Memory_Block_AllocateNew(Memory, F_Strings);
- block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index);
+ block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0);
sprintf(String->Char, "Layer %i", File->Layer_Count + 1); // CSbros...
String->Occupied = 1;
@@ -509,7 +636,7 @@ block_layer * Layer_Init(project_data *File, memory *Memory)
Layer->scale = Property_InitFloat("Scale", 1.0f, 0.005f);
Layer->rotation = Property_InitFloat("Rotation", 0.0f, 1.0f);
Layer->opacity = Property_InitFloat("Opacity", 1.0f, 0.005f, 0.0f, 1.0f);
- Layer->time = Property_InitFloat("Frame Number", 0.0f, 1.0f, 0, 100000);
+ Layer->time = Property_InitFloat("Frame Number", 0.0f, 1.0f, 0, 100000, 1);
Layer->IsVisible = 1;
@@ -546,6 +673,7 @@ void Source_UICreateButton(project_data *File, project_state *State, memory *Mem
Layer->x.CurrentValue = Source->Width / 2;
Layer->y.CurrentValue = Source->Height / 2;
Layer->Vertical_Offset = TopOffset-1;
+ Layer->Frame_Start = Comp->Frame_Start;
Layer->Frame_End = Comp->Frame_End;
TopOffset--;
}
@@ -556,6 +684,56 @@ void Source_UICreateButton(project_data *File, project_state *State, memory *Mem
Source_DeselectAll(File, Memory);
}
+void Precomp_UICreateButton(project_data *File, project_state *State, memory *Memory, uint16 CompIndex,
+ sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo)
+{
+ block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, CompIndex);
+ History_Entry_Commit(Memory, "Pre-compose layer");
+ block_composition *NewComp = Precomp_Init(File, Memory);
+ NewComp->Width = Comp->Width;
+ NewComp->Height = Comp->Height;
+ NewComp->FPS = Comp->FPS;
+ NewComp->BytesPerPixel = Comp->BytesPerPixel;
+ NewComp->Frame_Count = Comp->Frame_Count;
+ NewComp->Frame_Start = Comp->Frame_Start;
+ NewComp->Frame_End = Comp->Frame_End;
+ int32 TopOffset = 0;
+ 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->IsSelected) {
+ TopOffset = Layer->Vertical_Offset;
+ break;
+ }
+ }
+ 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->IsSelected) {
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Composition_Index), &Layer->Block_Composition_Index);
+ Layer->Block_Composition_Index = File->Comp_Count - 1;
+ }
+ }
+ block_layer *PrecompLayer = Layer_Init(File, Memory);
+ bezier_point Point0 = { 1, {0, 0, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
+ bezier_point Point1 = { 1, {(real32)NewComp->Frame_End, (real32)NewComp->Frame_End, 1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
+ Bezier_Add(Memory, &PrecompLayer->time, Point0);
+ Bezier_Add(Memory, &PrecompLayer->time, Point1);
+ PrecompLayer->IsPrecomp = true;
+ PrecompLayer->Block_Source_Index = File->Comp_Count - 1;
+ PrecompLayer->Block_Composition_Index = CompIndex;
+ PrecompLayer->Vertical_Offset = TopOffset;
+ PrecompLayer->Frame_End = NewComp->Frame_End;
+ PrecompLayer->ColIndex = 3;
+ PrecompLayer->x.CurrentValue = Comp->Width/2;
+ PrecompLayer->y.CurrentValue = Comp->Height/2;
+ History_Entry_End(Memory);
+ State->UpdateFrame = true;
+}
// Helper for working with different bit depths.
@@ -592,16 +770,19 @@ State_BindBrushTexture(memory *Memory, brush_state *Brush, uint32 BytesPerPixel)
static void
Brush_CalcBitmapAlphaFromSize(memory *Memory, brush_state *Brush, uint32 BytesPerPixel)
{
- real32 BrushLength = Brush->Size;
- real32 BrushCenter = BrushLength / 2;
+ int32 BrushLength = Brush->Size;
+ if (BrushLength > 128) {
+ BrushLength = BrushLength + (16 - (BrushLength % 16));
+ }
+ real32 BrushCenter = (real32)BrushLength / 2;
real32 MaxLength = BrushCenter;
void *BrushAddress = Brush->PaintBuffer;
render_byte_info Byte = Bitmap_ByteInfo(BytesPerPixel);
- for (int Y = 0; Y < (int)BrushLength; Y++) {
- for (int X = 0; X < (int)BrushLength; X++) {
- uint8 *PixelAddress = (uint8 *)BrushAddress + (Y * BytesPerPixel*(int)BrushLength) + (X * BytesPerPixel);
+ for (int Y = 0; Y < BrushLength; Y++) {
+ for (int X = 0; X < BrushLength; X++) {
+ uint8 *PixelAddress = (uint8 *)BrushAddress + (Y * BytesPerPixel*BrushLength) + (X * BytesPerPixel);
uint32 *R_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*0);
// uint32 *G_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*1);
// uint32 *B_DestAddress = (uint32 *)(PixelAddress + Byte.ByteOffset*2);
@@ -616,18 +797,21 @@ Brush_CalcBitmapAlphaFromSize(memory *Memory, brush_state *Brush, uint32 BytesPe
}
}
-// TODO(fox): We could merge this exactly with the standard rendering code.
static void
-PaintTest(memory *Memory, block_source *Source, brush_state *Brush, void *Address, v2 LayerPos, uint32 BytesPerPixel, v4 Color)
+Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, v4 Color)
{
- uint32 BrushLength = (uint32)Brush->Size;
+ B->BrushLength = (uint32)Brush->Size;
+ if (B->BrushLength > 128) {
+ B->BrushLength = B->BrushLength + (16 - (B->BrushLength % 16));
+ }
rectangle RenderRegion = { 0, 0, Source->Width, Source->Height };
- rectangle BrushPos = { (int32)(LayerPos.x - (BrushLength / 2)),
- (int32)(LayerPos.y - (BrushLength / 2)),
- (int32)(LayerPos.x + (BrushLength / 2)),
- (int32)(LayerPos.y + (BrushLength / 2)) };
- rectangle LayerBounds = ClipRectangle(BrushPos, RenderRegion);
+ rectangle BrushPos = { (int32)(LayerPos.x - (B->BrushLength / 2)),
+ (int32)(LayerPos.y - (B->BrushLength / 2)),
+ (int32)(LayerPos.x + (B->BrushLength / 2)),
+ (int32)(LayerPos.y + (B->BrushLength / 2)) };
+
+ B->LayerBounds = ClipRectangle(BrushPos, RenderRegion);
if (BrushPos.Min.x < Brush->CacheBounds.Min.x)
Brush->CacheBounds.Min.x = BrushPos.Min.x;
@@ -638,68 +822,79 @@ PaintTest(memory *Memory, block_source *Source, brush_state *Brush, void *Addres
if (BrushPos.Max.y > Brush->CacheBounds.Max.y)
Brush->CacheBounds.Max.y = BrushPos.Max.y;
- uint32 LayerPitch = Source->Width*Source->BytesPerPixel;
- uint32 BrushPitch = (int)BrushLength * BytesPerPixel;
+ B->BytesPerPixel = 4;
+ B->SourceWidth = Source->Width;
+ B->SourceBytesPerPixel = Source->BytesPerPixel;
+
+ Assert(Source->BytesPerPixel == 4);
- render_byte_info LayerBits = Bitmap_ByteInfo(Source->BytesPerPixel);
- render_byte_info BrushBits = Bitmap_ByteInfo(BytesPerPixel);
+ B->LayerPitch = Source->Width*Source->BytesPerPixel;
+ B->BrushPitch = (int)B->BrushLength * B->BytesPerPixel;
- int32 ExtraX = 0;
- int32 ExtraY = 0;
+ B->LayerBits = Bitmap_ByteInfo(Source->BytesPerPixel);
+ B->BrushBits = Bitmap_ByteInfo(B->BytesPerPixel);
+
+ B->ExtraX = 0;
+ B->ExtraY = 0;
if (BrushPos.Min.x < 0) {
- ExtraX = BrushPos.Min.x;
+ B->ExtraX = BrushPos.Min.x;
}
if (BrushPos.Min.y < 0) {
- ExtraY = BrushPos.Min.y;
+ B->ExtraY = BrushPos.Min.y;
}
- void *BrushBuffer = Brush->PaintBuffer;
+ B->BrushBuffer = Brush->PaintBuffer;
// ImGui's color picker works in sRGB, so we need to convert to linear.
// real32 R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92;
// real32 G_Brush = (Color.g >= 0.04045) ? pow((Color.g + 0.055) / (1 + 0.055), 2.4) : Color.g / 12.92;
// real32 B_Brush = (Color.b >= 0.04045) ? pow((Color.b + 0.055) / (1 + 0.055), 2.4) : Color.b / 12.92;
// real32 A_Brush = (Color.a >= 0.04045) ? pow((Color.a + 0.055) / (1 + 0.055), 2.4) : Color.a / 12.92;
- real32 R_Brush = Color.r;
- real32 G_Brush = Color.g;
- real32 B_Brush = Color.b;
- real32 A_Brush = Color.a;
+ B->R_Brush = Color.r;
+ B->G_Brush = Color.g;
+ B->B_Brush = Color.b;
+ B->A_Brush = Color.a;
- uint8 *BrushRow = (uint8 *)BrushBuffer;
- for (int32 Y = LayerBounds.Min.y; Y < LayerBounds.Max.y; Y++) {
- for (int32 X = LayerBounds.Min.x; X < LayerBounds.Max.x; X++) {
+ B->BrushRow = (uint8 *)B->BrushBuffer;
+}
+
+static void
+PaintTest(brush_info B, void *Buffer, rectangle RenderRegion)
+{
+ for (int32 Y = RenderRegion.Min.y; Y < RenderRegion.Max.y; Y++) {
+ for (int32 X = RenderRegion.Min.x; X < RenderRegion.Max.x; X++) {
- uint32 Offset = Y*LayerPitch + X*Source->BytesPerPixel;
- uint8 *LayerPixel = (uint8 *)Address + Offset;
+ uint32 Offset = Y*B.LayerPitch + X*B.SourceBytesPerPixel;
+ uint8 *LayerPixel = (uint8 *)Buffer + Offset;
- uint32 *R_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 0);
- uint32 *G_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 1);
- uint32 *B_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 2);
- uint32 *A_DestAddress = (uint32 *)(LayerPixel + LayerBits.ByteOffset * 3);
+ uint32 *R_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 0);
+ uint32 *G_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 1);
+ uint32 *B_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 2);
+ uint32 *A_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 3);
- real32 R_Layer = (real32)(*R_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
- real32 G_Layer = (real32)(*G_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
- real32 B_Layer = (real32)(*B_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
- real32 A_Layer = (real32)(*A_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized;
+ real32 R_Layer = (real32)(*R_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized;
+ real32 G_Layer = (real32)(*G_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized;
+ real32 B_Layer = (real32)(*B_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized;
+ real32 A_Layer = (real32)(*A_DestAddress & B.LayerBits.MaskPixel) * B.LayerBits.Normalized;
- int32 TrueX = (X - LayerBounds.Min.x) - ExtraX;
- int32 TrueY = (Y - LayerBounds.Min.y) - ExtraY;
+ int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX;
+ int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY;
// Assert(TrueX >= 0 && TrueX < BrushLength);
// Assert(TrueY >= 0 && TrueY < BrushLength);
- uint8 *BrushPixel = (uint8 *)BrushBuffer + (TrueY * BrushPitch) + (TrueX * BytesPerPixel);
+ uint8 *BrushPixel = (uint8 *)B.BrushRow + (TrueY * B.BrushPitch) + (TrueX * B.BytesPerPixel);
- real32 Brush_BitmapAlpha = (real32)((*(uint32 *)(BrushPixel + BrushBits.ByteOffset*3)) & BrushBits.MaskPixel) * BrushBits.Normalized;
+ real32 Brush_BitmapAlpha = (real32)((*(uint32 *)(BrushPixel + B.BrushBits.ByteOffset*3)) & B.BrushBits.MaskPixel) * B.BrushBits.Normalized;
- real32 BrushAlpha = Brush_BitmapAlpha * A_Brush;
+ real32 BrushAlpha = Brush_BitmapAlpha * B.A_Brush;
real32 LayerAlpha = A_Layer;
real32 A_Blend = LayerAlpha + BrushAlpha;
- real32 R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (R_Brush * BrushAlpha);
- real32 G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (G_Brush * BrushAlpha);
- real32 B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B_Brush * BrushAlpha);
+ real32 R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha);
+ real32 G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha);
+ real32 B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha);
/*
R_Blend = (R_Brush * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);
@@ -709,19 +904,102 @@ PaintTest(memory *Memory, block_source *Source, brush_state *Brush, void *Addres
Assert(R_Blend <= 1.0f);
- uint32 R_Out = (uint32)(Normalize(R_Blend) * LayerBits.Bits);
- uint32 G_Out = (uint32)(Normalize(G_Blend) * LayerBits.Bits);
- uint32 B_Out = (uint32)(Normalize(B_Blend) * LayerBits.Bits);
- uint32 A_Out = (uint32)(Normalize(A_Blend) * LayerBits.Bits);
+ uint32 R_Out = (uint32)(Normalize(R_Blend) * B.LayerBits.Bits);
+ uint32 G_Out = (uint32)(Normalize(G_Blend) * B.LayerBits.Bits);
+ uint32 B_Out = (uint32)(Normalize(B_Blend) * B.LayerBits.Bits);
+ uint32 A_Out = (uint32)(Normalize(A_Blend) * B.LayerBits.Bits);
- *R_DestAddress = (*R_DestAddress & ~LayerBits.MaskPixel) | R_Out;
- *G_DestAddress = (*G_DestAddress & ~LayerBits.MaskPixel) | G_Out;
- *B_DestAddress = (*B_DestAddress & ~LayerBits.MaskPixel) | B_Out;
- *A_DestAddress = (*A_DestAddress & ~LayerBits.MaskPixel) | A_Out;
+ *R_DestAddress = (*R_DestAddress & ~B.LayerBits.MaskPixel) | R_Out;
+ *G_DestAddress = (*G_DestAddress & ~B.LayerBits.MaskPixel) | G_Out;
+ *B_DestAddress = (*B_DestAddress & ~B.LayerBits.MaskPixel) | B_Out;
+ *A_DestAddress = (*A_DestAddress & ~B.LayerBits.MaskPixel) | A_Out;
}
}
}
+static void
+PaintTest_AVX2(brush_info B, void *Buffer, rectangle RenderRegion)
+{
+ __m256 One = _mm256_set1_ps(1);
+ __m256 Zero = _mm256_set1_ps(0);
+ __m256 Eight = _mm256_set1_ps(8);
+ __m256i FF = _mm256_set1_epi32(0xFF);
+ __m256 R_Brush =_mm256_set1_ps(B.R_Brush);
+ __m256 G_Brush =_mm256_set1_ps(B.G_Brush);
+ __m256 B_Brush =_mm256_set1_ps(B.B_Brush);
+ __m256 A_Brush =_mm256_set1_ps(B.A_Brush);
+ __m256 Norm255 = _mm256_set1_ps(1/255.0f);
+ __m256 Real255 = _mm256_set1_ps(255.0f);
+ __m256 LayerBoundsMaxX = _mm256_set1_ps(B.SourceWidth);
+
+ for (int32 Y = RenderRegion.Min.y; Y < RenderRegion.Max.y; Y++) {
+ __m256 PixelX = _mm256_setr_ps((real32)RenderRegion.Min.x,
+ (real32)RenderRegion.Min.x+1,
+ (real32)RenderRegion.Min.x+2,
+ (real32)RenderRegion.Min.x+3,
+ (real32)RenderRegion.Min.x+4,
+ (real32)RenderRegion.Min.x+5,
+ (real32)RenderRegion.Min.x+6,
+ (real32)RenderRegion.Min.x+7);
+ for (int32 X = RenderRegion.Min.x; X < RenderRegion.Max.x; X += 8) {
+
+ __m256i TileBarrier = _mm256_cvtps_epi32(_mm256_cmp_ps(PixelX, LayerBoundsMaxX, 1));
+
+ uint32 Offset = Y*B.LayerPitch + X*B.SourceBytesPerPixel;
+ uint8 *LayerPixelAddress = (uint8 *)Buffer + Offset;
+
+ __m256i LayerPixels = _mm256_loadu_si256((const __m256i *)LayerPixelAddress);
+
+ __m256 R_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256( LayerPixels, FF)), Norm255);
+ __m256 G_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 8), FF)), Norm255);
+ __m256 B_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 16), FF)), Norm255);
+ __m256 A_Layer = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(LayerPixels, 24), FF)), Norm255);
+
+ int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX;
+ int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY;
+ uint8 *BrushPixelAddress = (uint8 *)B.BrushRow + (TrueY * B.BrushPitch) + (TrueX * B.BytesPerPixel);
+ __m256i BrushPixels = _mm256_loadu_si256((const __m256i *)BrushPixelAddress);
+
+ __m256 Brush_BitmapAlpha = _mm256_mul_ps(_mm256_cvtepi32_ps(_mm256_and_si256(_mm256_srli_epi32(BrushPixels, 24), FF)), Norm255);
+
+ __m256 A_BrushMultiplied = _mm256_mul_ps(Brush_BitmapAlpha, A_Brush);
+
+ __m256 A_Blend = _mm256_add_ps(A_Layer, A_BrushMultiplied);
+
+ __m256 R_Blend = _mm256_add_ps(_mm256_mul_ps(R_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(R_Brush, A_BrushMultiplied));
+ __m256 G_Blend = _mm256_add_ps(_mm256_mul_ps(G_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(G_Brush, A_BrushMultiplied));
+ __m256 B_Blend = _mm256_add_ps(_mm256_mul_ps(B_Layer, _mm256_sub_ps(One, A_BrushMultiplied)), _mm256_mul_ps(B_Brush, A_BrushMultiplied));
+
+ __m256i R_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, R_Blend), Zero), Real255));
+ __m256i G_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, G_Blend), Zero), Real255));
+ __m256i B_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, B_Blend), Zero), Real255));
+ __m256i A_Out = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_max_ps(_mm256_min_ps(One, A_Blend), Zero), Real255));
+
+ __m256i OutputPixel = _mm256_or_si256(
+ _mm256_or_si256(R_Out, _mm256_slli_epi32(G_Out, 8)),
+ _mm256_or_si256(_mm256_slli_epi32(B_Out, 16), _mm256_slli_epi32(A_Out, 24)));
+
+ // _mm256_storeu_si256((__m256i *)LayerPixelAddress, OutputPixel);
+ _mm256_maskstore_epi32((int *)LayerPixelAddress, TileBarrier, OutputPixel);
+ PixelX = _mm256_add_ps(PixelX, Eight);
+ }
+ }
+}
+
+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_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);
+ } else {
+ PaintTest(B, BitmapAddress, B.LayerBounds);
+ }
+}
+
+
#if 0
static void
@@ -913,14 +1191,13 @@ Layer_LocalToScreenSpace(project_layer *Layer, ui *UI, comp_buffer CompBuffer, v
}
static v2
-Layer_ScreenSpaceToLocal(project_layer *Layer, ui *UI, comp_buffer CompBuffer, ImVec2 ViewportMin, ImVec2 Point)
+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, UI->CompPos, UI->CompZoom, Point);
+ 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)
{