Пример #1
0
        public override void Render()
        {
            if (mesh == null)
            {
                return;
            }
            Vertex[] tempVerts = new Vertex[] { new Vertex(), new Vertex(), new Vertex() };
            int      length    = mesh.Surfaces.Length;

            for (int i = 0; i < length; i++)
            {
                var surface = mesh.Surfaces[i];
                //不把变换后的结果保存顶点中,否则下次渲染顶点位置就不对了
                tempVerts[0].Copy(mesh.Vertices[surface.A]);
                tempVerts[1].Copy(mesh.Vertices[surface.B]);
                tempVerts[2].Copy(mesh.Vertices[surface.C]);

                Vector v1 = tempVerts[0].pos;
                Vector v2 = tempVerts[1].pos;
                Vector v3 = tempVerts[2].pos;

                //Obj -> World
                Vector wp1 = transform.ApplyObj2World(v1);
                Vector wp2 = transform.ApplyObj2World(v2);
                Vector wp3 = transform.ApplyObj2World(v3);

                //World -> view
                Vector vp1 = transform.ApplyWorldToView(wp1);
                Vector vp2 = transform.ApplyWorldToView(wp2);
                Vector vp3 = transform.ApplyWorldToView(wp3);

                //背面消隐
                if (TransformUtility.IsBackCulling(vp1, vp2, vp3))
                {
                    continue;
                }

                //view -> 齐次裁剪空间
                Vector cp1 = transform.ApplyViewToClip(vp1);
                Vector cp2 = transform.ApplyViewToClip(vp2);
                Vector cp3 = transform.ApplyViewToClip(vp3);

                // CVV裁剪
                //if(...)

                //变换到齐次裁剪空间后,w值保存view空间下的z信息
                //保存 1/z 用于后面求u'、v'

                tempVerts[0].onePerZ = 1 / cp1.w;
                tempVerts[1].onePerZ = 1 / cp2.w;
                tempVerts[2].onePerZ = 1 / cp3.w;

                tempVerts[0].u *= tempVerts[0].onePerZ;
                tempVerts[0].v *= tempVerts[0].onePerZ;
                tempVerts[1].u *= tempVerts[1].onePerZ;
                tempVerts[1].v *= tempVerts[1].onePerZ;
                tempVerts[2].u *= tempVerts[2].onePerZ;
                tempVerts[2].v *= tempVerts[2].onePerZ;

                //透视除法 齐次裁剪空间 -> NDC空间
                cp1 /= cp1.w;
                cp2 /= cp2.w;
                cp3 /= cp3.w;

                //屏幕映射 NDC空间下 -> 屏幕空间
                Vector sp1 = Screen.ComputeToScreenPos(cp1);
                Vector sp2 = Screen.ComputeToScreenPos(cp2);
                Vector sp3 = Screen.ComputeToScreenPos(cp3);

                tempVerts[0].pos = sp1;
                tempVerts[1].pos = sp2;
                tempVerts[2].pos = sp3;
                switch (Application.RenderType)
                {
                case RenderType.Wireframe:
                    graphics.DrawTriangleLine(tempVerts[0].pos, tempVerts[1].pos, tempVerts[2].pos, Color.Red);
                    break;

                case RenderType.Fill:
                    graphics.FillTriangle(tempVerts[0].pos, tempVerts[1].pos, tempVerts[2].pos, Color.Red);
                    break;

                case RenderType.VertexColor:
                    graphics.FillTriangle(tempVerts[0], tempVerts[1], tempVerts[2]);
                    break;

                case RenderType.Texture:
                    graphics.FillTriangle(tempVerts[0], tempVerts[1], tempVerts[2]);
                    break;
                }
            }
        }