如何在

时间:2017-06-01 23:20:43

标签: hook overlay directx-9 hud

我试图挂钩IDirect3DDevice9::Present::EndScene并在D3D9应用程序中的其他所有内容上渲染我自己的叠加层(现在,它只是一个简单的矩形),但是我的叠加层似乎随机出现并消失。我目前使用的绘图代码是:

typedef struct CUSTOMVERTEX {
    float x, y, z, rwh;
    DWORD color;
};

#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

void draw() {
    // the positions are just for testing purposes, so they don't really make sense
    CUSTOMVERTEX vertices[] = {
        { 0, 0, 0, 1.0f, D3DCOLOR_XRGB(255, 255, 255) },
        { 0, cursor_pos.y+500, 0, 1.0f, D3DCOLOR_XRGB(127, 255, 255) },
        { cursor_pos.x, cursor_pos.y, 0, 1.0f, D3DCOLOR_XRGB(255,255, 255) },
        { cursor_pos.x, 600, 0, 1.0f, D3DCOLOR_XRGB(127, 0, 0) }
    };

    if (vBuffer == 0) return;

    VOID* pVoid; 

    vBuffer->Lock(0, 0, &pVoid, 0); 
    memcpy(pVoid, vertices, sizeof(vertices));    
    vBuffer->Unlock(); 

    d3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
    d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

    D3DMATRIX orthographicMatrix;
    D3DMATRIX identityMatrix;

    // MAKE_D3DMATRIX should be equivalent to D3DXMATRIX constructor
    D3DMATRIX viewMatrix = MAKE_D3DMATRIX( 
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        ((float)-(get_window_width()/2)), ((float)-(get_window_height()/ 2)), 0, 1
    );
    // MAKE_ORTHO_LH is equivalent to D3DMatrixOrthoLH
    MAKE_ORTHO_LH(&orthographicMatrix, (FLOAT)get_window_width(), (FLOAT)get_window_height(), -1.0, 1.0); 

    // and this to D3DMatrixIdentity
    MAKE_IDENTITY(&identityMatrix); // and this to D3DMatrixIdentity

    d3dDevice->SetTransform(D3DTS_PROJECTION, &orthographicMatrix);
    d3dDevice->SetTransform(D3DTS_WORLD, &identityMatrix);
    d3dDevice->SetTransform(D3DTS_VIEW, &viewMatrix);

    d3dDevice->SetRenderState(D3DRS_ZENABLE, false);
    d3dDevice->SetFVF(CUSTOMFVF);
    d3dDevice->SetStreamSource(0, vBuffer, 0, sizeof(CUSTOMVERTEX));
    d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
    d3dDevice->SetRenderState(D3DRS_ZENABLE, true);
}

我似乎无法弄清楚为什么这会导致叠加层在看似随机的时间点突然出现。我错过了什么?

1 个答案:

答案 0 :(得分:0)

我找到了一种简单的方法将我的东西直接渲染到后台缓冲区(在CPU上):

IDirect3DSwapChain9 *sc;
if (FAILED(d3dDevice->GetSwapChain(0, &sc))) {
    PRINT("GetSwapChain failed\n");
    return;
}

IDirect3DSurface9 *s;
if (FAILED(sc->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &s))) {
    PRINT("GetBackBuffer failed\n");
    return;
}

D3DLOCKED_RECT r;
if (FAILED(s->LockRect(&r, NULL, D3DLOCK_DONOTWAIT))) {
    PRINT("LockRect failed\n");
    return;
}

// here, find out pixel format and manipulate 
// pixel buffer through r->pBits, using r->Pitch accordingly

s->UnlockRect();

s->Release();
sc->Release();

很可能会导致性能下降,但在我的应用程序中,这并没有什么不同。更优化的方法是利用GPU的hwacceled渲染功能,但我目前缺乏D3D知识。