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 static System.Drawing.Color SystemColor(Color a) { a.r = NewMath.Round(a.r, 0, 1); a.g = NewMath.Round(a.g, 0, 1); a.b = NewMath.Round(a.b, 0, 1); float _r = a.r * 255f; float _g = a.g * 255f; float _b = a.b * 255f; return(System.Drawing.Color.FromArgb((int)_r, (int)_g, (int)_b)); }
//光照相关 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 Color(System.Drawing.Color a) { this.r = NewMath.Round((float)a.R / 255f, 0, 1); this.g = NewMath.Round((float)a.G / 255f, 0, 1); this.b = NewMath.Round((float)a.B / 255f, 0, 1); }
//扫描填色 public void DrawScanline(Vectex v1, Vectex v2, int yIndex) { float x1 = v1.pos.x; float x2 = v2.pos.x; float dx = v2.pos.x - v1.pos.x; float x = x1; //扫描密度,可以减小 float stepx = 0.5f; int xIndex = (int)(x + 0.5f); for (; x <= x2 && xIndex <= x2; x += stepx) { //插值当前点 Vectex p; float t = (x - x1) / dx; p = NewMath.Interp(v1, v2, t); //画点坐标 xIndex = (int)(x + 0.5f); if (xIndex >= device.width || xIndex <= 0 || yIndex <= 0 || yIndex >= device.height) { return; } if (p.rhw >= device.zBuffer[xIndex, yIndex]) { device.zBuffer[xIndex, yIndex] = p.rhw; float w = 1 / p.rhw; if (device.lightMode == LightMode.ON) { Color lighlingColor = new Color(1, 1, 1); lighlingColor = w * p.lightcolor; if (device.renderState == RenderState.COLOR) { Color vertColor = new Color(1, 1, 1); vertColor = w * p.color; Color newColor = NewMath.Round(0.7f * vertColor + 0.3f * lighlingColor, 0, 1); device.frameBuffer.SetPixel(xIndex, yIndex, Color.SystemColor(newColor)); } if (device.renderState == RenderState.TEXTURE) { int uIndex; int vIndex; //目前只有点插值 int u = (int)(p.uvs.u * w * device.texWidth + 0.5f); int v = (int)(p.uvs.v * w * device.texHeight + 0.5f); uIndex = (int)NewMath.Round(u, 0, device.texWidth - 1); vIndex = (int)NewMath.Round(v, 0, device.texHeight - 1); //获取颜色 Color texColor = new Color(1, 1, 1); texColor = new Color(device.textureBuffer.GetPixel(uIndex, vIndex)); Color newColor = NewMath.Round(0.7f * texColor + 0.3f * lighlingColor, 0, 1); //画像素点 device.frameBuffer.SetPixel(xIndex, yIndex, Color.SystemColor(newColor)); } } else { if (device.renderState == RenderState.COLOR) { //用顶点颜色插值 Color vertColor = new Color(1, 1, 1); vertColor = w * p.color; device.frameBuffer.SetPixel(xIndex, yIndex, Color.SystemColor(vertColor)); } if (device.renderState == RenderState.TEXTURE) { int uIndex; int vIndex; //目前只有点插值 int u = (int)(p.uvs.u * w * device.texWidth + 0.5f); int v = (int)(p.uvs.v * w * device.texHeight + 0.5f); uIndex = (int)NewMath.Round(u, 0, device.texWidth - 1); vIndex = (int)NewMath.Round(v, 0, device.texHeight - 1); //获取颜色 Color texColor = new Color(1, 1, 1); texColor = new Color(device.textureBuffer.GetPixel(uIndex, vIndex)); //画像素点 device.frameBuffer.SetPixel(xIndex, yIndex, Color.SystemColor(texColor)); } } } } }