/// <inheritdoc /> public override void VisitSpan(Span span) { if (span.Kind == SpanKind.MetaCode) { VisitMetaCodeSpan(span); } else { ISpanRenderer renderer = null; if (_spanRenderers.TryGetValue(span.Kind, out renderer)) { renderer.Render(span, Scope, _textWriter); } } }
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.ToVector(); var vertexBColor = vertexB.Color.ToVector(); var vertexCColor = vertexC.Color.ToVector(); interpolator.SetPoint(4, vertexAColor.Red, vertexCColor.Red); interpolator.SetPoint(5, vertexAColor.Red, vertexBColor.Red, vertexBColor.Red, vertexCColor.Red, secondaryStartY); interpolator.SetPoint(6, vertexAColor.Green, vertexCColor.Green); interpolator.SetPoint(7, vertexAColor.Green, vertexBColor.Green, vertexBColor.Green, vertexCColor.Green, secondaryStartY); interpolator.SetPoint(8, vertexAColor.Blue, vertexCColor.Blue); interpolator.SetPoint(9, vertexAColor.Blue, vertexBColor.Blue, vertexBColor.Blue, vertexCColor.Blue, secondaryStartY); interpolator.SetPoint(10, vertexAColor.Alpha, vertexCColor.Alpha); interpolator.SetPoint(11, vertexAColor.Alpha, vertexBColor.Alpha, vertexBColor.Alpha, vertexCColor.Alpha, 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.Red = interpolator.Points[4 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Red = interpolator.Points[5 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Green = interpolator.Points[6 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Green = interpolator.Points[7 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Blue = interpolator.Points[8 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Blue = interpolator.Points[9 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Alpha = interpolator.Points[10 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Alpha = interpolator.Points[11 - swapIndex].InterpolatedValues[index]; renderer.Gouraud(buffers, actualSpan); } } break; } } yPosition++; } }
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++; } }