Example #1
0
        //从小到大输入
        private void RasterBottomTriangle(VertexOut v1, VertexOut v2, VertexOut v3, BaseShader shader)
        {
            VertexOut left   = v1;
            VertexOut right  = v2;
            VertexOut dest   = v3;
            float     weight = 0;
            VertexOut newLeft;
            VertexOut newRight;

            if (left.posProjective.x > right.posProjective.x)
            {
                VertexOut tmp = left;
                left  = right;
                right = tmp;
            }

            int dy = (int)dest.posProjective.y - (int)left.posProjective.y + 1;

            for (int i = 0; i < dy; i++)
            {
                if (dy != 0)
                {
                    weight = (float)i / dy;
                }
                newLeft  = LerpVertexOut(left, dest, weight);
                newRight = LerpVertexOut(right, dest, weight);
                newLeft.posProjective.y  = left.posProjective.y + i;
                newRight.posProjective.y = left.posProjective.y + i;
                ScanLinePerRow(newLeft, newRight, shader);
            }
        }
Example #2
0
        //按列逐行扫描
        private void ScanLinePerRow(VertexOut left, VertexOut right, BaseShader shader)
        {
            VertexOut current;
            int       length = (int)right.posProjective.x - (int)left.posProjective.x;

            if (length == 0)
            {
                return;
            }
            for (int i = 0; i <= length; i++)
            {
                float weight = (float)i / length;
                current = LerpVertexOut(left, right, weight);

                if (shader.ZTest == true)
                {
                    if (current.posProjective.z >= 0.5f &&
                        current.posProjective.z > backBuffer.GetDepth((int)current.posProjective.x, (int)current.posProjective.y))
                    {
                        continue;
                    }
                }

                if (shader.ZWrite == true)
                {
                    backBuffer.DrawDepth((int)current.posProjective.x, (int)current.posProjective.y, current.posProjective.z);
                }

                current.posProjective.x = left.posProjective.x + i;
                current.posProjective.y = left.posProjective.y;

                //透视纹理处理
                shader.ProjectedMapRestore(current);

                //片段着色
                backBuffer.DrawPixel((int)current.posProjective.x, (int)current.posProjective.y, shader.FragmentShader(current));
            }
        }
Example #3
0
        public void Render()
        {
            ////测试画线函数------>>>>>>
            //VertexOut pA = new VertexOut();
            //pA.posProjective = new Vector4D(100,0,0,1);

            //VertexOut pB = new VertexOut();
            //pB.posProjective = new Vector4D(100, 100, 0, 1);

            //BresenhamLineRasterization(pA, pB);

            //return;
            ////测试画线函数<<<<<<<--------
            ///
            Vector3D tmp = scene.camera.transform.GetPosition();

            cameraPosition = new Vector3D(tmp.x, tmp.y, tmp.z);
            //cameraPosition.x = -cameraPosition.x;
            //cameraPosition.y = -cameraPosition.y;
            //cameraPosition.z = -cameraPosition.z;

            Vector3D up = new Vector3D(0, 1, 0);

            //up.x = -up.x;
            //up.y = -up.y;
            //up.z = -up.z;
            viewMatrix.SetLookAt(cameraPosition, new Vector3D(0, 0, 0), up);

            backBuffer.Clear();
            //scene.camera
            for (int i = 0; i < scene.gameObjects.Count; i++)
            {
                GameObject3D gameObject = scene.gameObjects[i];
                BaseShader   shader     = gameObject.meshRenderer.material.shader;
                shader.SetModelMatrix(gameObject.transform.ToMatrix());

                shader.SetViewMatrix(viewMatrix);
                shader.SetEyePos(cameraPosition);
                shader.SetProjectMatrix(projectMatrix);
                shader.SetLight(scene.light);

                //图元装配
                Mesh mesh = gameObject.meshRenderer.mesh;

                //Debug.LogError("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");

                for (int j = 0; j < mesh.indices.Length; j += 3)
                {
                    Vertex p1, p2, p3;
                    p1 = mesh.vertices[mesh.indices[j]];
                    p2 = mesh.vertices[mesh.indices[j + 1]];
                    p3 = mesh.vertices[mesh.indices[j + 2]];

                    //顶点着色(遍历三角形)
                    VertexOut vertexOut1, vertexOut2, vertexOut3;
                    vertexOut1 = shader.VertexShader(p1);
                    vertexOut2 = shader.VertexShader(p2);
                    vertexOut3 = shader.VertexShader(p3);

                    shader.ProjectedMap(vertexOut1);
                    shader.ProjectedMap(vertexOut2);
                    shader.ProjectedMap(vertexOut3);
                    //背面裁剪
                    if (shader.backFaceCulling)
                    {
                        if (polygonMode != PolygonMode.Wire && !BackFaceCulling(vertexOut1.posWorld, vertexOut2.posWorld, vertexOut3.posWorld))
                        {
                            continue;
                        }
                    }

                    //透视处理
                    PerspectiveDivision(vertexOut1);
                    PerspectiveDivision(vertexOut2);
                    PerspectiveDivision(vertexOut3);

                    //几何裁剪

                    //屏幕空间转换
                    vertexOut1.posProjective = Matrix4x4.MultiplyVector4D(viewPortMatrix, vertexOut1.posProjective);
                    vertexOut2.posProjective = Matrix4x4.MultiplyVector4D(viewPortMatrix, vertexOut2.posProjective);
                    vertexOut3.posProjective = Matrix4x4.MultiplyVector4D(viewPortMatrix, vertexOut3.posProjective);

                    //Debug.LogError("vertexOut1.posProjective " + vertexOut1.posProjective.x
                    //    + " " + vertexOut1.posProjective.y + " " + vertexOut1.posProjective.z );
                    //Debug.LogError("vertexOut2.posProjective " + vertexOut2.posProjective.x
                    //    + " " + vertexOut2.posProjective.y + " " + vertexOut2.posProjective.z );
                    //Debug.LogError("vertexOut3.posProjective " + vertexOut3.posProjective.x
                    //    + " " + vertexOut3.posProjective.y + " " + vertexOut3.posProjective.z );
                    //Debug.LogError("-----------------");

                    //片段着色
                    if (polygonMode == PolygonMode.Wire)
                    {
                        //线框模式
                        BresenhamLineRasterization(vertexOut1, vertexOut2);
                        BresenhamLineRasterization(vertexOut1, vertexOut3);
                        BresenhamLineRasterization(vertexOut2, vertexOut3);
                    }
                    else
                    {
                        //三角形填充模式
                        EdgeWalkingFillRasterization(vertexOut1, vertexOut2, vertexOut3, shader);
                    }
                }
            }
        }
Example #4
0
        private void EdgeWalkingFillRasterization(VertexOut v1, VertexOut v2, VertexOut v3, BaseShader shader)
        {
            //先把三个点按y从小到大排序
            VertexOut[] targets = { v1, v2, v3 };
            VertexOut   tmp;

            if (targets[0].posProjective.y > targets[1].posProjective.y)
            {
                tmp        = targets[0];
                targets[0] = targets[1];
                targets[1] = tmp;
            }
            if (targets[0].posProjective.y > targets[2].posProjective.y)
            {
                tmp        = targets[0];
                targets[0] = targets[2];
                targets[2] = tmp;
            }
            if (targets[1].posProjective.y > targets[2].posProjective.y)
            {
                tmp        = targets[1];
                targets[1] = targets[2];
                targets[2] = tmp;
            }

            if ((int)targets[0].posProjective.y == (int)targets[1].posProjective.y)
            {
                //下三角形
                RasterBottomTriangle(targets[0], targets[1], targets[2], shader);
            }
            else if ((int)targets[1].posProjective.y == (int)targets[2].posProjective.y)
            {
                //上三角形
                RasterTopTriangle(targets[0], targets[1], targets[2], shader);
            }
            else
            {
                //需要分割为上三角形下三角形
                float weight = (targets[1].posProjective.y - targets[0].posProjective.y)
                               / (targets[2].posProjective.y - targets[0].posProjective.y);

                VertexOut vertexOutNew = LerpVertexOut(targets[0], targets[2], weight);
                vertexOutNew.posProjective.y = targets[1].posProjective.y;

                RasterTopTriangle(targets[0], vertexOutNew, targets[1], shader);
                RasterBottomTriangle(vertexOutNew, targets[1], targets[2], shader);
            }
        }