Я пишу универсальное оверлейное приложение (не чит) для полноэкранных приложений 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
}
Что я делаю не так ? Думаю, я сделал больше одной ошибки, учитывая, что ввожу эту функцию после того, как игра уже все подготовила.
Должен ли я использовать цепочку обмена из игры? Создать второй?
Я немного (сильно) запутался.