Advertisement
Guest User

DX11 Overlay

a guest
Apr 26th, 2014
538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.44 KB | None | 0 0
  1. #if defined(DEBUG) || defined(_DEBUG)
  2. #define _CRTDBG_MAP_ALLOC
  3. #include <crtdbg.h>
  4. #endif
  5.  
  6.  
  7.  
  8. using namespace DirectX;
  9.  
  10. std::wstring s2ws(const std::string& s)
  11. {
  12.     int len;
  13.     int slength = (int)s.length() + 1;
  14.     len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
  15.     wchar_t* buf = new wchar_t[len];
  16.     MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
  17.     std::wstring r(buf);
  18.     delete[] buf;
  19.     return r;
  20. }
  21.  
  22. #define ReleaseCOM(x) { if(x){ x->Release(); x = 0; } }
  23.  
  24. #ifdef _UNICODE
  25. #define _T(x) x
  26. #else
  27. #define _T(x)  L##x
  28. #endif
  29.  
  30. #if defined(DEBUG) | defined(_DEBUG)
  31. #ifndef HR
  32. #define HR(x)                                              \
  33. {                                                          \
  34.     HRESULT hr = (x);                                      \
  35. if (FAILED(hr))                                         \
  36. {                                                      \
  37.     DXTraceW(__FILE__, (DWORD)__LINE__, hr, _T(#x), true); \
  38. }                                                      \
  39. }
  40. #endif
  41. #else
  42. #ifndef HR
  43.     #define HR(x) (x)
  44. #endif
  45. #endif
  46.  
  47. class DXOverlay
  48. {
  49. public:
  50.     DXOverlay(String title, UINT width, UINT height, HINSTANCE inst, String target, UINT msaa);
  51.     bool MakeWindow();
  52.     int RunOverlay();
  53.     void SetToTarget();
  54.     virtual ~DXOverlay();
  55.     bool InitializeDX();
  56.     virtual void OnResize();
  57.     virtual void DrawScene() = 0;
  58.     virtual LRESULT MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  59.     void DrawString(XMFLOAT2 position,FXMVECTOR color, float scale, bool center, const char* Format, ...);
  60.     void DrawLine(FXMVECTOR pos1, FXMVECTOR pos2, FXMVECTOR color);
  61.     void DrawCircle(FXMVECTOR center, FXMVECTOR color, float radius, UINT samples);
  62. protected:
  63.     String WindowTitle;
  64.     UINT m_width;
  65.     UINT m_height;
  66.     HINSTANCE m_appInst;
  67.     HWND m_MainWndHandle;
  68.     String m_targetWindowName;
  69.     HWND m_targetApplication;
  70.     bool m_Paused;
  71.     bool m_Minimized;
  72.     bool m_Resizing;
  73.     UINT m_MSAAQualtiy;
  74.  
  75.     ID3D11Device* m_pDevice;
  76.     ID3D11DeviceContext* m_pImmediateDeviceContext;
  77.     ID3D11RenderTargetView* m_pRenderTargetView;
  78.     IDXGISwapChain* m_pSwapChain;
  79.     D3D_DRIVER_TYPE m_DriverType;
  80.     D3D11_VIEWPORT m_Viewport;
  81.     D3D11_BLEND_DESC m_BlendStateDesc;
  82.     ID3D11BlendState* m_pAlphaOnBlendState;
  83.     ID3D11BlendState* m_pAlphaOffBlendState;
  84.     ID3D11InputLayout* m_pBatchInputLayout;
  85.  
  86.     std::unique_ptr<CommonStates>                           m_upStates;
  87.     std::unique_ptr<EffectFactory>                          m_upFXFactory;
  88.     std::unique_ptr<SpriteBatch>                            m_upSprites;
  89.     std::unique_ptr<SpriteFont>                             m_upFont;
  90.     std::unique_ptr<PrimitiveBatch<VertexPositionColor>>    m_upBatch;
  91.     std::unique_ptr<BasicEffect>                            m_upBatchEffect;
  92. };
  93. namespace
  94. {
  95.     DXOverlay* DXInst = 0;
  96. }
  97. LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  98. {
  99.     // Forward hwnd on because we can get messages (e.g., WM_CREATE)
  100.     // before CreateWindow returns, and thus before mhMainWnd is valid.
  101.     return DXInst->MsgProc(hwnd, msg, wParam, lParam);
  102. }
  103. bool DXOverlay::MakeWindow()
  104. {
  105.     WNDCLASSEX wcex;
  106.  
  107.     wcex.cbSize = sizeof(WNDCLASSEX);
  108.  
  109.     wcex.style = CS_HREDRAW | CS_VREDRAW;
  110.     wcex.lpfnWndProc = MainWndProc;
  111.     wcex.cbClsExtra = 0;
  112.     wcex.cbWndExtra = 0;
  113.     wcex.hInstance = m_appInst;
  114.     wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
  115.     wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  116.     wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
  117.     wcex.lpszMenuName = WindowTitle.c_str();
  118.     wcex.lpszClassName = WindowTitle.c_str();
  119.     wcex.hIconSm = LoadIcon(0, IDI_APPLICATION);
  120.  
  121.  
  122.     if (!RegisterClassEx(&wcex))
  123.     {
  124.         return false;
  125.     }
  126.     //
  127.     m_MainWndHandle = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, WindowTitle.c_str(), WindowTitle.c_str(), WS_POPUP, 1, 1, m_width, m_height, 0, 0, 0, 0);
  128.  
  129.     SetLayeredWindowAttributes(m_MainWndHandle, 0, 0.0f, LWA_ALPHA);
  130.     SetLayeredWindowAttributes(m_MainWndHandle, 0, RGB(0, 0, 0), LWA_COLORKEY);
  131.     ShowWindow(m_MainWndHandle, SW_SHOW);
  132.  
  133.     const MARGINS Margin = { -1 };
  134.     HR(DwmExtendFrameIntoClientArea(m_MainWndHandle, &Margin));
  135.  
  136.     return true;
  137. }
  138. bool DXOverlay::InitializeDX()
  139. {
  140.     UINT createDeviceFlags = 0;
  141. #if defined(DEBUG) || defined(_DEBUG)  
  142.     createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
  143. #endif
  144.  
  145.     D3D_FEATURE_LEVEL featureLevel;
  146.     m_DriverType = D3D_DRIVER_TYPE_HARDWARE;
  147.     //HRESULT hr = D3D11CreateDevice(
  148.     //  0,                 // default adapter
  149.     //  m_DriverType,
  150.     //  0,                 // no software device
  151.     //  createDeviceFlags,
  152.     //  0, 0,              // default feature level array
  153.     //  D3D11_SDK_VERSION,
  154.     //  &m_pDevice,
  155.     //  &featureLevel,
  156.     //  &m_pImmediateDeviceContext);
  157.  
  158.  
  159.    
  160.  
  161.     //if (featureLevel != D3D_FEATURE_LEVEL_11_0)
  162.     //  return false;
  163.  
  164.     /*HR(m_pDevice->CheckMultisampleQualityLevels(
  165.         DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_MSAAQualtiy));*/
  166.  
  167.     //assert(m_MSAAQualtiy > 0);
  168.  
  169.     DXGI_SWAP_CHAIN_DESC swapdesc;
  170.     swapdesc.BufferDesc.Width = m_width;
  171.     swapdesc.BufferDesc.Height = m_height;
  172.     swapdesc.BufferDesc.RefreshRate.Numerator = 75;
  173.     swapdesc.BufferDesc.RefreshRate.Denominator = 1;
  174.     swapdesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  175.     swapdesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
  176.     swapdesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
  177.  
  178.     swapdesc.SampleDesc.Count = 4;
  179.     swapdesc.SampleDesc.Quality = m_MSAAQualtiy - 1;
  180.  
  181.     swapdesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  182.     swapdesc.BufferCount = 1;
  183.     swapdesc.OutputWindow = m_MainWndHandle;
  184.     swapdesc.Windowed = true;
  185.     swapdesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  186.     swapdesc.Flags = 0;
  187.  
  188.     HRESULT hr = D3D11CreateDeviceAndSwapChain(0, m_DriverType, 0, createDeviceFlags, 0, 0,
  189.         D3D11_SDK_VERSION, &swapdesc, &m_pSwapChain, &m_pDevice, &featureLevel, &m_pImmediateDeviceContext);
  190.  
  191.     if (FAILED(hr))
  192.         return false;
  193.  
  194.     /*IDXGIDevice* dxgiDevice = 0;
  195.     HR(m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice));
  196.  
  197.     IDXGIAdapter* dxgiAdapter = 0;
  198.     HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter));
  199.  
  200.     IDXGIFactory* dxgiFactory = 0;
  201.     HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory));
  202.  
  203.     HR(dxgiFactory->CreateSwapChain(m_pDevice, &swapdesc, &m_pSwapChain));
  204.  
  205.     ReleaseCOM(dxgiDevice);
  206.     ReleaseCOM(dxgiAdapter);
  207.     ReleaseCOM(dxgiFactory);*/
  208.  
  209.     ////////////DXTK STUFF/////////////
  210.     m_upStates.reset(new CommonStates(m_pDevice));
  211.     m_upSprites.reset(new SpriteBatch(m_pImmediateDeviceContext));
  212.     m_upFXFactory.reset(new EffectFactory(m_pDevice));
  213.     m_upFont.reset(new SpriteFont(m_pDevice, L"C:\\Users\\Steve\\Documents\\Visual Studio 2012\\Projects\\DX11Overlay\\Calibri.spritefont"));
  214.     m_upBatch.reset(new PrimitiveBatch<VertexPositionColor>(m_pImmediateDeviceContext));
  215.  
  216.     m_upBatchEffect.reset(new BasicEffect(m_pDevice));
  217.     m_upBatchEffect->SetVertexColorEnabled(true);
  218.  
  219.     void const* shaderByteCode;
  220.     size_t byteCodeLength;
  221.  
  222.     m_upBatchEffect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);
  223.  
  224.     HR(m_pDevice->CreateInputLayout(VertexPositionColor::InputElements,
  225.         VertexPositionColor::InputElementCount,
  226.         shaderByteCode, byteCodeLength,
  227.         &m_pBatchInputLayout));
  228.  
  229.     OnResize();
  230. }
  231. void DXOverlay::OnResize()
  232. {
  233.     XMMATRIX Projection = XMMatrixOrthographicOffCenterRH(0.0f, m_width, m_height, 0.0f, 0.0f, 1.0f); //XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
  234.     m_upBatchEffect->SetProjection(Projection);
  235.     m_upBatchEffect->SetWorld(XMMatrixIdentity());
  236.     m_upBatchEffect->SetView(XMMatrixIdentity()); //g_view
  237.     // Initialize the projection matrix
  238.  
  239.     assert(m_pImmediateDeviceContext);
  240.     assert(m_pDevice);
  241.     assert(m_pSwapChain);
  242.  
  243.     ReleaseCOM(m_pRenderTargetView);
  244.  
  245.     HR(m_pSwapChain->ResizeBuffers(1, m_width, m_height, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
  246.     ID3D11Texture2D* backBuffer;
  247.     HR(m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)));
  248.     HR(m_pDevice->CreateRenderTargetView(backBuffer, 0, &m_pRenderTargetView));
  249.     ReleaseCOM(backBuffer);
  250.  
  251.     m_pImmediateDeviceContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
  252.  
  253.     m_Viewport.TopLeftX = 0;
  254.     m_Viewport.TopLeftY = 0;
  255.     m_Viewport.Width = static_cast<float>(m_width);
  256.     m_Viewport.Height = static_cast<float>(m_height);
  257.     m_Viewport.MinDepth = 0.0f;
  258.     m_Viewport.MaxDepth = 1.0f;
  259.     m_pImmediateDeviceContext->RSSetViewports(1, &m_Viewport);
  260. }
  261. int DXOverlay::RunOverlay()
  262. {
  263.     MSG msg = { 0 };
  264.     while (msg.message != WM_QUIT)
  265.     {
  266.         // If there are Window messages then process them.
  267.         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  268.         {
  269.             TranslateMessage(&msg);
  270.             DispatchMessage(&msg);
  271.         }
  272.         else{
  273.             SetToTarget();
  274.             DrawScene();
  275.         }
  276.     }
  277.     return (int)msg.wParam;
  278. }
  279. void DXOverlay::SetToTarget()
  280. {
  281.     m_targetApplication = FindWindow(0, m_targetWindowName.c_str());
  282.     if (m_targetApplication)
  283.     {
  284.         RECT tClient, tSize;
  285.         GetClientRect(m_targetApplication, &tClient);
  286.         GetWindowRect(m_targetApplication, &tSize);
  287.  
  288.         DWORD dwStyle = GetWindowLong(m_targetApplication, GWL_STYLE);
  289.         int windowheight;
  290.         int windowwidth;
  291.         int clientheight;
  292.         int clientwidth;
  293.         int borderheight;
  294.         int borderwidth;
  295.         if (dwStyle & WS_BORDER)
  296.         {
  297.             windowwidth = tSize.right - tSize.left;
  298.             windowheight = tSize.bottom - tSize.top;
  299.  
  300.             clientwidth = tClient.right - tClient.left;
  301.             clientheight = tClient.bottom - tClient.top;
  302.  
  303.             borderheight = (windowheight - tClient.bottom);
  304.             borderwidth = (windowwidth - tClient.right) / 2; //only want one side
  305.             borderheight -= borderwidth; //remove bottom
  306.  
  307.             tSize.left += borderwidth;
  308.             tSize.top += borderheight;
  309.         }
  310.         m_width = clientwidth;
  311.         m_height = clientheight;
  312.         MoveWindow(m_MainWndHandle, tSize.left, tSize.top, clientwidth, clientheight, true);
  313.     }
  314. }
  315. void DXOverlay::DrawString(XMFLOAT2 position,FXMVECTOR color, float scale, bool center, const char* Format, ...)
  316. {
  317.     char Buffer[1024] = { '\0' };
  318.     va_list va_alist;
  319.     va_start(va_alist, Format);
  320.     vsprintf_s(Buffer, Format, va_alist);
  321.     va_end(va_alist);
  322.     String buf = Buffer;
  323.     std::wstring wbuf = s2ws(buf);
  324.  
  325.     XMFLOAT2 origin(0, 0);
  326.     if (center)
  327.     {
  328.         XMVECTOR size = m_upFont->MeasureString(wbuf.c_str());
  329.         float sizeX = XMVectorGetX(size);
  330.         float sizeY = XMVectorGetY(size);
  331.         origin = XMFLOAT2(sizeX / 2, sizeY / 2);
  332.     }
  333.  
  334.     m_upSprites->Begin(SpriteSortMode_Deferred);
  335.     m_upFont->DrawString(m_upSprites.get(), wbuf.c_str(), position, color, 0.0f, origin, scale, SpriteEffects_None, 0);
  336.     m_upSprites->End();
  337. }
  338. void DXOverlay::DrawLine(FXMVECTOR pos1, FXMVECTOR pos2, FXMVECTOR color)
  339. {
  340.     m_upBatchEffect->Apply(m_pImmediateDeviceContext);
  341.     m_pImmediateDeviceContext->IASetInputLayout(m_pBatchInputLayout);
  342.     m_upBatch->Begin();
  343.  
  344.     VertexPositionColor draw1(pos1, color);
  345.     VertexPositionColor draw2(pos2, color);
  346.     m_upBatch->DrawLine(draw1, draw2);
  347.     m_upBatch->End();
  348. }
  349. void DXOverlay::DrawCircle(FXMVECTOR center, FXMVECTOR color, float radius, UINT samples)
  350. {
  351.     float Angle = (360.0f / samples)*(3.1415926f / 180); //to radians
  352.  
  353.     float Cos = cos(Angle);
  354.     float Sin = sin(Angle);
  355.  
  356.     XMVECTOR vec = { radius, 0 };
  357.  
  358.     for (unsigned short i = 0; i < samples; ++i)
  359.     {
  360.         XMVECTOR rot = { Cos*XMVectorGetX(vec) - Sin*XMVectorGetY(vec), Sin*XMVectorGetX(vec) + Cos*XMVectorGetY(vec) };
  361.         rot += center;
  362.         vec += center;
  363.  
  364.         XMVECTOR pos1 = { XMVectorGetX(vec), XMVectorGetY(vec) };
  365.         XMVECTOR pos2 = { XMVectorGetX(rot), XMVectorGetY(rot) };
  366.         DrawLine(pos1, pos2, color);
  367.         vec = rot - center;
  368.     }
  369. }
  370. LRESULT DXOverlay::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  371. {
  372.  
  373.     switch (msg)
  374.     {
  375.         // WM_ACTIVATE is sent when the window is activated or deactivated.  
  376.         // We pause the game when the window is deactivated and unpause it
  377.         // when it becomes active.  
  378.     case WM_ACTIVATE:
  379.         return 0;
  380.     case WM_SIZE:
  381.         // Save the new client area dimensions.
  382.  
  383.         if (m_pDevice)
  384.         {
  385.             if (wParam == SIZE_MINIMIZED)
  386.             {
  387.                 m_Minimized = true;
  388.             }
  389.             else if (wParam == SIZE_MAXIMIZED)
  390.             {
  391.                 m_Minimized = false;
  392.                 OnResize();
  393.             }
  394.             else if (wParam == SIZE_RESTORED)
  395.             {
  396.                 if (m_Minimized)
  397.                 {
  398.                     m_Minimized = false;
  399.                     OnResize();
  400.                 }
  401.                 else if (m_Resizing){
  402.                     // If user is dragging the resize bars, we do not resize
  403.                     // the buffers here because as the user continuously
  404.                     // drags the resize bars, a stream of WM_SIZE messages are
  405.                     // sent to the window, and it would be pointless (and slow)
  406.                     // to resize for each WM_SIZE message received from dragging
  407.                     // the resize bars.  So instead, we reset after the user is
  408.                     // done resizing the window and releases the resize bars, which
  409.                     // sends a WM_EXITSIZEMOVE message.
  410.                 }
  411.                 else // API call such as SetWindowPos or mSwapChain->SetFullscreenState.
  412.                 {
  413.                     OnResize();
  414.                 }
  415.             }
  416.         }
  417.         return 0;
  418.  
  419.         // WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
  420.     case WM_ENTERSIZEMOVE:
  421.         m_Resizing = true;
  422.         return 0;
  423.  
  424.     case WM_EXITSIZEMOVE:
  425.         m_Resizing = false;
  426.         OnResize();
  427.         return 0;
  428.  
  429.     case WM_DESTROY:
  430.         PostQuitMessage(0);
  431.         return 0;
  432.  
  433.     case WM_MENUCHAR:
  434.         // Don't beep when we alt-enter.
  435.         return MAKELRESULT(0, MNC_CLOSE);
  436.  
  437.         // Catch this message so to prevent the window from becoming too small.
  438.     case WM_GETMINMAXINFO:
  439.         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
  440.         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200;
  441.         return 0;
  442.  
  443.     }
  444.  
  445.     return DefWindowProc(hwnd, msg, wParam, lParam);
  446. }
  447. DXOverlay::DXOverlay(String title, UINT width, UINT height, HINSTANCE inst, String target, UINT msaa)
  448. {
  449.     WindowTitle = title;
  450.     m_width = width;
  451.     m_height = height;
  452.     m_appInst = inst;
  453.     DXInst = this;//for msgproc
  454.     m_Paused = false;
  455.     m_Minimized = false;
  456.     m_Resizing = false;
  457.     m_MSAAQualtiy = msaa;
  458.     m_targetWindowName = target;
  459.     ZeroMemory(&m_Viewport, sizeof(D3D11_VIEWPORT));
  460. }
  461. DXOverlay::~DXOverlay()
  462. {
  463.     ReleaseCOM(m_pRenderTargetView);
  464.     ReleaseCOM(m_pDevice);
  465.     if (m_pImmediateDeviceContext)
  466.         m_pImmediateDeviceContext->ClearState();
  467.     ReleaseCOM(m_pImmediateDeviceContext);
  468.     ReleaseCOM(m_pSwapChain);
  469.  
  470.     m_upStates.release();
  471.     m_upFXFactory.release();
  472.     m_upSprites.release();
  473.     m_upFont.release();
  474.     m_upBatch.release();
  475.     m_upBatchEffect.release();
  476. }
  477.  
  478. class D3DApp :public DXOverlay
  479. {
  480. public:
  481.     D3DApp(String title, UINT width, UINT height, HINSTANCE inst, String target, UINT msaa);
  482.     ~D3DApp();
  483.     void DrawScene();
  484. };
  485.  
  486. D3DApp::D3DApp(String title, UINT width, UINT height, HINSTANCE inst, String target, UINT msaa) :DXOverlay(title, width, height, inst, target, msaa)
  487. {
  488.     //just call base class constructor
  489. }
  490. D3DApp::~D3DApp()
  491. {
  492.  
  493. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement