Рисовать в хуке Present(), не разрушая существующий контент

Я пишу универсальное оверлейное приложение (не чит) для полноэкранных приложений DX11.
Я полный новичок в DX11 и стараюсь быстро наверстать упущенное, так как у меня не хватает времени на проект. Надеюсь на вашу помощь.

Я вставляю dll и перехватываю DX11 Present(), кажется, работает довольно хорошо.
Используя цепочку обмена из Present(), я могу получить обработчик окна, устройство и контекст.

Мне не хватает понимания, я пытаюсь разобраться в существующем коде, руководствах и документах. Моим текущим подходом было демонстрационное «наложение», я хотел нарисовать треугольник и наложить его на существующую сцену.
Прямо сейчас я, кажется, стираю все существующие вещи вместо наложения.

Моя первая цель — наложить на простую прямоугольную коробку и добавить к ней существующее изображение в качестве текстуры. Любая помощь в отношении этой цели будет очень признательна.

Вот моя текущая демонстрационная функция наложения, которая вызывается в хуке 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
    }

Что я делаю не так ? Думаю, я сделал больше одной ошибки, учитывая, что ввожу эту функцию после того, как игра уже все подготовила.
Должен ли я использовать цепочку обмена из игры? Создать второй?
Я немного (сильно) запутался.


person John    schedule 23.02.2015    source источник
comment
Обновление: Скорее всего, проблемы возникают из-за того, что не восстанавливаются измененные буферы, сейчас мы работаем над тем, чтобы определить, какие буферы важны, а какие нет.   -  person John    schedule 24.02.2015


Ответы (1)


Это решено, у меня ушло довольно много времени, но проблема действительно заключалась в том, что буферы были повреждены. Это совершенно очевидно, я думаю, что не мог видеть этого раньше, потому что весь новый материал 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 строк кода.

person John    schedule 24.02.2015