Example #1
0
        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);
        }
Example #2
0
		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;
		}
Example #3
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.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++;
            }
        }
Example #4
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++;
            }
        }