public void DrawTriangleBottom(Vectex v1, Vectex v2, Vectex v3) { //先确定好形状 if (v1.pos.x > v2.pos.x) { Vectex p; p = Vectex.Colone(v1); v1 = Vectex.Colone(v2); v2 = Vectex.Colone(p); } float y, dy, dy2, t; int yIndex, stepy; stepy = -1; dy = v1.pos.y - v3.pos.y; y = v1.pos.y; yIndex = (int)y; for (; yIndex > v3.pos.y; yIndex += stepy) { //求该y值处的左右顶点 dy2 = yIndex - v3.pos.y; t = dy2 / dy; Vectex left, right; left = NewMath.Interp(v3, v1, t); right = NewMath.Interp(v3, v2, t); DrawScanline(left, right, yIndex); } }
//光栅化开始 public void Rasterization(Vectex v1, Vectex v2, Vectex v3) { //保护? if (v1.pos.y == v2.pos.y && v1.pos.y == v3.pos.y) { return; } //交换v1,v2,v3使纵向1<2<3 if (v1.pos.y > v2.pos.y) { Vectex v = Vectex.Colone(v2); v2 = Vectex.Colone(v1); v1 = Vectex.Colone(v); } if (v1.pos.y > v3.pos.y) { Vectex v = Vectex.Colone(v3); v3 = Vectex.Colone(v1); v1 = Vectex.Colone(v); } if (v2.pos.y > v3.pos.y) { Vectex v = Vectex.Colone(v3); v3 = Vectex.Colone(v2); v2 = Vectex.Colone(v); } //初步分析 if (v1.pos.y == v2.pos.y) { DrawTriangleTop(v1, v2, v3); } else if (v2.pos.y == v3.pos.y) { DrawTriangleBottom(v2, v3, v1); } else//分割三角形 { //重点在于找到13边上的中间点 作为新顶点 Vectex newMiddle = new Vectex(); float x1 = v1.pos.x; float y1 = v1.pos.y; float dx = v3.pos.x - v1.pos.x; float dy = v3.pos.y - v1.pos.y; //确定纵坐标 float y = v2.pos.y; //进行插值 float dy2 = y - v1.pos.y; float t = dy2 / dy; newMiddle = NewMath.Interp(v1, v3, t); //来吧 DrawTriangleBottom(newMiddle, v2, v1); DrawTriangleTop(newMiddle, v2, v3); } }
//光照相关 public void SetLightingColor(Vectex v1) { //将顶点转换到世界空间中 Vectex v = Vectex.Colone(v1); //求世界空间中的法向量 Vector3 n = v.nomal * device.ts.world.Inverse().Transpose(); //光线向量 Vector3 l = device.light.lightPosition - v.pos; //公式 c=cr(ca+cl*n*l) float t = NewMath.Round(Vector3.Dot(n, l), 0, 1); Color c = device.light.diffuse * (device.light.ambient + device.light.sourse * t); c = NewMath.Round(c, 0, 1); v1.lightcolor = c; }
public void DrawTriangle(Vectex v1, Vectex v2, Vectex v3) { Vector3 p1, p2, p3, c1, c2, c3; //背面剔除 2 3 p1 = v1.pos * (device.ts.world * device.ts.view); p2 = v2.pos * (device.ts.world * device.ts.view); p3 = v3.pos * (device.ts.world * device.ts.view); if (device.renderState != RenderState.WIRE) { if (!CheckIsFront(p1, p2, p3)) { return; } } //设置顶点光照颜色 4 if (device.lightMode == LightMode.ON) { SetLightingColor(v1); SetLightingColor(v2); SetLightingColor(v3); } //坐标转换 123 p1 = v1.pos * device.ts.transform; p2 = v2.pos * device.ts.transform; p3 = v3.pos * device.ts.transform; //cvv裁剪 123 if (!p1.CheckCVV() || !p2.CheckCVV() || !p3.CheckCVV()) { return; } //归一化得到屏幕坐标 123 c1 = Vector3.Homogenize(device.ts, p1); c2 = Vector3.Homogenize(device.ts, p2); c3 = Vector3.Homogenize(device.ts, p3); //坐标转换完毕 c为屏幕坐标,顶点其他信息来自v //开始渲染 //初始化渲染顶点信息 123 Vectex d1, d2, d3; //顶点的color等信息来自v d1 = Vectex.Colone(v1); d2 = Vectex.Colone(v2); d3 = Vectex.Colone(v3); //顶点位置信息来自最终屏幕坐标c d1.pos = Vector3.Colone(c1); d2.pos = Vector3.Colone(c2); d3.pos = Vector3.Colone(c3); //顶点w信息来自未归一化的p,w代表原z值 d1.pos.w = p1.w; d2.pos.w = p2.w; d3.pos.w = p3.w; //初始化顶点的rhw数据并用此数据加工颜色,uv数据,为后续顶点颜色的深度插值作准备 d1.InitRhw(); d2.InitRhw(); d3.InitRhw(); //线框模式 1 if (device.renderState == RenderState.WIRE) { DrawLine(d1, d2); DrawLine(d1, d3); DrawLine(d3, d2); } else { //color2 Rasterization(d1, d2, d3); } }