Пример #1
0
        private void RenderHorizontalLine(IDisplayer displayer, int x1, int x2, int y, double z1, double z2,
                                          Color color, List <Light> lights, Color gourandIntensity1, Color gourandIntensity2, Vector normal1, Vector normal2,
                                          Vector cameraPos, Vector world1, Vector world2)
        {
            double z = 0;

            if (x1 > x2)
            {
                int tmp = x1;
                x1 = x2;
                x2 = tmp;
                double tmp2 = z1;
                z1 = z2;
                z2 = tmp2;
                Color tmp3 = gourandIntensity1;
                gourandIntensity1 = gourandIntensity2;
                gourandIntensity2 = tmp3;
                Vector nTmp = null;
                if (normal1 != null)
                {
                    nTmp    = normal1.Clone();
                    normal1 = normal2.Clone();
                    normal2 = nTmp;
                }
                Vector wTmp = null;
                if (world1 != null)
                {
                    wTmp   = world1.Clone();
                    world1 = world2.Clone();
                    world2 = wTmp;
                }
            }
            for (int x = x1; x <= x2; ++x)
            {
                Color usedColor = new Color();
                if (displayer.GetShading() == Shading.Gourand)
                {
                    usedColor = InterpolateColorGourandShading(x2, x1, x, gourandIntensity2, gourandIntensity1);
                }
                else if (displayer.GetShading() == Shading.Phong)
                {
                    Vector normal = InterpolateNormalPhongShading(x2, x1, x, normal2, normal1);
                    Vector world  = InterpolateWorldPhongShading(x2, x1, x, world2, world1);
                    usedColor = ComputeColorPhongModel(color, lights, world, cameraPos, normal, displayer.IsFog());
                }
                else
                {
                    usedColor = color;
                }
                double q = x2 == x1 ? 0 : (x - x1) / (x2 - x1);
                z = InterpolateZ(z1, z2, q);
                displayer.Display(x, y, z, usedColor); // TODO: consider changing to primitive types instead of passing Vector
            }
        }
Пример #2
0
        private void FillBottomTriangle(IDisplayer displayer,
                                        int x0, int y0, double z0, Color c0, Vector n0, Vector w0,
                                        int x1, int y1, double z1, Color c1, Vector n1, Vector w1,
                                        int x2, int y2, double z2, Color c2, Vector n2, Vector w2,
                                        Color color, List <Light> lights, Vector cameraPos)
        {
            double d1 = (double)(x1 - x0) / (double)(y1 - y0 + 1);
            double d2 = (double)(x2 - x0) / (double)(y2 - y0 + 1);
            double xa = x0;
            double xb = x0;

            for (int sc = y0; sc <= y1; ++sc)
            {
                Color  leftInsensity = new Color();
                Color  rightIntensity = new Color();
                Vector leftNormal = null, rightNormal = null, leftWorld = null, rightWorld = null;
                if (displayer.GetShading() == Shading.Gourand)
                {
                    leftInsensity  = InterpolateColorGourandShading(y1, y0, sc, c1, c0);
                    rightIntensity = InterpolateColorGourandShading(y2, y0, sc, c2, c0);
                }
                else if (displayer.GetShading() == Shading.Phong)
                {
                    leftNormal  = InterpolateNormalPhongShading(y1, y0, sc, n1, n0);
                    rightNormal = InterpolateNormalPhongShading(y2, y0, sc, n2, n0);
                    leftWorld   = InterpolateWorldPhongShading(y1, y0, sc, w1, w0);
                    rightWorld  = InterpolateWorldPhongShading(y2, y0, sc, w2, w0);
                }
                xa += d1;
                xb += d2;
                RenderHorizontalLine(displayer, (int)xa, (int)xb, sc,
                                     InterpolateZ(z0, z1, (double)(sc - y0) / (double)(y1 - y0)),
                                     InterpolateZ(z0, z2, (double)(sc - y0) / (double)(y1 - y0)),
                                     color, lights, leftInsensity, rightIntensity, leftNormal, rightNormal, cameraPos, leftWorld, rightWorld);
            }
        }
Пример #3
0
        private void RenderFillingScanLine(IDisplayer displayer, Color color, List <Light> lights, Vector cameraPos) // TODO: Fix missing Gourand cases (if, else if)
        {
            List <Vertex> vertices = new List <Vertex>()
            {
                v1, v2, v3
            };

            vertices.Sort(CompareByY);
            int    x0 = (int)vertices[0].GetScreenPosition().x;
            int    y0 = (int)vertices[0].GetScreenPosition().y;
            int    x1 = (int)vertices[1].GetScreenPosition().x;
            int    y1 = (int)vertices[1].GetScreenPosition().y;
            int    x2 = (int)vertices[2].GetScreenPosition().x;
            int    y2 = (int)vertices[2].GetScreenPosition().y;
            double z0 = vertices[0].GetScreenPosition().z;
            double z1 = vertices[1].GetScreenPosition().z;
            double z2 = vertices[2].GetScreenPosition().z;

            if (displayer.GetShading() == Shading.Gourand)
            {
                PrepareGourandVertexIntensities(color, lights, cameraPos, vertices, displayer.IsFog());
            }
            else if (displayer.GetShading() == Shading.Flat)
            {
                color = ComputeColorPhongModel(color, lights, GetWorldMiddle(), cameraPos, normalVector, displayer.IsFog());
            }
            Color  c0 = vertices[0].GetScreenPosition().GetColor();
            Color  c1 = vertices[1].GetScreenPosition().GetColor();
            Color  c2 = vertices[2].GetScreenPosition().GetColor();
            Vector n0 = null, n1 = null, n2 = null;
            Vector w0 = null, w1 = null, w2 = null;

            if (displayer.GetShading() == Shading.Phong)
            {
                n0 = vertices[0].GetNormalVector();
                n1 = vertices[1].GetNormalVector();
                n2 = vertices[2].GetNormalVector();
                w0 = vertices[0].GetWorldPosition();
                w1 = vertices[1].GetWorldPosition();
                w2 = vertices[2].GetWorldPosition();
            }

            if (y1 == y2)
            {
                FillBottomTriangle(displayer, x0, y0, z0, c0, n0, w0, x1, y1, z1, c1, n1, w1, x2, y2, z2, c2, n2, w2, color, lights, cameraPos);
            }
            else if (y0 == y1)
            {
                FillTopTriangle(displayer, x0, y0, z0, c0, n0, w0, x1, y1, z1, c1, n1, w1, x2, y2, z2, c2, n2, w2, color, lights, cameraPos);
            }
            else
            {
                int    x3 = x0 + (int)(((double)(y1 - y0) / (double)(y2 - y0)) * (x2 - x0));
                int    y3 = y1;
                double z3 = InterpolateZ(z0, z2, (double)(y1 - y0) / (double)(y2 - y0));
                Color  c3 = new Color();
                Vector n3 = null, w3 = null;
                if (displayer.GetShading() == Shading.Gourand)
                {
                    c3 = InterpolateColorGourandShading(y2, y0, y1, c2, c0);
                }
                else if (displayer.GetShading() == Shading.Phong)
                {
                    n3 = InterpolateNormalPhongShading(y2, y0, y1, n2, n0);
                    w3 = InterpolateWorldPhongShading(y2, y0, y1, w2, w0);
                }
                FillBottomTriangle(displayer, x0, y0, z0, c0, n0, w0, x1, y1, z1, c1, n1, w1, x3, y3, z3, c3, n3, w3, color, lights, cameraPos);
                FillTopTriangle(displayer, x1, y1, z1, c1, n1, w1, x3, y3, z3, c3, n3, w3, x2, y2, z2, c2, n2, w2, color, lights, cameraPos);
            }
        }