private void OnRendering(object sender, EventArgs e)
        {
            Debug.Assert(_d3dimage.IsFrontBufferAvailable);

            if (DirectXStatus != DirectXStatus.Available)
            {
                return;
            }

            bool needToReset = false;

            try
            {
                if (Direct3D == null)
                {
                    InitializeDirect3D();
                }
                if (Device == null)
                {
                    InitializeDevice();
                    ForceRendering();
                }
                if (Device == null)
                {
                    // device might still be not available, so we'll just have to try again next time around
                    return;
                }

                if (_sizeChanged)
                {
                    _presentParameters.BackBufferWidth  = (int)ActualWidth;
                    _presentParameters.BackBufferHeight = (int)ActualHeight;
                    ReleaseBackBuffer();
                    OnDeviceLost(EventArgs.Empty);
                    Device.Reset(_presentParameters);
                    OnDeviceReset(EventArgs.Empty);
                    _sizeChanged = false;
                    ForceRendering();
                }

                bool needsRendering = ResetForceRendering();
                if (needsRendering)
                {
                    _d3dimage.Lock();
                    if (_d3dimage.IsFrontBufferAvailable)
                    {
                        Result result = Device.TestCooperativeLevel();
                        if (result.IsFailure)
                        {
                            // we'll change the status in the needToReset block below
                            DirectXStatus = DirectXStatus.Unavailable_Unknown;
                            throw new Direct3D9Exception("Device.TestCooperativeLevel() failed");
                        }

                        Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, new Color4(System.Drawing.Color.Black), 1, 0);
                        Device.BeginScene();

                        try
                        {
                            // call the user's method
                            OnMainLoop(EventArgs.Empty);
                        }
                        catch (Direct3D9Exception d3dex)
                        {
                            if (d3dex.Message.StartsWith("D3DERR_OUTOFVIDEOMEMORY"))
                            {
                                needToReset = true;
                            }
                            else
                            {
                                throw;
                            }
                        }
                        catch (Exception)
                        {
                            //MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [d] " + ex.ToString());
                            throw;
                        }

                        Device.EndScene();
                        Device.Present();
                    }
                    _backBufferSurface = Device.GetBackBuffer(0, 0);
                    _d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _backBufferSurface.ComPointer);
                    _d3dimage.AddDirtyRect(new Int32Rect(0, 0, _d3dimage.PixelWidth, _d3dimage.PixelHeight));
                    _d3dimage.Unlock();
                }
            }
            catch (Direct3D9Exception)
            {
                needToReset = true;
            }
            catch (Exception)
            {
                //MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [a] " + ex.ToString());
                throw;
            }

            if (needToReset)
            {
                try
                {
                    InitializeDirect3D();
                    InitializeDevice();
                    if (DirectXStatus != DirectXStatus.Available)
                    {
                        // we were once available (because we were able to enter the OnRender function), but now we're not available
                        // This could be due to a return from Ctrl-Alt-Del under XP and things just aren't ready yet.
                        // Keep everything nulled out and we'll just try the next time around.
                        ReleaseDevice();
                        ReleaseDirect3D();
                        DirectXStatus = DirectXStatus.Available;
                    }
                    else
                    {
                        // we're available now, that's good
                        // force a rendering next time around
                        ForceRendering();
                    }
                }
                catch (Direct3D9Exception)
                {
                    //MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [b] " + ex.ToString());
                    throw;
                }
                catch (Exception)
                {
                    //MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [c] " + ex.ToString());
                    throw;
                }
            }

            return;
        }
        /// <summary>
        /// Initializes the Device and starts up the d3dimage object
        /// </summary>
        private void InitializeDevice()
        {
            if (DirectXStatus != DirectXStatus.Available)
            {
                return;
            }

            Debug.Assert(Direct3D != null);

            ReleaseDevice();

            HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, _d3dimage.PixelWidth, _d3dimage.PixelHeight, "SlimDXControl", IntPtr.Zero);

            _presentParameters                        = new PresentParameters();
            _presentParameters.SwapEffect             = SwapEffect.Copy;
            _presentParameters.DeviceWindowHandle     = hwnd.Handle;
            _presentParameters.Windowed               = true;
            _presentParameters.BackBufferWidth        = ((int)ActualWidth <= 0) ? 1 : (int)ActualWidth;
            _presentParameters.BackBufferHeight       = ((int)ActualHeight <= 0) ? 1 : (int)ActualHeight;
            _presentParameters.BackBufferFormat       = _backbufferFormat;
            _presentParameters.AutoDepthStencilFormat = _depthStencilFormat;

            try
            {
                if (UseDeviceEx)
                {
                    _deviceEx = new DeviceEx((Direct3DEx)Direct3D, 0,
                                             DeviceType.Hardware,
                                             hwnd.Handle,
                                             _createFlags,
                                             _presentParameters);
                }
                else
                {
                    _device = new Device(Direct3D, 0,
                                         DeviceType.Hardware,
                                         hwnd.Handle,
                                         _createFlags,
                                         _presentParameters);
                }
            }
            catch (Direct3D9Exception)
            {
                DirectXStatus = DirectXStatus.Unavailable_Unknown;
                return;
            }
            // call the user's ones
            OnDeviceCreated(EventArgs.Empty);
            OnDeviceReset(EventArgs.Empty);

            {
                // is it the case that someone else is nulling these out on us?  seems so
                // this means we need to be careful not to let multiple copies of the delegate get onto the list
                // not sure what else we can do here...
                CompositionTarget.Rendering             -= OnRendering;
                _d3dimage.IsFrontBufferAvailableChanged -= OnIsFrontBufferAvailableChanged;
                CompositionTarget.Rendering             += OnRendering;
                _d3dimage.IsFrontBufferAvailableChanged += OnIsFrontBufferAvailableChanged;
            }

            _d3dimage.Lock();
            _backBufferSurface = Device.GetBackBuffer(0, 0);
            _d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _backBufferSurface.ComPointer);
            _d3dimage.Unlock();

            return;
        }
        /// <summary>
        /// Initializes the Direct3D objects and sets the Available flag
        /// </summary>
        private void InitializeDirect3D()
        {
            DirectXStatus = DirectXStatus.Unavailable_Unknown;

            ReleaseDevice();
            ReleaseDirect3D();

            // assume that we can't run at all under terminal services
            if (GetSystemMetrics(SM_REMOTESESSION) != 0)
            {
                DirectXStatus = DirectXStatus.Unavailable_RemoteSession;
                return;
            }

            int renderingTier = (RenderCapability.Tier >> 16);

            if (renderingTier < 2)
            {
                DirectXStatus = DirectXStatus.Unavailable_LowTier;
                return;
            }

#if USE_XP_MODE
            _direct3D   = new Direct3D();
            UseDeviceEx = false;
#else
            try
            {
                _direct3DEx = new Direct3DEx();
                UseDeviceEx = true;
            }
            catch
            {
                try
                {
                    _direct3D   = new Direct3D();
                    UseDeviceEx = false;
                }
                catch (Direct3DX9NotFoundException)
                {
                    DirectXStatus = DirectXStatus.Unavailable_MissingDirectX;
                    return;
                }
                catch
                {
                    DirectXStatus = DirectXStatus.Unavailable_Unknown;
                    return;
                }
            }
#endif

            bool   ok;
            Result result;

            ok = Direct3D.CheckDeviceType(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, true, out result);
            if (!ok)
            {
                //const int D3DERR_NOTAVAILABLE = -2005530518;
                //if (result.Code == D3DERR_NOTAVAILABLE)
                //{
                //   ReleaseDirect3D();
                //   Available = Status.Unavailable_NotReady;
                //   return;
                //}
                ReleaseDirect3D();
                return;
            }

            ok = Direct3D.CheckDepthStencilMatch(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, _depthStencilFormat, out result);
            if (!ok)
            {
                ReleaseDirect3D();
                return;
            }

            Capabilities deviceCaps = Direct3D.GetDeviceCaps(0, DeviceType.Hardware);
            if ((deviceCaps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
            {
                _createFlags |= CreateFlags.HardwareVertexProcessing;
            }
            else
            {
                _createFlags |= CreateFlags.SoftwareVertexProcessing;
            }

            DirectXStatus = DirectXStatus.Available;

            return;
        }
Exemple #4
0
		private void OnRendering(object sender, EventArgs e)
		{
			Debug.Assert(_d3dimage.IsFrontBufferAvailable);

			if(DirectXStatus != DirectXStatus.Available)
				return;

			bool needToReset = false;

			try
			{
				if(Direct3D == null)
				{
					InitializeDirect3D();
				}
				if(Device == null)
				{
					InitializeDevice();
					ForceRendering();
				}
				if(Device == null)
				{
					// device might still be not available, so we'll just have to try again next time around
					return;
				}

				if(_sizeChanged)
				{
					_presentParameters.BackBufferWidth = (int) ActualWidth;
					_presentParameters.BackBufferHeight = (int) ActualHeight;
					ReleaseBackBuffer();
					OnDeviceLost(EventArgs.Empty);
					Device.Reset(_presentParameters);
					OnDeviceReset(EventArgs.Empty);
					_sizeChanged = false;
					ForceRendering();
				}

				bool needsRendering = ResetForceRendering();
				if(needsRendering)
				{
					_d3dimage.Lock();
					if(_d3dimage.IsFrontBufferAvailable)
					{
						Result result = Device.TestCooperativeLevel();
						if(result.IsFailure)
						{
							// we'll change the status in the needToReset block below
							DirectXStatus = DirectXStatus.Unavailable_Unknown;
							throw new Direct3D9Exception("Device.TestCooperativeLevel() failed");
						}

						Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, new Color4(System.Drawing.Color.Black), 1, 0);
						Device.BeginScene();

						try
						{
							// call the user's method
							OnMainLoop(EventArgs.Empty);
						}
						catch(Direct3D9Exception d3dex)
						{
							if(d3dex.Message.StartsWith("D3DERR_OUTOFVIDEOMEMORY"))
							{
								needToReset = true;
							}
							else
							{
								throw;
							}
						}
						catch(Exception)
						{
							//MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [d] " + ex.ToString());
							throw;
						}

						Device.EndScene();
						Device.Present();

					}
					_backBufferSurface = Device.GetBackBuffer(0, 0);
					_d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _backBufferSurface.ComPointer);
					_d3dimage.AddDirtyRect(new Int32Rect(0, 0, _d3dimage.PixelWidth, _d3dimage.PixelHeight));
					_d3dimage.Unlock();
				}
			}
			catch(Direct3D9Exception)
			{
				needToReset = true;
			}
			catch(Exception)
			{
				//MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [a] " + ex.ToString());
				throw;
			}

			if(needToReset)
			{
				try
				{
					InitializeDirect3D();
					InitializeDevice();
					if(DirectXStatus != DirectXStatus.Available)
					{
						// we were once available (because we were able to enter the OnRender function), but now we're not available
						// This could be due to a return from Ctrl-Alt-Del under XP and things just aren't ready yet.
						// Keep everything nulled out and we'll just try the next time around.
						ReleaseDevice();
						ReleaseDirect3D();
						DirectXStatus = DirectXStatus.Available;
					}
					else
					{
						// we're available now, that's good
						// force a rendering next time around
						ForceRendering();
					}
				}
				catch(Direct3D9Exception)
				{
					//MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [b] " + ex.ToString());
					throw;
				}
				catch(Exception)
				{
					//MessageBox.Show(ex.Message, "Caught Exception in SlimDXControl.OnRendering() [c] " + ex.ToString());
					throw;
				}
			}

			return;
		}
Exemple #5
0
		/// <summary>
		/// Initializes the Device and starts up the d3dimage object
		/// </summary>
		private void InitializeDevice()
		{
			if(DirectXStatus != DirectXStatus.Available)
				return;

			Debug.Assert(Direct3D != null);

			ReleaseDevice();

			HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, _d3dimage.PixelWidth, _d3dimage.PixelHeight, "SlimDXControl", IntPtr.Zero);

			_presentParameters = new PresentParameters();
			_presentParameters.SwapEffect = SwapEffect.Copy;
			_presentParameters.DeviceWindowHandle = hwnd.Handle;
			_presentParameters.Windowed = true;
			_presentParameters.BackBufferWidth = ((int) ActualWidth < 0) ? 1 : (int) ActualWidth;
			_presentParameters.BackBufferHeight = ((int) ActualHeight < 0) ? 1 : (int) ActualHeight;
			_presentParameters.BackBufferFormat = _backbufferFormat;
			_presentParameters.AutoDepthStencilFormat = _depthStencilFormat;

			try
			{
				if(UseDeviceEx)
				{
					_deviceEx = new DeviceEx((Direct3DEx) Direct3D, 0,
					   DeviceType.Hardware,
					   hwnd.Handle,
					   _createFlags,
					   _presentParameters);
				}
				else
				{
					_device = new Device(Direct3D, 0,
					   DeviceType.Hardware,
					   hwnd.Handle,
					   _createFlags,
					   _presentParameters);
				}
			}
			catch(Direct3D9Exception)
			{
				DirectXStatus = DirectXStatus.Unavailable_Unknown;
				return;
			}
			// call the user's ones
			OnDeviceCreated(EventArgs.Empty);
			OnDeviceReset(EventArgs.Empty);

			{
				// is it the case that someone else is nulling these out on us?  seems so
				// this means we need to be careful not to let multiple copies of the delegate get onto the list
				// not sure what else we can do here...
				CompositionTarget.Rendering -= OnRendering;
				_d3dimage.IsFrontBufferAvailableChanged -= OnIsFrontBufferAvailableChanged;
				CompositionTarget.Rendering += OnRendering;
				_d3dimage.IsFrontBufferAvailableChanged += OnIsFrontBufferAvailableChanged;
			}

			_d3dimage.Lock();
			_backBufferSurface = Device.GetBackBuffer(0, 0);
			_d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _backBufferSurface.ComPointer);
			_d3dimage.Unlock();

			return;
		}
Exemple #6
0
		/// <summary>
		/// Initializes the Direct3D objects and sets the Available flag
		/// </summary>
		private void InitializeDirect3D()
		{
			DirectXStatus = DirectXStatus.Unavailable_Unknown;

			ReleaseDevice();
			ReleaseDirect3D();

			// assume that we can't run at all under terminal services
			if(GetSystemMetrics(SM_REMOTESESSION) != 0)
			{
				DirectXStatus = DirectXStatus.Unavailable_RemoteSession;
				return;
			}

			int renderingTier = (RenderCapability.Tier >> 16);
			if(renderingTier < 2)
			{
				DirectXStatus = DirectXStatus.Unavailable_LowTier;
				return;
			}

#if USE_XP_MODE
         _direct3D = new Direct3D();
         UseDeviceEx = false;
#else
			try
			{
				_direct3DEx = new Direct3DEx();
				UseDeviceEx = true;
			}
			catch
			{
				try
				{
					_direct3D = new Direct3D();
					UseDeviceEx = false;
				}
				catch(Direct3DX9NotFoundException)
				{
					DirectXStatus = DirectXStatus.Unavailable_MissingDirectX;
					return;
				}
				catch
				{
					DirectXStatus = DirectXStatus.Unavailable_Unknown;
					return;
				}
			}
#endif

			bool ok;
			Result result;

			ok = Direct3D.CheckDeviceType(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, true, out result);
			if(!ok)
			{
				//const int D3DERR_NOTAVAILABLE = -2005530518;
				//if (result.Code == D3DERR_NOTAVAILABLE)
				//{
				//   ReleaseDirect3D();
				//   Available = Status.Unavailable_NotReady;
				//   return;
				//}
				ReleaseDirect3D();
				return;
			}

			ok = Direct3D.CheckDepthStencilMatch(0, DeviceType.Hardware, _adapterFormat, _backbufferFormat, _depthStencilFormat, out result);
			if(!ok)
			{
				ReleaseDirect3D();
				return;
			}

			Capabilities deviceCaps = Direct3D.GetDeviceCaps(0, DeviceType.Hardware);
			if((deviceCaps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
				_createFlags |= CreateFlags.HardwareVertexProcessing;
			else
				_createFlags |= CreateFlags.SoftwareVertexProcessing;

			DirectXStatus = DirectXStatus.Available;

			return;
		}