private static Interpolator GetInterpolatorForFace(Face face, TriangleShade shade) { var useTexture = false; if( null != face.Material && null != face.Material.DiffuseMap) { useTexture = true; } switch (shade) { case TriangleShade.Flat: { if( useTexture ) { return TextureInterpolator; } return FlatInterpolator; } break; case TriangleShade.Gouraud: { if (useTexture) { return TextureInterpolator; } return GouraudInterpolator; } break; } return null; }
public void SetFace(int index, Face face) { var v1 = Vertices[face.B].Vector - Vertices[face.A].Vector; var v2 = Vertices[face.C].Vector - Vertices[face.A].Vector; var cross = v1.Cross(v2); cross.Normalize(); face.Normal = cross; var v = Vertices[face.A].Vector + Vertices[face.B].Vector + Vertices[face.C].Vector; face.Position = v / 3; Faces[index] = face; }
internal BoxSideDescriptor(Face face1, Face face2) : this() { Face1 = face1; Face2 = face2; }
public override void Draw(Face face, Vertex[] vertices) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; vertexA.TextureCoordinate = face.DiffuseTextureCoordinateA; vertexB.TextureCoordinate = face.DiffuseTextureCoordinateB; vertexC.TextureCoordinate = face.DiffuseTextureCoordinateC; Image image = null; if (null != face.Material.DiffuseMap) { image = face.Material.DiffuseMap; } else if (null != face.Material.ReflectionMap) { image = face.Material.ReflectionMap; SetSphericalEnvironmentMapTextureCoordinate(ref vertexA, ref vertexA.TextureCoordinate); SetSphericalEnvironmentMapTextureCoordinate(ref vertexB, ref vertexB.TextureCoordinate); SetSphericalEnvironmentMapTextureCoordinate(ref vertexC, ref vertexC.TextureCoordinate); } if( null == image ) { return; } var imageContext = image.ImageContext as ImageContext; GetSortedPoints(ref vertexA, ref vertexB, ref vertexC); var xa = vertexA.TranslatedScreenCoordinates.X; var ya = vertexA.TranslatedScreenCoordinates.Y; var za = vertexA.DepthBufferAdjustedZ; var ua = vertexA.TextureCoordinate.U * image.Width; var va = vertexA.TextureCoordinate.V * image.Height; var xb = vertexB.TranslatedScreenCoordinates.X; var yb = vertexB.TranslatedScreenCoordinates.Y; var zb = vertexB.DepthBufferAdjustedZ; var ub = vertexB.TextureCoordinate.U * image.Width; var vb = vertexB.TextureCoordinate.V * image.Height; var xc = vertexC.TranslatedScreenCoordinates.X; var yc = vertexC.TranslatedScreenCoordinates.Y; var zc = vertexC.DepthBufferAdjustedZ; var uc = vertexC.TextureCoordinate.U * image.Width; var vc = vertexC.TextureCoordinate.V * image.Height; var deltaX1 = xb - xa; var deltaX2 = xc - xb; var deltaX3 = xc - xa; var deltaY1 = yb - ya; var deltaY2 = yc - yb; var deltaY3 = yc - ya; var deltaZ1 = zb - za; var deltaZ2 = zc - zb; var deltaZ3 = zc - za; var deltaU1 = ub - ua; var deltaU2 = uc - ub; var deltaU3 = uc - ua; var deltaV1 = vb - va; var deltaV2 = vc - vb; var deltaV3 = vc - va; var x1 = xa; var x2 = xa; var z1 = za; var z2 = za; var u1 = ua; var u2 = ua; var v1 = va; var v2 = va; var xInterpolate1 = deltaX3 / deltaY3; var xInterpolate2 = deltaX1 / deltaY1; var xInterpolate3 = deltaX2 / deltaY2; var zInterpolate1 = deltaZ3 / deltaY3; var zInterpolate2 = deltaZ1 / deltaY1; var zInterpolate3 = deltaZ2 / deltaY2; var uInterpolate1 = deltaU3 / deltaY3; var uInterpolate2 = deltaU1 / deltaY1; var uInterpolate3 = deltaU2 / deltaY2; var vInterpolate1 = deltaV3 / deltaY3; var vInterpolate2 = deltaV1 / deltaY1; var vInterpolate3 = deltaV2 / deltaY2; var framebuffer = BufferContainer.Framebuffer; var depthBuffer = BufferContainer.DepthBuffer; var frameBufferWidth = BufferContainer.Width; var frameBufferHeight = BufferContainer.Height; var yStart = (int)ya; var yEnd = (int)yc; var yClipTop = 0; if (yStart < 0) { yClipTop = -yStart; yStart = 0; } if (yEnd >= frameBufferHeight) { yEnd = frameBufferHeight - 1; } var height = yEnd - yStart; if (height == 0) { return; } if (yClipTop > 0) { var yClipTopAsFloat = (float)yClipTop; x1 = xa + xInterpolate1 * yClipTopAsFloat; z1 = za + zInterpolate1 * yClipTopAsFloat; u1 = ua + uInterpolate1 * yClipTopAsFloat; v1 = va + vInterpolate1 * yClipTopAsFloat; if (yb < 0) { var ySecondClipTop = -yb; x2 = xb + (xInterpolate3 * ySecondClipTop); xInterpolate2 = xInterpolate3; z2 = zb + (zInterpolate3 * ySecondClipTop); zInterpolate2 = zInterpolate3; u2 = ub + (uInterpolate3 * ySecondClipTop); uInterpolate2 = uInterpolate3; v2 = vb + (vInterpolate3 * ySecondClipTop); vInterpolate2 = vInterpolate3; } else { x2 = xa + xInterpolate2 * yClipTopAsFloat; z2 = za + zInterpolate2 * yClipTopAsFloat; u2 = ua + uInterpolate2 * yClipTopAsFloat; v2 = va + vInterpolate2 * yClipTopAsFloat; } } var yoffset = BufferContainer.Width * yStart; var offset = 0; var length = 0; var originalLength = 0; var xStart = 0; var xEnd = 0; var zStart = 0f; var zEnd = 0f; var zAdd = 0f; var xClipStart = 0; var uStart = 0f; var uEnd = 0f; var uAdd = 0f; var vStart = 0f; var vEnd = 0f; var vAdd = 0f; for (var y = yStart; y <= yEnd; y++) { if (x2 < x1) { xStart = (int)x2; xEnd = (int)x1; zStart = z2; zEnd = z1; uStart = u2; uEnd = u1; vStart = v2; vEnd = v1; } else { offset = yoffset + (int)x1; xStart = (int)x1; xEnd = (int)x2; zStart = z1; zEnd = z2; uStart = u1; uEnd = u2; vStart = v1; vEnd = v2; } originalLength = xEnd - xStart; if (xStart < 0) { xClipStart = -xStart; xStart = 0; } if (xEnd >= frameBufferWidth) { xEnd = frameBufferWidth - 1; } length = xEnd - xStart; if (length != 0) { var xClipStartAsFloat = (float)xClipStart; var lengthAsFloat = (float)originalLength; zAdd = (zEnd - zStart) / lengthAsFloat; uAdd = (uEnd - uStart) / lengthAsFloat; vAdd = (vEnd - vStart) / lengthAsFloat; if (xClipStartAsFloat > 0) { zStart += (zAdd * xClipStartAsFloat); uStart += (uAdd * xClipStartAsFloat); vStart += (vAdd * xClipStartAsFloat); } offset = yoffset + xStart; DrawSpan(length, zStart, zAdd, uStart, uAdd, vStart, vAdd, depthBuffer, offset, framebuffer, image, imageContext); } if (y == (int)yb) { x2 = xb; xInterpolate2 = xInterpolate3; z2 = zb; zInterpolate2 = zInterpolate3; u2 = ub; uInterpolate2 = uInterpolate3; v2 = vb; vInterpolate2 = vInterpolate3; } x1 += xInterpolate1; x2 += xInterpolate2; z1 += zInterpolate1; z2 += zInterpolate2; u1 += uInterpolate1; u2 += uInterpolate2; v1 += vInterpolate1; v2 += vInterpolate2; yoffset += BufferContainer.Width; } }
private Face CreateFace(int a, int b, int c) { var face = new Face { A = a, B = b, C = c, DiffuseA = a, DiffuseB = b, DiffuseC = c }; return face; }
private void CalculateVertexColorsForFace(ref Face face, Viewport viewport, Node node) { if (null == face.Material || face.Material.Shade == MaterialShade.Gouraud) { if (!Vertices[face.A].IsColorCalculated) { CalculateColorForVertex(ref Vertices[face.A], viewport, node); } if (!Vertices[face.B].IsColorCalculated) { CalculateColorForVertex(ref Vertices[face.B], viewport, node); } if (!Vertices[face.C].IsColorCalculated) { CalculateColorForVertex(ref Vertices[face.C], viewport, node); } } }
public void AllocateFaces(int count) { Faces = new Face[count]; }
public static void Draw(IBuffers buffers, ISpanRenderer renderer, TriangleShade shade, Face face, Vertex[] vertices, TextureCoordinate[] textureCoordinates) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; var textureA = ZeroTextureCoordinate; var textureB = ZeroTextureCoordinate; var textureC = ZeroTextureCoordinate; Image image = null; ImageContext texture = null; var useTexture = false; if( null != face.Material && null != face.Material.DiffuseMap) { useTexture = true; image = face.Material.DiffuseMap; texture = face.Material.DiffuseMap.ImageContext as ImageContext; textureA = textureCoordinates[face.DiffuseA]; textureB = textureCoordinates[face.DiffuseB]; textureC = textureCoordinates[face.DiffuseC]; } /* SetSphericalEnvironmentMapTextureCoordinate(ref vertexA, ref textureA); SetSphericalEnvironmentMapTextureCoordinate(ref vertexB, ref textureB); SetSphericalEnvironmentMapTextureCoordinate(ref vertexC, ref textureC); */ GetSortedPoints(ref vertexA, ref vertexB, ref vertexC, ref textureA, ref textureB, ref textureC); var interpolator = GetInterpolatorForFace(face, shade); var secondaryStartY = (int)(vertexB.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y); var spreadCount = ((int)(vertexC.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y)) + 1; interpolator.SetPoint(0, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X); interpolator.SetPoint(1, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X, secondaryStartY); interpolator.SetPoint(2, vertexA.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ); interpolator.SetPoint(3, vertexA.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ, secondaryStartY); if (useTexture) { interpolator.SetPoint(4, textureA.U, textureC.U); interpolator.SetPoint(5, textureA.U, textureB.U, textureB.U, textureC.U, secondaryStartY); interpolator.SetPoint(6, textureA.V, textureC.V); interpolator.SetPoint(7, textureA.V, textureB.V, textureB.V, textureC.V, secondaryStartY); } var color = Color.FromArgb(0xff, 0xff, 0xff, 0xff); if (shade == TriangleShade.Gouraud && !useTexture) { var vertexAColor = vertexA.Color; var vertexBColor = vertexB.Color; var vertexCColor = vertexC.Color; interpolator.SetPoint(4, vertexAColor.RedAsFloat, vertexCColor.RedAsFloat); interpolator.SetPoint(5, vertexAColor.RedAsFloat, vertexBColor.RedAsFloat, vertexBColor.RedAsFloat, vertexCColor.RedAsFloat, secondaryStartY); interpolator.SetPoint(6, vertexAColor.GreenAsFloat, vertexCColor.GreenAsFloat); interpolator.SetPoint(7, vertexAColor.GreenAsFloat, vertexBColor.GreenAsFloat, vertexBColor.GreenAsFloat, vertexCColor.GreenAsFloat, secondaryStartY); interpolator.SetPoint(8, vertexAColor.BlueAsFloat, vertexCColor.BlueAsFloat); interpolator.SetPoint(9, vertexAColor.BlueAsFloat, vertexBColor.BlueAsFloat, vertexBColor.BlueAsFloat, vertexCColor.BlueAsFloat, secondaryStartY); interpolator.SetPoint(10, vertexAColor.AlphaAsFloat, vertexCColor.AlphaAsFloat); interpolator.SetPoint(11, vertexAColor.AlphaAsFloat, vertexBColor.AlphaAsFloat, vertexBColor.AlphaAsFloat, vertexCColor.AlphaAsFloat, secondaryStartY); } else { color = face.Color; } interpolator.Interpolate(spreadCount); var yPosition = vertexA.TranslatedScreenCoordinates.Y; var clip = false; if( null == buffers ) { return; } for (var index = 0; index < spreadCount; index++) { if( yPosition < 0 || yPosition >= buffers.Height ) { clip = true; } else { clip = false; } var span = GetSpan(index, interpolator, vertexA, useTexture); if (null != span && !clip ) { var actualSpan = (Span)span; var swapIndex = ((Span)span).Swap ? 1 : 0; actualSpan.ZStart = interpolator.Points[2 + swapIndex].InterpolatedValues[index]; actualSpan.ZEnd = interpolator.Points[3 - swapIndex].InterpolatedValues[index]; switch (shade) { case TriangleShade.Flat: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { renderer.Flat(buffers, actualSpan, color); } } break; case TriangleShade.Gouraud: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { actualSpan.ColorStart.RedAsFloat = interpolator.Points[4 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.RedAsFloat = interpolator.Points[5 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.GreenAsFloat = interpolator.Points[6 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.GreenAsFloat = interpolator.Points[7 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.BlueAsFloat = interpolator.Points[8 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.BlueAsFloat = interpolator.Points[9 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.AlphaAsFloat = interpolator.Points[10 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.AlphaAsFloat = interpolator.Points[11 - swapIndex].InterpolatedValues[index]; renderer.Gouraud(buffers, actualSpan); } } break; } } yPosition++; } }
public abstract void Draw(Face face, Vertex[] vertices);
public override void Draw(Face face, Vertex[] vertices) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; GetSortedPoints(ref vertexA, ref vertexB, ref vertexC); var xa = vertexA.TranslatedScreenCoordinates.X; var ya = vertexA.TranslatedScreenCoordinates.Y; var za = vertexA.DepthBufferAdjustedZ; var xb = vertexB.TranslatedScreenCoordinates.X; var yb = vertexB.TranslatedScreenCoordinates.Y; var zb = vertexB.DepthBufferAdjustedZ; var xc = vertexC.TranslatedScreenCoordinates.X; var yc = vertexC.TranslatedScreenCoordinates.Y; var zc = vertexC.DepthBufferAdjustedZ; var deltaX1 = xb - xa; var deltaX2 = xc - xb; var deltaX3 = xc - xa; var deltaY1 = yb - ya; var deltaY2 = yc - yb; var deltaY3 = yc - ya; var deltaZ1 = zb - za; var deltaZ2 = zc - zb; var deltaZ3 = zc - za; var x1 = xa; var x2 = xa; var z1 = za; var z2 = za; var xInterpolate1 = deltaX3 / deltaY3; var xInterpolate2 = deltaX1 / deltaY1; var xInterpolate3 = deltaX2 / deltaY2; var zInterpolate1 = deltaZ3 / deltaY3; var zInterpolate2 = deltaZ1 / deltaY1; var zInterpolate3 = deltaZ2 / deltaY2; var framebuffer = BufferContainer.Framebuffer; var depthBuffer = BufferContainer.DepthBuffer; var frameBufferWidth = BufferContainer.Width; var frameBufferHeight = BufferContainer.Height; var yStart = (int)ya; var yEnd = (int) yc; var yClipTop = 0; if( yStart < 0 ) { yClipTop = -yStart; yStart = 0; } if( yEnd >= frameBufferHeight ) { yEnd = frameBufferHeight-1; } var height = yEnd - yStart; if (height == 0) { return; } if( yClipTop > 0 ) { x1 = xa+xInterpolate1*(float) yClipTop; z1 = za+zInterpolate1*(float) yClipTop; if( yb < 0 ) { var ySecondClipTop = -yb; x2 = xb + (xInterpolate3*ySecondClipTop); xInterpolate2 = xInterpolate3; z2 = zb + (zInterpolate3 * ySecondClipTop); zInterpolate2 = zInterpolate3; } else { x2 = xa + xInterpolate2*(float) yClipTop; z2 = za + zInterpolate2*(float) yClipTop; } } var yoffset = BufferContainer.Width * yStart; var colorAsInt = (int) face.Color.ToUInt32(); var offset = 0; var length = 0; var originalLength = 0; var xStart = 0; var xEnd = 0; var zStart = 0f; var zEnd = 0f; var zAdd = 0f; var xClipStart = 0; for (var y = yStart; y <= yEnd; y++) { if (x2 < x1) { xStart = (int)x2; xEnd = (int)x1; zStart = z2; zEnd = z1; } else { xStart = (int)x1; xEnd = (int)x2; offset = yoffset + (int)x1; zStart = z1; zEnd = z2; } originalLength = xEnd - xStart; if( xStart < 0 ) { xClipStart = -xStart; xStart = 0; } if( xEnd >= frameBufferWidth ) { xEnd = frameBufferWidth - 1; } length = xEnd - xStart; if (length != 0) { zAdd = (zEnd - zStart) / (float)length; zStart += zAdd*(float) xClipStart; offset = yoffset + xStart; DrawSpan(length, zStart, zAdd, depthBuffer, offset, framebuffer, colorAsInt); } if (y == (int)yb) { x2 = xb; xInterpolate2 = xInterpolate3; z2 = zb; zInterpolate2 = zInterpolate3; } x1 += xInterpolate1; x2 += xInterpolate2; z1 += zInterpolate1; z2 += zInterpolate2; yoffset += BufferContainer.Width; } }
private int BuildFaces(int actualSegments, int actualStacks, int nextSegmentOffset, int faceSegments, int faceOffset, int additionalFaceSegments, bool isFull) { var faceIndex = 0; var faceCount = actualStacks * (actualSegments * 2); if (CapEnds) { faceCount += actualSegments * 2; } if (!isFull) { faceCount += actualStacks * 2; } GeometryContext.AllocateFaces(faceCount); Face face; for (var y = 0; y < actualStacks - 1; y++) { var vertexOffset = (y * actualSegments); var nextSegmentVertexOffset = (y + 1) * nextSegmentOffset; for (var x = 0; x < faceSegments; x++) { var actualX = x + faceOffset; var nextX = ((x + 1) % (actualSegments + additionalFaceSegments))+faceOffset; face = new Face(vertexOffset + actualX, vertexOffset + nextX, nextSegmentVertexOffset + actualX); face.DiffuseA = face.A; face.DiffuseB = face.B; face.DiffuseC = face.C; GeometryContext.SetFace(faceIndex, face); faceIndex++; face = new Face(nextSegmentVertexOffset + nextX, nextSegmentVertexOffset + actualX, vertexOffset + nextX); face.DiffuseA = face.A; face.DiffuseB = face.B; face.DiffuseC = face.C; GeometryContext.SetFace(faceIndex, face); faceIndex++; } } return faceIndex; }
private void BuildEnds(int actualSegments, int actualStacks, int nextSegmentOffset, int faceSegments, int faceOffset, int additionalFaceSegments, int faceIndex) { var vertexOffset = 0; Face face; for (var x = 0; x < faceSegments; x++) { var actualX = x + faceOffset; var nextX = ((x + 1) % (actualSegments + additionalFaceSegments)) + faceOffset; face = new Face(vertexOffset, vertexOffset + nextX, vertexOffset + actualX); face.DiffuseA = face.A; face.DiffuseB = face.B; face.DiffuseC = face.C; GeometryContext.SetFace(faceIndex, face); faceIndex++; } vertexOffset = (actualStacks - 1) * nextSegmentOffset; for (var x = 0; x < faceSegments; x++) { var actualX = x + faceOffset; var nextX = ((x + 1) % (actualSegments + additionalFaceSegments)) + faceOffset; face = new Face(vertexOffset + actualX, vertexOffset + nextX, vertexOffset); face.DiffuseA = face.A; face.DiffuseB = face.B; face.DiffuseC = face.C; GeometryContext.SetFace(faceIndex, face); faceIndex++; } }
protected override void Prepare() { var radius = (float)Radius; var segments = Segments; var segmentRadius = System.Math.PI / 2 / (segments + 1); var ySegments = (int)segments * 2; var xSegments = 4 * segments + 4; int ySegment = 0; var vertexCount = (int)(xSegments) * (int)ySegments; GeometryContext.AllocateVertices(vertexCount); Vertex vertex; var vertexIndex = 0; var currentYSegment = -segments; for (ySegment = -segments; ySegment < segments; ySegment++) { var r = radius * System.Math.Cos(segmentRadius * ySegment); var y = radius * System.Math.Sin(segmentRadius * ySegment); for (var xSegment = 0; xSegment < xSegments - 1; xSegment++) { var z = r * System.Math.Sin(segmentRadius * xSegment) * (-1); var x = r * System.Math.Cos(segmentRadius * xSegment); vertex = new Vertex((float)x, (float)y, (float)z); GeometryContext.SetVertex(vertexIndex, vertex); vertexIndex++; } } vertex = new Vertex(0, radius, 0); GeometryContext.SetVertex(vertexIndex++, vertex); vertex = new Vertex(0, -1 * radius, 0); GeometryContext.SetVertex(vertexIndex, vertex); var faceCount = ((ySegments * segments) * 2); GeometryContext.AllocateFaces(faceCount); var faceIndex = 0; for (ySegment = 0; ySegment < ySegments; ySegment++) { for (var xSegment = 0; xSegment < segments; xSegment++) { var index = ySegment * segments + xSegment; var face = new Face( index, index + segments, index + 1 % segments + segments); GeometryContext.SetFace(faceIndex, face); faceIndex++; face = new Face( index + 1 % segments + segments, index + 1 % segments, index); GeometryContext.SetFace(faceIndex, face); faceIndex++; } } /* for (var xSegment = 0; xSegment < segments; xSegment++) { var index = ySegment * segments + xSegment; var face = new Face( index, index + 1 % segments + segments, segments * (2 * xSegment + 1)); GeometryContext.SetFace(faceIndex, face); } for (var xSegment = 0; xSegment < segments; xSegment++) { var face = new Face( ySegment, ySegment + 1 % segments, segments * (2 * xSegment + 1)+1); GeometryContext.SetFace(faceIndex, face); }*/ GeometryHelper.CalculateVertexNormals(GeometryContext); base.Prepare(); }
public void SetFace(int index, Face face) { Faces[index] = face; }
public override void Draw(Face face, Vertex[] vertices) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; GetSortedPoints(ref vertexA, ref vertexB, ref vertexC); var xa = vertexA.TranslatedScreenCoordinates.X; var ya = vertexA.TranslatedScreenCoordinates.Y; var za = vertexA.DepthBufferAdjustedZ; var ra = vertexA.CalculatedColor.RedAsFloat; var ga = vertexA.CalculatedColor.GreenAsFloat; var ba = vertexA.CalculatedColor.BlueAsFloat; var aa = vertexA.CalculatedColor.AlphaAsFloat; var xb = vertexB.TranslatedScreenCoordinates.X; var yb = vertexB.TranslatedScreenCoordinates.Y; var zb = vertexB.DepthBufferAdjustedZ; var rb = vertexB.CalculatedColor.RedAsFloat; var gb = vertexB.CalculatedColor.GreenAsFloat; var bb = vertexB.CalculatedColor.BlueAsFloat; var ab = vertexB.CalculatedColor.AlphaAsFloat; var xc = vertexC.TranslatedScreenCoordinates.X; var yc = vertexC.TranslatedScreenCoordinates.Y; var zc = vertexC.DepthBufferAdjustedZ; var rc = vertexC.CalculatedColor.RedAsFloat; var gc = vertexC.CalculatedColor.GreenAsFloat; var bc = vertexC.CalculatedColor.BlueAsFloat; var ac = vertexC.CalculatedColor.AlphaAsFloat; var deltaX1 = xb - xa; var deltaX2 = xc - xb; var deltaX3 = xc - xa; var deltaY1 = yb - ya; var deltaY2 = yc - yb; var deltaY3 = yc - ya; var deltaZ1 = zb - za; var deltaZ2 = zc - zb; var deltaZ3 = zc - za; var deltaR1 = rb - ra; var deltaR2 = rc - rb; var deltaR3 = rc - ra; var deltaG1 = gb - ga; var deltaG2 = gc - gb; var deltaG3 = gc - ga; var deltaB1 = bb - ba; var deltaB2 = bc - bb; var deltaB3 = bc - ba; var deltaA1 = ab - aa; var deltaA2 = ac - ab; var deltaA3 = ac - aa; var x1 = xa; var x2 = xa; var z1 = za; var z2 = za; var r1 = ra; var r2 = ra; var g1 = ga; var g2 = ga; var b1 = ba; var b2 = ba; var a1 = aa; var a2 = aa; var xInterpolate1 = deltaX3 / deltaY3; var xInterpolate2 = deltaX1 / deltaY1; var xInterpolate3 = deltaX2 / deltaY2; var zInterpolate1 = deltaZ3 / deltaY3; var zInterpolate2 = deltaZ1 / deltaY1; var zInterpolate3 = deltaZ2 / deltaY2; var rInterpolate1 = deltaR3 / deltaY3; var rInterpolate2 = deltaR1 / deltaY1; var rInterpolate3 = deltaR2 / deltaY2; var gInterpolate1 = deltaG3 / deltaY3; var gInterpolate2 = deltaG1 / deltaY1; var gInterpolate3 = deltaG2 / deltaY2; var bInterpolate1 = deltaB3 / deltaY3; var bInterpolate2 = deltaB1 / deltaY1; var bInterpolate3 = deltaB2 / deltaY2; var aInterpolate1 = deltaA3 / deltaY3; var aInterpolate2 = deltaA1 / deltaY1; var aInterpolate3 = deltaA2 / deltaY2; var framebuffer = BufferContainer.Framebuffer; var depthBuffer = BufferContainer.DepthBuffer; var frameBufferWidth = BufferContainer.Width; var frameBufferHeight = BufferContainer.Height; var yStart = (int)ya; var yEnd = (int)yc; var yClipTop = 0; if (yStart < 0) { yClipTop = -yStart; yStart = 0; } if (yEnd >= frameBufferHeight) { yEnd = frameBufferHeight - 1; } var height = yEnd - yStart; if (height == 0) { return; } if (yClipTop > 0) { var yClipTopAsFloat = (float)yClipTop; x1 = xa + xInterpolate1 * yClipTopAsFloat; z1 = za + zInterpolate1 * yClipTopAsFloat; r1 = ra + rInterpolate1 * yClipTopAsFloat; g1 = ga + gInterpolate1 * yClipTopAsFloat; b1 = ba + bInterpolate1 * yClipTopAsFloat; a1 = aa + aInterpolate1 * yClipTopAsFloat; if (yb < 0) { var ySecondClipTop = -yb; x2 = xb + (xInterpolate3 * ySecondClipTop); xInterpolate2 = xInterpolate3; z2 = zb + (zInterpolate3 * ySecondClipTop); zInterpolate2 = zInterpolate3; r2 = rb + (rInterpolate3 * ySecondClipTop); rInterpolate2 = rInterpolate3; g2 = gb + (gInterpolate3 * ySecondClipTop); gInterpolate2 = gInterpolate3; b2 = bb + (bInterpolate3 * ySecondClipTop); bInterpolate2 = bInterpolate3; a2 = ab + (aInterpolate3 * ySecondClipTop); aInterpolate2 = aInterpolate3; } else { x2 = xa + xInterpolate2 * yClipTopAsFloat; z2 = za + zInterpolate2 * yClipTopAsFloat; r2 = ra + rInterpolate2 * yClipTopAsFloat; g2 = ga + gInterpolate2 * yClipTopAsFloat; b2 = ba + bInterpolate2 * yClipTopAsFloat; a2 = aa + aInterpolate2 * yClipTopAsFloat; } } var yoffset = BufferContainer.Width * yStart; var offset = 0; var length = 0; var originalLength = 0; var xStart = 0; var xEnd = 0; var zStart = 0f; var zEnd = 0f; var zAdd = 0f; var xClipStart = 0; var rStart = 0f; var rEnd = 0f; var rAdd = 0f; var gStart = 0f; var gEnd = 0f; var gAdd = 0f; var bStart = 0f; var bEnd = 0f; var bAdd = 0f; var aStart = 0f; var aEnd = 0f; var aAdd = 0f; var rgbaStart = 0L; var rgbaAdd = 0L; for (var y = yStart; y <= yEnd; y++) { if (x2 < x1) { xStart = (int)x2; xEnd = (int)x1; zStart = z2; zEnd = z1; rStart = r2; rEnd = r1; gStart = g2; gEnd = g1; bStart = b2; bEnd = b1; aStart = a2; aEnd = a1; } else { offset = yoffset + (int)x1; xStart = (int)x1; xEnd = (int)x2; zStart = z1; zEnd = z2; rStart = r1; rEnd = r2; gStart = g1; gEnd = g2; bStart = b1; bEnd = b2; aStart = a1; aEnd = a2; } originalLength = xEnd - xStart; if (xStart < 0) { xClipStart = -xStart; xStart = 0; } if (xEnd >= frameBufferWidth) { xEnd = frameBufferWidth - 1; } length = xEnd - xStart; if (length != 0) { var xClipStartAsFloat = (float)xClipStart; var lengthAsFloat = (float)originalLength; zAdd = (zEnd - zStart) / lengthAsFloat; rAdd = (rEnd - rStart) / lengthAsFloat; gAdd = (gEnd - gStart) / lengthAsFloat; bAdd = (bEnd - bStart) / lengthAsFloat; aAdd = (aEnd - aStart) / lengthAsFloat; if (xClipStartAsFloat > 0) { zStart += (zAdd*xClipStartAsFloat); rStart += (rAdd*xClipStartAsFloat); gStart += (gAdd*xClipStartAsFloat); bStart += (bAdd*xClipStartAsFloat); aStart += (aAdd*xClipStartAsFloat); } var rStartInt = ((int)(rStart * 255f))<<8; var rAddInt = (int)(rAdd * 65535f); var gStartInt = ((int)(gStart * 255f))<<8; var gAddInt = (int)(gAdd * 65535f); var bStartInt = ((int)(bStart * 255f))<<8; var bAddInt = (int)(bAdd * 65535f); var aStartInt = ((int)(aStart * 255f))<<8; var aAddInt = (int)(aAdd * 65535f); offset = yoffset + xStart; DrawSpan( length, zStart, zAdd, rStartInt, rAddInt, gStartInt, gAddInt, bStartInt, bAddInt, aStartInt, aAddInt, depthBuffer, offset, framebuffer); } if (y == (int)yb) { x2 = xb; xInterpolate2 = xInterpolate3; z2 = zb; zInterpolate2 = zInterpolate3; r2 = rb; rInterpolate2 = rInterpolate3; g2 = gb; gInterpolate2 = gInterpolate3; b2 = bb; bInterpolate2 = bInterpolate3; a2 = ab; aInterpolate2 = aInterpolate3; } x1 += xInterpolate1; x2 += xInterpolate2; z1 += zInterpolate1; z2 += zInterpolate2; r1 += rInterpolate1; r2 += rInterpolate2; g1 += gInterpolate1; g2 += gInterpolate2; b1 += bInterpolate1; b2 += bInterpolate2; a1 += aInterpolate1; a2 += aInterpolate2; yoffset += BufferContainer.Width; } }