void ProcessScanLine(DetailsForShading details) { var gradient1 = details.pa.Y != details.pb.Y ? (details.currentY - details.pa.Y) / (details.pb.Y - details.pa.Y) : 1; var gradient2 = details.pc.Y != details.pd.Y ? (details.currentY - details.pc.Y) / (details.pd.Y - details.pc.Y) : 1; int sx = (int)Interpolate(details.pa.X, details.pb.X, gradient1); int ex = (int)Interpolate(details.pc.X, details.pd.X, gradient2); // starting Z & ending Z float z1 = Interpolate(details.pa.Z, details.pb.Z, gradient1); float z2 = Interpolate(details.pc.Z, details.pd.Z, gradient2); // drawing a line from left (sx) to right (ex) for (var x = sx; x < ex; x++) { float gradient = (x - sx) / (float)(ex - sx); var z = Interpolate(z1, z2, gradient); Vertex current = new Vertex(); current.Coordinates = new Vector3(x, details.currentY, z); Color color = shadingMachine.GetColorPerPixel(current, details); DrawPoint(current.Coordinates, color); } }
public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3) { DetailsForShading details = new DetailsForShading(); details.v1 = v1; details.v2 = v2; details.v3 = v3; details.area = CalculateArea(v1.Coordinates, v2.Coordinates, v3.Coordinates); details.lightParameters = meshLightParameters; return(details); }
public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details) { (double alpha, double beta, double gamma) = CalculateAlphaBetaGammaForVertex(vertex.Coordinates, details); float r = (float)(alpha * details.v1Color.R / 255 + beta * details.v2Color.R / 255 + gamma * details.v3Color.R / 255); float g = (float)(alpha * details.v1Color.G / 255 + beta * details.v2Color.G / 255 + gamma * details.v3Color.G / 255); float b = (float)(alpha * details.v1Color.B / 255 + beta * details.v2Color.B / 255 + gamma * details.v3Color.B / 255); int R = (int)(r * 255); int G = (int)(g * 255); int B = (int)(b * 255); (R, G, B) = ValidateRGB(R, G, B); return(Color.FromArgb(R, G, B)); }
public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3) { DetailsForShading details = new DetailsForShading(); details.v1Color = ComputeColorPerVertex(v1); details.v2Color = ComputeColorPerVertex(v2); details.v3Color = ComputeColorPerVertex(v3); details.v1 = v1; details.v2 = v2; details.v3 = v3; details.area = CalculateArea(v1.Coordinates, v2.Coordinates, v3.Coordinates); return(details); }
public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details) { (double alpha, double beta, double gamma) = CalculateAlphaBetaGammaForVertex(vertex.Coordinates, details); Vector3 normal = (float)alpha * details.v1.Normal + (float)beta * details.v2.Normal + (float)gamma * details.v3.Normal; normal.Normalize(); Vector3 wcoordinates = (float)alpha * details.v1.WorldCoordinates + (float)beta * details.v2.WorldCoordinates + (float)gamma * details.v3.WorldCoordinates; vertex.Normal = normal; vertex.WorldCoordinates = wcoordinates; Color color = ComputeColorPerVertex(vertex); return(color); }
public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3) { Vector3 vNormal = (v1.Normal + v2.Normal + v3.Normal) / 3; Vector3 vCenterPoint = (v1.WorldCoordinates + v2.WorldCoordinates + v3.WorldCoordinates) / 3; Vertex v = new Vertex(); v.Normal = vNormal; v.WorldCoordinates = vCenterPoint; DetailsForShading details = new DetailsForShading(); details.globalColor = ComputeColorPerVertex(v); return(details); }
public void DrawTriangle(Vertex v1, Vertex v2, Vertex v3, MeshLightParameters lightParameters) { // Sorting the points in order to always have this order on screen p1, p2 & p3 // with p1 always up (thus having the Y the lowest possible to be near the top screen) // then p2 between p1 & p3 if (v1.Coordinates.Y > v2.Coordinates.Y) { var temp = v2; v2 = v1; v1 = temp; } if (v2.Coordinates.Y > v3.Coordinates.Y) { var temp = v2; v2 = v3; v3 = temp; } if (v1.Coordinates.Y > v2.Coordinates.Y) { var temp = v2; v2 = v1; v1 = temp; } Vector3 p1 = v1.Coordinates; Vector3 p2 = v2.Coordinates; Vector3 p3 = v3.Coordinates; DetailsForShading details = shadingMachine.GetDetailsForShading(v1, v2, v3); // computing lines' directions float dP1P2, dP1P3; // http://en.wikipedia.org/wiki/Slope // Computing slopes if (p2.Y - p1.Y > 0) { dP1P2 = (p2.X - p1.X) / (p2.Y - p1.Y); } else { dP1P2 = 0; } if (p3.Y - p1.Y > 0) { dP1P3 = (p3.X - p1.X) / (p3.Y - p1.Y); } else { dP1P3 = 0; } // First case where triangles are like that: // P1 // - // -- // - - // - - // - - P2 // - - // - - // - // P3 if (dP1P2 > dP1P3) { for (var y = (int)p1.Y; y <= (int)p3.Y; y++) { //data.currentY = y; details.currentY = y; if (y < p2.Y) { details.pa = v1.Coordinates; details.pb = v3.Coordinates; details.pc = v1.Coordinates; details.pd = v2.Coordinates; //ProcessScanLine(data, v1, v3, v1, v2, details.globalColor); ProcessScanLine(details); } else { details.pa = v1.Coordinates; details.pb = v3.Coordinates; details.pc = v2.Coordinates; details.pd = v3.Coordinates; // ProcessScanLine(data, v1, v3, v2, v3, details.globalColor); ProcessScanLine(details); } } } // First case where triangles are like that: // P1 // - // -- // - - // - - // P2 - - // - - // - - // - // P3 else { for (var y = (int)p1.Y; y <= (int)p3.Y; y++) { //data.currentY = y; details.currentY = y; if (y < p2.Y) { details.pa = v1.Coordinates; details.pb = v2.Coordinates; details.pc = v1.Coordinates; details.pd = v3.Coordinates; //ProcessScanLine(data, v1, v2, v1, v3, details.globalColor); ProcessScanLine(details); } else { details.pa = v2.Coordinates; details.pb = v3.Coordinates; details.pc = v1.Coordinates; details.pd = v3.Coordinates; // ProcessScanLine(data, v2, v3, v1, v3, details.globalColor); ProcessScanLine(details); } } } }
public abstract Color GetColorPerPixel(Vertex vertex, DetailsForShading details);
public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details) { return(details.globalColor); }
protected (double alpha, double beta, double gamma) CalculateAlphaBetaGammaForVertex(Vector3 v, DetailsForShading details) { double a, b, g; double areaA, areaB, areaG; areaA = CalculateArea(v, details.v2.Coordinates, details.v3.Coordinates); areaB = CalculateArea(v, details.v1.Coordinates, details.v3.Coordinates); areaG = CalculateArea(v, details.v1.Coordinates, details.v2.Coordinates); a = areaA / details.area; b = areaB / details.area; g = areaG / details.area; return(a, b, g); }