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
		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;
		}
Example #3
0
			internal BoxSideDescriptor(Face face1, Face face2)
				: this()
			{
				Face1 = face1;
				Face2 = face2;
			}
Example #4
0
        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;
            }
        }
Example #5
0
 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;
 }
Example #6
0
 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);
         }
     }
 }
Example #7
0
 public void AllocateFaces(int count)
 {
     Faces = new Face[count];
 }
Example #8
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++;
            }
        }
Example #9
0
 public abstract void Draw(Face face, Vertex[] vertices);
Example #10
0
        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;
            }
        }
Example #11
0
        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;
        }
Example #12
0
        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++;
            }
        }
Example #13
0
        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();
        }
Example #14
0
		public void SetFace(int index, Face face)
		{
			Faces[index] = face;
		}
Example #15
0
        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;
            }
        }