Пример #1
0
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool InitializeGraphics()
        {
            //初始化设备参数
            CreatePresentParameters(FSAA);

            Device.IsUsingEventHandlers = false;             //关闭MDX的自动事件布线机制!

            if (D3DConfiguration.SupportsHardwareVertexProcessing())
            {
                device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, present_params);
            }
            else
            {
                device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, present_params);
            }

            device.DeviceReset += new EventHandler(this.OnDeviceReset);
            device.DeviceLost  += new EventHandler(this.OnDeviceLost);

            axises = new CoordAxies(); //初始化坐标轴

            SetupDevice();             //重建所有资源

            camera = new FreeRotateCamera(mm.radius);

            return(true);
        }
Пример #2
0
        public void CreatePresentParameters(bool FSAA)
        {
            //初始化设备参数
            present_params = new PresentParameters();

#if FULL_SCREEN
            //全屏
            present_params.Windowed               = false;
            present_params.BackBufferCount        = 2;
            present_params.BackBufferWidth        = 1024;
            present_params.BackBufferHeight       = 768;
            present_params.BackBufferFormat       = Format.X8R8G8B8;
            present_params.SwapEffect             = SwapEffect.Flip;
            present_params.EnableAutoDepthStencil = true;
            present_params.AutoDepthStencilFormat = DepthFormat.D24X8;
#else
            //窗口
            present_params.Windowed         = true;
            present_params.BackBufferWidth  = ClientSize.Width;
            present_params.BackBufferHeight = ClientSize.Height;
            present_params.BackBufferCount  = 1;
            present_params.SwapEffect       = SwapEffect.Flip;

            present_params.EnableAutoDepthStencil = true;
            present_params.AutoDepthStencilFormat = D3DConfiguration.GetAppropriateDepthFormat();

            //谨慎开启全屏反锯齿FSAA:其性能冲击非常大
            if (FSAA)
            {
                int             quality;
                MultiSampleType type;

                D3DConfiguration.GetAppropriateMultiSampleType(out type, out quality);
                if (type == MultiSampleType.NonMaskable)
                {
                    present_params.SwapEffect         = SwapEffect.Discard;             //必须!
                    present_params.MultiSample        = type;                           //开启全屏反锯齿FSAA
                    present_params.MultiSampleQuality = quality - 1;                    //容许的最高级别
                }
            }
#endif
        }
Пример #3
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;
            }
        }