refactored layer blending

This commit is contained in:
PS 2020-11-14 12:47:51 -08:00
parent 708ac91afe
commit a6c8d0c955
3 changed files with 44 additions and 8 deletions

View File

@ -41,6 +41,7 @@ enum blend_mode
BlendMode_Count, BlendMode_Count,
}; };
// TODO(pjs): Add Opacity to this
typedef pixel led_blend_proc(pixel PixelA, pixel PixelB); typedef pixel led_blend_proc(pixel PixelA, pixel PixelB);
global gs_const_string BlendModeStrings[] = { global gs_const_string BlendModeStrings[] = {
@ -84,10 +85,22 @@ struct animation_array
u32 CountMax; u32 CountMax;
}; };
struct animation_layer_frame
{
animation_block Hot;
animation_block NextHot;
bool HasNextHot;
};
// NOTE(pjs): This is an evaluated frame - across all layers in an // NOTE(pjs): This is an evaluated frame - across all layers in an
// animation, these are the blocks that need to be run // animation, these are the blocks that need to be run
struct animation_frame struct animation_frame
{ {
animation_layer_frame* Layers;
b8* LayersFilled;
u32 LayersCount;
u32 LayersCountMax;
// NOTE(pjs): These are all parallel arrays of equal length // NOTE(pjs): These are all parallel arrays of equal length
animation_block* Blocks; animation_block* Blocks;
b8* BlocksFilled; b8* BlocksFilled;

View File

@ -77,35 +77,47 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
s32 CurrentFrame = System->CurrentFrame; s32 CurrentFrame = System->CurrentFrame;
r32 FrameTime = CurrentFrame * System->SecondsPerFrame; r32 FrameTime = CurrentFrame * System->SecondsPerFrame;
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System);
animation_frame CurrFrame = AnimationSystem_CalculateAnimationFrame(System, Transient); animation_frame CurrFrame = AnimationSystem_CalculateAnimationFrame(System, Transient);
led_buffer* LayerLEDBuffers = PushArray(Transient, led_buffer, CurrFrame.BlocksCountMax); led_buffer* LayerLedBuffers = PushArray(Transient, led_buffer, CurrFrame.BlocksCountMax);
for (u32 AssemblyIndex = 0; AssemblyIndex < Assemblies.Count; AssemblyIndex++) for (u32 AssemblyIndex = 0; AssemblyIndex < Assemblies.Count; AssemblyIndex++)
{ {
assembly* Assembly = &Assemblies.Values[AssemblyIndex]; assembly* Assembly = &Assemblies.Values[AssemblyIndex];
led_buffer* AssemblyLedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex); led_buffer* AssemblyLedBuffer = LedSystemGetBuffer(LedSystem, Assembly->LedBufferIndex);
// Create the LayerLEDBuffers
for (u32 Layer = 0; Layer < CurrFrame.BlocksCountMax; Layer++) for (u32 Layer = 0; Layer < CurrFrame.BlocksCountMax; Layer++)
{ {
led_buffer TempBuffer = {};
TempBuffer.LedCount = AssemblyLedBuffer->LedCount;
TempBuffer.Positions = AssemblyLedBuffer->Positions;
TempBuffer.Colors = PushArray(Transient, pixel, TempBuffer.LedCount);
LedBuffer_ClearToBlack(&TempBuffer);
LayerLedBuffers[Layer] = TempBuffer;
}
// Render Each layer's block to the appropriate temp buffer
for (u32 Layer = 0; Layer < CurrFrame.BlocksCountMax; Layer++)
{
led_buffer TempBuffer = LayerLedBuffers[Layer];
if (!CurrFrame.BlocksFilled[Layer]) { continue; } if (!CurrFrame.BlocksFilled[Layer]) { continue; }
animation_block Block = CurrFrame.Blocks[Layer]; animation_block Block = CurrFrame.Blocks[Layer];
// Prep Temp Buffer
LayerLEDBuffers[Layer] = *AssemblyLedBuffer;
LayerLEDBuffers[Layer].Colors = PushArray(Transient, pixel, AssemblyLedBuffer->LedCount);
u32 FramesIntoBlock = CurrentFrame - Block.Range.Min; u32 FramesIntoBlock = CurrentFrame - Block.Range.Min;
r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame; r32 SecondsIntoBlock = FramesIntoBlock * System->SecondsPerFrame;
// :AnimProcHandle // :AnimProcHandle
u32 AnimationProcIndex = Block.AnimationProcHandle - 1; u32 AnimationProcIndex = Block.AnimationProcHandle - 1;
animation_proc* AnimationProc = Patterns[AnimationProcIndex].Proc; animation_proc* AnimationProc = Patterns[AnimationProcIndex].Proc;
AnimationProc(&LayerLEDBuffers[Layer], *Assembly, SecondsIntoBlock, Transient); AnimationProc(&TempBuffer, *Assembly, SecondsIntoBlock, Transient);
} }
// Consolidate Temp Buffers // Consolidate Temp Buffers
// We do this in reverse order so that they go from top to bottom // We do this in reverse order so that they go from top to bottom
animation* ActiveAnim = AnimationSystem_GetActiveAnimation(System);
for (u32 Layer = 0; Layer < CurrFrame.BlocksCountMax; Layer++) for (u32 Layer = 0; Layer < CurrFrame.BlocksCountMax; Layer++)
{ {
if (!CurrFrame.BlocksFilled[Layer]) { continue; } if (!CurrFrame.BlocksFilled[Layer]) { continue; }
@ -115,7 +127,7 @@ AnimationSystem_RenderToLedBuffers(animation_system* System, assembly_array Asse
for (u32 LED = 0; LED < AssemblyLedBuffer->LedCount; LED++) for (u32 LED = 0; LED < AssemblyLedBuffer->LedCount; LED++)
{ {
pixel A = AssemblyLedBuffer->Colors[LED]; pixel A = AssemblyLedBuffer->Colors[LED];
pixel B = LayerLEDBuffers[Layer].Colors[LED]; pixel B = LayerLedBuffers[Layer].Colors[LED];
AssemblyLedBuffer->Colors[LED] = Blend(A, B); AssemblyLedBuffer->Colors[LED] = Blend(A, B);
} }
} }

View File

@ -168,6 +168,17 @@ LedSystemGetBuffer(led_system* System, u32 Index)
return Result; return Result;
} }
internal void
LedBuffer_ClearToBlack(led_buffer* Buffer)
{
for (u32 i = 0; i < Buffer->LedCount; i++)
{
Buffer->Colors[i].R = 0;
Buffer->Colors[i].G = 0;
Buffer->Colors[i].B = 0;
}
}
internal u32 internal u32
StripGenData_CountLeds(strip_gen_data Data) StripGenData_CountLeds(strip_gen_data Data)
{ {