summaryrefslogtreecommitdiff
path: root/prenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'prenderer.cpp')
-rw-r--r--prenderer.cpp435
1 files changed, 435 insertions, 0 deletions
diff --git a/prenderer.cpp b/prenderer.cpp
index 9752663..b61290a 100644
--- a/prenderer.cpp
+++ b/prenderer.cpp
@@ -1,3 +1,437 @@
+
+static void
+Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegion);
+
+static void
+RenderLayers(render_entry Entry) {
+ Fallback_RenderLayer(*(transform_info *)Entry.RenderData, Entry.OutputBuffer, Entry.RenderRegion);
+#if 0
+#if ARM
+ Fallback_RenderLayer(RenderData->TransformInfo[i], RenderInfo->CompBuffer, RenderRegion);
+#else
+ if (InstructionMode == instruction_mode_avx)
+ AVX2_RenderLayer(Entry.T, Entry.OutputBuffer, Entry.RenderRegion);
+ else
+ Fallback_RenderLayer(Entry.T, Entry.OutputBuffer, Entry.RenderRegion);
+#endif
+#endif
+}
+
+static void
+Renderer_Start(void *Data, void *OutputBuffer, rectangle RenderRegion)
+{
+ // CPU
+ Threading_BitmapOp(Data, OutputBuffer, RenderRegion);
+}
+
+static void
+Renderer_Check(bool32 *Test)
+{
+ // CPU
+ *Test = Threading_IsActive();
+}
+
+// Helper for working with different bit depths.
+static render_byte_info
+Bitmap_ByteInfo(uint32 BytesPerPixel) {
+ render_byte_info Byte = {};
+ if (BytesPerPixel == 4) {
+ Byte.MaskPixel = 0xFF;
+ Byte.ByteOffset = 1;
+ Byte.Normalized = 1 / 255.0f;
+ Byte.Bits = 255;
+ } else if (BytesPerPixel == 8) {
+ Byte.MaskPixel = 0xFFFF;
+ Byte.ByteOffset = 2;
+ Byte.Normalized = 1 / 65535.0f;
+ Byte.Bits = 65535;
+ } else {
+ Byte.MaskPixel = 0xFFFFFFFF;
+ Byte.ByteOffset = 4;
+ Byte.Normalized = 1 / 4294967295.0f;
+ Byte.Bits = 4294967295;
+ Assert(0);
+ }
+ return Byte;
+}
+
+static transform_info
+Transform_Calculate(project_state *State, memory *Memory, project_data *File, block_layer *Layer, block_composition *Comp)
+{
+ transform_info TransformInfo;
+ int Width = 0, Height = 0, BytesPerPixel = 0;
+ if (!Layer->IsPrecomp) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ Width = Source->Width;
+ Height = Source->Height;
+ BytesPerPixel = Source->BytesPerPixel;
+ } else {
+ block_composition *Precomp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
+ Width = Precomp->Width;
+ Height = Precomp->Height;
+ BytesPerPixel = Precomp->BytesPerPixel;
+ }
+
+ real32 Rotation = Layer->rotation.CurrentValue;
+ real32 X = Layer->x.CurrentValue;
+ real32 Y = Layer->y.CurrentValue;
+ real32 s = Layer->scale.CurrentValue;
+ blend_mode BlendMode = Layer->BlendMode;
+
+ /*
+ state_file_ui *UI = &State->Context[State->CurrentFileIndex].UI;
+ if (UI->IsInteracting == true && UI->InteractMode == interact_transforms && Layer->IsSelected && !Layer->IsAdjustment)
+ Transform_ApplyInteractive(UI, &X, &Y, &Rotation, &s);
+
+ if (UI->IsInteractingBlendmode == true && Layer->IsSelected)
+ BlendMode = UI->InteractBlendmode;
+ */
+
+ real32 Rad = (Rotation * (PI / 180));
+ // v2 Scale = {Source->Raster.Width * s, Source->Raster.Height * s};
+
+ v2 XAxis = (Width * s)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Height * -s)*V2(sin(Rad), -cos(Rad));
+
+ real32 AnchorX = Layer->ax.CurrentValue;
+ real32 AnchorY = Layer->ay.CurrentValue;
+
+ v2 Pos = {X, Y};
+ v2 Origin = Pos - (XAxis * AnchorX) - (YAxis * AnchorY);
+
+ real32 XLengthSq = 1.0f / LengthSq(XAxis);
+ real32 YLengthSq = 1.0f / LengthSq(YAxis);
+
+ int32 MaxX = 0;
+ int32 MaxY = 0;
+ int32 MinX = Comp->Width;
+ int32 MinY = Comp->Height;
+
+ v2 Points[4] = {Origin, Origin + XAxis, Origin + YAxis, Origin + XAxis + YAxis};
+ for (int i = 0; i < 4; i++) {
+ if (Points[i].x < MinX) { MinX = Points[i].x; }
+ if (Points[i].y < MinY) { MinY = Points[i].y; }
+ if (Points[i].x > MaxX) { MaxX = Points[i].x; }
+ if (Points[i].y > MaxY) { MaxY = Points[i].y; }
+ }
+
+ TransformInfo.XAxisPX = XLengthSq*XAxis.x;
+ TransformInfo.XAxisPY = XLengthSq*XAxis.y;
+ TransformInfo.YAxisPX = YLengthSq*YAxis.x;
+ TransformInfo.YAxisPY = YLengthSq*YAxis.y;
+
+ TransformInfo.BufferWidth = Comp->Width;
+ TransformInfo.BufferHeight = Comp->Height;
+ TransformInfo.BufferBytesPerPixel = Comp->BytesPerPixel;
+ TransformInfo.BufferBits = Bitmap_ByteInfo(Comp->BytesPerPixel);
+
+ TransformInfo.LayerWidth = Width;
+ TransformInfo.LayerHeight = Height;
+ TransformInfo.LayerBytesPerPixel = BytesPerPixel;
+ TransformInfo.LayerBits = Bitmap_ByteInfo(BytesPerPixel);
+
+ TransformInfo.LayerOpacity = Layer->opacity.CurrentValue;
+ TransformInfo.BlendMode = BlendMode;
+ TransformInfo.OriginX = Origin.x;
+ TransformInfo.OriginY = Origin.y;
+ TransformInfo.BufferPitch = Comp->Width*Comp->BytesPerPixel;
+ TransformInfo.LayerPitch = Width*BytesPerPixel;
+ TransformInfo.ClipRect = {MinX - (MinX & 3), MinY, MaxX + 1, MaxY + 1};
+
+ TransformInfo.IsAdjustment = Layer->IsAdjustment;
+
+ return TransformInfo;
+}
+
+static void
+Fallback_RenderLayer(transform_info T, void *OutputBuffer, rectangle RenderRegion)
+{
+ rectangle LayerBounds = ClipRectangle( T.ClipRect, RenderRegion);
+
+ Assert(LayerBounds.Max.x <= T.BufferWidth);
+ Assert(LayerBounds.Max.y <= T.BufferHeight);
+
+ for (int16 Y = LayerBounds.Min.y; Y < LayerBounds.Max.y; Y++)
+ {
+ real32 StartVectorY = (real32)Y - T.OriginY;
+
+ for (int16 X = LayerBounds.Min.x; X < LayerBounds.Max.x; X++)
+ {
+
+ real32 StartVectorX = X - T.OriginX;
+ real32 U = (StartVectorX * T.XAxisPX) + (StartVectorY * T.XAxisPY);
+ real32 V = (StartVectorX * T.YAxisPX) + (StartVectorY * T.YAxisPY);
+
+ if (U < 1.0f && U >= 0.0f && V < 1.0f && V >= 0.0f) {
+
+ real32 TexXFull = U * T.LayerWidth;
+ uint32 TexXInt = (uint32)TexXFull;
+ real32 TexX = TexXFull - TexXInt;
+
+ real32 TexYFull = V * T.LayerHeight;
+ uint32 TexYInt = (uint32)TexYFull;
+ real32 TexY = TexYFull - TexYInt;
+
+ real32 TexXInv = 1 - TexX;
+ real32 TexYInv = 1 - TexY;
+ real32 TexBothXInv = TexXInv * TexY;
+ real32 TexBothYInv = TexX * TexYInv;
+ real32 TexBoth = TexY * TexX;
+ real32 TexBothInv = TexXInv * TexYInv;
+
+ uint32 XLookup, YLookup, PixelToSeek;
+
+ uint16 LX = TexXInt;
+ uint16 LY = TexYInt;
+ uint16 LXPlus = Ceil(TexXInt+1, (uint32)T.LayerWidth - 1);
+ uint16 LYPlus = Ceil(TexYInt+1, (uint32)T.LayerHeight - 1);
+
+ uint8 *TexPTR0 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LY) + (LX * (uint16)T.LayerBytesPerPixel));
+ uint8 *TexPTR1 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LY) + (LXPlus * (uint16)T.LayerBytesPerPixel));
+ uint8 *TexPTR2 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LYPlus) + (LX * (uint16)T.LayerBytesPerPixel));
+ uint8 *TexPTR3 = ((uint8 *)T.SourceBuffer + ((uint16)T.LayerPitch * LYPlus) + (LXPlus * (uint16)T.LayerBytesPerPixel));
+
+ uint32 PixelA = *(uint32 *)TexPTR0;
+ uint32 PixelB = *(uint32 *)TexPTR1;
+ uint32 PixelC = *(uint32 *)TexPTR2;
+ uint32 PixelD = *(uint32 *)TexPTR3;
+
+
+#if 0
+ real32 TexRA = (real32)(PixelA & 0xFF) * Normalized255;
+ real32 TexRB = (real32)(PixelB & 0xFF) * Normalized255;
+ real32 TexRC = (real32)(PixelC & 0xFF) * Normalized255;
+ real32 TexRD = (real32)(PixelD & 0xFF) * Normalized255;
+
+ real32 TexGA = (real32)((PixelA >> 8) & 0xFF) * Normalized255;
+ real32 TexGB = (real32)((PixelB >> 8) & 0xFF) * Normalized255;
+ real32 TexGC = (real32)((PixelC >> 8) & 0xFF) * Normalized255;
+ real32 TexGD = (real32)((PixelD >> 8) & 0xFF) * Normalized255;
+
+ real32 TexBA = (real32)((PixelA >> 16) & 0xFF) * Normalized255;
+ real32 TexBB = (real32)((PixelB >> 16) & 0xFF) * Normalized255;
+ real32 TexBC = (real32)((PixelC >> 16) & 0xFF) * Normalized255;
+ real32 TexBD = (real32)((PixelD >> 16) & 0xFF) * Normalized255;
+
+ real32 TexAA = (real32)((PixelA >> 24) & 0xFF) * Normalized255;
+ real32 TexAB = (real32)((PixelB >> 24) & 0xFF) * Normalized255;
+ real32 TexAC = (real32)((PixelC >> 24) & 0xFF) * Normalized255;
+ real32 TexAD = (real32)((PixelD >> 24) & 0xFF) * Normalized255;
+#else
+ real32 TexRA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+#if 0
+ for (int i = 0; i < 50; i++) {
+ real32 TexRA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAA = (real32)(*(uint32 *)(TexPTR0 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAB = (real32)(*(uint32 *)(TexPTR1 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAC = (real32)(*(uint32 *)(TexPTR2 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+
+ real32 TexRD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 0) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexGD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 1) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexBD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 2) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ real32 TexAD = (real32)(*(uint32 *)(TexPTR3 + T.LayerBits.ByteOffset * 3) & T.LayerBits.MaskPixel) * T.LayerBits.Normalized;
+ }
+#endif
+#endif
+
+ real32 R_Col = (TexBothInv * TexRA) + (TexBothYInv * TexRB)
+ + (TexBothXInv * TexRC) + (TexBoth * TexRD);
+ real32 G_Col = (TexBothInv * TexGA) + (TexBothYInv * TexGB)
+ + (TexBothXInv * TexGC) + (TexBoth * TexGD);
+ real32 B_Col = (TexBothInv * TexBA) + (TexBothYInv * TexBB)
+ + (TexBothXInv * TexBC) + (TexBoth * TexBD);
+ real32 A_Col = (TexBothInv * TexAA) + (TexBothYInv * TexAB)
+ + (TexBothXInv * TexAC) + (TexBoth * TexAD);
+
+ real32 LayerAlpha = A_Col * T.LayerOpacity;
+
+ real32 R_Blend = R_Col;
+ real32 G_Blend = G_Col;
+ real32 B_Blend = B_Col;
+ real32 A_Blend = A_Col;
+
+ uint8 *DestPixel =((uint8 *)OutputBuffer + ((uint16)Y * (uint16)T.BufferPitch) + ((uint16)X * (uint16)T.BufferBytesPerPixel));
+
+ uint32 *R_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 0);
+ uint32 *G_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 1);
+ uint32 *B_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 2);
+ uint32 *A_DestAddress = (uint32 *)(DestPixel + T.BufferBits.ByteOffset * 3);
+
+ if (LayerAlpha != 1.0f || T.BlendMode != blend_normal) {
+
+ real32 R_Dest = (real32)(*R_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 G_Dest = (real32)(*G_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 B_Dest = (real32)(*B_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+ real32 A_Dest = (real32)(*A_DestAddress & T.BufferBits.MaskPixel) * T.BufferBits.Normalized;
+
+ switch (T.BlendMode)
+ {
+ case blend_normal:
+ {
+ } break;
+ case blend_multiply:
+ {
+ R_Blend = R_Dest * R_Col;
+ G_Blend = G_Dest * G_Col;
+ B_Blend = B_Dest * B_Col;
+ } break;
+ case blend_colorburn:
+ {
+ // NOTE(fox): Padding to prevent actual crashing from zero division
+ R_Blend = 1.0f - ((1.0f - R_Dest) / (R_Col + 0.001f));
+ G_Blend = 1.0f - ((1.0f - G_Dest) / (G_Col + 0.001f));
+ B_Blend = 1.0f - ((1.0f - B_Dest) / (B_Col + 0.001f));
+ } break;
+ case blend_linearburn:
+ {
+ R_Blend = (R_Dest + R_Col) - 1.0f;
+ G_Blend = (G_Dest + G_Col) - 1.0f;
+ B_Blend = (B_Dest + B_Col) - 1.0f;
+ } break;
+ case blend_add:
+ {
+ R_Blend = R_Dest + R_Col;
+ G_Blend = G_Dest + G_Col;
+ B_Blend = B_Dest + B_Col;
+ } break;
+ case blend_screen:
+ {
+ R_Blend = 1.0f - ((1.0f - R_Dest) * (1.0f - R_Col));
+ G_Blend = 1.0f - ((1.0f - G_Dest) * (1.0f - G_Col));
+ B_Blend = 1.0f - ((1.0f - B_Dest) * (1.0f - B_Col));
+ } break;
+ case blend_overlay:
+ {
+ if (R_Dest < 0.5) {
+ R_Blend = 2.0f * R_Dest * R_Col;
+ } else {
+ R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
+ }
+ if (G_Dest < 0.5) {
+ G_Blend = 2.0f * G_Dest * G_Col;
+ } else {
+ G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
+ }
+ if (B_Dest < 0.5) {
+ B_Blend = 2.0f * B_Dest * B_Col;
+ } else {
+ B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
+ }
+ } break;
+ case blend_softlight:
+ {
+ // using Pegtop's equation
+ R_Blend = ((1.0f - R_Col * 2) * R_Dest * R_Dest) + (R_Col * 2 * R_Dest);
+ G_Blend = ((1.0f - G_Col * 2) * G_Dest * G_Dest) + (G_Col * 2 * G_Dest);
+ B_Blend = ((1.0f - B_Col * 2) * B_Dest * B_Dest) + (B_Col * 2 * B_Dest);
+ } break;
+ case blend_hardlight:
+ {
+ if (R_Dest > 0.5) {
+ R_Blend = 2.0f * R_Dest * R_Col;
+ } else {
+ R_Blend = 1.0f - (2.0f * (1.0f - R_Dest) * (1.0f - R_Col));
+ }
+ if (G_Dest > 0.5) {
+ G_Blend = 2.0f * G_Dest * G_Col;
+ } else {
+ G_Blend = 1.0f - (2.0f * (1.0f - G_Dest) * (1.0f - G_Col));
+ }
+ if (B_Dest > 0.5) {
+ B_Blend = 2.0f * B_Dest * B_Col;
+ } else {
+ B_Blend = 1.0f - (2.0f * (1.0f - B_Dest) * (1.0f - B_Col));
+ }
+ } break;
+ case blend_subtract:
+ {
+ R_Blend = R_Dest - R_Col;
+ G_Blend = G_Dest - G_Col;
+ B_Blend = B_Dest - B_Col;
+ } break;
+ case blend_divide:
+ {
+ R_Blend = R_Dest / (R_Col + 0.001f);
+ G_Blend = G_Dest / (G_Col + 0.001f);
+ B_Blend = B_Dest / (B_Col + 0.001f);
+ } break;
+ case blend_difference:
+ {
+ if (R_Col - R_Dest > 0) {
+ R_Blend = R_Col - R_Dest;
+ } else {
+ R_Blend = R_Dest - R_Col;
+ }
+ if (G_Col - G_Dest > 0) {
+ G_Blend = G_Col - G_Dest;
+ } else {
+ G_Blend = G_Dest - G_Col;
+ }
+ if (B_Col - B_Dest > 0) {
+ B_Blend = B_Col - B_Dest;
+ } else {
+ B_Blend = B_Dest - B_Col;
+ }
+ } break;
+ }
+
+ R_Blend = (R_Dest * (1.0f - LayerAlpha)) + (R_Blend * LayerAlpha);
+ G_Blend = (G_Dest * (1.0f - LayerAlpha)) + (G_Blend * LayerAlpha);
+ B_Blend = (B_Dest * (1.0f - LayerAlpha)) + (B_Blend * LayerAlpha);
+
+ if (T.BlendMode == blend_normal)
+ A_Blend = A_Dest + LayerAlpha;
+ else
+ A_Blend = A_Dest;
+ }
+
+ uint32 R_Out = (uint32)(Normalize(R_Blend) * T.BufferBits.Bits);
+ uint32 G_Out = (uint32)(Normalize(G_Blend) * T.BufferBits.Bits);
+ uint32 B_Out = (uint32)(Normalize(B_Blend) * T.BufferBits.Bits);
+ uint32 A_Out = (uint32)(Normalize(A_Blend) * T.BufferBits.Bits);
+
+ *R_DestAddress = (*R_DestAddress & ~T.BufferBits.MaskPixel) | R_Out;
+ *G_DestAddress = (*G_DestAddress & ~T.BufferBits.MaskPixel) | G_Out;
+ *B_DestAddress = (*B_DestAddress & ~T.BufferBits.MaskPixel) | B_Out;
+ *A_DestAddress = (*A_DestAddress & ~T.BufferBits.MaskPixel) | A_Out;
+ // *R_DestAddress = 255;
+ // *G_DestAddress = 255;
+ // *B_DestAddress = 255;
+ // *A_DestAddress = 255;
+ }
+ }
+ }
+}
+
+#if 0
static void
Layer_CalcRotatedOffset(project_layer *Layer, v2 Increment, v2 Divisor, real32 *ValueX, real32 *ValueY)
{
@@ -1380,3 +1814,4 @@ Fallback_RenderLayer(transform_info T, comp_buffer *Buffer, rectangle RenderRegi
}
}
}
+#endif