private void HorizontalEdgeTriangle(Vector2 apex, float leftBottomX, float rightBottomX, float bottomY, bool skipBottomEdge = false, bool interpolate = true) { if (skipBottomEdge && MathF.Abs(apex.Y - bottomY) < 1f) { return; } bool isUpward = apex.Y > bottomY; float invHeight = 1f / (isUpward ? apex.Y - bottomY : apex.Y - bottomY); float leftInvSlope = (apex.X - leftBottomX) * invHeight; float rightInvSlope = (apex.X - rightBottomX) * invHeight; Vector2Int result = Vector2Int.Zero; int endX, endY; if (isUpward) { endY = skipBottomEdge ? (int)bottomY + 1 : (int)bottomY; result.Y = (int)apex.Y; leftBottomX = rightBottomX = apex.X; } else { endY = (int)apex.Y; if (skipBottomEdge) { result.Y = (int)bottomY - 1; leftBottomX -= leftInvSlope; rightBottomX -= rightInvSlope; } else { result.Y = (int)bottomY; } } for (; result.Y >= endY; result.Y--) { endX = (int)rightBottomX; for (result.X = (int)leftBottomX; result.X <= endX; result.X++) { if (interpolate) { RasterizerEntry.OutputRasterization(result, TriangleInterpolator_Horizontal.InterpolatedValues); TriangleInterpolator_Horizontal.IncrementStep(); } else { RasterizerEntry.OutputRasterization(result); } } leftBottomX -= leftInvSlope; rightBottomX -= rightInvSlope; if (interpolate) { TriangleInterpolator_Vertical.IncrementStep(); } } }
public void Rasterize(LinePrimitive *linePtr) { Vector2 *verticesPtr = linePtr->CoordsPtr; float ** verticesDataPtr = linePtr->VerticesDataPtr; int verticesDataCount = linePtr->VerticesDataCount; Vector2 from = verticesPtr[0] * Resolution, to = verticesPtr[1] * Resolution; float xSub = to.X - from.X, ySub = to.Y - from.Y; //0: X-major 1:Y-major int dir; int dirStep, otherDirStep; float slopeAbs; if (Math.Abs(xSub) >= Math.Abs(ySub)) { dir = 0; } else { dir = 1; float temp = xSub; xSub = ySub; ySub = temp; } dirStep = Math.Sign(xSub); otherDirStep = Math.Sign(ySub); slopeAbs = Math.Abs(ySub / xSub); bool ifInterpolate = verticesDataCount > 0; if (ifInterpolate) { LineInterpolator.SetInterpolation(verticesDataPtr[0], verticesDataPtr[1], verticesDataCount, Math.Abs(xSub)); } Vector2Int resultPoint = new Vector2Int(JMath.RoundToInt(from.X), JMath.RoundToInt(from.Y)); if (resultPoint.X == Resolution.X) { resultPoint.X--; } if (resultPoint.Y == Resolution.Y) { resultPoint.Y--; } //End coordinate in Int int end = JMath.RoundToInt(to[dir]); for (float otherDirFrac = slopeAbs; resultPoint[dir] != end; otherDirFrac += slopeAbs, resultPoint[dir] += dirStep) { if (ifInterpolate) { RasterizerEntry.OutputRasterization(resultPoint, LineInterpolator.InterpolatedValues); LineInterpolator.IncrementStep(); } else { RasterizerEntry.OutputRasterization(resultPoint, LineInterpolator.InterpolatedValues); } if (otherDirFrac >= 1f) { resultPoint[1 - dir] += otherDirStep; otherDirFrac--; } } }