protected void GetSortedPoints( ref Vertex vertexA, ref Vertex vertexB, ref Vertex vertexC) { var point1 = vertexA; var point2 = vertexB; var point3 = vertexC; if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y) { var p = point1; point1 = point2; point2 = p; } if (point3.TranslatedScreenCoordinates.Y < point2.TranslatedScreenCoordinates.Y) { var p = point2; point2 = point3; point3 = p; } if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y) { var p = point1; point1 = point2; point2 = p; } vertexA = point1; vertexB = point2; vertexC = point3; }
protected override void Prepare() { var dimensionAsVector = (Vector)Dimension; var halfDimension = dimensionAsVector / 2f; var frontUpperRight = new Vertex(-halfDimension.X, halfDimension.Y, -halfDimension.Z); var frontUpperLeft = new Vertex(halfDimension.X, halfDimension.Y, -halfDimension.Z); var frontLowerRight = new Vertex(-halfDimension.X, -halfDimension.Y, -halfDimension.Z); var frontLowerLeft = new Vertex(halfDimension.X, -halfDimension.Y, -halfDimension.Z); var backUpperRight = new Vertex(-halfDimension.X, halfDimension.Y, halfDimension.Z); var backUpperLeft = new Vertex(halfDimension.X, halfDimension.Y, halfDimension.Z); var backLowerRight = new Vertex(-halfDimension.X, -halfDimension.Y, halfDimension.Z); var backLowerLeft = new Vertex(halfDimension.X, -halfDimension.Y, halfDimension.Z); GeometryContext.AllocateVertices(8); GeometryContext.SetVertex(0, frontUpperRight); GeometryContext.SetVertex(1, frontUpperLeft); GeometryContext.SetVertex(2, frontLowerRight); GeometryContext.SetVertex(3, frontLowerLeft); GeometryContext.SetVertex(4, backUpperRight); GeometryContext.SetVertex(5, backUpperLeft); GeometryContext.SetVertex(6, backLowerRight); GeometryContext.SetVertex(7, backLowerLeft); GeometryContext.AllocateTextureCoordinates(4); GeometryContext.SetTextureCoordinate(0, new TextureCoordinate(0f, 0f)); GeometryContext.SetTextureCoordinate(1, new TextureCoordinate(1f, 0f)); GeometryContext.SetTextureCoordinate(2, new TextureCoordinate(0f, 1f)); GeometryContext.SetTextureCoordinate(3, new TextureCoordinate(1f, 1f)); GeometryContext.AllocateFaces(12); GeometryContext.SetFace(0, new Face(2, 1, 0) { Normal = Vector.Backward, DiffuseA = 2, DiffuseB = 1, DiffuseC = 0}); GeometryContext.SetFace(1, new Face(1, 2, 3) { Normal = Vector.Backward, DiffuseA = 1, DiffuseB = 2, DiffuseC = 3}); GeometryContext.SetFace(2, new Face(4, 5, 6) { Normal = Vector.Forward, DiffuseA = 1, DiffuseB = 0, DiffuseC = 3 }); GeometryContext.SetFace(3, new Face(7, 6, 5) { Normal = Vector.Forward, DiffuseA = 2, DiffuseB = 3, DiffuseC = 0 }); GeometryContext.SetFace(4, new Face(0, 4, 2) { Normal = Vector.Left, DiffuseA = 1, DiffuseB = 0, DiffuseC = 3 }); GeometryContext.SetFace(5, new Face(6, 2, 4) { Normal = Vector.Left, DiffuseA = 2, DiffuseB = 3, DiffuseC = 0 }); GeometryContext.SetFace(6, new Face(3, 5, 1) { Normal = Vector.Right, DiffuseA = 2, DiffuseB = 1, DiffuseC = 0 }); GeometryContext.SetFace(7, new Face(5, 3, 7) { Normal = Vector.Right, DiffuseA = 1, DiffuseB = 2, DiffuseC = 3 }); GeometryContext.SetFace(8, new Face(0, 1, 4) { Normal = Vector.Up, DiffuseA = 2, DiffuseB = 3, DiffuseC = 0 }); GeometryContext.SetFace(9, new Face(5, 4, 1) { Normal = Vector.Up, DiffuseA = 1, DiffuseB = 0, DiffuseC = 3 }); GeometryContext.SetFace(10, new Face(6, 3, 2) { Normal = Vector.Down, DiffuseA = 2, DiffuseB = 1, DiffuseC = 0 }); GeometryContext.SetFace(11, new Face(3, 6, 7) { Normal = Vector.Down, DiffuseA = 1, DiffuseB = 2, DiffuseC = 3 }); GeometryHelper.CalculateVertexNormals(GeometryContext); }
private void InitializeVertices() { const float angle = MathHelper.TwoPi / NumberOfCirclePoints; GeometryContext.AllocateVertices(NumberOfCirclePoints); for (var vertexIndex = 0; vertexIndex < NumberOfCirclePoints; vertexIndex++) { var x = (float)System.Math.Round(System.Math.Sin(angle * vertexIndex), 4); var y = (float)System.Math.Round(System.Math.Cos(angle * vertexIndex), 4); var vertex = new Vertex(x, y, 0f); GeometryContext.SetVertex(vertexIndex, vertex); } }
private static void GetSortedPoints(ref Vertex vertexA, ref Vertex vertexB, ref Vertex vertexC, ref TextureCoordinate textureA, ref TextureCoordinate textureB, ref TextureCoordinate textureC) { var point1 = vertexA; var point2 = vertexB; var point3 = vertexC; if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y) { var p = point1; point1 = point2; point2 = p; var t = textureA; textureA = textureB; textureB = t; } if (point3.TranslatedScreenCoordinates.Y < point2.TranslatedScreenCoordinates.Y) { var p = point2; point2 = point3; point3 = p; var t = textureB; textureB = textureC; textureC = t; } if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y) { var p = point1; point1 = point2; point2 = p; var t = textureA; textureA = textureB; textureB = t; } vertexA = point1; vertexB = point2; vertexC = point3; }
private void PrepareVertices() { Vertex[] vertices = new Vertex[2 * Slices]; _geometry.GeometryContext.AllocateVertices(2 * Slices); for (int i = 0; i < Slices; i++) { float innerX = (float)(InnerRadius * System.Math.Sin(2 * i * System.Math.PI / Slices)); float innerY = (float)(InnerRadius * System.Math.Cos(2 * i * System.Math.PI / Slices)); _geometry.GeometryContext.SetVertex(i, new Vertex(innerX, innerY, 0)); float outerX = (float)(InnerRadius * System.Math.Sin(2 * i * System.Math.PI / Slices)); float outerY = (float)(InnerRadius * System.Math.Cos(2 * i * System.Math.PI / Slices)); _geometry.GeometryContext.SetVertex(i + Slices, new Vertex(innerX, innerY, 0)); } }
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++; } }
private void CalculateColorForVertex(ref Vertex vertex, Viewport viewport, Node node) { vertex.CalculatedColor = vertex.Color.Additive(_colorCalculator.Calculate(viewport, vertex.TransformedVector, vertex.TransformedNormal)); }
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 SetVertex(int index, Vertex vertex) { Vertices[index] = vertex; }
private static void TransformAndTranslateVertex(ref Vertex vertex, Viewport viewport, Matrix view, Matrix projection) { vertex.Transform(view); vertex.Translate(projection, viewport.Width, viewport.Height); vertex.MakeScreenCoordinates(); vertex.TransformedVectorNormalized = vertex.TransformedNormal; vertex.TransformedVectorNormalized.Normalize(); var z = ((vertex.TransformedVector.Z / viewport.View.DepthDivisor) + viewport.View.DepthZero); vertex.DepthBufferAdjustedZ = z; }
private void BuildVertices(int actualSegments, int actualStacks, double startRadian, double radianAdd, float currentY, double currentRadius, float currentV, float uAdd, double radiusAdd, float yAdd, float vAdd) { Vertex vertex; var vertexCount = (actualStacks * (actualSegments + 1)); var vertexIndex = 0; GeometryContext.AllocateVertices(vertexCount); GeometryContext.AllocateTextureCoordinates(vertexCount); for (var y = 0; y < actualStacks; y++) { var currentU = 0f; var currentRadian = startRadian; var centerTextureCoordinate = new TextureCoordinate(0.5f, 0.5f); vertex = new Vertex(0, currentY, 0); GeometryContext.SetVertex(vertexIndex, vertex); GeometryContext.SetTextureCoordinate(vertexIndex, centerTextureCoordinate); vertexIndex++; for (var x = 0; x < actualSegments; x++) { var currentX = (float)(System.Math.Sin(currentRadian) * currentRadius); var currentZ = (float)(System.Math.Cos(currentRadian) * currentRadius); vertex = new Vertex(currentX, currentY, currentZ); GeometryContext.SetVertex(vertexIndex, vertex); var textureCoordinate = new TextureCoordinate(1f - currentU, currentV); GeometryContext.SetTextureCoordinate(vertexIndex, textureCoordinate); vertexIndex++; currentRadian += radianAdd; currentU += uAdd; } currentRadius += radiusAdd; currentY -= yAdd; currentV += vAdd; } }
private void TransformAndTranslateVertex(ref Vertex vertex, Viewport viewport, Matrix view, Matrix projection, Matrix world) { var matrix = (world*view)*projection; vertex.Transform(world, matrix); vertex.Translate(projection, viewport.Width, viewport.Height); vertex.MakeScreenCoordinates(); vertex.TransformedVectorNormalized = vertex.TransformedNormal; vertex.TransformedVectorNormalized.Normalize(); var z = ((vertex.TransformedVector.Z/viewport.Camera.DepthDivisor) + viewport.Camera.DepthZero); vertex.DepthBufferAdjustedZ = z; }
private static void SetSphericalEnvironmentMapTextureCoordinate(ref Vertex vertex, ref TextureCoordinate textureCoordinate) { var u = vertex.TransformedVectorNormalized; var n = vertex.TransformedNormal; var r = Vector.Reflect(n, u); var m = MathHelper.Sqrt((r.X * r.X) + (r.Y * r.Y) + ((r.Z + 0f) * (r.Z + 0f))); var s = (r.X / m); var t = (r.Y / m); textureCoordinate.U = (s * 0.5f) + 0.5f; textureCoordinate.V = -(t * 0.5f) + 0.5f; }
private void BuildVertices(int actualSegments, int actualStacks, int vertexCount) { GeometryContext.AllocateVertices(vertexCount); GeometryContext.AllocateTextureCoordinates(vertexCount); var yStart = (float)Size / 2; var yEnd = (float)-Size / 2; var yDelta = yEnd - yStart; var yAdd = yDelta / actualStacks; var startRadian = MathHelper.ToRadians((float)StartAngle); var endRadian = MathHelper.ToRadians((float)EndAngle); var deltaRadian = endRadian - startRadian; var addRadian = deltaRadian / actualSegments; var uDelta = 1f; var vDelta = 2f; var uAdd = uDelta / actualSegments; var vAdd = vDelta / actualStacks; var vertexIndex = 0; var currentY = yStart; var currentV = 0f; for (var stack = 0; stack < actualStacks; stack++) { var currentU = 0f; var currentRadian = startRadian; for (var segment = 0; segment < actualSegments; segment++) { var innerX = (float)(System.Math.Sin(currentRadian) * InnerRadius); var innerZ = (float)(System.Math.Cos(currentRadian) * InnerRadius); var innerVertex = new Vertex(innerX, currentY, innerZ); GeometryContext.SetVertex(vertexIndex, innerVertex); var textureCoordinate = new TextureCoordinate(1f - currentU, 0); GeometryContext.SetTextureCoordinate(vertexIndex, textureCoordinate); vertexIndex++; var outerX = (float)(System.Math.Sin(currentRadian) * OuterRadius); var outerZ = (float)(System.Math.Cos(currentRadian) * OuterRadius); var outerVertex = new Vertex(outerX, currentY, outerZ); GeometryContext.SetVertex(vertexIndex, outerVertex); textureCoordinate = new TextureCoordinate(1f - currentU, 1); GeometryContext.SetTextureCoordinate(vertexIndex, textureCoordinate); vertexIndex++; currentRadian += addRadian; currentU += uAdd; } currentY += yAdd; currentV += vAdd; } }
private static Span? GetSpan(int interpolationIndex, Interpolator interpolator, Vertex vertexA, bool useTexture) { var y = ((int)vertexA.TranslatedScreenCoordinates.Y) + interpolationIndex; var xstart = interpolator.Points[0].InterpolatedValues[interpolationIndex]; var xend = interpolator.Points[1].InterpolatedValues[interpolationIndex]; var ustart = 0f; var vstart = 0f; var uend = 0f; var vend = 0f; if (useTexture) { ustart = interpolator.Points[4].InterpolatedValues[interpolationIndex]; uend = interpolator.Points[5].InterpolatedValues[interpolationIndex]; vstart = interpolator.Points[6].InterpolatedValues[interpolationIndex]; vend = interpolator.Points[7].InterpolatedValues[interpolationIndex]; } var swap = false; if (xstart > xend) { var temp = xstart; xstart = xend; xend = temp; swap = true; temp = ustart; ustart = uend; uend = temp; temp = vstart; vstart = vend; vend = temp; } xend += 0.5f; var length = xend - xstart; var absLength = (int)System.Math.Round((double)length + 0.5); if (absLength >= 1) { var span = new Span { Y = y, XStart = (int)xstart, XEnd = (int)xend, UStart = ustart, UEnd = uend, VStart = vstart, VEnd = vend, Length = absLength, Swap = swap }; return span; } return null; }
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; } }
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]; 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; } }
public void AllocateVertices(int count) { Vertices = new Vertex[count]; }
private void CalculateColorForVertex(ref Vertex vertex, Viewport viewport, RenderableNode node) { vertex.Color = viewport.Scene.CalculateColorForVector(viewport, vertex.TransformedVector, vertex.Normal, node.Color, node.Color, node.Color); }
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; } }