Exemple #1
0
        private void DrawScanLine(PrimitiveContext ctx, int y, float xe, float xd)
        {
            int xmin = glm.Max((int)xe, 0);
            int xmax = glm.Min((int)xd, (int)m_CurrentViewport.width);

            int ib = ctx.baseIndex;

            float w0 = ctx.w[ctx.iV0];
            float w1 = ctx.w[ctx.iV1];
            float w2 = ctx.w[ctx.iV2];

            float dn01 = Linear2Homo(ctx.dfd01, w0, w1);
            float dn12 = Linear2Homo(ctx.dfd12, w1, w2);
            float dn02 = Linear2Homo(ctx.dfe02, w0, w2);
            float dn21 = Linear2Homo(ctx.dfe21, w2, w1);

            float dr01 = 1f - dn01;
            float dr12 = 1f - dn12;
            float dr02 = 1f - dn02;
            float dr21 = 1f - dn21;

            float bn012 = ctx.dfd012;
            float bn021 = ctx.dfe021;
            float br012 = 1f - bn012;
            float br021 = 1f - bn021;

            float R0  = dr01 * br012;
            float R1  = dr02 * br021;
            float R23 = dn01 * br012 + dr12 * bn012;
            float R4  = dn21 * bn021;
            float R5  = dn12 * bn012;
            float R67 = dn02 * br021 + dr21 * bn021;

            float wLeft  = w0 * R1 + w1 * R4 + w2 * R67;
            float wRight = w0 * R0 + w1 * R23 + w2 * R5;

            float zLeft  = ctx.v[ctx.iV0].z * R1 + ctx.v[ctx.iV1].z * R4 + ctx.v[ctx.iV2].z * R67;
            float zRight = ctx.v[ctx.iV0].z * R0 + ctx.v[ctx.iV1].z * R23 + ctx.v[ctx.iV2].z * R5;

            float deltaDx = (xd != xe) ? 1f / (float)(xd - xe) : 0f;

            for (int x = xmin; x <= xmax; x++)
            {
                float dx = (float)(x - xe) * deltaDx;

                dx = Linear2Homo(dx, wLeft, wRight);

                float z = zLeft + (zRight - zLeft) * dx;

                internal_FragCoord.x = x;
                internal_FragCoord.y = y;

                if (m_DepthBuffer.IsDepthTestEnabled())
                {
                    if (!m_DepthBuffer.TestDepth(internal_FragCoord, z))
                    {
                        continue;
                    }
                }
                m_DepthBuffer.WriteDepth(internal_FragCoord, z);

                ctx.RDX[ctx.iV0] = R1 + ((R0 - R1) * dx);
                ctx.RDX[ctx.iV1] = R4 + ((R23 - R4) * dx);
                ctx.RDX[ctx.iV2] = R67 + ((R5 - R67) * dx);

                gl_FragCoord.x = x;
                gl_FragCoord.y = y;
                gl_FragCoord.z = z;
                gl_FragCoord.w = 1;                 // TODO: gl_FragCoord.w = 1/w ?

                // RUN FRAGMENT SHADER
                // RunStage(StageType.FragmentShader);
                m_CompiledPipelineProgram.FragmentShader();
            }
        }
Exemple #2
0
        public void Prepare()
        {
            switch (m_context.m_GraphicsPipeline.m_graphicsPipelineCreateInfo.pInputAssemblyState.topology)
            {
            case VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
                PrimitiveLength = 2;
                break;

            case VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
                PrimitiveLength = 3;
                break;

            default:
                throw new NotImplementedException();
            }

            // m_Stages.Clear();
            m_Storage.Clear();
            m_FragCoordUsed = false;
            m_FragDepthUsed = false;

            m_PrimiteContext = new PrimitiveContext();

            gl_Position = new vec4[PrimitiveLength];

            m_DepthBuffer = SoftwareDepthBuffer.Create(m_context);

            CurrentStage = StageType.Start;
            // m_Stages[StageType.InputAssembler] = MyProgram.Create(InputAssemblerStage);
            // m_Stages[StageType.Rasterization] = MyProgram.Create(RasterizationStage);
            // m_Stages[StageType.ColorBlending] = MyProgram.Create(ColorBlendingStage);

            m_PipelineProgramDefinition = new SoftwarePipelineProgram();

            foreach (var stageItem in m_context.m_GraphicsPipeline.m_graphicsPipelineCreateInfo.pStages)
            {
                var compiledModule = SoftwareShaderModule.Compile(stageItem);

                switch (stageItem.stage)
                {
                case VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT:
                    m_VertexShaderInstance = compiledModule.instance;
                    m_PipelineProgramDefinition.ShaderEntry[StageType.VertexShader].Add(compiledModule.entryPoint);
                    break;

                case VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT:
                    m_FragmentShaderInstance = compiledModule.instance;
                    m_PipelineProgramDefinition.ShaderEntry[StageType.FragmentShader].Add(compiledModule.entryPoint);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            PrepareShaderStage(StageType.VertexShader, m_VertexShaderInstance);
            PrepareShaderStage(StageType.FragmentShader, m_FragmentShaderInstance);

            m_CurrentViewport = m_context.m_GraphicsPipeline.m_graphicsPipelineCreateInfo.pViewportState.pViewports[0];

            m_CompiledPipelineProgram = m_PipelineProgramDefinition.Compile();
        }
Exemple #3
0
        private void DrawTriangle(PrimitiveContext ctx)
        {
            int itop = 0;

            if (ctx.v[ctx.iV1].y < ctx.v[itop].y)
            {
                itop = ctx.iV1;
            }
            if (ctx.v[ctx.iV2].y < ctx.v[itop].y)
            {
                itop = ctx.iV2;
            }

            ctx.iV0 = itop;
            ctx.iV1 = (itop + 1) % 3;
            ctx.iV2 = (itop + 2) % 3;

            ctx.Slope01 = GetSlope(ctx.v, ctx.iV0, ctx.iV1);
            ctx.Slope02 = GetSlope(ctx.v, ctx.iV0, ctx.iV2);

            if (ctx.Slope02 > ctx.Slope01)
            {
                int t = ctx.iV1;
                ctx.iV1 = ctx.iV2;
                ctx.iV2 = t;

                ctx.Slope01 = GetSlope(ctx.v, ctx.iV0, ctx.iV1);
                ctx.Slope02 = GetSlope(ctx.v, ctx.iV0, ctx.iV2);
            }

            ctx.Slope12 = GetSlope(ctx.v, ctx.iV1, ctx.iV2);
            ctx.Slope21 = GetSlope(ctx.v, ctx.iV2, ctx.iV1);

            int minY = (int)ctx.v[ctx.iV0].y;
            int maxY = (int)Math.Max(ctx.v[ctx.iV1].y, ctx.v[ctx.iV2].y);

            int startY = (minY < 0 ? 0 : minY);
            int endY   = (maxY >= this.m_CurrentViewport.height ? (int)this.m_CurrentViewport.height - 1 : maxY);

            float yv0 = ctx.v[ctx.iV0].y;
            float yv1 = ctx.v[ctx.iV1].y;
            float yv2 = ctx.v[ctx.iV2].y;

            float xv0 = ctx.v[ctx.iV0].x;
            float xv1 = ctx.v[ctx.iV1].x;
            float xv2 = ctx.v[ctx.iV2].x;

            bool bEqY01 = (yv0 == yv1);
            bool bEqY12 = (yv1 == yv2);
            bool bEqY20 = (yv2 == yv0);

            float dy12 = bEqY12 ? 0f : 1f / (yv1 - yv2);
            float dy20 = bEqY20 ? 0f : 1f / (yv2 - yv0);
            float dy21 = bEqY12 ? 0f : 1f / (yv2 - yv1);
            float dy10 = bEqY01 ? 0f : 1f / (yv1 - yv0);


            float xe;
            float xd;
            float delta;

            for (int y = startY; y <= endY; y++)
            {
                if ((!bEqY12) && (y > yv2 || bEqY20))
                {
                    xe         = xv2 + ((y - yv2) * ctx.Slope21);
                    ctx.dfe021 = 1f;
                    delta      = (y - yv2) * dy12;
                    ctx.dfe21  = glm.Clamp(delta, 0f, 1f);
                }
                else if (!bEqY20)
                {
                    xe         = xv0 + ((y - yv0) * ctx.Slope02);
                    ctx.dfe021 = 0f;
                    delta      = (y - yv0) * dy20;
                    ctx.dfe02  = glm.Clamp(delta, 0f, 1f);
                }
                else
                {
                    continue;
                }


                if ((!bEqY12) && (y > yv1 || bEqY01))
                {
                    xd         = xv1 + ((y - yv1) * ctx.Slope12);
                    ctx.dfd012 = 1f;
                    delta      = (y - yv1) * dy21;
                    ctx.dfd12  = glm.Clamp(delta, 0f, 1f);
                }
                else if (!bEqY01)
                {
                    xd         = xv0 + ((y - yv0) * ctx.Slope01);
                    ctx.dfd012 = 0f;
                    delta      = (y - yv0) * dy10;
                    ctx.dfd01  = glm.Clamp(delta, 0f, 1f);
                }
                else
                {
                    continue;
                }


                DrawScanLine(ctx, y, xe, xd);
            }
        }