The next thing is how to anti-alias the edge. I found two concepts SSAA and MSAA about that but I don't know what is the difference. I know that both takes more than one sample for a pixel.
So I implemented what I've understood from Scratchpixel website on top of the fuction DrawRectangleSlowly Like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | void FillRectangle(win32_screen_buffer *Buffer, basis Basis, v2 Dim, v4 Color) { v2 P1 = Basis.O; v2 P2 = Basis.O + Dim.x*Basis.X; v2 P3 = Basis.O + Dim.x*Basis.X + Dim.y*Basis.Y; v2 P4 = Basis.O + Dim.y*Basis.Y; s32 MinX = FloorF32ToS32(MIN(MIN(P1.x, P2.x), MIN(P3.x, P4.x))) - 1; s32 MinY = FloorF32ToS32(MIN(MIN(P1.y, P2.y), MIN(P3.y, P4.y))) - 1; s32 MaxX = CeilF32ToS32(MAX(MAX(P1.x, P2.x), MAX(P3.x, P4.x))) + 1; s32 MaxY = CeilF32ToS32(MAX(MAX(P1.y, P2.y), MAX(P3.y, P4.y))) + 1; if(MinX < 0) MinX = 0; if(MinY < 0) MinY = 0; if(MaxX > Buffer->Width) MaxX = Buffer->Width; if(MaxY > Buffer->Height) MaxY = Buffer->Height; #define SAMPLING 1 #if SAMPLING v2 SampleOffsets[4] = { V2(1.0f/3, 1.0f/3), V2(2.0f/3, 1.0f/3), V2(1.0f/3, 2.0f/3), V2(2.0f/3, 2.0f/3) }; v4 Samples[4]; #endif f32 SA = Color.a; f32 SR = (Color.r*SA) * 255; f32 SG = (Color.g*SA) * 255; f32 SB = (Color.b*SA) * 255; u8 *Row = (u8 *)Buffer->Memory + MinY*Buffer->Pitch + MinX*4; for(s32 Y = MinY; Y<MaxY; Y++) { u32 *Pixels = (u32 *)Row; for(s32 X = MinX; X<MaxX; X++) { bool32 Touched = false; #if SAMPLING for(u32 I=0; I<ARRAY_COUNT(SampleOffsets); I++) { v2 PP = Vi2(X, Y) + SampleOffsets[I]; #else v2 PP = Vi2(X, Y); v4 C = V4(0,0,0,0); #endif if(Inner(PP-P1, Perp(P2-P1)) >= 0 && Inner(PP-P2, Perp(P3-P2)) >= 0 && Inner(PP-P3, Perp(P4-P3)) >= 0 && Inner(PP-P4, Perp(P1-P4)) >= 0) { Touched = true; #if SAMPLING Samples[I] = V4(SR, SG, SB, SA); #else C = V4(SR, SG, SB, SA); #endif } #if SAMPLING else { Samples[I] = V4(0, 0, 0, 0); } } #endif if(Touched) { #if SAMPLING v4 C = (Samples[0] + Samples[1] + Samples[2] + Samples[3]); C *= 1.0f/4; #endif f32 DA = 1.0f-C.a; f32 DR = DA * ((*Pixels >> 16) & 0xff); f32 DG = DA * ((*Pixels >> 8) & 0xff); f32 DB = DA * (*Pixels & 0xff); u32 Color = (RoundF32ToU32(C.r + DR) << 16 | RoundF32ToU32(C.g + DG) << 8 | RoundF32ToU32(C.b + DB)); *Pixels = Color; } *Pixels++; } Row += Buffer->Pitch; } } |
Is this SSAA or MSAA?
The other thing is in the website mentioned they were saying you can optimize this by doing the sampling only around the edges. Any ideas on how to do that?
The last thing, can this edge test algorithm work with curved edges or I have to use something else?