2015-03-09 21:03:46 +08:00
// ImGui Win32 + DirectX9 binding
2018-02-06 03:34:11 +08:00
// Implemented features:
// [X] User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
2016-03-24 18:00:47 +08:00
2015-11-29 19:19:30 +08:00
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
2015-10-13 23:53:43 +08:00
// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown().
2015-11-29 19:19:30 +08:00
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
2015-03-09 21:03:46 +08:00
// https://github.com/ocornut/imgui
2018-02-17 02:18:16 +08:00
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
2018-03-21 04:19:23 +08:00
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoSetMouseCursor flag.
2018-02-20 20:55:09 +08:00
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
2018-02-17 02:18:16 +08:00
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
2018-03-21 03:12:34 +08:00
// 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavEnableSetMousePos is set).
2018-02-17 02:18:16 +08:00
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
2018-01-29 21:38:46 +08:00
# include "imgui.h"
2015-03-09 21:03:46 +08:00
# include "imgui_impl_dx9.h"
// DirectX
2016-05-03 16:47:42 +08:00
# include <d3d9.h>
2015-03-09 21:03:46 +08:00
# define DIRECTINPUT_VERSION 0x0800
# include <dinput.h>
2018-02-20 20:55:09 +08:00
// Win32 data
2015-03-09 22:13:29 +08:00
static HWND g_hWnd = 0 ;
2015-03-09 21:03:46 +08:00
static INT64 g_Time = 0 ;
static INT64 g_TicksPerSecond = 0 ;
2018-03-04 03:15:10 +08:00
static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT ;
2018-02-20 20:55:09 +08:00
// DirectX data
2015-03-09 21:03:46 +08:00
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL ;
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL ;
2015-04-10 04:05:35 +08:00
static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL ;
2015-08-14 13:06:11 +08:00
static LPDIRECT3DTEXTURE9 g_FontTexture = NULL ;
static int g_VertexBufferSize = 5000 , g_IndexBufferSize = 10000 ;
2015-03-09 21:03:46 +08:00
struct CUSTOMVERTEX
{
2016-05-03 16:47:42 +08:00
float pos [ 3 ] ;
D3DCOLOR col ;
float uv [ 2 ] ;
2015-03-09 21:03:46 +08:00
} ;
# define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
2018-02-17 02:18:16 +08:00
// Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplDX9_RenderDrawData ( ImDrawData * draw_data )
2015-03-09 21:03:46 +08:00
{
2016-05-03 16:47:42 +08:00
// Avoid rendering when minimized
ImGuiIO & io = ImGui : : GetIO ( ) ;
if ( io . DisplaySize . x < = 0.0f | | io . DisplaySize . y < = 0.0f )
return ;
2015-08-14 13:13:20 +08:00
// Create and grow buffers if needed
2015-08-14 13:06:11 +08:00
if ( ! g_pVB | | g_VertexBufferSize < draw_data - > TotalVtxCount )
{
2015-08-14 13:13:20 +08:00
if ( g_pVB ) { g_pVB - > Release ( ) ; g_pVB = NULL ; }
2015-08-14 13:06:11 +08:00
g_VertexBufferSize = draw_data - > TotalVtxCount + 5000 ;
if ( g_pd3dDevice - > CreateVertexBuffer ( g_VertexBufferSize * sizeof ( CUSTOMVERTEX ) , D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY , D3DFVF_CUSTOMVERTEX , D3DPOOL_DEFAULT , & g_pVB , NULL ) < 0 )
return ;
}
if ( ! g_pIB | | g_IndexBufferSize < draw_data - > TotalIdxCount )
{
2015-08-14 13:13:20 +08:00
if ( g_pIB ) { g_pIB - > Release ( ) ; g_pIB = NULL ; }
2015-08-14 13:06:11 +08:00
g_IndexBufferSize = draw_data - > TotalIdxCount + 10000 ;
2015-11-08 19:00:31 +08:00
if ( g_pd3dDevice - > CreateIndexBuffer ( g_IndexBufferSize * sizeof ( ImDrawIdx ) , D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY , sizeof ( ImDrawIdx ) = = 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32 , D3DPOOL_DEFAULT , & g_pIB , NULL ) < 0 )
2015-08-14 13:06:11 +08:00
return ;
}
2016-05-16 08:02:09 +08:00
// Backup the DX9 state
IDirect3DStateBlock9 * d3d9_state_block = NULL ;
2016-05-16 16:54:52 +08:00
if ( g_pd3dDevice - > CreateStateBlock ( D3DSBT_ALL , & d3d9_state_block ) < 0 )
2016-05-16 08:02:09 +08:00
return ;
2016-04-12 00:33:16 +08:00
2015-03-09 21:03:46 +08:00
// Copy and convert all vertices into a single contiguous buffer
CUSTOMVERTEX * vtx_dst ;
2015-04-10 04:05:35 +08:00
ImDrawIdx * idx_dst ;
2015-07-08 10:17:07 +08:00
if ( g_pVB - > Lock ( 0 , ( UINT ) ( draw_data - > TotalVtxCount * sizeof ( CUSTOMVERTEX ) ) , ( void * * ) & vtx_dst , D3DLOCK_DISCARD ) < 0 )
2015-03-09 21:03:46 +08:00
return ;
2015-07-08 10:17:07 +08:00
if ( g_pIB - > Lock ( 0 , ( UINT ) ( draw_data - > TotalIdxCount * sizeof ( ImDrawIdx ) ) , ( void * * ) & idx_dst , D3DLOCK_DISCARD ) < 0 )
2015-04-10 04:05:35 +08:00
return ;
2015-07-08 10:17:07 +08:00
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
2015-03-09 21:03:46 +08:00
{
2015-07-08 10:17:07 +08:00
const ImDrawList * cmd_list = draw_data - > CmdLists [ n ] ;
2016-09-04 01:24:57 +08:00
const ImDrawVert * vtx_src = cmd_list - > VtxBuffer . Data ;
for ( int i = 0 ; i < cmd_list - > VtxBuffer . Size ; i + + )
2015-03-09 21:03:46 +08:00
{
2016-05-03 16:47:42 +08:00
vtx_dst - > pos [ 0 ] = vtx_src - > pos . x ;
vtx_dst - > pos [ 1 ] = vtx_src - > pos . y ;
vtx_dst - > pos [ 2 ] = 0.0f ;
2015-03-09 21:03:46 +08:00
vtx_dst - > col = ( vtx_src - > col & 0xFF00FF00 ) | ( ( vtx_src - > col & 0xFF0000 ) > > 16 ) | ( ( vtx_src - > col & 0xFF ) < < 16 ) ; // RGBA --> ARGB for DirectX9
2016-05-03 16:47:42 +08:00
vtx_dst - > uv [ 0 ] = vtx_src - > uv . x ;
vtx_dst - > uv [ 1 ] = vtx_src - > uv . y ;
2015-03-09 21:03:46 +08:00
vtx_dst + + ;
vtx_src + + ;
}
2016-09-04 01:24:57 +08:00
memcpy ( idx_dst , cmd_list - > IdxBuffer . Data , cmd_list - > IdxBuffer . Size * sizeof ( ImDrawIdx ) ) ;
idx_dst + = cmd_list - > IdxBuffer . Size ;
2015-03-09 21:03:46 +08:00
}
g_pVB - > Unlock ( ) ;
2015-04-10 04:05:35 +08:00
g_pIB - > Unlock ( ) ;
2016-05-16 16:54:52 +08:00
g_pd3dDevice - > SetStreamSource ( 0 , g_pVB , 0 , sizeof ( CUSTOMVERTEX ) ) ;
g_pd3dDevice - > SetIndices ( g_pIB ) ;
g_pd3dDevice - > SetFVF ( D3DFVF_CUSTOMVERTEX ) ;
2015-03-09 21:03:46 +08:00
2016-12-20 06:15:38 +08:00
// Setup viewport
D3DVIEWPORT9 vp ;
vp . X = vp . Y = 0 ;
vp . Width = ( DWORD ) io . DisplaySize . x ;
vp . Height = ( DWORD ) io . DisplaySize . y ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
g_pd3dDevice - > SetViewport ( & vp ) ;
2015-04-07 19:56:52 +08:00
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing
2016-05-16 16:54:52 +08:00
g_pd3dDevice - > SetPixelShader ( NULL ) ;
g_pd3dDevice - > SetVertexShader ( NULL ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_CULLMODE , D3DCULL_NONE ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_LIGHTING , false ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_ZENABLE , false ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_ALPHABLENDENABLE , true ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_ALPHATESTENABLE , false ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_BLENDOP , D3DBLENDOP_ADD ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ) ;
g_pd3dDevice - > SetRenderState ( D3DRS_SCISSORTESTENABLE , true ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLORARG1 , D3DTA_TEXTURE ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_MODULATE ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAARG1 , D3DTA_TEXTURE ) ;
g_pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAARG2 , D3DTA_DIFFUSE ) ;
g_pd3dDevice - > SetSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR ) ;
g_pd3dDevice - > SetSamplerState ( 0 , D3DSAMP_MAGFILTER , D3DTEXF_LINEAR ) ;
2015-03-09 21:03:46 +08:00
// Setup orthographic projection matrix
2016-05-03 16:47:42 +08:00
// Being agnostic of whether <d3dx9.h> or <DirectXMath.h> can be used, we aren't relying on D3DXMatrixIdentity()/D3DXMatrixOrthoOffCenterLH() or DirectX::XMMatrixIdentity()/DirectX::XMMatrixOrthographicOffCenterLH()
{
const float L = 0.5f , R = io . DisplaySize . x + 0.5f , T = 0.5f , B = io . DisplaySize . y + 0.5f ;
D3DMATRIX mat_identity = { { 1.0f , 0.0f , 0.0f , 0.0f , 0.0f , 1.0f , 0.0f , 0.0f , 0.0f , 0.0f , 1.0f , 0.0f , 0.0f , 0.0f , 0.0f , 1.0f } } ;
D3DMATRIX mat_projection =
{
2.0f / ( R - L ) , 0.0f , 0.0f , 0.0f ,
0.0f , 2.0f / ( T - B ) , 0.0f , 0.0f ,
0.0f , 0.0f , 0.5f , 0.0f ,
( L + R ) / ( L - R ) , ( T + B ) / ( B - T ) , 0.5f , 1.0f ,
} ;
g_pd3dDevice - > SetTransform ( D3DTS_WORLD , & mat_identity ) ;
g_pd3dDevice - > SetTransform ( D3DTS_VIEW , & mat_identity ) ;
g_pd3dDevice - > SetTransform ( D3DTS_PROJECTION , & mat_projection ) ;
}
2015-03-09 21:03:46 +08:00
// Render command lists
int vtx_offset = 0 ;
2015-04-10 04:05:35 +08:00
int idx_offset = 0 ;
2015-07-08 10:17:07 +08:00
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
2015-03-09 21:03:46 +08:00
{
2015-07-08 10:17:07 +08:00
const ImDrawList * cmd_list = draw_data - > CmdLists [ n ] ;
2016-09-04 01:24:57 +08:00
for ( int cmd_i = 0 ; cmd_i < cmd_list - > CmdBuffer . Size ; cmd_i + + )
2015-03-09 21:03:46 +08:00
{
2015-07-08 10:17:07 +08:00
const ImDrawCmd * pcmd = & cmd_list - > CmdBuffer [ cmd_i ] ;
if ( pcmd - > UserCallback )
2015-03-09 23:26:58 +08:00
{
2015-07-08 10:17:07 +08:00
pcmd - > UserCallback ( cmd_list , pcmd ) ;
2015-03-09 23:26:58 +08:00
}
else
{
2015-07-08 10:17:07 +08:00
const RECT r = { ( LONG ) pcmd - > ClipRect . x , ( LONG ) pcmd - > ClipRect . y , ( LONG ) pcmd - > ClipRect . z , ( LONG ) pcmd - > ClipRect . w } ;
2016-05-16 16:54:52 +08:00
g_pd3dDevice - > SetTexture ( 0 , ( LPDIRECT3DTEXTURE9 ) pcmd - > TextureId ) ;
g_pd3dDevice - > SetScissorRect ( & r ) ;
2016-09-04 01:24:57 +08:00
g_pd3dDevice - > DrawIndexedPrimitive ( D3DPT_TRIANGLELIST , vtx_offset , 0 , ( UINT ) cmd_list - > VtxBuffer . Size , idx_offset , pcmd - > ElemCount / 3 ) ;
2015-03-09 23:26:58 +08:00
}
2015-07-08 10:17:07 +08:00
idx_offset + = pcmd - > ElemCount ;
2015-03-09 21:03:46 +08:00
}
2016-09-04 01:24:57 +08:00
vtx_offset + = cmd_list - > VtxBuffer . Size ;
2015-03-09 21:03:46 +08:00
}
2016-04-12 00:33:16 +08:00
2016-05-16 08:02:09 +08:00
// Restore the DX9 state
d3d9_state_block - > Apply ( ) ;
d3d9_state_block - > Release ( ) ;
2015-03-09 21:03:46 +08:00
}
2018-03-21 04:19:23 +08:00
static bool ImGui_ImplWin32_UpdateMouseCursor ( )
2018-02-20 20:55:09 +08:00
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-03-21 04:19:23 +08:00
if ( io . ConfigFlags & ImGuiConfigFlags_NoSetMouseCursor )
return false ;
2018-02-20 20:55:09 +08:00
ImGuiMouseCursor imgui_cursor = io . MouseDrawCursor ? ImGuiMouseCursor_None : ImGui : : GetMouseCursor ( ) ;
if ( imgui_cursor = = ImGuiMouseCursor_None )
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
: : SetCursor ( NULL ) ;
}
else
{
// Hardware cursor type
LPTSTR win32_cursor = IDC_ARROW ;
switch ( imgui_cursor )
{
case ImGuiMouseCursor_Arrow : win32_cursor = IDC_ARROW ; break ;
case ImGuiMouseCursor_TextInput : win32_cursor = IDC_IBEAM ; break ;
case ImGuiMouseCursor_ResizeAll : win32_cursor = IDC_SIZEALL ; break ;
case ImGuiMouseCursor_ResizeEW : win32_cursor = IDC_SIZEWE ; break ;
case ImGuiMouseCursor_ResizeNS : win32_cursor = IDC_SIZENS ; break ;
case ImGuiMouseCursor_ResizeNESW : win32_cursor = IDC_SIZENESW ; break ;
case ImGuiMouseCursor_ResizeNWSE : win32_cursor = IDC_SIZENWSE ; break ;
}
: : SetCursor ( : : LoadCursor ( NULL , win32_cursor ) ) ;
}
2018-03-21 04:19:23 +08:00
return true ;
2018-02-20 20:55:09 +08:00
}
2018-04-02 23:31:51 +08:00
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
2018-03-29 05:32:02 +08:00
# ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
# endif
Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more)
2017-11-01 21:24:09 +08:00
// Process Win32 mouse/keyboard inputs.
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds.
2018-01-06 05:32:27 +08:00
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
2017-10-23 15:57:59 +08:00
IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler ( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam )
2015-03-09 21:03:46 +08:00
{
2018-01-22 03:58:50 +08:00
if ( ImGui : : GetCurrentContext ( ) = = NULL )
return 0 ;
2015-03-09 21:03:46 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
switch ( msg )
{
2018-01-06 05:32:27 +08:00
case WM_LBUTTONDOWN : case WM_LBUTTONDBLCLK :
case WM_RBUTTONDOWN : case WM_RBUTTONDBLCLK :
case WM_MBUTTONDOWN : case WM_MBUTTONDBLCLK :
2017-10-24 20:48:00 +08:00
{
int button = 0 ;
2018-01-06 04:16:35 +08:00
if ( msg = = WM_LBUTTONDOWN | | msg = = WM_LBUTTONDBLCLK ) button = 0 ;
if ( msg = = WM_RBUTTONDOWN | | msg = = WM_RBUTTONDBLCLK ) button = 1 ;
if ( msg = = WM_MBUTTONDOWN | | msg = = WM_MBUTTONDBLCLK ) button = 2 ;
2018-02-10 23:47:13 +08:00
if ( ! ImGui : : IsAnyMouseDown ( ) & & : : GetCapture ( ) = = NULL )
: : SetCapture ( hwnd ) ;
2017-10-24 20:48:00 +08:00
io . MouseDown [ button ] = true ;
2017-10-23 15:57:59 +08:00
return 0 ;
2017-10-24 20:48:00 +08:00
}
2017-10-23 15:43:13 +08:00
case WM_LBUTTONUP :
case WM_RBUTTONUP :
2015-08-25 23:54:47 +08:00
case WM_MBUTTONUP :
2017-10-24 20:48:00 +08:00
{
int button = 0 ;
if ( msg = = WM_LBUTTONUP ) button = 0 ;
if ( msg = = WM_RBUTTONUP ) button = 1 ;
if ( msg = = WM_MBUTTONUP ) button = 2 ;
io . MouseDown [ button ] = false ;
2018-02-10 23:47:13 +08:00
if ( ! ImGui : : IsAnyMouseDown ( ) & & : : GetCapture ( ) = = hwnd )
: : ReleaseCapture ( ) ;
2017-10-23 15:57:59 +08:00
return 0 ;
2017-10-24 20:48:00 +08:00
}
2015-03-09 21:03:46 +08:00
case WM_MOUSEWHEEL :
io . MouseWheel + = GET_WHEEL_DELTA_WPARAM ( wParam ) > 0 ? + 1.0f : - 1.0f ;
2017-10-23 15:57:59 +08:00
return 0 ;
2018-01-20 19:36:59 +08:00
case WM_MOUSEHWHEEL :
io . MouseWheelH + = GET_WHEEL_DELTA_WPARAM ( wParam ) > 0 ? + 1.0f : - 1.0f ;
return 0 ;
2015-03-09 21:03:46 +08:00
case WM_MOUSEMOVE :
io . MousePos . x = ( signed short ) ( lParam ) ;
2016-03-26 22:43:45 +08:00
io . MousePos . y = ( signed short ) ( lParam > > 16 ) ;
2017-10-23 15:57:59 +08:00
return 0 ;
2015-03-09 21:03:46 +08:00
case WM_KEYDOWN :
2017-10-23 16:01:18 +08:00
case WM_SYSKEYDOWN :
2015-03-14 18:49:26 +08:00
if ( wParam < 256 )
2015-03-09 21:03:46 +08:00
io . KeysDown [ wParam ] = 1 ;
2017-10-23 15:57:59 +08:00
return 0 ;
2015-03-09 21:03:46 +08:00
case WM_KEYUP :
2017-10-23 16:01:18 +08:00
case WM_SYSKEYUP :
2015-03-14 18:49:26 +08:00
if ( wParam < 256 )
2015-03-09 21:03:46 +08:00
io . KeysDown [ wParam ] = 0 ;
2017-10-23 15:57:59 +08:00
return 0 ;
2015-03-09 21:03:46 +08:00
case WM_CHAR :
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
if ( wParam > 0 & & wParam < 0x10000 )
io . AddInputCharacter ( ( unsigned short ) wParam ) ;
2017-10-23 15:57:59 +08:00
return 0 ;
2018-02-20 20:55:09 +08:00
case WM_SETCURSOR :
2018-03-21 04:19:23 +08:00
if ( LOWORD ( lParam ) = = HTCLIENT & & ImGui_ImplWin32_UpdateMouseCursor ( ) )
2018-02-20 20:55:09 +08:00
return 1 ;
return 0 ;
2015-03-09 21:03:46 +08:00
}
return 0 ;
}
2015-03-09 21:05:18 +08:00
bool ImGui_ImplDX9_Init ( void * hwnd , IDirect3DDevice9 * device )
2015-03-09 21:03:46 +08:00
{
2015-03-09 22:13:29 +08:00
g_hWnd = ( HWND ) hwnd ;
2015-03-09 21:03:46 +08:00
g_pd3dDevice = device ;
2015-03-09 22:13:29 +08:00
2016-03-26 22:43:45 +08:00
if ( ! QueryPerformanceFrequency ( ( LARGE_INTEGER * ) & g_TicksPerSecond ) )
2015-03-09 21:03:46 +08:00
return false ;
if ( ! QueryPerformanceCounter ( ( LARGE_INTEGER * ) & g_Time ) )
return false ;
2018-03-21 04:19:23 +08:00
// Setup back-end capabilities flags
2015-03-09 21:03:46 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-03-21 04:19:23 +08:00
io . BackendFlags | = ImGuiBackendFlags_HasMouseCursors ; // We can honor GetMouseCursor() values (optional)
io . BackendFlags | = ImGuiBackendFlags_HasSetMousePos ; // We can honor io.WantSetMousePos requests (optional, rarely used)
// Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
io . KeyMap [ ImGuiKey_Tab ] = VK_TAB ;
2015-03-09 21:03:46 +08:00
io . KeyMap [ ImGuiKey_LeftArrow ] = VK_LEFT ;
io . KeyMap [ ImGuiKey_RightArrow ] = VK_RIGHT ;
io . KeyMap [ ImGuiKey_UpArrow ] = VK_UP ;
2015-04-24 15:18:56 +08:00
io . KeyMap [ ImGuiKey_DownArrow ] = VK_DOWN ;
2015-07-03 11:43:07 +08:00
io . KeyMap [ ImGuiKey_PageUp ] = VK_PRIOR ;
io . KeyMap [ ImGuiKey_PageDown ] = VK_NEXT ;
2015-03-09 21:03:46 +08:00
io . KeyMap [ ImGuiKey_Home ] = VK_HOME ;
io . KeyMap [ ImGuiKey_End ] = VK_END ;
2018-01-08 22:30:39 +08:00
io . KeyMap [ ImGuiKey_Insert ] = VK_INSERT ;
2015-03-09 21:03:46 +08:00
io . KeyMap [ ImGuiKey_Delete ] = VK_DELETE ;
io . KeyMap [ ImGuiKey_Backspace ] = VK_BACK ;
2018-02-07 02:29:31 +08:00
io . KeyMap [ ImGuiKey_Space ] = VK_SPACE ;
2015-03-09 21:03:46 +08:00
io . KeyMap [ ImGuiKey_Enter ] = VK_RETURN ;
io . KeyMap [ ImGuiKey_Escape ] = VK_ESCAPE ;
io . KeyMap [ ImGuiKey_A ] = ' A ' ;
io . KeyMap [ ImGuiKey_C ] = ' C ' ;
io . KeyMap [ ImGuiKey_V ] = ' V ' ;
io . KeyMap [ ImGuiKey_X ] = ' X ' ;
io . KeyMap [ ImGuiKey_Y ] = ' Y ' ;
io . KeyMap [ ImGuiKey_Z ] = ' Z ' ;
2015-03-09 22:13:29 +08:00
io . ImeWindowHandle = g_hWnd ;
2015-03-09 21:03:46 +08:00
return true ;
}
2015-03-09 22:55:46 +08:00
void ImGui_ImplDX9_Shutdown ( )
{
ImGui_ImplDX9_InvalidateDeviceObjects ( ) ;
g_pd3dDevice = NULL ;
g_hWnd = 0 ;
}
2015-08-14 13:07:53 +08:00
static bool ImGui_ImplDX9_CreateFontsTexture ( )
2015-03-09 22:55:46 +08:00
{
2015-11-29 22:54:05 +08:00
// Build texture atlas
2015-03-09 22:55:46 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
unsigned char * pixels ;
int width , height , bytes_per_pixel ;
2016-02-08 16:03:43 +08:00
io . Fonts - > GetTexDataAsRGBA32 ( & pixels , & width , & height , & bytes_per_pixel ) ;
2015-03-09 22:55:46 +08:00
2015-11-29 22:54:05 +08:00
// Upload texture to graphics system
2015-08-14 13:06:11 +08:00
g_FontTexture = NULL ;
2016-05-03 16:47:42 +08:00
if ( g_pd3dDevice - > CreateTexture ( width , height , 1 , D3DUSAGE_DYNAMIC , D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT , & g_FontTexture , NULL ) < 0 )
2015-08-14 13:07:53 +08:00
return false ;
2015-03-09 22:55:46 +08:00
D3DLOCKED_RECT tex_locked_rect ;
2016-03-26 22:43:45 +08:00
if ( g_FontTexture - > LockRect ( 0 , & tex_locked_rect , NULL , 0 ) ! = D3D_OK )
2015-08-14 13:07:53 +08:00
return false ;
2015-03-09 22:55:46 +08:00
for ( int y = 0 ; y < height ; y + + )
memcpy ( ( unsigned char * ) tex_locked_rect . pBits + tex_locked_rect . Pitch * y , pixels + ( width * bytes_per_pixel ) * y , ( width * bytes_per_pixel ) ) ;
2015-08-14 13:06:11 +08:00
g_FontTexture - > UnlockRect ( 0 ) ;
2015-03-09 22:55:46 +08:00
// Store our identifier
2015-08-14 13:06:11 +08:00
io . Fonts - > TexID = ( void * ) g_FontTexture ;
2015-05-12 22:16:12 +08:00
2015-08-14 13:07:53 +08:00
return true ;
2015-03-09 22:55:46 +08:00
}
bool ImGui_ImplDX9_CreateDeviceObjects ( )
{
if ( ! g_pd3dDevice )
return false ;
2015-08-14 13:07:53 +08:00
if ( ! ImGui_ImplDX9_CreateFontsTexture ( ) )
return false ;
2015-03-09 22:55:46 +08:00
return true ;
}
2015-03-09 22:13:29 +08:00
void ImGui_ImplDX9_InvalidateDeviceObjects ( )
2015-03-09 21:03:46 +08:00
{
2015-03-09 22:13:29 +08:00
if ( ! g_pd3dDevice )
return ;
2015-03-09 21:03:46 +08:00
if ( g_pVB )
{
g_pVB - > Release ( ) ;
g_pVB = NULL ;
}
2015-04-10 04:05:35 +08:00
if ( g_pIB )
{
g_pIB - > Release ( ) ;
g_pIB = NULL ;
}
2017-06-02 17:23:35 +08:00
// At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both.
2017-06-02 17:28:48 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
IM_ASSERT ( g_FontTexture = = io . Fonts - > TexID ) ;
2017-06-02 17:23:35 +08:00
if ( g_FontTexture )
g_FontTexture - > Release ( ) ;
2015-10-19 01:05:04 +08:00
g_FontTexture = NULL ;
2017-06-02 17:23:35 +08:00
io . Fonts - > TexID = NULL ;
2015-03-09 22:13:29 +08:00
}
2015-03-09 21:03:46 +08:00
void ImGui_ImplDX9_NewFrame ( )
{
2015-08-14 13:06:11 +08:00
if ( ! g_FontTexture )
2015-03-09 22:55:46 +08:00
ImGui_ImplDX9_CreateDeviceObjects ( ) ;
2015-03-09 21:03:46 +08:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2015-03-09 22:13:29 +08:00
// Setup display size (every frame to accommodate for window resizing)
RECT rect ;
GetClientRect ( g_hWnd , & rect ) ;
io . DisplaySize = ImVec2 ( ( float ) ( rect . right - rect . left ) , ( float ) ( rect . bottom - rect . top ) ) ;
2015-03-09 21:03:46 +08:00
// Setup time step
INT64 current_time ;
2016-03-26 22:43:45 +08:00
QueryPerformanceCounter ( ( LARGE_INTEGER * ) & current_time ) ;
2015-03-09 21:03:46 +08:00
io . DeltaTime = ( float ) ( current_time - g_Time ) / g_TicksPerSecond ;
g_Time = current_time ;
// Read keyboard modifiers inputs
io . KeyCtrl = ( GetKeyState ( VK_CONTROL ) & 0x8000 ) ! = 0 ;
io . KeyShift = ( GetKeyState ( VK_SHIFT ) & 0x8000 ) ! = 0 ;
2015-03-13 17:49:38 +08:00
io . KeyAlt = ( GetKeyState ( VK_MENU ) & 0x8000 ) ! = 0 ;
2016-04-03 00:22:40 +08:00
io . KeySuper = false ;
2015-03-09 21:03:46 +08:00
// io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events
// io.MousePos : filled by WM_MOUSEMOVE events
// io.MouseDown : filled by WM_*BUTTON* events
// io.MouseWheel : filled by WM_MOUSEWHEEL events
2018-03-21 03:12:34 +08:00
// Set OS mouse position if requested (only used when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if ( io . WantSetMousePos )
2016-07-31 05:17:11 +08:00
{
POINT pos = { ( int ) io . MousePos . x , ( int ) io . MousePos . y } ;
ClientToScreen ( g_hWnd , & pos ) ;
SetCursorPos ( pos . x , pos . y ) ;
}
2018-02-20 20:55:09 +08:00
// Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io . MouseDrawCursor ? ImGuiMouseCursor_None : ImGui : : GetMouseCursor ( ) ;
if ( g_LastMouseCursor ! = mouse_cursor )
{
g_LastMouseCursor = mouse_cursor ;
ImGui_ImplWin32_UpdateMouseCursor ( ) ;
}
2015-05-01 17:25:15 +08:00
Examples: Added a bunch of comments/referencs related to io.WantCaptureMouse, io.WantCaptureKeyboard (#1262, #1237, #1219, #635, #1058, #1051, #912, #533, #703, #446, #459, #364, #213, #52, and more)
2017-11-01 21:24:09 +08:00
// Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application.
2015-03-09 21:03:46 +08:00
ImGui : : NewFrame ( ) ;
}