diff options
Diffstat (limited to 'createcalls.cpp')
-rw-r--r-- | createcalls.cpp | 338 |
1 files changed, 239 insertions, 99 deletions
diff --git a/createcalls.cpp b/createcalls.cpp index 912917f..4be6b45 100644 --- a/createcalls.cpp +++ b/createcalls.cpp @@ -102,14 +102,15 @@ 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, 0); + History_Action_Block_Swap(Memory, F_Sources, Source); Source->Occupied = 1; Source->Width = Width; Source->Height = Height; - Source->BytesPerPixel= BytesPerPixel; + Source->BytesPerPixel = BytesPerPixel; Source->Type = source_type_principal; Source->Bitmap_Index = Memory_Block_PrincipalBitmap_AllocateNew(File, State, Memory); Source->Path_String_Index = String_AddToFile(Memory, "test"); - // History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count); + History_Action_Swap(Memory, F_File, sizeof(File->Source_Count), &File->Source_Count); File->Source_Count++; return Index; } @@ -204,15 +205,15 @@ Bezier_EvaluateValue(project_state *State, bezier_point *PointAddress, v2 *Pos, } } - +// TODO(fox): Test multiple keyframe blocks! static void Bezier_Add(memory *Memory, memory_table_list TableName, property_channel *Property, bezier_point PointData, uint16 *ArrayLocation) { if (!Property->Block_Bezier_Count) { + Assert(Property->Keyframe_Count < MAX_KEYFRAMES_PER_BLOCK); Property->Block_Bezier_Index[0] = Memory_Block_AllocateNew(Memory, F_Bezier); block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[0], 0); Bezier->Occupied = true; - // NOTE(fox): Effects will change this! History_Action_Swap(Memory, TableName, sizeof(Property->Block_Bezier_Count), &Property->Block_Bezier_Count); Property->Block_Bezier_Count++; } @@ -320,6 +321,8 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E { uint16 EffectAddressIndex = Memory_Block_AllocateNew(Memory, F_Effects); block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, EffectAddressIndex, 0); + History_Action_Block_Swap(Memory, F_Effects, Effect); + *Effect = {}; Effect->Occupied = true; header_effect *EffectHeader = &State->Effect[EffectEntryIndex]; String_Copy(Effect->ID, EffectHeader->ID, 8); @@ -328,6 +331,7 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E for (int e = 0; e < EffectHeader->Property_Count; e++) { Effect->Block_Property_Index[e] = Memory_Block_AllocateNew(Memory, F_Properties); property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[e], 0); + History_Action_Block_Swap(Memory, F_Properties, Property); Property->Occupied = true; header_property PropertyHeader = State->Property[EffectHeader->PropertyStartIndex + e]; Property->Identifier = -1; @@ -341,15 +345,21 @@ Effect_Init(project_state *State, memory *Memory, uint32 EffectEntryIndex, int E static void Effect_Add(project_data *File, project_state *State, memory *Memory, uint32 EffectEntryIndex) { + History_Entry_Commit(Memory, "Add effect"); int h = 0, c = 0, i = 0; + int Selected = 0; while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); if (Layer->IsSelected) { Layer->Block_Effect_Index[Layer->Block_Effect_Count] = Effect_Init(State, Memory, EffectEntryIndex, Layer->Block_Effect_Count); + History_Action_Swap(Memory, F_File, sizeof(Layer->Block_Effect_Count), &Layer->Block_Effect_Count); Layer->Block_Effect_Count++; + Selected++; } } + History_Entry_End(Memory); + Assert(Selected); } static void @@ -793,13 +803,13 @@ Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index); layer_transforms T = Layer_GetTransforms(Layer); Layer_GetDimensions(Memory, Layer, &InnerWidth, &InnerHeight); - PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, State->TempZoomRatio); + PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV); } else { for (int i = 1; i <= Recursions; i++) { block_layer *InnerLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, RecursionIdx[i]); layer_transforms T = Layer_GetTransforms(InnerLayer); Layer_GetDimensions(Memory, InnerLayer, &InnerWidth, &InnerHeight); - PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, State->TempZoomRatio); + PointUV = T_CompUVToLayerUV(T, OuterWidth, OuterHeight, InnerWidth, InnerHeight, PrincipalCompUV); OuterWidth = InnerWidth; OuterHeight = InnerHeight; } @@ -971,10 +981,6 @@ void Property_SortAll(memory *Memory, project_state *State, property_channel *Pr 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) { @@ -1316,17 +1322,73 @@ void File_Sort_Pop(memory *Memory, uint64 Layer_SortSize, uint64 Property_SortSi Memory_PopScratch(Memory, Layer_SortSize); } - +// lots of cleanup... static void -Layer_Delete(project_data *File, memory *Memory, uint32 Index) +Layer_Delete(project_data *File, project_state *State, memory *Memory, uint32 Index) { block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index); History_Action_Block_Swap(Memory, F_Layers, Layer); Layer->Occupied = 0; + + block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0); + History_Action_Block_Swap(Memory, F_Strings, String); + String->Occupied = 0; + + for (int i = 0; i < Layer->Block_Effect_Count; i++) { + block_effect *Effect = (block_effect *)Memory_Block_AddressAtIndex(Memory, F_Effects, Layer->Block_Effect_Index[i]); + header_effect *EffectHeader = Effect_EntryFromID(State, Effect->ID); + for (int h = 0; h < EffectHeader->Property_Count; h++) { + header_property ChannelHeader = State->Property[EffectHeader->PropertyStartIndex + h]; + property_channel *Property = (property_channel *)Memory_Block_AddressAtIndex(Memory, F_Properties, Effect->Block_Property_Index[h]); + if (Property->Block_Bezier_Count) { + block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Property->Block_Bezier_Index[i], 0); + History_Action_Block_Swap(Memory, F_Bezier, Bezier); + Bezier->Occupied = 0; + } + History_Action_Block_Swap(Memory, F_Properties, Property); + Property->Occupied = 0; + } + History_Action_Block_Swap(Memory, F_Effects, Effect); + Effect->Occupied = 0; + } History_Action_Swap(Memory, F_File, sizeof(File->Layer_Count), &File->Layer_Count); File->Layer_Count--; } +static void +Project_Layer_Delete(project_data *File, project_state *State, memory *Memory) +{ + bool32 CommitAction = 0; + int h = 0, c = 0, i = 0; + int LayerCount = File->Layer_Count; + while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i); + if (Layer->IsSelected) { + if (!CommitAction) { + History_Entry_Commit(Memory, "Delete layer"); + CommitAction = 1; + } + Layer_Delete(File, State, Memory, i); + } + } + if (CommitAction) { + History_Entry_End(Memory); + State->UpdateFrame = true; + State->MostRecentlySelectedLayer = -1; + } +} + +static bool32 +Property_IsGraphSelected(memory *Memory, property_channel *Property, uint16 *ArrayLocation) +{ + for (int p = 0; p < Property->Keyframe_Count; p++) { + int k = ArrayLocation[p]; + bezier_point *Point = Bezier_LookupAddress(Memory, Property, k); + if (Point->IsSelected) + return 1; + } + return 0; +} block_layer * Layer_Init(project_data *File, memory *Memory) { @@ -1342,6 +1404,7 @@ block_layer * Layer_Init(project_data *File, memory *Memory) 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, 0); sprintf(String->Char, "Layer %i", File->Layer_Count + 1); // CSbros... + History_Action_Swap(Memory, F_File, sizeof(String->Occupied), &String->Occupied); String->Occupied = 1; Layer->x = Property_InitFloat(0.0f, 1.0f); @@ -1361,19 +1424,52 @@ block_layer * Layer_Init(project_data *File, memory *Memory) return Layer; } -void Source_UICreateButton(project_data *File, project_state *State, memory *Memory, - sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray) +static int +Layer_GetTopOffset(project_data *File, memory *Memory) { - block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); - sorted_comp_info *SortedCompInfo = &SortedCompArray[File->PrincipalCompIndex]; - int32 TopOffset; - if (!File->Layer_Count) { - TopOffset = 11; + int TopOffset = 9999; + 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->Block_Composition_Index == File->PrincipalCompIndex) { + TopOffset = (Layer->Vertical_Offset < TopOffset) ? Layer->Vertical_Offset : TopOffset; + } + } + return TopOffset; +} + +static void +Project_PaintLayer_New(project_data *File, project_state *State, memory *Memory) +{ + int TopOffset = Layer_GetTopOffset(File, Memory); + block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); + Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4); + State->Interact_Active = interact_type_brush; + Layer_DeselectAll(File, State, Memory); + History_Entry_Commit(Memory, "Paint new layer"); + uint16 i = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel); + block_layer *Layer = Layer_Init(File, Memory); + block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); + State->Brush.LayerToPaint_Index = Memory_Block_LazyIndexAtAddress(Memory, F_Layers, (void *)Layer); + Layer->Block_Source_Index = i; + Layer->x.CurrentValue = MainComp->Width / 2; + Layer->y.CurrentValue = MainComp->Height / 2; + if (File->Layer_Count == 1) { + Layer->Vertical_Offset = 11 - 1; } else { - sorted_layer *SortedLayerInfo = Layer_GetSortedArray(SortedLayerArray, SortedCompArray, File->PrincipalCompIndex); - block_layer *TopLayer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, SortedLayerInfo[SortedCompInfo->LayerCount - 1].Block_Layer_Index); - TopOffset = TopLayer->Vertical_Offset; + Layer->Vertical_Offset = TopOffset - 1; } + Layer->Frame_Start = MainComp->Frame_Start; + Layer->Frame_End = MainComp->Frame_End; + Layer_Select(Memory, State, Memory_Block_LazyIndexAtAddress(Memory, F_Layers, Layer)); + History_Entry_End(Memory); + State->UpdateFrame = true; +} + +void Source_UICreateButton(project_data *File, project_state *State, memory *Memory) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); + int TopOffset = Layer_GetTopOffset(File, Memory); bool32 CommitAction = 0; int h = 0, c = 0, i = 0; while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) { @@ -1434,6 +1530,20 @@ void Precomp_UIDuplicate(project_data *File, project_state *State, memory *Memor } } +void Precomp_UIDelete(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, + sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) +{ + block_layer *Layer = NULL; + for (int i = SortedCompInfo.LayerCount - 1; i >= 0; i--) + { + sorted_layer SortEntry = SortedLayerInfo[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + if (Layer->IsSelected) { + } + } +} + void Precomp_UICreateButton(project_data *File, project_state *State, memory *Memory, uint16 CompIndex, sorted_comp_info SortedCompInfo, sorted_layer *SortedLayerInfo) { @@ -1542,14 +1652,63 @@ Brush_CalcBitmapAlphaFromSize(memory *Memory, brush_state *Brush, uint32 BytesPe real32 L = sqrt(LengthSq(Pos)); real32 Gradient = Ceil(L, MaxLength) / MaxLength; Gradient = pow(Gradient, Brush->Hardness); + // Gradient = (Gradient >= 0.04045) ? pow((Gradient + 0.055) / (1 + 0.055), 2.4) : Gradient / 12.92; + // Gradient = (Gradient >= 0.0031308) ? (1.055) * pow(Gradient, (1.0/2.4)) - 0.055 : 12.92 * Gradient; *R_DestAddress = (*R_DestAddress & ~Byte.MaskPixel) | Byte.Bits; // brush preview is red *A_DestAddress = (*A_DestAddress & ~Byte.MaskPixel) | (uint32)((1.0f - Gradient)*Byte.Bits); } } } +// Imported bitmaps are stored in linear, and all ops are also done in linear. +static void +Bitmap_SRGBToLinear(void *Buffer, uint16 Width, uint16 Height, uint16 BytesPerPixel, bool32 ToLinear) +{ + uint8 *Row = (uint8 *)Buffer; + uint64 TotalBytes = Width * Height * BytesPerPixel; + + render_byte_info LayerBits = Bitmap_ByteInfo(BytesPerPixel); + + uint64 bytes = 0; + while (bytes < TotalBytes) { + uint8 *LayerPixel = Row + bytes; + 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); + + real32 TexR = (real32)(*R_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; + real32 TexG = (real32)(*G_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; + real32 TexB = (real32)(*B_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; + real32 TexA = (real32)(*A_DestAddress & LayerBits.MaskPixel) * LayerBits.Normalized; + + if (ToLinear) { + TexR = (TexR >= 0.04045) ? pow((TexR + 0.055) / (1 + 0.055), 2.4) : TexR / 12.92; + TexG = (TexG >= 0.04045) ? pow((TexG + 0.055) / (1 + 0.055), 2.4) : TexG / 12.92; + TexB = (TexB >= 0.04045) ? pow((TexB + 0.055) / (1 + 0.055), 2.4) : TexB / 12.92; + TexA = (TexA >= 0.04045) ? pow((TexA + 0.055) / (1 + 0.055), 2.4) : TexA / 12.92; + } else { + TexR = (TexR >= 0.0031308) ? (1.055) * pow(TexR, (1.0/2.4)) - 0.055 : 12.92 * TexR; + TexG = (TexG >= 0.0031308) ? (1.055) * pow(TexG, (1.0/2.4)) - 0.055 : 12.92 * TexG; + TexB = (TexB >= 0.0031308) ? (1.055) * pow(TexB, (1.0/2.4)) - 0.055 : 12.92 * TexB; + TexA = (TexA >= 0.0031308) ? (1.055) * pow(TexA, (1.0/2.4)) - 0.055 : 12.92 * TexA; + } + + uint32 R_Out = (uint32)(Normalize(TexR) * LayerBits.Bits); + uint32 G_Out = (uint32)(Normalize(TexG) * LayerBits.Bits); + uint32 B_Out = (uint32)(Normalize(TexB) * LayerBits.Bits); + uint32 A_Out = (uint32)(Normalize(TexA) * 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; + bytes += BytesPerPixel; + } +} + static void -Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, v4 Color) +Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, void *SourceBuffer, v2 LayerPos, v4 Color) { B->BrushLength = (uint32)Brush->Size; if (B->BrushLength > 128) { @@ -1573,9 +1732,12 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, if (BrushPos.Max.y > Brush->CacheBounds.Max.y) Brush->CacheBounds.Max.y = BrushPos.Max.y; + Assert(Source->Type == source_type_principal); + B->BytesPerPixel = 4; B->SourceWidth = Source->Width; B->SourceBytesPerPixel = Source->BytesPerPixel; + B->SourceBuffer = SourceBuffer; Assert(Source->BytesPerPixel == 4); @@ -1597,15 +1759,10 @@ Brush_Info(brush_info *B, brush_state *Brush, block_source *Source, v2 LayerPos, B->BrushBuffer = Brush->PaintBuffer; B->EraseMode = Brush->EraseMode; - // ImGui's color picker works in sRGB, so we need to convert to linear. - // real32 R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92; - // 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; - B->R_Brush = Color.r; - B->G_Brush = Color.g; - B->B_Brush = Color.b; - B->A_Brush = Color.a; + B->R_Brush = (Color.r >= 0.04045) ? pow((Color.r + 0.055) / (1 + 0.055), 2.4) : Color.r / 12.92; + B->G_Brush = (Color.g >= 0.04045) ? pow((Color.g + 0.055) / (1 + 0.055), 2.4) : Color.g / 12.92; + B->B_Brush = (Color.b >= 0.04045) ? pow((Color.b + 0.055) / (1 + 0.055), 2.4) : Color.b / 12.92; + B->A_Brush = (Color.a >= 0.04045) ? pow((Color.a + 0.055) / (1 + 0.055), 2.4) : Color.a / 12.92; B->BrushRow = (uint8 *)B->BrushBuffer; } @@ -1615,68 +1772,29 @@ void Bitmap_SwapData(uint8 *Address_0, uint8 *Address_1, uint64 Size, uint16 Byt uint64 i = 0; uint16 ByteOffset = Bitmap_ByteInfo(BytesPerPixel).ByteOffset; uint64 RemainderBytes = Size % ByteOffset; - Assert(BytesPerPixel == 8); - -#if ARM - Assert(InstructionMode != instruction_mode_neon); -#else - if (BytesPerPixel == 4) { - uint32 Temp = 0; - while (i < Size) { - uint32 *Pixel_0 = (uint32 *)(Address_0 + i); - uint32 *Pixel_1 = (uint32 *)(Address_1 + i); - if (*Pixel_0 != 0x00000000) { - Temp = *Pixel_1; - *Pixel_1 = *Pixel_0; - *Pixel_0 = Temp; - } - i += sizeof(uint32); + Assert(BytesPerPixel == 4); + + while (i < Size) { + uint32 *Pixel_0 = (uint32 *)(Address_0 + i); + uint32 *Pixel_1 = (uint32 *)(Address_1 + i); + if (*Pixel_0 != 0x00000000) { + uint32 Temp = *Pixel_1; + *Pixel_1 = *Pixel_0; + *Pixel_0 = Temp; } - } else if (BytesPerPixel == 8) { - uint64 Temp = 0; - __m256i Zero = _mm256_set1_epi64x(0); - __m256i Max32 = _mm256_set1_epi32(0xFFFFFFFF); - if (InstructionMode == instruction_mode_avx) { - while (i < Size - RemainderBytes) { - uint8 *Pixel_0_Address = (Address_0 + i); - __m256i Pixel_0 = _mm256_loadu_si256((__m256i *)Pixel_0_Address); - __m256i AlphaMask = _mm256_cmpeq_epi64(Pixel_0, Zero); - if (_mm256_movemask_epi8(AlphaMask) != 0xFFFFFFFF) { - uint8 *Pixel_1_Address = (Address_1 + i); - __m256i Pixel_1 = _mm256_loadu_si256((__m256i *)Pixel_1_Address); - AlphaMask = _mm256_andnot_si256(AlphaMask, Max32); - _mm256_maskstore_epi64((long long *)Pixel_1_Address, AlphaMask, Pixel_0); - _mm256_maskstore_epi64((long long *)Pixel_0_Address, AlphaMask, Pixel_1); - } - i += sizeof(uint64)*4; - } - } - while (i < Size) { - uint64 *Pixel_0 = (uint64 *)(Address_0 + i); - uint64 *Pixel_1 = (uint64 *)(Address_1 + i); - if (*Pixel_0 != 0x0000000000000000) { - Temp = *Pixel_1; - *Pixel_1 = *Pixel_0; - *Pixel_0 = Temp; - } - i += sizeof(uint64); - } - } else { - Assert(0); + i += sizeof(uint32); } -#endif - } static void -PaintTest(brush_info B, void *Buffer, rectangle RenderRegion) +PaintTest(brush_info B, void *CacheBuffer, 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*B.LayerPitch + X*B.SourceBytesPerPixel; - uint8 *LayerPixel = (uint8 *)Buffer + Offset; + uint8 *LayerPixel = (uint8 *)CacheBuffer + Offset; uint32 *R_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 0); uint32 *G_DestAddress = (uint32 *)(LayerPixel + B.LayerBits.ByteOffset * 1); @@ -1691,6 +1809,12 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion) int32 TrueX = (X - B.LayerBounds.Min.x) - B.ExtraX; int32 TrueY = (Y - B.LayerBounds.Min.y) - B.ExtraY; + uint8 *SourcePixel = (uint8 *)B.SourceBuffer + Offset; + Assert(B.SourceBytesPerPixel == 4); + bool32 IsEmpty = (*(uint32 *)SourcePixel == 0x00000000); + if (IsEmpty) + *(uint32 *)SourcePixel = 0x00010101; + // Assert(TrueX >= 0 && TrueX < BrushLength); // Assert(TrueY >= 0 && TrueY < BrushLength); @@ -1698,7 +1822,10 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion) real32 Brush_BitmapAlpha = (real32)((*(uint32 *)(BrushPixel + B.BrushBits.ByteOffset*3)) & B.BrushBits.MaskPixel) * B.BrushBits.Normalized; - real32 BrushAlpha = Brush_BitmapAlpha * B.A_Brush; + if (!Brush_BitmapAlpha) + continue; + + real32 BrushAlpha = Brush_BitmapAlpha; real32 LayerAlpha = A_Layer; real32 A_Blend = 0; @@ -1707,13 +1834,22 @@ PaintTest(brush_info B, void *Buffer, rectangle RenderRegion) real32 B_Blend = 0; if (!B.EraseMode) { - A_Blend = LayerAlpha + BrushAlpha; - // R_Blend = (R_Layer * (1.0f - BrushAlpha)) + (B.R_Brush * BrushAlpha); - // G_Blend = (G_Layer * (1.0f - BrushAlpha)) + (B.G_Brush * BrushAlpha); - // B_Blend = (B_Layer * (1.0f - BrushAlpha)) + (B.B_Brush * BrushAlpha); - R_Blend = B.R_Brush; - G_Blend = B.G_Brush; - B_Blend = B.B_Brush; + if (IsEmpty) { + R_Blend = B.R_Brush; + G_Blend = B.G_Brush; + B_Blend = B.B_Brush; + A_Blend = LayerAlpha + BrushAlpha; + } else { + R_Blend = B.R_Brush; + G_Blend = B.G_Brush; + B_Blend = B.B_Brush; + A_Blend = LayerAlpha + ((1.0f - LayerAlpha) * BrushAlpha); + real32 Blend = BrushAlpha; + // R_Blend = (R_Layer * (1.0f - Blend)) + (B.R_Brush * Blend); + // G_Blend = (G_Layer * (1.0f - Blend)) + (B.G_Brush * Blend); + // B_Blend = (B_Layer * (1.0f - Blend)) + (B.B_Brush * Blend); + } + // A_Blend = BrushAlpha; } else { A_Blend = A_Layer * (1.0f - BrushAlpha); R_Blend = R_Layer; @@ -1815,13 +1951,17 @@ PaintTest_AVX2(brush_info B, void *Buffer, rectangle RenderRegion) #endif static void -Brush_Render(project_state *State, ui *UI, layer_transforms T_Layer, block_composition *MainComp, block_source *Source, void *BitmapAddress, ImVec2 ViewportMin, v2 LayerPos) +RenderQueue_AddBrush(project_state *State, v2 LayerPos) { - brush_info B; - 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); - } + State->Queue.Item[State->Queue.CurrentIdx].Pos = LayerPos; + State->Queue.Item[State->Queue.CurrentIdx].Type = 1; + State->Queue.CurrentIdx++; + State->Brush.PrevPos = LayerPos; +} + +static void +RenderQueue_AddBlit(project_state *State) +{ + State->Queue.Item[State->Queue.CurrentIdx].Type = 2; + State->Queue.CurrentIdx++; } |