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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 | // NOTE(shvayko):Check if any vertex lying beyond near plane
if(IsBitSet(ClipCode[0],7) ||
IsBitSet(ClipCode[1],7) ||
IsBitSet(ClipCode[2],7))
{
if(VerticesInsideZRange == 1)
{
// NOTE(shvayko): The simplest case where only one interior vertex.
// Just interpolate each exterior vertex with interior vertex and that
// will produce new vertices which will represent one new triangle.
// NOTE(shvayko): TmpV0 - Interior vertex; TmpV1 - Exterior vertex;
// TmpV2 - Exterior vertex
v3 TmpV0,TmpV1,TmpV2;
if(IsBitSet(ClipCode[0],8))
{
TmpV0 = V0;
TmpV1 = V1;
TmpV2 = V2;
}
else if(IsBitSet(ClipCode[1],8))
{
TmpV0 = V1;
TmpV1 = V0;
TmpV2 = V2;
}
else
{
TmpV0 = V2;
TmpV1 = V0;
TmpV2 = V1;
}
// NOTE(shvayko): Solve for t when z component is equal to near z
// Pi(x,y,z) = P0(x,y,z) + (P1(x,y,z) - P0(x,y,z))*t
// NOTE(shvayko): 1.0f is near plane Z
// NOTE(shvayko): TmpV0 and TmpV2
f32 t = 1.0f-TmpV1.z / (TmpV0.z - TmpV1.z);
f32 x = TmpV1.x + (TmpV0.x - TmpV1.x)*t;
f32 y = TmpV1.y + (TmpV0.y - TmpV1.y)*t;
f32 z = TmpV1.z + (TmpV0.z - TmpV1.z)*t;
TmpV1 = v3f(x,y,1.1f);
// NOTE(shvayko): TmpV0 and TmpV2
f32 t1 = 1.0f-TmpV2.z / (TmpV0.z - TmpV2.z);
x = TmpV2.x + (TmpV0.x - TmpV2.x)*t1;
y = TmpV2.y + (TmpV0.y - TmpV2.y)*t1;
z = TmpV2.z + (TmpV0.z - TmpV2.z)*t1;
TmpV2 = v3f(x,y,1.1f);
// NOTE(shvayko): New triangle
v3 NT0 = TmpV0;
v3 NT1 = TmpV1;
v3 NT2 = TmpV2;
AddTriangle(NT0,NT1,NT2,Triangle->Color);
}
else if(VerticesInsideZRange == 2)
{
// NOTE(shvayko): The case where two interior vertex.
// That case will produce 2 triangles
// NOTE(shvayko): TmpV0 - Interior vertex; TmpV1 - Interior vertex;
// TmpV2 - Exterior vertex
v3 TmpV0,TmpV1,TmpV2;
if(ClipCode[0] & CLIPCODE_Z_INSIDE)
{
TmpV0 = V0;
if(ClipCode[1] & CLIPCODE_Z_INSIDE)
{
TmpV1 = V1;
TmpV2 = V2;
}
else
{
TmpV1 = V2;
TmpV2 = V1;
}
}
else if(ClipCode[1] & CLIPCODE_Z_INSIDE)
{
TmpV0 = V1;
TmpV1 = V2;
TmpV2 = V0;
}
// NOTE(shvayko): Solve for t when z component is equal to near z
// NOTE(shvayko): first created new vertex
// NOTE(shvayko): 1.0f is near plane Z
f32 t = 1.0f-TmpV2.z / (TmpV0.z - TmpV2.z);
f32 X0i = TmpV2.x + (TmpV0.x - TmpV2.x)*t;
f32 Y0i = TmpV2.y + (TmpV0.y - TmpV2.y)*t;
f32 Z0i = TmpV2.z + (TmpV0.z - TmpV2.z)*t;
// NOTE(shvayko): second created new vertex
f32 t1 = 1.0f-TmpV2.z / (TmpV1.z - TmpV2.z);
f32 X1i = TmpV2.x + (TmpV1.x - TmpV2.x)*t1;
f32 Y1i = TmpV2.y + (TmpV1.y - TmpV2.y)*t1;
f32 Z1i = TmpV2.z + (TmpV1.z - TmpV2.z)*t1;
// NOTE(shvayko): Split into 2 triangles
AddTriangle(TmpV0,v3f(X0i,Y0i,1.1f),TmpV1,Triangle->Color);
AddTriangle(TmpV0,TmpV1,v3f(X1i,Y1i,1.1f),Triangle->Color);
}
else
{
assert(!"lol");
}
}
else
{
// NOTE(shvayko): All vertices is in Z range. Process without any clipping
// NOTE(shvayko): Pespective divide. (Transforming from Clip Space into NDC space)
v3 NdcV0,NdcV1,NdcV2;
TransformHomogeneousToNDC(ClipV0,ClipV1,ClipV2,&NdcV0,&NdcV1,&NdcV2);
// NOTE(shvayko):Viewport tranformation(Transforming from NDC space(-1.0f - 1.0f))
// to screen space(0 - Width, 0 - Height)
v3 WinPV0,WinPV1,WinPV2;
Viewport(NdcV0,NdcV1,NdcV2,&WinPV0,&WinPV1,&WinPV2,ClipV0.z,ClipV1.z,ClipV2.z);
// NOTE(shvayko): Rasterization Stage
DrawTriangle(Backbuffer,WinPV0,WinPV1,WinPV2, Triangle->Color);
}
|