在不破坏现有内容的情况下绘制Present()钩子

时间:2015-02-23 22:13:09

标签: c++ code-injection directx-11 dxgi

我正在为DX11全屏应用程序编写一个通用覆盖应用程序(不是作弊) 我是DX11的一个完整的新手,并试图快速赶上,因为我在项目的时间压力下。希望得到你的帮助。

我正在注入一个dll并挂钩DX11 Present(),它似乎工作得很好 使用Present()中的swapchain,我可以获得Window处理程序,Device和Context。

我缺乏很多理解,试图通过现有的代码,教程和文档爬行。 我目前的方法是演示"叠加",我想绘制一个三角形并将其叠加在现有场景上。
现在我似乎擦除了所有现有的东西,而不是覆盖。

我的第一个目标是覆盖一个简单的矩形框,并在其上添加现有图像作为纹理。任何有关该目标的帮助都将非常感激。

这是我当前的演示覆盖函数,它在Present()钩子中被调用。 DX11对象是一个结构,包含我从Present()交换链(游戏交换链)收集的东西。

void draw_simple_test()
{
    ID3D11InputLayout*          g_pInputLayout = NULL;
    ID3D11Buffer*               g_pVertexBuffer = NULL;
    ID3D11RenderTargetView*     g_pRenderTargetView = NULL;
    ID3D11VertexShader*         g_pVertexShader = NULL;
    ID3D11PixelShader*          g_pPixelShader = NULL;
    HRESULT hr = S_OK;
    CHAR* g_strVS =
        "void VS( in float4 posIn : POSITION,\n"
        "         out float4 posOut : SV_Position )\n"
        "{\n"
        "    // Output the vertex position, unchanged\n"
        "    posOut = posIn;\n"
        "}\n";

    CHAR* g_strPS =
        "void PS( out float4 colorOut : SV_Target )\n"
        "{\n"
        "    // Make each pixel yellow, with alpha = 1\n"
        "    colorOut = float4( 1.0f, 1.0f, 1.0f, 1.0f );\n"
        "}\n";


    // Create the render target view
    ID3D11Texture2D* pRenderTargetTexture;
    hr = DX11.SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pRenderTargetTexture);
    if (FAILED(hr))
        return; //hr

    hr = DX11.Device->CreateRenderTargetView(pRenderTargetTexture, NULL, &g_pRenderTargetView);
    pRenderTargetTexture->Release();


    float ClearColor[4] = { 1.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
    //DX11.BackBufferRT
    //DX11.Context->ClearRenderTargetView(g_pRenderTargetView, ClearColor); // clear whole view to color

    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
    ID3D10Blob* pBlobVS = NULL;
    ID3D10Blob* pBlobError = NULL;
    hr = D3DCompile(g_strVS, lstrlenA(g_strVS) + 1, "VS", NULL, NULL, "VS",
        "vs_4_0", dwShaderFlags, 0, &pBlobVS, &pBlobError);
    if (FAILED(hr))
    {
        if (pBlobError != NULL)
        {
            OutputDebugStringA((CHAR*)pBlobError->GetBufferPointer());
            pBlobError->Release();
        }
        return ;//hr
    }
    hr = DX11.Device->CreateVertexShader(pBlobVS->GetBufferPointer(), pBlobVS->GetBufferSize(),
        NULL, &g_pVertexShader);
    if (FAILED(hr))
        return ; //hr

    // Compile and create the pixel shader
    ID3D10Blob* pBlobPS = NULL;
    hr = D3DCompile(g_strPS, lstrlenA(g_strPS) + 1, "PS", NULL, NULL, "PS",
        "ps_4_0", dwShaderFlags, 0, &pBlobPS, &pBlobError);
    if (FAILED(hr))
    {
        if (pBlobError != NULL)
        {
            OutputDebugStringA((CHAR*)pBlobError->GetBufferPointer());
            pBlobError->Release();
        }
        return; //hr
    }
    hr = DX11.Device->CreatePixelShader(pBlobPS->GetBufferPointer(), pBlobPS->GetBufferSize(),
        NULL, &g_pPixelShader);
    if (FAILED(hr))
        return ;//hr
    pBlobPS->Release();


    // Create the input layout
    D3D11_INPUT_ELEMENT_DESC elements[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = _countof(elements);

    hr = DX11.Device->CreateInputLayout(elements, numElements, pBlobVS->GetBufferPointer(),
        pBlobVS->GetBufferSize(), &g_pInputLayout);
    if (FAILED(hr))
        return ;

    pBlobVS->Release();


    SimpleVertex vertices[] =
    {
        0.0f, 0.2f, 0.2f, // top
        0.5f, -0.5f, 0.5f, // left
        -0.5f, -0.5f, 0.5f, // right
    };
    D3D11_BUFFER_DESC bd;
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof(vertices);
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    bd.StructureByteStride = 0;
    D3D11_SUBRESOURCE_DATA initData;
    initData.pSysMem = vertices;
    hr = DX11.Device->CreateBuffer(&bd, &initData, &g_pVertexBuffer);
    if (FAILED(hr))
        return ;//hr



    // ---
    // zuweisen
    DX11.Context->IASetInputLayout(g_pInputLayout);

    UINT stride = sizeof(SimpleVertex);
    UINT offset = 0;
    DX11.Context->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);

    DX11.Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    DX11.Context->VSSetShader(g_pVertexShader, NULL, 0);

    DX11.Context->PSSetShader(g_pPixelShader, NULL, 0);

    RECT rc;
    GetClientRect(DX11.Window, &rc);
    D3D11_VIEWPORT vp;
    vp.Width = (FLOAT)(rc.right - rc.left);
    vp.Height = (FLOAT)(rc.bottom - rc.top);
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    DX11.Context->RSSetViewports(1, &vp);

    DX11.Context->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);


    DX11.Context->Draw(3, 0); //3 vertices start at 0
    //cleanup
    }

我做错了什么? 考虑到我在游戏准备完毕后注入了这个功能,我想我犯了不止一个错误 我应该使用游戏中的交换链吗?创建自己的第二个?
我有点(很多)迷路了。

1 个答案:

答案 0 :(得分:0)

它已经解决了,花了我一段时间,但问题确实是缓冲区受损了。 这很明显,我想我之前看不到,因为所有新DX的东西都让我不知所措。

这为我做了(并且应该坚持一段时间): 为了最大限度地减少影响,您只能将您实际使用的那些功能放在自己的绘图代码中。

m_pContext->AddRef();
m_pContext->IAGetPrimitiveTopology(&m_primitiveTopology);
m_pContext->IAGetInputLayout(&m_pInputLayout);
m_pContext->OMGetBlendState(&m_pBlendState, m_blendFactor, &m_sampleMask);
m_pContext->OMGetDepthStencilState(&m_pDepthStencilState, &m_stencilRef);

m_pContext->RSGetState(&m_pRasterizerState);

m_pContext->VSGetShader(&m_pVS, 256, &m_numVSClassInstances);
m_pContext->VSGetConstantBuffers(0, 4, m_pVSConstantBuffer);

m_pContext->PSGetShader(&m_pPS, 256, &m_numPSClassInstances);
m_pContext->PSGetShaderResources(0, 9, m_pPSSRV);
pContext->PSGetSamplers(0, 10, m_pSamplerState);
m_pContext->PSGetConstantBuffers(0, 3, m_ppConstantBuffers);
m_pContext->OMGetRenderTargetsAndUnorderedAccessViews(2, m_RTView, &m_DepthView, 0, 0, NULL);
m_pContext->RSGetViewports(&m_numViewports, m_RSViewports);
m_pContext->GSGetShader(&m_pGS, 256, &m_numGSClassInstances);
m_pContext->GSGetConstantBuffers(0, 2, m_pGSConstantBuffer);

m_pContext->GSGetShaderResources(0, 1, &m_pGSSRV);

m_pContext->HSGetShader(&m_pHS, 256, &m_numHSClassInstances);

m_pContext->DSGetShader(&m_pDS, 256, &m_numDSClassInstances);
m_pContext->DSGetSamplers(0, 3, m_dSSamplers);

m_pContext->IAGetVertexBuffers(0, 3, m_pVB, m_vertexStride, m_vertexOffset);
m_pContext->IAGetIndexBuffer(&m_pIndexBuffer, &m_indexFormat, &m_indexOffset);

需要在“释放”时调用'set'函数来恢复缓冲区。 只需选择实际使用的函数,在一个简单的例子中,它将是5-6行代码。