-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRenderContext.java
91 lines (71 loc) · 2.48 KB
/
RenderContext.java
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
public class RenderContext extends Bitmap{
private final int m_scanBuffer[];
public RenderContext(int width, int height){
super(width,height);
m_scanBuffer = new int[height * 2];
}
public void DrawScanBuffer(int yCoord, int xMin, int xMax){
m_scanBuffer[yCoord * 2 ] = xMin;
m_scanBuffer[yCoord * 2 +1] = xMax;
}
public void FillShape(int yMin, int yMax){
for(int j = Math.max(0,yMin); j < Math.min(m_height,yMax); j++){
int xMin = m_scanBuffer[j * 2];
int xMax = m_scanBuffer[j * 2 + 1];
for(int i = Math.max(0,xMin); i < Math.min(m_width,xMax); i++){
DrawPixel(i,j, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF);
}
}
}
public void FillTriangle(Vertex v1, Vertex v2, Vertex v3){
Matrix4f screenSpaceTransform = new Matrix4f().InitScreenSpaceTransform(
GetWidth()/2, GetHeight()/2);
Vertex minYVert = v1.Transform(screenSpaceTransform).PerspectiveDivide();
Vertex midYVert = v2.Transform(screenSpaceTransform).PerspectiveDivide();
Vertex maxYVert = v3.Transform(screenSpaceTransform).PerspectiveDivide();
if(maxYVert.GetY() < midYVert.GetY()){
Vertex temp = maxYVert;
maxYVert = midYVert;
midYVert = temp;
}
if(midYVert.GetY() < minYVert.GetY()){
Vertex temp = midYVert;
midYVert = minYVert;
minYVert = temp;
}
if(maxYVert.GetY() < midYVert.GetY()){
Vertex temp = maxYVert;
maxYVert = midYVert;
midYVert = temp;
}
float area = minYVert.TriangleAreaTimesTwo(maxYVert , midYVert);
int handedness = area >=0 ? 1 : 0;
ScanConvertTriangle(minYVert, midYVert, maxYVert, handedness);
FillShape((int)minYVert.GetY(),(int)maxYVert.GetY());
}
public void ScanConvertTriangle(Vertex minYVert, Vertex midYVert,
Vertex maxYVert, int handedness){
ScanConvertLine(minYVert, maxYVert, 0 + handedness);
ScanConvertLine(minYVert, midYVert, 1 - handedness);
ScanConvertLine(midYVert, maxYVert, 1 - handedness);
}
private void ScanConvertLine(Vertex minYVert, Vertex maxYVert, int whichSide){
int yStart = (int)minYVert.GetY();
int yEnd = (int)maxYVert.GetY();
int xStart = (int)minYVert.GetX();
int xEnd = (int)maxYVert.GetX();
int yDist = yEnd - yStart;
int xDist = xEnd - xStart;
if(yDist <= 0)
return;
float xStep = ((float)xDist)/((float)yDist);
float curX = (float)Math.max(0,xStart);
for(int j = Math.max(0,yStart); j < Math.min(yEnd,m_height); j++){
m_scanBuffer[j * 2 + whichSide] = (int)curX;
curX += xStep;
if(curX>=m_width){
break;
}
}
}
}