////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }