🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Problems Rendering DirectXTK Game Overlay

Started by
0 comments, last by kqlq0 4 years, 2 months ago

Hello,

Recently I've been trying to create an overlay for a game I play with some friends. I would like to track in-game stats, and allow users to make events to see who can reach some goal within the game first.

To do this, I've been using the same techniques I originally read about the steam overlay (and discord overlay) using: hooking direct 3d interfaces.

I would like my overlay to support D3D11, and so I am hooking the swap chain's present function. It's nothing too complicated, just a VFT/VMT redirection.

It should also be said that I don't have much of a background in 3D rendering, so I'm trying to use the Microsoft DirectX Tool Kit where I can to simplify things (i.e. not having to create vertex buffers to render my interface).

The code below is what I'm currently working with, after having attempted to follow a tutorial on rendering basic shapes. The hook works, and my code is being called, but these basic shapes (a triangle, for now) never renders within the context of my game.

I'm certain I'm missing something within my code, considering my lack of knowledge when it comes to using D3D11. Would anyone happen to know what the problem may be?

Also, I've removed the error checking in the code for the sake of brevity. Just know: I'm using meticulous checks within my application, and stepping through my code within a debugger wherever possible. None of the calls in the code below have ever returned errors.

Thank you for your time.

    #define _CRT_SECURE_NO_WARNINGS
    #include <Windows.h>
     
    #include <stdio.h>
     
    #include <d3d11.h>
    #pragma comment(lib, "d3d11.lib")
     
    #define PRESENT_FN_IDX 8
     
     
     
    #include <DirectXColors.h>
    // DirectXTK -------------------------------------------------------------
    #include <VertexTypes.h>
    #include <Effects.h>
    #include <CommonStates.h>
    #include <SimpleMath.h>
    #include <PrimitiveBatch.h>
     
    using namespace DirectX;
    using namespace SimpleMath;
     
    std::unique_ptr<PrimitiveBatch<VertexPositionColor>> primitiveBatch;
     
    std::unique_ptr<BasicEffect> basicEffect;
     
    ID3D11InputLayout* inputLayout = NULL;
     
    void const* shaderByteCode;
    size_t byteCodeLength;
    // -----------------------------------------------------------------------
     
     
     
    ID3D11Device* g_pDevice = NULL;
    ID3D11DeviceContext* g_pContext = NULL;
    IDXGISwapChain* g_pSwapChain = NULL;
     
    typedef HRESULT(__stdcall* tPresent)(IDXGISwapChain* pThis, UINT SyncInternal, UINT Flags);
    tPresent oPresent = NULL;
     
    HRESULT __stdcall hkPresent(IDXGISwapChain* pThis, UINT SyncInternal, UINT Flags)
    {
    	// https://github.com/microsoft/DirectXTK/wiki/Simple-rendering#drawing-a-triangle
     
    	std::unique_ptr<CommonStates> states = std::make_unique<CommonStates>(g_pDevice);
     
    	g_pContext->OMSetBlendState(states->Opaque(), nullptr, 0xFFFFFFFF);
    	g_pContext->OMSetDepthStencilState(states->DepthNone(), 0);
    	g_pContext->RSSetState(states->CullNone());
     
    	basicEffect->Apply(g_pContext);
    	g_pContext->IASetInputLayout(inputLayout);
     
    	primitiveBatch->Begin();
     
    	primitiveBatch->DrawTriangle(
    		VertexPositionColor(Vector3(0.f, 0.5f, 0.5f), Colors::Yellow),
    		VertexPositionColor(Vector3(0.5f, -0.5f, 0.5f), Colors::Yellow),
    		VertexPositionColor(Vector3(-0.5f, -0.5f, 0.5f), Colors::Yellow)
    		);
     
    	primitiveBatch->End();
     
    	return oPresent(pThis, SyncInternal, Flags);
    }
     
    IDXGISwapChain* getSwapChain(PDWORD const pCode) { /* removed */ }
     
    DWORD WINAPI InitHook(LPVOID lpvParam)
    {
    	DWORD dwError = 0, dwOldProt = 0, dwPatchProt = PAGE_READWRITE;
    	PDWORD64 pSwapChainVFT = NULL;
     
    	g_pSwapChain = getSwapChain(&amp;dwError);
     
    	g_pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&amp;g_pDevice);
     
    	g_pDevice->GetImmediateContext(&amp;g_pContext);
    	
     
    	// DirectXTK -----------------------------------------------------------------------------
    	primitiveBatch = std::make_unique<PrimitiveBatch<VertexPositionColor>>(g_pContext);
     
    	basicEffect = std::make_unique<BasicEffect>(g_pDevice);
     
    	basicEffect->SetProjection(XMMatrixOrthographicOffCenterRH(0, 1920, 1080, 0, 0, 1));
    	basicEffect->SetVertexColorEnabled(true);
     
    	basicEffect->GetVertexShaderBytecode(&amp;shaderByteCode, &amp;byteCodeLength);
     
    	g_pDevice->CreateInputLayout(
    		VertexPositionColor::InputElements,
    		VertexPositionColor::InputElementCount,
    		shaderByteCode, byteCodeLength,
    		&amp;inputLayout
    		);
     
    	// ---------------------------------------------------------------------------------------
    	
     
    	pSwapChainVFT = *(PDWORD64*)g_pSwapChain;
     
    	oPresent = (tPresent)pSwapChainVFT[PRESENT_FN_IDX];
     
    	VirtualProtect((PVOID)pSwapChainVFT, 0x1000, dwPatchProt, &amp;dwOldProt);
    	
    	pSwapChainVFT[PRESENT_FN_IDX] = (DWORD64)hkPresent;
     
    	VirtualProtect((PVOID)pSwapChainVFT, 0x1000, dwOldProt, &amp;dwPatchProt);
     
    	return 0;
    }
     
    BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvParam)
    {
        // unsafe, will be removed after testing 
    	if (fdwReason == DLL_PROCESS_ATTACH)
    		CreateThread(NULL, 0, InitHook, NULL, 0, NULL);
     
    	return TRUE;
    }

This topic is closed to new replies.

Advertisement