Пример #1
0
            public unsafe void DrawTriangleSpanTemplate(ref RasterizerVertex v0, ref RasterizerVertex v1, ref RasterizerVertex v2)
            {
                // Compute triangle equations.
                TriangleEquations eqn = new TriangleEquations(ref v0, ref v1, ref v2, shader.AVarCount, shader.PVarCount);

                // Check if triangle is backfacing.
                if (eqn.area2 <= 0)
                {
                    return;
                }

                ref RasterizerVertex t = ref v0;
Пример #2
0
        public static void DrawBlock(ref T shader, ref TriangleEquations eqn, int x, int y, bool TestEdges)
        {
            float xf = x + 0.5f;
            float yf = y + 0.5f;

            PixelData po = new PixelData();

            po.Init(ref eqn, xf, yf, shader.AVarCount, shader.PVarCount, shader.InterpolateZ, shader.InterpolateW);

            EdgeData eo = new EdgeData();

            if (TestEdges)
            {
                eo.init(ref eqn, xf, yf);
            }

            for (int yy = y; yy < y + Constants.BlockSize; yy++)
            {
                PixelData pi = CopyPixelData(ref shader, ref po);

                EdgeData ei = new EdgeData();
                if (TestEdges)
                {
                    ei = eo;
                }

                for (int xx = x; xx < x + Constants.BlockSize; xx++)
                {
                    if (!TestEdges || ei.test(ref eqn))
                    {
                        pi.x = xx;
                        pi.y = yy;
                        shader.DrawPixel(ref pi);
                    }

                    pi.StepX(ref eqn, shader.AVarCount, shader.PVarCount, shader.InterpolateZ, shader.InterpolateW);
                    if (TestEdges)
                    {
                        ei.stepX(ref eqn);
                    }
                }

                po.StepY(ref eqn, shader.AVarCount, shader.PVarCount, shader.InterpolateZ, shader.InterpolateW);
                if (TestEdges)
                {
                    eo.stepY(ref eqn);
                }
            }
        }
Пример #3
0
        public static void DrawSpan(ref T shader, ref TriangleEquations eqn, int x, int y, int x2)
        {
            float xf = x + 0.5f;
            float yf = y + 0.5f;

            PixelData p = new PixelData();

            p.y = y;
            p.Init(ref eqn, xf, yf, shader.AVarCount, shader.PVarCount, shader.InterpolateZ, shader.InterpolateW);

            while (x < x2)
            {
                p.x = x;
                shader.DrawPixel(ref p);
                p.StepX(ref eqn, shader.AVarCount, shader.PVarCount, shader.InterpolateZ, shader.InterpolateW);
                x++;
            }
        }
Пример #4
0
        public void StepY(ref TriangleEquations eqn, int aVarCount, int pVarCount, bool interpolateZ, bool interpolateW)
        {
            if (interpolateZ)
            {
                z = eqn.z.StepY(z);
            }

            if (interpolateW || pVarCount > 0)
            {
                invw = eqn.invw.StepY(invw);
                w    = 1.0f / invw;
            }

            for (int i = 0; i < aVarCount; ++i)
            {
                avar[i] = eqn.avar[i].StepY(avar[i]);
            }

            for (int i = 0; i < pVarCount; ++i)
            {
                pvarTemp[i] = eqn.pvar[i].StepY(pvarTemp[i]);
                pvar[i]     = pvarTemp[i] * w;
            }
        }
Пример #5
0
        public void Init(ref TriangleEquations eqn, float x, float y, int aVarCount, int pVarCount, bool interpolateZ, bool interpolateW)
        {
            if (interpolateZ)
            {
                z = eqn.z.Evaluate(x, y);
            }

            if (interpolateW || pVarCount > 0)
            {
                invw = eqn.invw.Evaluate(x, y);
                w    = 1.0f / invw;
            }

            for (int i = 0; i < aVarCount; ++i)
            {
                avar[i] = eqn.avar[i].Evaluate(x, y);
            }

            for (int i = 0; i < pVarCount; ++i)
            {
                pvarTemp[i] = eqn.pvar[i].Evaluate(x, y);
                pvar[i]     = pvarTemp[i] * w;
            }
        }
Пример #6
0
            public void DrawTriangleBlockTemplate(ref RasterizerVertex v0, ref RasterizerVertex v1, ref RasterizerVertex v2)
            {
                // Compute triangle equations.
                TriangleEquations eqn = new TriangleEquations(ref v0, ref v1, ref v2, shader.AVarCount, shader.PVarCount);

                // Check if triangle is backfacing.
                if (eqn.area2 <= 0)
                {
                    return;
                }

                // Compute triangle bounding box.
                int minX = (int)Math.Min(Math.Min(v0.x, v1.x), v2.x);
                int maxX = (int)Math.Max(Math.Max(v0.x, v1.x), v2.x);
                int minY = (int)Math.Min(Math.Min(v0.y, v1.y), v2.y);
                int maxY = (int)Math.Max(Math.Max(v0.y, v1.y), v2.y);

                // Clip to scissor rect.
                minX = Math.Max(minX, rasterizer.m_minX);
                maxX = Math.Min(maxX, rasterizer.m_maxX);
                minY = Math.Max(minY, rasterizer.m_minY);
                maxY = Math.Min(maxY, rasterizer.m_maxY);

                // Round to block grid.
                minX &= ~(Constants.BlockSize - 1);
                maxX &= ~(Constants.BlockSize - 1);
                minY &= ~(Constants.BlockSize - 1);
                maxY &= ~(Constants.BlockSize - 1);

                float s = Constants.BlockSize - 1;

                int stepsX = (maxX - minX) / Constants.BlockSize + 1;
                int stepsY = (maxY - minY) / Constants.BlockSize + 1;

                for (int i = 0; i < stepsX * stepsY; ++i)
                {
                    int sx = i % stepsX;
                    int sy = i / stepsX;

                    // Add 0.5 to sample at pixel centers.
                    int x = minX + sx * Constants.BlockSize;
                    int y = minY + sy * Constants.BlockSize;

                    float xf = x + 0.5f;
                    float yf = y + 0.5f;

                    // Test if block is inside or outside triangle or touches it.
                    EdgeData e00 = new EdgeData(); e00.init(ref eqn, xf, yf);
                    EdgeData e01 = e00; e01.stepY(ref eqn, s);
                    EdgeData e10 = e00; e10.stepX(ref eqn, s);
                    EdgeData e11 = e01; e11.stepX(ref eqn, s);

                    bool e00_0 = eqn.e0.test(e00.ev0), e00_1 = eqn.e1.test(e00.ev1), e00_2 = eqn.e2.test(e00.ev2), e00_all = e00_0 && e00_1 && e00_2;
                    bool e01_0 = eqn.e0.test(e01.ev0), e01_1 = eqn.e1.test(e01.ev1), e01_2 = eqn.e2.test(e01.ev2), e01_all = e01_0 && e01_1 && e01_2;
                    bool e10_0 = eqn.e0.test(e10.ev0), e10_1 = eqn.e1.test(e10.ev1), e10_2 = eqn.e2.test(e10.ev2), e10_all = e10_0 && e10_1 && e10_2;
                    bool e11_0 = eqn.e0.test(e11.ev0), e11_1 = eqn.e1.test(e11.ev1), e11_2 = eqn.e2.test(e11.ev2), e11_all = e11_0 && e11_1 && e11_2;

                    int result = (e00_all ? 1 : 0) + (e01_all ? 1 : 0) + (e10_all ? 1 : 0) + (e11_all ? 1 : 0);

                    // Potentially all out.
                    if (result == 0)
                    {
                        // Test for special case.
                        bool e00Same = e00_0 == e00_1 == e00_2;
                        bool e01Same = e01_0 == e01_1 == e01_2;
                        bool e10Same = e10_0 == e10_1 == e10_2;
                        bool e11Same = e11_0 == e11_1 == e11_2;

                        if (!e00Same || !e01Same || !e10Same || !e11Same)
                        {
                            shader.DrawBlock(ref eqn, x, y, true);
                        }
                    }
                    else if (result == 4)
                    {
                        // Fully Covered.
                        shader.DrawBlock(ref eqn, x, y, false);
                    }
                    else
                    {
                        // Partially Covered.
                        shader.DrawBlock(ref eqn, x, y, true);
                    }
                }
            }