my program use Windows Desktop Duplication API to do screen capture,the captured image is stored in a D3D11 texture,so I use "WGL_NV_DX_interop2" extension to copy the D3D texture to a OpenGL texture,because the screen capture task and OpenGL rendering task is running on different thread,I create a D3D texture named "tex_exchange", and register it as gl texture obj,the screen capture task copy its rendering result to tex_exchange,and OpenGL task copy tex_exchange's content to a gl texture; but I found when OpenGL task do texture copying, the screen capture will report a error, the D3D api report error is ID3D11Device::CreateShaderResourceView(), and the error code is 0x887A0005,is seems my texture copy code has some problem,so I post some code of my program,to hope some helps;
// the function to create intermedia texture "tex_exchange"
D3D11_TEXTURE2D_DESC desc;
RtlZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = desktopDup->m_dupDesc.ModeDesc.Width;
desc.Height = desktopDup->m_dupDesc.ModeDesc.Height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.CPUAccessFlags = 0;
desc.MiscFlags = i0;
HRESULT hr = desktopDup->m_device->CreateTexture2D(&desc, NULL, ppTex);
if (FAILED(hr))
{
gLogger->WriteLog(LogLevel::error, "%s() fail for CreateTexture2D() fail, hr=%08X", __FUNCTION__, hr);
assert(S_OK == hr);
return false;
}
// the function to register tex_exchange in OpenGL
gl_DXDev = wglDXOpenDeviceNV(desktopDup->m_device.p);
if (!gl_DXDev)
{
gLogger->WriteLog(LogLevel::error, "%s() fail for glDXDev is null, glError=%u", __FUNCTION__,glGetError());
assert(gl_DXDev);
return E_FAIL;
}
glGenTextures(1, &gl_tex_id);
if (gl_tex_id == 0)
{
gLogger->WriteLog(LogLevel::error, "%s() gen gl texture fail, glError=%u", __FUNCTION__, glGetError());
assert(gl_tex_id);
return E_FAIL;
}
glBindTexture(GL_TEXTURE_2D, gl_tex_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, 0);
gl_tex_obj = wglDXRegisterObjectNV(gl_DXDev, d3dtex_exchange.p, gl_tex_id, GL_TEXTURE_2D, WGL_ACCESS_READ_ONLY_NV);
if (!gl_tex_obj)
{
gLogger->WriteLog(LogLevel::error, "%s() reg gl texture fail,errCode=%u", __FUNCTION__, GetLastError());
assert(gl_tex_obj);
return E_FAIL;
}
// the function to copy D3D Desktop Duplication rendering result to tex_exchange
desktopDup->m_context->CopyResource(d3dtex_exchange, desktopSurf);
// the function to copy tex_exchange to OpenGL
if (!wglDXLockObjectsNV(gl_DXDev, 1, &gl_tex_obj)) // when the function is called, DX task will report a error
{
gLogger->WriteLog(LogLevel::error, "%s() wglDXLockObjectsNV() fail,errCode=%u", __FUNCTION__, GetLastError());
assert(FALSE);
return;
}
if (!wglDXUnlockObjectsNV(gl_DXDev, 1, &gl_tex_obj))
{
gLogger->WriteLog(LogLevel::error, "%s() wglDXUnlockObjectsNV() fail,errCode=%u", __FUNCTION__, GetLastError());
assert(FALSE);
return;
}
User contributions licensed under CC BY-SA 3.0