Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 public void SetTextureCoordinate(int index, TextureCoordinate textureCoordinate)
 {
     TextureCoordinates[index] = textureCoordinate;
 }
Beispiel #4
0
 public void AllocateTextureCoordinates(int count)
 {
     TextureCoordinates = new TextureCoordinate[count];
 }
Beispiel #5
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++;
            }
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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;
            }
        }