コード例 #1
0
        public void ProcessScanLine(ScanLineData data, Vertex va, Vertex vb, Vertex vc, Vertex vd, Color4 color, Texture texture)
        {
            var pa = va.Coordinates;
            var pb = vb.Coordinates;
            var pc = vc.Coordinates;
            var pd = vd.Coordinates;

            var gradient1 = pa.Y != pb.Y ? (data.CurrentY - pa.Y) / (pb.Y - pa.Y) : 1;
            var gradient2 = pc.Y != pd.Y ? (data.CurrentY - pc.Y) / (pd.Y - pc.Y) : 1;

            int sx = (int)MathLib.Interpolate(pa.X, pb.X, gradient1);
            int ex = (int)MathLib.Interpolate(pc.X, pd.X, gradient2);

            float z1 = MathLib.Interpolate(pa.Z, pb.Z, gradient1);
            float z2 = MathLib.Interpolate(pc.Z, pd.Z, gradient2);

            var snl = MathLib.Interpolate(data.NDotla, data.NDotlb, gradient1);
            var enl = MathLib.Interpolate(data.NDotlc, data.NDotld, gradient2);

            var su = MathLib.Interpolate(data.ua, data.ub, gradient1);
            var eu = MathLib.Interpolate(data.uc, data.ud, gradient2);
            var sv = MathLib.Interpolate(data.va, data.vb, gradient1);
            var ev = MathLib.Interpolate(data.vc, data.vd, gradient2);

            for (int index = sx; index < ex; index++)
            {
                var grad  = (index - sx) / (float)(ex - sx);
                var z     = MathLib.Interpolate(z1, z2, grad);
                var ndotl = MathLib.Interpolate(snl, enl, grad);

                var u = MathLib.Interpolate(su, eu, grad);
                var v = MathLib.Interpolate(sv, ev, grad);

                var textureColor = texture?.Map(u, v) ?? new Color4(1, 1, 1, 1);

                DrawPoint(index, data.CurrentY, z, new Color4(
                              color.Red * ndotl * textureColor.Red,
                              color.Green * ndotl * textureColor.Green,
                              color.Blue * ndotl * textureColor.Blue,
                              color.Alpha * textureColor.Alpha));
            }
        }
コード例 #2
0
        public void DrawTriangle(Vertex v0, Vertex v1, Vertex v2, Color4 color, Texture texture)
        {
            if (v0.Coordinates.Y > v1.Coordinates.Y)
            {
                var temp = v1;
                v1 = v0;
                v0 = temp;
            }

            if (v1.Coordinates.Y > v2.Coordinates.Y)
            {
                var temp = v1;
                v1 = v2;
                v2 = temp;
            }

            if (v0.Coordinates.Y > v1.Coordinates.Y)
            {
                var temp = v1;
                v1 = v0;
                v0 = temp;
            }

            var p0 = v0.Coordinates;
            var p1 = v1.Coordinates;
            var p2 = v2.Coordinates;

            //var vnFace = (v0.Normal + v1.Normal + v2.Normal) / 3f;
            //var centerPoint = (v0.WorldCoordinates + v1.WorldCoordinates + v2.WorldCoordinates) / 3f;

            //var ndotl = MathLib.ComputeNDotL(centerPoint, vnFace, lightPos);
            //var data = new ScanLineData{NDotla = ndotl};

            //var cent = (v0.Coordinates + v1.Coordinates + v2.Coordinates) / 3f;
            //DrawBresenhamLine(cent, cent + vnFace * 10);
            float nl0 = MathLib.ComputeNDotL(v0.WorldCoordinates, v0.Normal, lightPos);
            float nl1 = MathLib.ComputeNDotL(v1.WorldCoordinates, v1.Normal, lightPos);
            float nl2 = MathLib.ComputeNDotL(v2.WorldCoordinates, v2.Normal, lightPos);

            var data = new ScanLineData();

            float dP0P1, dP0P2;

            if (p1.Y - p0.Y > 0)
            {
                dP0P1 = (p1.X - p0.X) / (p1.Y - p0.Y);
            }
            else
            {
                dP0P1 = 0;
            }

            if (p2.Y - p0.Y > 0)
            {
                dP0P2 = (p2.X - p0.X) / (p2.Y - p0.Y);
            }
            else
            {
                dP0P2 = 0;
            }

            if (dP0P1 > dP0P2)
            {
                for (var y = (int)p0.Y; y <= (int)p2.Y; y++)
                {
                    data.CurrentY = y;
                    if (y < p1.Y)
                    {
                        data.NDotla = nl0;
                        data.NDotlb = nl2;
                        data.NDotlc = nl0;
                        data.NDotld = nl1;

                        data.ua = v0.TextureCoordinates.X;
                        data.ub = v2.TextureCoordinates.X;
                        data.uc = v0.TextureCoordinates.X;
                        data.ud = v1.TextureCoordinates.X;

                        data.va = v0.TextureCoordinates.Y;
                        data.vb = v2.TextureCoordinates.Y;
                        data.vc = v0.TextureCoordinates.Y;
                        data.vd = v1.TextureCoordinates.Y;

                        ProcessScanLine(data, v0, v2, v0, v1, color, texture);
                    }
                    else
                    {
                        data.NDotla = nl0;
                        data.NDotlb = nl2;
                        data.NDotlc = nl1;
                        data.NDotld = nl2;

                        data.ua = v0.TextureCoordinates.X;
                        data.ub = v2.TextureCoordinates.X;
                        data.uc = v1.TextureCoordinates.X;
                        data.ud = v2.TextureCoordinates.X;

                        data.va = v0.TextureCoordinates.Y;
                        data.vb = v2.TextureCoordinates.Y;
                        data.vc = v1.TextureCoordinates.Y;
                        data.vd = v2.TextureCoordinates.Y;

                        ProcessScanLine(data, v0, v2, v1, v2, color, texture);
                    }
                }
            }
            else
            {
                for (var y = (int)p0.Y; y <= (int)p2.Y; y++)
                {
                    data.CurrentY = y;
                    if (y < p1.Y)
                    {
                        data.NDotla = nl0;
                        data.NDotlb = nl1;
                        data.NDotlc = nl0;
                        data.NDotld = nl2;

                        data.ua = v0.TextureCoordinates.X;
                        data.ub = v1.TextureCoordinates.X;
                        data.uc = v0.TextureCoordinates.X;
                        data.ud = v2.TextureCoordinates.X;

                        data.va = v0.TextureCoordinates.Y;
                        data.vb = v1.TextureCoordinates.Y;
                        data.vc = v0.TextureCoordinates.Y;
                        data.vd = v2.TextureCoordinates.Y;

                        ProcessScanLine(data, v0, v1, v0, v2, color, texture);
                    }
                    else
                    {
                        data.NDotla = nl1;
                        data.NDotlb = nl2;
                        data.NDotlc = nl0;
                        data.NDotld = nl2;

                        data.ua = v1.TextureCoordinates.X;
                        data.ub = v2.TextureCoordinates.X;
                        data.uc = v0.TextureCoordinates.X;
                        data.ud = v2.TextureCoordinates.X;

                        data.va = v1.TextureCoordinates.Y;
                        data.vb = v2.TextureCoordinates.Y;
                        data.vc = v0.TextureCoordinates.Y;
                        data.vd = v2.TextureCoordinates.Y;

                        ProcessScanLine(data, v1, v2, v0, v2, color, texture);
                    }
                }
            }
        }