Exemplo n.º 1
0
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        public void Render()
        {
            if (deviceLost)
            {
                AttemptRecovery();
            }
            if (deviceLost)
            {
                return;
            }

            device.RenderState.Lighting = false;
            device.RenderState.CullMode = Cull.CounterClockwise;                                  //右手系拣选

            device.SamplerState[0].MagFilter = D3DConfiguration.GetAppropriateTextureMagFilter(); //放大滤波
            device.SamplerState[0].MinFilter = D3DConfiguration.GetAppropriateTextureMinFilter(); //缩小滤波

            if (DisplayWireFrame == 1 || DisplayWireFrame == 2)                                   //显示贴图线框或纯线框
            {
                device.RenderState.FillMode = FillMode.WireFrame;
            }
            else             //显示贴图
            {
                device.RenderState.FillMode = FillMode.Solid;
            }

            if (DrawBackground)
            {
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(0xff, 0x0, 0xff), 1.0F, 0);
            }
            else
            {
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0F, 0);
            }

            device.RenderState.SlopeScaleDepthBias = 3F;             //全局性的加大所有Z-Depth间隔值,防止Z-Fighting
            //device.RenderState.DepthBias = 1F; //加性调整个别对象的Z-Depth值,其值因不同对象而异,因此效果远不及全局性调整SlopeScaleDepthBias好

            //处理Transparent Color Key的关键点:
            //只要alpha值大于等于1的点才显示并更新zbuf!即,alpha=0的点直接不画,也不会影响zbuf!
            device.RenderState.AlphaTestEnable = true;
            device.RenderState.AlphaFunction   = Compare.GreaterEqual;
            device.RenderState.ReferenceAlpha  = 1;

            //用于AlphaBlend的贴图Alpha混合参数,注意,AlphaBlend与AlphaTest是完全不同的概念
            device.RenderState.SourceBlend        = Blend.SourceAlpha;
            device.RenderState.DestinationBlend   = Blend.InvSourceAlpha;
            device.TextureState[0].ColorOperation = TextureOperation.Modulate;
            device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
            device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
            device.TextureState[0].AlphaOperation = TextureOperation.Modulate;
            device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
            device.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;

            device.BeginScene();
            {
                SetupMatrices();
                device.VertexFormat = CustomVertex.PositionColoredTextured.Format;

                device.SetStreamSource(0, mm.vexbuf, 0);

                //以下是无需alpha混合的贴图处理过程
                device.RenderState.AlphaBlendEnable = false;
                for (int i = 0; i < mm.texture.Length; i++)
                {
                    if (DisplayWireFrame == 2)                    //纯线框
                    {
                        device.SetTexture(0, null);
                    }
                    else                     //贴图线框或者是贴图
                    {
                        device.SetTexture(0, mm.texture[i]);
                    }

                    //必须首先绘制无Alpha混合的贴图(包括未知类型的贴图),否则将导致后继Alpha混合不正确
                    if (mbi.texturetype[i] != 2 && mbi.texturetype[i] != 4)
                    {
                        int count = (mm.txtoffset[i + 1] - mm.txtoffset[i]) / 3;
                        if (count != 0)
                        {
                            device.DrawPrimitives(PrimitiveType.TriangleList, mm.txtoffset[i], count);
                        }
                    }
                }

                //以下是需要alpha混合的贴图处理过程
                device.RenderState.AlphaBlendEnable = true;
                for (int i = 0; i < mm.texture.Length; i++)
                {
                    if (DisplayWireFrame == 2)                     //纯线框
                    {
                        device.SetTexture(0, null);
                    }
                    else                     //贴图线框或者是贴图
                    {
                        device.SetTexture(0, mm.texture[i]);
                    }

                    //然后再绘制贴图类型为2,4的区域,因为这些区域需要Alpha混合
                    //贴图的索引顺序其实部分决定了Alpha混合的顺序,所以值得特别注意!
                    //这里,无需担心光晕贴图和反射贴图会发生混合错误,因为前者永远是最后一个贴图
                    if (mbi.texturetype[i] == 2 || mbi.texturetype[i] == 4)
                    {
                        int count = (mm.txtoffset[i + 1] - mm.txtoffset[i]) / 3;
                        if (count != 0)
                        {
                            device.DrawPrimitives(PrimitiveType.TriangleList, mm.txtoffset[i], count);
                        }
                    }
                }

                //画其他东西之前,先把Alpha混合关了!
                device.RenderState.AlphaBlendEnable = false;

                if (DrawCoordinateAxies)
                {
                    axises.Render(device);
                }
            }
            device.EndScene();

            try
            {
                device.Present();
            }
            catch (DeviceLostException)
            {
                deviceLost = true;
            }
        }