Exemplo n.º 1
0
        private ClipMask GetClipMask(RasterizerVertex v)
        {
            ClipMask mask = 0;

            if (v.w - v.x < 0)
            {
                mask |= ClipMask.PosX;
            }
            if (v.x + v.w < 0)
            {
                mask |= ClipMask.NegX;
            }
            if (v.w - v.y < 0)
            {
                mask |= ClipMask.PosY;
            }
            if (v.y + v.w < 0)
            {
                mask |= ClipMask.NegY;
            }
            if (v.w - v.z < 0)
            {
                mask |= ClipMask.PosZ;
            }
            if (v.z + v.w < 0)
            {
                mask |= ClipMask.NegZ;
            }
            return(mask);
        }
Exemplo n.º 2
0
 public void init(ref RasterizerVertex v0, ref RasterizerVertex v1)
 {
     a   = v0.y - v1.y;
     b   = v1.x - v0.x;
     c   = -(a * (v0.x + v1.x) + b * (v0.y + v1.y)) / 2;
     tie = a != 0 ? a > 0 : b > 0;
 }
Exemplo n.º 3
0
 public LineClipper(RasterizerVertex v0, RasterizerVertex v1)
 {
     m_v0         = v0;
     m_v1         = v1;
     t0           = 0.0f;
     t1           = 1.0f;
     fullyClipped = false;
 }
Exemplo n.º 4
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;
Exemplo n.º 5
0
 public void DrawPointList(List <RasterizerVertex> vertices, List <int> indices, int indexCount)
 {
     for (int i = 0; i < indexCount; ++i)
     {
         if (indices[i] == -1)
         {
             continue;
         }
         RasterizerVertex v = vertices[indices[i]];
         DrawPoint(ref v);
     }
 }
Exemplo n.º 6
0
            public void DrawPointTemplate(ref RasterizerVertex v)
            {
                // Check scissor rect
                if (!rasterizer.ScissorTest(v.x, v.y))
                {
                    return;
                }

                PixelData p = PixelDataFromVertex(ref v);

                shader.DrawPixel(ref p);
            }
Exemplo n.º 7
0
 public void DrawLineList(List <RasterizerVertex> vertices, List <int> indices, int indexCount)
 {
     for (int i = 0; i + 2 <= indexCount; i += 2)
     {
         if (indices[i] == -1)
         {
             continue;
         }
         RasterizerVertex v0 = vertices[indices[i]];
         RasterizerVertex v1 = vertices[indices[i + 1]];
         DrawLine(ref v0, ref v1);
     }
 }
Exemplo n.º 8
0
 public void DrawTriangleList(List <RasterizerVertex> vertices, List <int> indices, int indexCount)
 {
     for (int i = 0; i + 3 <= indexCount; i += 3)
     {
         if (indices[i] == -1)
         {
             continue;
         }
         RasterizerVertex v0 = vertices[indices[i]];
         RasterizerVertex v1 = vertices[indices[i + 1]];
         RasterizerVertex v2 = vertices[indices[i + 2]];
         DrawTriangle(ref v0, ref v1, ref v2);
     }
 }
Exemplo n.º 9
0
        // Clip the poly to the plane given by the formula a * x + b * y + c * z + d * w.
        public void ClipToPlane(float a, float b, float c, float d)
        {
            if (IsFullyClipped())
            {
                return;
            }

            m_indicesOut.Clear();

            int idxPrev = m_indicesIn[0];

            m_indicesIn.Add(idxPrev);

            RasterizerVertex vPrev  = m_vertices[idxPrev];
            float            dpPrev = a * vPrev.x + b * vPrev.y + c * vPrev.z + d * vPrev.w;

            for (int i = 1; i < m_indicesIn.Count; ++i)
            {
                int idx             = m_indicesIn[i];
                RasterizerVertex v  = m_vertices[idx];
                float            dp = a * v.x + b * v.y + c * v.z + d * v.w;

                if (dpPrev >= 0)
                {
                    m_indicesOut.Add(idxPrev);
                }

                if (Math.Sign(dp) != Math.Sign(dpPrev))
                {
                    float t = dp < 0 ? dpPrev / (dpPrev - dp) : -dpPrev / (dp - dpPrev);

                    RasterizerVertex vOut = Helper.InterpolateVertex(m_vertices[idxPrev], m_vertices[idx], t, m_avarCount, m_pvarCount);
                    m_vertices.Add(vOut);
                    m_indicesOut.Add(m_vertices.Count - 1);
                }

                idxPrev = idx;
                dpPrev  = dp;
            }

            var temp = m_indicesIn;

            m_indicesIn  = m_indicesOut;
            m_indicesOut = temp;
        }
Exemplo n.º 10
0
 public unsafe void StepVertex(ref RasterizerVertex v, ref RasterizerVertex step)
 {
     v.x += step.x;
     v.y += step.y;
     if (shader.InterpolateZ)
     {
         v.z += step.z;
     }
     if (shader.InterpolateW)
     {
         v.w += step.w;
     }
     for (int i = 0; i < shader.AVarCount; ++i)
     {
         v.avar[i] += step.avar[i];
     }
     for (int i = 0; i < shader.PVarCount; ++i)
     {
         v.pvar[i] += step.pvar[i];
     }
 }
Exemplo n.º 11
0
        /// Draw a number of points, lines or triangles.
        public void DrawElements(DrawMode mode, int count, List <int> indices)
        {
            m_verticesOut.Clear();
            m_indicesOut.Clear();

            // TODO: Max 1024 primitives per batch.
            m_vCache.clear();

            for (int i = 0; i < count; i++)
            {
                int index       = indices[i];
                int outputIndex = m_vCache.lookup(index);

                if (outputIndex != -1)
                {
                    m_indicesOut.Add(outputIndex);
                }
                else
                {
                    RasterizerVertex vOut = new RasterizerVertex();
                    ProcessVertex(index, ref vOut);

                    outputIndex = m_verticesOut.Count;
                    m_indicesOut.Add(outputIndex);
                    m_verticesOut.Add(vOut);

                    m_vCache.set(index, outputIndex);
                }

                if (PrimitiveCount(mode) >= 1024)
                {
                    ProcessPrimitives(mode);
                    m_verticesOut.Clear();
                    m_indicesOut.Clear();
                    m_vCache.clear();
                }
            }

            ProcessPrimitives(mode);
        }
Exemplo n.º 12
0
            public void DrawLineTemplate(ref RasterizerVertex v0, ref RasterizerVertex v1)
            {
                int adx   = Math.Abs((int)v1.x - (int)v0.x);
                int ady   = Math.Abs((int)v1.y - (int)v0.y);
                int steps = Math.Max(adx, ady);

                RasterizerVertex step = ComputeVertexStep(ref v0, ref v1, steps);

                RasterizerVertex v = v0;

                while (steps-- > 0)
                {
                    PixelData p = PixelDataFromVertex(ref v);

                    if (rasterizer.ScissorTest(v.x, v.y))
                    {
                        shader.DrawPixel(ref p);
                    }

                    StepVertex(ref v, ref step);
                }
            }
Exemplo n.º 13
0
        private void TransformVertices()
        {
            m_alreadyProcessed.Clear();
            for (int i = 0; i < m_verticesOut.Count; i++)
            {
                m_alreadyProcessed.Add(false);
            }

            for (int i = 0; i < m_indicesOut.Count; i++)
            {
                int index = m_indicesOut[i];

                if (index == -1)
                {
                    continue;
                }

                if (m_alreadyProcessed[index])
                {
                    continue;
                }

                RasterizerVertex vOut = m_verticesOut[index];

                // Perspective divide
                float invW = 1.0f / vOut.w;
                vOut.x *= invW;
                vOut.y *= invW;
                vOut.z *= invW;

                // Viewport transform
                vOut.x = (m_viewport.px * vOut.x + m_viewport.ox);
                vOut.y = (m_viewport.py * -vOut.y + m_viewport.oy);
                vOut.z = 0.5f * (m_depthRange.f - m_depthRange.n) * vOut.z + 0.5f * (m_depthRange.n + m_depthRange.f);

                m_verticesOut[index]      = vOut;
                m_alreadyProcessed[index] = true;
            }
        }
Exemplo n.º 14
0
        private void CullTriangles()
        {
            for (int i = 0; i + 3 <= m_indicesOut.Count; i += 3)
            {
                if (m_indicesOut[i] == -1)
                {
                    continue;
                }

                RasterizerVertex v0 = m_verticesOut[m_indicesOut[i]];
                RasterizerVertex v1 = m_verticesOut[m_indicesOut[i + 1]];
                RasterizerVertex v2 = m_verticesOut[m_indicesOut[i + 2]];

                float facing = (v0.x - v1.x) * (v2.y - v1.y) - (v2.x - v1.x) * (v0.y - v1.y);

                if (facing < 0)
                {
                    if (m_cullMode == CullMode.CW)
                    {
                        m_indicesOut[i] = m_indicesOut[i + 1] = m_indicesOut[i + 2] = -1;
                    }
                }
                else
                {
                    if (m_cullMode == CullMode.CCW)
                    {
                        m_indicesOut[i] = m_indicesOut[i + 1] = m_indicesOut[i + 2] = -1;
                    }
                    else

                    {
                        int temp = m_indicesOut[i];
                        m_indicesOut[i]     = m_indicesOut[i + 2];
                        m_indicesOut[i + 2] = temp;
                    }
                }
            }
        }
Exemplo n.º 15
0
            public unsafe PixelData PixelDataFromVertex(ref RasterizerVertex v)
            {
                PixelData p = new PixelData();

                p.x = (int)v.x;
                p.y = (int)v.y;
                if (shader.InterpolateZ)
                {
                    p.z = v.z;
                }
                if (shader.InterpolateW)
                {
                    p.w = v.w; p.invw = 1.0f / v.w;
                }
                for (int i = 0; i < shader.AVarCount; ++i)
                {
                    p.avar[i] = v.avar[i];
                }
                for (int i = 0; i < shader.PVarCount; ++i)
                {
                    p.pvar[i] = v.pvar[i];
                }
                return(p);
            }
Exemplo n.º 16
0
            public unsafe RasterizerVertex ComputeVertexStep(ref RasterizerVertex v0, ref RasterizerVertex v1, int adx)
            {
                RasterizerVertex step = new RasterizerVertex();

                step.x = (v1.x - v0.x) / adx;
                step.y = (v1.y - v0.y) / adx;
                if (shader.InterpolateZ)
                {
                    step.z = (v1.z - v0.z) / adx;
                }
                if (shader.InterpolateW)
                {
                    step.w = (v1.w - v0.w) / adx;
                }
                for (int i = 0; i < shader.AVarCount; ++i)
                {
                    step.avar[i] = (v1.avar[i] - v0.avar[i]) / adx;
                }
                for (int i = 0; i < shader.PVarCount; ++i)
                {
                    step.pvar[i] = (v1.pvar[i] - v0.pvar[i]) / adx;
                }
                return(step);
            }
Exemplo n.º 17
0
 /// Draw a single line.
 public void DrawLine(ref RasterizerVertex v0, ref RasterizerVertex v1)
 {
     m_lineFunc(ref v0, ref v1);
 }
Exemplo n.º 18
0
        private void ClipLines()
        {
            m_clipMask.Clear();
            for (int i = 0; i < m_verticesOut.Count; i++)
            {
                m_clipMask.Add(0);
            }

            for (int i = 0; i < m_verticesOut.Count; i++)
            {
                m_clipMask[i] = GetClipMask(m_verticesOut[i]);
            }

            for (int i = 0; i < m_indicesOut.Count; i += 2)
            {
                int index0 = m_indicesOut[i];
                int index1 = m_indicesOut[i + 1];

                RasterizerVertex v0 = m_verticesOut[index0];
                RasterizerVertex v1 = m_verticesOut[index1];

                ClipMask clipMask = m_clipMask[index0] | m_clipMask[index1];

                LineClipper lineClipper = new LineClipper(v0, v1);

                if ((clipMask & ClipMask.PosX) == ClipMask.PosX)
                {
                    lineClipper.clipToPlane(-1, 0, 0, 1);
                }
                if ((clipMask & ClipMask.NegX) == ClipMask.NegX)
                {
                    lineClipper.clipToPlane(1, 0, 0, 1);
                }
                if ((clipMask & ClipMask.PosY) == ClipMask.PosY)
                {
                    lineClipper.clipToPlane(0, -1, 0, 1);
                }
                if ((clipMask & ClipMask.NegY) == ClipMask.NegY)
                {
                    lineClipper.clipToPlane(0, 1, 0, 1);
                }
                if ((clipMask & ClipMask.PosZ) == ClipMask.PosZ)
                {
                    lineClipper.clipToPlane(0, 0, -1, 1);
                }
                if ((clipMask & ClipMask.NegZ) == ClipMask.NegZ)
                {
                    lineClipper.clipToPlane(0, 0, 1, 1);
                }

                if (lineClipper.fullyClipped)
                {
                    m_indicesOut[i]     = -1;
                    m_indicesOut[i + 1] = -1;
                    continue;
                }

                if (m_clipMask[index0] > 0)
                {
                    RasterizerVertex newV = Helper.InterpolateVertex(v0, v1, lineClipper.t0, m_shader.AVarCount, m_shader.PVarCount);
                    m_verticesOut.Add(newV);
                    m_indicesOut[i] = m_verticesOut.Count - 1;
                }

                if (m_clipMask[index1] > 0)
                {
                    RasterizerVertex newV = Helper.InterpolateVertex(v0, v1, lineClipper.t1, m_shader.AVarCount, m_shader.PVarCount);
                    m_verticesOut.Add(newV);
                    m_indicesOut[i + 1] = m_verticesOut.Count - 1;
                }
            }
        }
Exemplo n.º 19
0
 private void ProcessVertex(int index, ref RasterizerVertex output)
 {
     m_shader.ProcessVertex(index, ref output);
 }
Exemplo n.º 20
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);
                    }
                }
            }
Exemplo n.º 21
0
 /// Draw a single point.
 public void DrawPoint(ref RasterizerVertex v)
 {
     m_pointFunc(ref v);
 }
Exemplo n.º 22
0
 /// Draw a single triangle.
 public void DrawTriangle(ref RasterizerVertex v0, ref RasterizerVertex v1, ref RasterizerVertex v2)
 {
     m_triangleFunc(ref v0, ref v1, ref v2);
 }
Exemplo n.º 23
0
 public void ProcessVertex(int index, ref RasterizerVertex output)
 {
 }