/// <summary> /// Initializes a new instance of the <see cref="D3D9"/> class. /// </summary> public D3D9() { // Create Direct3DEx device on Windows Vista/7/8 with a display configured to use // the Windows Display Driver Model (WDDM). Use Direct3D on any other platform. _direct3D = new Direct3DEx(); PresentParameters presentparams = new PresentParameters { Windowed = true, SwapEffect = SwapEffect.Discard, PresentationInterval = PresentInterval.Default, // The device back buffer is not used. BackBufferFormat = Format.Unknown, BackBufferWidth = 1, BackBufferHeight = 1, // Use dummy window handle. DeviceWindowHandle = GetDesktopWindow() }; _device = new DeviceEx(_direct3D, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams); }
public Graphics(RenderForm form, int width, int height) { reset = () => form.Invoke(new Action(() => { device.Reset(presentParameters); fontRenderer.Flush(); textureRenderer.Flush(); resized = false; })); form.UserResized += (sender, args) => Resize(form.ClientSize.Width, form.ClientSize.Height); presentParameters = new PresentParameters { Windowed = true, SwapEffect = SwapEffect.Discard, BackBufferFormat = Format.A8R8G8B8, BackBufferCount = 1, BackBufferWidth = width, BackBufferHeight = height, PresentationInterval = PresentInterval.One, MultiSampleType = MultisampleType.None, MultiSampleQuality = 0, PresentFlags = PresentFlags.LockableBackBuffer }; direct3D = new Direct3DEx(); device = new DeviceEx(direct3D, 0, DeviceType.Hardware, form.Handle, CREATE_FLAGS, presentParameters); fontRenderer = new FontRenderer(device); textureRenderer = new TextureRenderer(device); renderLocker.Reset(); }
private void StartD3D() { if (DX10ImageSource.ActiveClients != 0) return; D3DContext = new Direct3DEx(); PresentParameters presentparams = new PresentParameters(); presentparams.Windowed = true; presentparams.SwapEffect = SwapEffect.Discard; presentparams.DeviceWindowHandle = GetDesktopWindow(); presentparams.PresentationInterval = PresentInterval.Default; DX10ImageSource.D3DDevice = new DeviceEx(D3DContext, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams); }
public static void StartD3D(Window parentWindow) { _activeClients++; if (_activeClients > 1) return; _d3DContext = new Direct3DEx(); var presentParameters = new PresentParameters { Windowed = true, SwapEffect = SwapEffect.Discard, DeviceWindowHandle = new WindowInteropHelper(parentWindow).Handle, PresentationInterval = PresentInterval.Default }; _d3DDevice = new DeviceEx(_d3DContext, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentParameters); }
/// <summary> /// Creates a new instance of <see cref="SharpDXElement"/> class. /// Initializes the D3D9 runtime. /// </summary> public SharpDXElement() { image = new D3DImage(); var presentparams = new PresentParameters { Windowed = true, SwapEffect = SwapEffect.Discard, DeviceWindowHandle = GetDesktopWindow(), PresentationInterval = PresentInterval.Default }; direct3D = new Direct3DEx(); device9 = new DeviceEx(direct3D, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams); Unloaded += HandleUnloaded; }
public static void Unload() { if (_d3d != null) _d3d.Dispose(); _d3d = null; }
public static void Load() { if (_d3d == null) _d3d = new Direct3DEx(); }
// - private methods ------------------------------------------------------------- private void StartD3D() { if( Dx11ImageSource.ActiveClients != 0 ) { return; } var presentParams = GetPresentParameters(); var createFlags = CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve; Dx11ImageSource.D3DContext = new Direct3DEx(); Dx11ImageSource.D3DDevice = new DeviceEx( D3DContext, 0, DeviceType.Hardware, IntPtr.Zero, createFlags, presentParams ); }
/// <summary> /// Creates a device to represent the display adapter. /// </summary> /// <param name="direct3D">an instance of <see cref="SharpDX.Direct3D9.Direct3D"/></param> /// <param name="adapter">Ordinal number that denotes the display adapter. {{D3DADAPTER_DEFAULT}} is always the primary display adapter.</param> /// <param name="deviceType">Member of the <see cref="SharpDX.Direct3D9.DeviceType"/> enumerated type that denotes the desired device type. If the desired device type is not available, the method will fail.</param> /// <param name="controlHandle">The focus window alerts Direct3D when an application switches from foreground mode to background mode. See Remarks. For full-screen mode, the window specified must be a top-level window. For windowed mode, this parameter may be NULL only if the hDeviceWindow member of pPresentationParameters is set to a valid, non-NULL value.</param> /// <param name="createFlags">Combination of one or more options that control device creation. For more information, see {{D3DCREATE}}.</param> /// <param name="presentParameters">Pointer to a <see cref="SharpDX.Direct3D9.PresentParameters"/> structure, describing the presentation parameters for the device to be created. If BehaviorFlags specifies {{D3DCREATE_ADAPTERGROUP_DEVICE}}, pPresentationParameters is an array. Regardless of the number of heads that exist, only one depth/stencil surface is automatically created. For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order: User-specified nonzero ForcedRefreshRate registry key, if supported by the device. Application-specified nonzero refresh rate value in the presentation parameter. Refresh rate of the latest desktop mode, if supported by the device. 75 hertz if supported by the device. 60 hertz if supported by the device. Device default. An unsupported refresh rate will default to the closest supported refresh rate below it. For example, if the application specifies 63 hertz, 60 hertz will be used. There are no supported refresh rates below 57 hertz. pPresentationParameters is both an input and an output parameter. Calling this method may change several members including: If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns. If BackBufferFormat equals <see cref="SharpDX.Direct3D9.Format.Unknown"/> before the method is called, it will be changed when the method returns.</param> /// <param name="fullScreenDisplayMode">The full screen display mode.</param> /// <remarks> /// This method returns a fully working device interface, set to the required display mode (or windowed), and allocated with the appropriate back buffers. To begin rendering, the application needs only to create and set a depth buffer (assuming EnableAutoDepthStencil is FALSE in <see cref="SharpDX.Direct3D9.PresentParameters"/>). When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in <see cref="SharpDX.Direct3D9.PresentParameters"/>). The purpose of each window is: The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application. The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during {{Present}}. This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window. Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method. Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.) The methods {{Reset}}, <see cref="SharpDX.ComObject"/>, and {{TestCooperativeLevel}} must be called from the same thread that used this method to create a device. D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling CreateDevice, {{Reset}}, and {{CreateAdditionalSwapChain}}. This means the application does not have to query the current desktop format before calling CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified. If you attempt to create a device on a 0x0 sized window, CreateDevice will fail. /// </remarks> /// <unmanaged>HRESULT CreateDevice([None] UINT Adapter,[None] D3DDEVTYPE DeviceType,[None] HWND hFocusWindow,[None] int BehaviorFlags,[None] D3DPRESENT_PARAMETERS* pPresentationParameters,[None] IDirect3DDevice9** ppReturnedDeviceInterface)</unmanaged> public DeviceEx(Direct3DEx direct3D, int adapter, DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, PresentParameters[] presentParameters, DisplayModeEx[] fullScreenDisplayMode) : base(IntPtr.Zero) { direct3D.CreateDeviceEx(adapter, deviceType, controlHandle, (int)createFlags, presentParameters, fullScreenDisplayMode, this); }
/// <summary> /// Creates a new instance of <see cref="SharpDXElement"/> class. /// Initializes the D3D9 runtime. /// </summary> public SharpDXElement() { image = new D3DImage(); var presentparams = new PresentParameters { Windowed = true, SwapEffect = SwapEffect.Discard, DeviceWindowHandle = GetDesktopWindow(), PresentationInterval = PresentInterval.Default }; direct3D = new Direct3DEx(); device9 = new DeviceEx(direct3D, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams); resizeDelayTimer = new DispatcherTimer(DispatcherPriority.Normal); resizeDelayTimer.Interval = SendResizeDelay; resizeDelayTimer.Tick += HandleResizeDelayTimerTick; SizeChanged += HandleSizeChanged; Unloaded += HandleUnloaded; }
public override unsafe void Hook() { this.DebugMessage("Hook: Begin"); this.DebugMessage("Hook: Before device creation"); using (var d3d = new Direct3D()) { this.DebugMessage("Hook: Direct3D created"); using ( var device = new Device( d3d, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1 })) { this.id3dDeviceFunctionAddresses.AddRange(this.GetVTblAddresses(device.NativePointer, D3D9_DEVICE_METHOD_COUNT)); } } try { using (var d3dEx = new Direct3DEx()) { this.DebugMessage("Hook: Try Direct3DEx..."); using ( var deviceEx = new DeviceEx( d3dEx, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1 }, new DisplayModeEx() { Width = 800, Height = 600 })) { this.id3dDeviceFunctionAddresses.AddRange( this.GetVTblAddresses(deviceEx.NativePointer, D3D9_DEVICE_METHOD_COUNT, D3D9Ex_DEVICE_METHOD_COUNT)); this.supportsDirect3DEx = true; } } } catch (Exception) { throw; } this.DebugMessage("Setting up Direct3D hooks..."); this.Direct3DDevice_EndSceneHook = new HookData<Direct3D9Device_EndSceneDelegate>( this.id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.EndScene], new Direct3D9Device_EndSceneDelegate(this.EndSceneHook), this); this.Direct3DDevice_EndSceneHook.ReHook(); this.Hooks.Add(this.Direct3DDevice_EndSceneHook.Hook); this.Direct3DDevice_PresentHook = new HookData<Direct3D9Device_PresentDelegate>( this.id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.Present], new Direct3D9Device_PresentDelegate(this.PresentHook), this); this.Direct3DDevice_ResetHook = new HookData<Direct3D9Device_ResetDelegate>( this.id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.Reset], new Direct3D9Device_ResetDelegate(this.ResetHook), this); if (this.supportsDirect3DEx) { this.DebugMessage("Setting up Direct3DEx hooks..."); this.Direct3DDeviceEx_PresentExHook = new HookData<Direct3D9DeviceEx_PresentExDelegate>( this.id3dDeviceFunctionAddresses[(int)Direct3DDevice9ExFunctionOrdinals.PresentEx], new Direct3D9DeviceEx_PresentExDelegate(this.PresentExHook), this); this.Direct3DDeviceEx_ResetExHook = new HookData<Direct3D9DeviceEx_ResetExDelegate>( this.id3dDeviceFunctionAddresses[(int)Direct3DDevice9ExFunctionOrdinals.ResetEx], new Direct3D9DeviceEx_ResetExDelegate(this.ResetExHook), this); } this.Direct3DDevice_ResetHook.ReHook(); this.Hooks.Add(this.Direct3DDevice_ResetHook.Hook); this.Direct3DDevice_PresentHook.ReHook(); this.Hooks.Add(this.Direct3DDevice_PresentHook.Hook); if (this.supportsDirect3DEx) { this.Direct3DDeviceEx_PresentExHook.ReHook(); this.Hooks.Add(this.Direct3DDeviceEx_PresentExHook.Hook); this.Direct3DDeviceEx_ResetExHook.ReHook(); this.Hooks.Add(this.Direct3DDeviceEx_ResetExHook.Hook); } this.DebugMessage("Hook: End"); }
/// <summary> /// Releases the unmanaged resources used by an instance of the <see cref="D3D9"/> class /// and optionally releases the managed resources. /// </summary> /// <param name="disposing"> /// <see langword="true"/> to release both managed and unmanaged resources; /// <see langword="false"/> to release only unmanaged resources. /// </param> protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // Dispose managed resources. if (_device != null) { _device.Dispose(); _device = null; } if (_direct3D != null) { _direct3D.Dispose(); _direct3D = null; } } // Release unmanaged resources. _disposed = true; } }
static void ShutdownD3D9() { s_numActiveClients--; if (s_numActiveClients != 0) return; if (s_device != null) { s_device.Dispose(); s_device = null; } if (s_context != null) { s_context.Dispose(); s_context = null; } }
static void InitD3D9() { if (s_numActiveClients == 0) { s_context = new D3D9.Direct3DEx(); var presentparams = new D3D9.PresentParameters() { Windowed = true, SwapEffect = D3D9.SwapEffect.Discard, DeviceWindowHandle = GetDesktopWindow(), PresentationInterval = D3D9.PresentInterval.Immediate, }; s_device = new D3D9.DeviceEx(s_context, 0, D3D9.DeviceType.Hardware, IntPtr.Zero, D3D9.CreateFlags.HardwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve, presentparams); } s_numActiveClients++; }
internal AdapterInformationEx(Direct3DEx direct3D, int adapter) { this.direct3d = direct3D; Adapter = adapter; Details = direct3D.GetAdapterIdentifier(adapter, 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; }
private void ReleaseDirect3D() { if (direct3D != null) { if (!direct3D.IsDisposed) { direct3D.Dispose(); direct3D = null; } } if (direct3DEx != null) { if (!direct3DEx.IsDisposed) { direct3DEx.Dispose(); direct3DEx = null; } } }
/// <summary> /// Creates a device to represent the display adapter. /// </summary> /// <param name="direct3D">an instance of <see cref="SharpDX.Direct3D9.Direct3D"/></param> /// <param name="adapter">Ordinal number that denotes the display adapter. {{D3DADAPTER_DEFAULT}} is always the primary display adapter.</param> /// <param name="deviceType">Member of the <see cref="SharpDX.Direct3D9.DeviceType"/> enumerated type that denotes the desired device type. If the desired device type is not available, the method will fail.</param> /// <param name="controlHandle">The focus window alerts Direct3D when an application switches from foreground mode to background mode. See Remarks. For full-screen mode, the window specified must be a top-level window. For windowed mode, this parameter may be NULL only if the hDeviceWindow member of pPresentationParameters is set to a valid, non-NULL value.</param> /// <param name="createFlags">Combination of one or more options that control device creation. For more information, see {{D3DCREATE}}.</param> /// <param name="presentParameters">Pointer to a <see cref="SharpDX.Direct3D9.PresentParameters"/> structure, describing the presentation parameters for the device to be created. If BehaviorFlags specifies {{D3DCREATE_ADAPTERGROUP_DEVICE}}, pPresentationParameters is an array. Regardless of the number of heads that exist, only one depth/stencil surface is automatically created. For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order: User-specified nonzero ForcedRefreshRate registry key, if supported by the device. Application-specified nonzero refresh rate value in the presentation parameter. Refresh rate of the latest desktop mode, if supported by the device. 75 hertz if supported by the device. 60 hertz if supported by the device. Device default. An unsupported refresh rate will default to the closest supported refresh rate below it. For example, if the application specifies 63 hertz, 60 hertz will be used. There are no supported refresh rates below 57 hertz. pPresentationParameters is both an input and an output parameter. Calling this method may change several members including: If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns. If BackBufferFormat equals <see cref="SharpDX.Direct3D9.Format.Unknown"/> before the method is called, it will be changed when the method returns.</param> /// <remarks> /// This method returns a fully working device interface, set to the required display mode (or windowed), and allocated with the appropriate back buffers. To begin rendering, the application needs only to create and set a depth buffer (assuming EnableAutoDepthStencil is FALSE in <see cref="SharpDX.Direct3D9.PresentParameters"/>). When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in <see cref="SharpDX.Direct3D9.PresentParameters"/>). The purpose of each window is: The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application. The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during {{Present}}. This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window. Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method. Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.) The methods {{Reset}}, <see cref="SharpDX.ComObject"/>, and {{TestCooperativeLevel}} must be called from the same thread that used this method to create a device. D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling CreateDevice, {{Reset}}, and {{CreateAdditionalSwapChain}}. This means the application does not have to query the current desktop format before calling CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified. If you attempt to create a device on a 0x0 sized window, CreateDevice will fail. /// </remarks> /// <unmanaged>HRESULT CreateDevice([None] UINT Adapter,[None] D3DDEVTYPE DeviceType,[None] HWND hFocusWindow,[None] int BehaviorFlags,[None] D3DPRESENT_PARAMETERS* pPresentationParameters,[None] IDirect3DDevice9** ppReturnedDeviceInterface)</unmanaged> public DeviceEx(Direct3DEx direct3D, int adapter, SharpDX.Direct3D9.DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, params SharpDX.Direct3D9.PresentParameters[] presentParameters) : base(IntPtr.Zero) { direct3D.CreateDeviceEx(adapter, deviceType, controlHandle, (int)createFlags, presentParameters, null, this); }
/// <summary> /// Creates a device to represent the display adapter. /// </summary> /// <param name="direct3D">an instance of <see cref="SharpDX.Direct3D9.Direct3D"/></param> /// <param name="adapter">Ordinal number that denotes the display adapter. {{D3DADAPTER_DEFAULT}} is always the primary display adapter.</param> /// <param name="deviceType">Member of the <see cref="SharpDX.Direct3D9.DeviceType"/> enumerated type that denotes the desired device type. If the desired device type is not available, the method will fail.</param> /// <param name="controlHandle">The focus window alerts Direct3D when an application switches from foreground mode to background mode. See Remarks. For full-screen mode, the window specified must be a top-level window. For windowed mode, this parameter may be NULL only if the hDeviceWindow member of pPresentationParameters is set to a valid, non-NULL value.</param> /// <param name="createFlags">Combination of one or more options that control device creation. For more information, see {{D3DCREATE}}.</param> /// <param name="presentParameters">Pointer to a <see cref="SharpDX.Direct3D9.PresentParameters"/> structure, describing the presentation parameters for the device to be created. If BehaviorFlags specifies {{D3DCREATE_ADAPTERGROUP_DEVICE}}, pPresentationParameters is an array. Regardless of the number of heads that exist, only one depth/stencil surface is automatically created. For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order: User-specified nonzero ForcedRefreshRate registry key, if supported by the device. Application-specified nonzero refresh rate value in the presentation parameter. Refresh rate of the latest desktop mode, if supported by the device. 75 hertz if supported by the device. 60 hertz if supported by the device. Device default. An unsupported refresh rate will default to the closest supported refresh rate below it. For example, if the application specifies 63 hertz, 60 hertz will be used. There are no supported refresh rates below 57 hertz. pPresentationParameters is both an input and an output parameter. Calling this method may change several members including: If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns. If BackBufferFormat equals <see cref="SharpDX.Direct3D9.Format.Unknown"/> before the method is called, it will be changed when the method returns.</param> /// <remarks> /// This method returns a fully working device interface, set to the required display mode (or windowed), and allocated with the appropriate back buffers. To begin rendering, the application needs only to create and set a depth buffer (assuming EnableAutoDepthStencil is FALSE in <see cref="SharpDX.Direct3D9.PresentParameters"/>). When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in <see cref="SharpDX.Direct3D9.PresentParameters"/>). The purpose of each window is: The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application. The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during {{Present}}. This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window. Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method. Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.) The methods {{Reset}}, <see cref="SharpDX.ComObject"/>, and {{TestCooperativeLevel}} must be called from the same thread that used this method to create a device. D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling CreateDevice, {{Reset}}, and {{CreateAdditionalSwapChain}}. This means the application does not have to query the current desktop format before calling CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified. If you attempt to create a device on a 0x0 sized window, CreateDevice will fail. /// </remarks> /// <unmanaged>HRESULT CreateDevice([None] UINT Adapter,[None] D3DDEVTYPE DeviceType,[None] HWND hFocusWindow,[None] int BehaviorFlags,[None] D3DPRESENT_PARAMETERS* pPresentationParameters,[None] IDirect3DDevice9** ppReturnedDeviceInterface)</unmanaged> public DeviceEx(Direct3DEx direct3D, int adapter, DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, PresentParameters presentParameters) : base(IntPtr.Zero) { direct3D.CreateDeviceEx(adapter, deviceType, controlHandle, (int)createFlags, new[] { presentParameters }, null, this); }
/// <summary> /// Creates a device to represent the display adapter. /// </summary> /// <param name="direct3D">an instance of <see cref="SharpDX.Direct3D9.Direct3D"/></param> /// <param name="adapter">Ordinal number that denotes the display adapter. {{D3DADAPTER_DEFAULT}} is always the primary display adapter.</param> /// <param name="deviceType">Member of the <see cref="SharpDX.Direct3D9.DeviceType"/> enumerated type that denotes the desired device type. If the desired device type is not available, the method will fail.</param> /// <param name="controlHandle">The focus window alerts Direct3D when an application switches from foreground mode to background mode. See Remarks. For full-screen mode, the window specified must be a top-level window. For windowed mode, this parameter may be NULL only if the hDeviceWindow member of pPresentationParameters is set to a valid, non-NULL value.</param> /// <param name="createFlags">Combination of one or more options that control device creation. For more information, see {{D3DCREATE}}.</param> /// <param name="presentParameters">Pointer to a <see cref="SharpDX.Direct3D9.PresentParameters"/> structure, describing the presentation parameters for the device to be created. If BehaviorFlags specifies {{D3DCREATE_ADAPTERGROUP_DEVICE}}, pPresentationParameters is an array. Regardless of the number of heads that exist, only one depth/stencil surface is automatically created. For Windows 2000 and Windows XP, the full-screen device display refresh rate is set in the following order: User-specified nonzero ForcedRefreshRate registry key, if supported by the device. Application-specified nonzero refresh rate value in the presentation parameter. Refresh rate of the latest desktop mode, if supported by the device. 75 hertz if supported by the device. 60 hertz if supported by the device. Device default. An unsupported refresh rate will default to the closest supported refresh rate below it. For example, if the application specifies 63 hertz, 60 hertz will be used. There are no supported refresh rates below 57 hertz. pPresentationParameters is both an input and an output parameter. Calling this method may change several members including: If BackBufferCount, BackBufferWidth, and BackBufferHeight are 0 before the method is called, they will be changed when the method returns. If BackBufferFormat equals <see cref="SharpDX.Direct3D9.Format.Unknown"/> before the method is called, it will be changed when the method returns.</param> /// <param name="fullScreenDisplayMode">The full screen display mode.</param> /// <remarks> /// This method returns a fully working device interface, set to the required display mode (or windowed), and allocated with the appropriate back buffers. To begin rendering, the application needs only to create and set a depth buffer (assuming EnableAutoDepthStencil is FALSE in <see cref="SharpDX.Direct3D9.PresentParameters"/>). When you create a Direct3D device, you supply two different window parameters: a focus window (hFocusWindow) and a device window (the hDeviceWindow in <see cref="SharpDX.Direct3D9.PresentParameters"/>). The purpose of each window is: The focus window alerts Direct3D when an application switches from foreground mode to background mode (via Alt-Tab, a mouse click, or some other method). A single focus window is shared by each device created by an application. The device window determines the location and size of the back buffer on screen. This is used by Direct3D when the back buffer contents are copied to the front buffer during {{Present}}. This method should not be run during the handling of WM_CREATE. An application should never pass a window handle to Direct3D while handling WM_CREATE. Any call to create, release, or reset the device must be done using the same thread as the window procedure of the focus window. Note that D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, and D3DCREATE_SOFTWARE_VERTEXPROCESSING are mutually exclusive flags, and at least one of these vertex processing flags must be specified when calling this method. Back buffers created as part of the device are only lockable if D3DPRESENTFLAG_LOCKABLE_BACKBUFFER is specified in the presentation parameters. (Multisampled back buffers and depth surfaces are never lockable.) The methods {{Reset}}, <see cref="SharpDX.ComObject"/>, and {{TestCooperativeLevel}} must be called from the same thread that used this method to create a device. D3DFMT_UNKNOWN can be specified for the windowed mode back buffer format when calling CreateDevice, {{Reset}}, and {{CreateAdditionalSwapChain}}. This means the application does not have to query the current desktop format before calling CreateDevice for windowed mode. For full-screen mode, the back buffer format must be specified. If you attempt to create a device on a 0x0 sized window, CreateDevice will fail. /// </remarks> /// <unmanaged>HRESULT CreateDevice([None] UINT Adapter,[None] D3DDEVTYPE DeviceType,[None] HWND hFocusWindow,[None] int BehaviorFlags,[None] D3DPRESENT_PARAMETERS* pPresentationParameters,[None] IDirect3DDevice9** ppReturnedDeviceInterface)</unmanaged> public DeviceEx(Direct3DEx direct3D, int adapter, DeviceType deviceType, IntPtr controlHandle, CreateFlags createFlags, PresentParameters presentParameters, DisplayModeEx fullScreenDisplayMode) : base(IntPtr.Zero) { direct3D.CreateDeviceEx(adapter, deviceType, controlHandle, (int)createFlags, new[] {presentParameters}, fullScreenDisplayMode == null ? null : new[] {fullScreenDisplayMode}, this); }
public override void Hook() { this.DebugMessage("Hook: Begin"); // First we need to determine the function address for IDirect3DDevice9 Device device; id3dDeviceFunctionAddresses = new List<IntPtr>(); //id3dDeviceExFunctionAddresses = new List<IntPtr>(); this.DebugMessage("Hook: Before device creation"); using (Direct3D d3d = new Direct3D()) { using (var renderForm = new System.Windows.Forms.Form()) { using (device = new Device(d3d, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle })) { this.DebugMessage("Hook: Device created"); id3dDeviceFunctionAddresses.AddRange(GetVTblAddresses(device.NativePointer, D3D9_DEVICE_METHOD_COUNT)); } } } try { using (Direct3DEx d3dEx = new Direct3DEx()) { this.DebugMessage("Hook: Direct3DEx..."); using (var renderForm = new System.Windows.Forms.Form()) { using (var deviceEx = new DeviceEx(d3dEx, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle }, new DisplayModeEx() { Width = 800, Height = 600 })) { this.DebugMessage("Hook: DeviceEx created - PresentEx supported"); id3dDeviceFunctionAddresses.AddRange(GetVTblAddresses(deviceEx.NativePointer, D3D9_DEVICE_METHOD_COUNT, D3D9Ex_DEVICE_METHOD_COUNT)); _supportsDirect3D9Ex = true; } } } } catch (Exception) { _supportsDirect3D9Ex = false; } // We want to hook each method of the IDirect3DDevice9 interface that we are interested in // 42 - EndScene (we will retrieve the back buffer here) Direct3DDevice_EndSceneHook = new Hook<Direct3D9Device_EndSceneDelegate>( id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.EndScene], // On Windows 7 64-bit w/ 32-bit app and d3d9 dll version 6.1.7600.16385, the address is equiv to: // (IntPtr)(GetModuleHandle("d3d9").ToInt32() + 0x1ce09), // A 64-bit app would use 0xff18 // Note: GetD3D9DeviceFunctionAddress will output these addresses to a log file new Direct3D9Device_EndSceneDelegate(EndSceneHook), this); unsafe { // If Direct3D9Ex is available - hook the PresentEx if (_supportsDirect3D9Ex) { Direct3DDeviceEx_PresentExHook = new Hook<Direct3D9DeviceEx_PresentExDelegate>( id3dDeviceFunctionAddresses[(int)Direct3DDevice9ExFunctionOrdinals.PresentEx], new Direct3D9DeviceEx_PresentExDelegate(PresentExHook), this); } // Always hook Present also (device will only call Present or PresentEx not both) Direct3DDevice_PresentHook = new Hook<Direct3D9Device_PresentDelegate>( id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.Present], new Direct3D9Device_PresentDelegate(PresentHook), this); } // 16 - Reset (called on resolution change or windowed/fullscreen change - we will reset some things as well) Direct3DDevice_ResetHook = new Hook<Direct3D9Device_ResetDelegate>( id3dDeviceFunctionAddresses[(int)Direct3DDevice9FunctionOrdinals.Reset], // On Windows 7 64-bit w/ 32-bit app and d3d9 dll version 6.1.7600.16385, the address is equiv to: //(IntPtr)(GetModuleHandle("d3d9").ToInt32() + 0x58dda), // A 64-bit app would use 0x3b3a0 // Note: GetD3D9DeviceFunctionAddress will output these addresses to a log file new Direct3D9Device_ResetDelegate(ResetHook), this); /* * Don't forget that all hooks will start deactivated... * The following ensures that all threads are intercepted: * Note: you must do this for each hook. */ Direct3DDevice_EndSceneHook.Activate(); Hooks.Add(Direct3DDevice_EndSceneHook); Direct3DDevice_PresentHook.Activate(); Hooks.Add(Direct3DDevice_PresentHook); if (_supportsDirect3D9Ex) { Direct3DDeviceEx_PresentExHook.Activate(); Hooks.Add(Direct3DDeviceEx_PresentExHook); } Direct3DDevice_ResetHook.Activate(); Hooks.Add(Direct3DDevice_ResetHook); this.DebugMessage("Hook: End"); }
/// <summary> /// Create D3D9Ex context and OpenGL framebuffer /// </summary> /// <param name="handle"></param> /// <param name="hasDepthBuffer"></param> /// <param name="hasStencilBuffer"></param> private void CreateD3D9ExContext(IntPtr handle, bool hasDepthBuffer, bool hasStencilBuffer) { var d3d = new Direct3DEx(); int initW = Size.Width; int initH = Size.Height; this.presentparams = new PresentParameters(); this.presentparams.Windowed = true; this.presentparams.SwapEffect = SwapEffect.Discard; this.presentparams.DeviceWindowHandle = handle; this.presentparams.PresentationInterval = PresentInterval.Default; // FpuPreserve for WPF // Multithreaded so that resources are actually sharable between DX and GL this.device = new DeviceEx( d3d, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, this.presentparams); // create shared surface this.sharedSurface = Surface.CreateRenderTarget( this.device, initW, initH, Format.A8R8G8B8, MultisampleType.None, 0, false); #region OpenGL Interop this.wgl = new WGL_NV_DX_interop(); this.wglHandleDevice = wgl.WglDXOpenDeviceNV(device.NativePointer); this.glSharedSurface = GL.GenTexture(); this.fbo = GL.GenFramebuffer(); // refer D3D9 surface and OpenGL Texture2D this.wglHandleSharedSurface = wgl.WglDXRegisterObjectNV( this.wglHandleDevice, this.sharedSurface.NativePointer, (uint)this.glSharedSurface, (uint)TextureTarget.Texture2D, WGL_NV_DX_interop.WGL_ACCESS_READ_WRITE_NV); this.singleWglHandleSharedSurfaceArray = new IntPtr[] { this.wglHandleSharedSurface }; // setup framebuffer Console.WriteLine(GL.GetError()); GL.BindFramebuffer(FramebufferTarget.Framebuffer, this.fbo); Console.WriteLine(GL.GetError()); GL.FramebufferTexture2D( FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, this.glSharedSurface, 0); Console.WriteLine(GL.GetError()); if (hasDepthBuffer) { var depth = GL.GenRenderbuffer(); GL.FramebufferRenderbuffer( FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, depth); GL.DeleteRenderbuffer(depth); } if (hasStencilBuffer) { var stencil = GL.GenRenderbuffer(); GL.FramebufferRenderbuffer( FramebufferTarget.Framebuffer, FramebufferAttachment.StencilAttachment, RenderbufferTarget.Renderbuffer, stencil); GL.DeleteRenderbuffer(stencil); } GL.DrawBuffer((DrawBufferMode)FramebufferAttachment.ColorAttachment0); #endregion }