void CFullscreenTriangleDrawer::DrawDX11( ID3D11ShaderResourceView* pTextureSRV ) { ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); CDX11StateGuard stateGuard; pContext->IASetInputLayout( NULL ); pContext->IASetIndexBuffer( NULL, DXGI_FORMAT_UNKNOWN, 0 ); pContext->IASetVertexBuffers( 0, 0, NULL, NULL, NULL ); pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); pContext->VSSetShader( m_pVertexShader11, NULL, 0 ); pContext->PSSetShader( m_pPixelShader11, NULL, 0 ); ID3D11SamplerState* pNullSampler[] = { NULL }; pContext->PSSetSamplers( 0, 1, pNullSampler ); pContext->PSSetShaderResources( 0, 1, &pTextureSRV ); pContext->OMSetBlendState( m_pBlendState11, NULL, 0xFFFFFFFF ); // Draw pContext->Draw( 3, 0 ); }
static bool grabFrameD3D11(IDXGISwapChain *swap) { ID3D11Device *device = 0; ID3D11DeviceContext *context = 0; ID3D11Texture2D *tex = 0, *captureTex = 0; if (FAILED(swap->GetBuffer(0, IID_ID3D11Texture2D, (void**)&tex))) return false; D3D11_TEXTURE2D_DESC desc; tex->GetDevice(&device); tex->GetDesc(&desc); // re-creating the capture staging texture each frame is definitely not the most efficient // way to handle things, but it frees me of all kind of resource management trouble, so // here goes... desc.MipLevels = 1; desc.ArraySize = 1; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.MiscFlags = 0; if(FAILED(device->CreateTexture2D(&desc,0,&captureTex))) printLog("video/d3d11: couldn't create staging texture for gpu->cpu download!\n"); else setCaptureResolution(desc.Width,desc.Height); device->GetImmediateContext(&context); context->CopySubresourceRegion(captureTex,0,0,0,0,tex,0,0); D3D11_MAPPED_SUBRESOURCE mapped; bool grabOk = false; if(captureTex && SUCCEEDED(context->Map(captureTex,0,D3D11_MAP_READ,0,&mapped))) { switch(desc.Format) { case DXGI_FORMAT_R8G8B8A8_UNORM: blitAndFlipRGBAToCaptureData((unsigned char *) mapped.pData,mapped.RowPitch); grabOk = true; break; default: printLog("video/d3d11: unsupported backbuffer format, can't grab pixels!\n"); break; } context->Unmap(captureTex,0); } tex->Release(); if(captureTex) captureTex->Release(); context->Release(); device->Release(); return grabOk; }
void checkPixelsUsingD3D(bool usingPresentPathFast) { ASSERT_NE(nullptr, mOffscreenSurfaceD3D11Texture); D3D11_TEXTURE2D_DESC textureDesc = {0}; ID3D11Device *device; ID3D11DeviceContext *context; mOffscreenSurfaceD3D11Texture->GetDesc(&textureDesc); mOffscreenSurfaceD3D11Texture->GetDevice(&device); device->GetImmediateContext(&context); ASSERT_NE(nullptr, device); ASSERT_NE(nullptr, context); textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; textureDesc.Usage = D3D11_USAGE_STAGING; textureDesc.BindFlags = 0; textureDesc.MiscFlags = 0; ID3D11Texture2D *cpuTexture = nullptr; ASSERT_TRUE(SUCCEEDED(device->CreateTexture2D(&textureDesc, nullptr, &cpuTexture))); context->CopyResource(cpuTexture, mOffscreenSurfaceD3D11Texture); D3D11_MAPPED_SUBRESOURCE mappedSubresource; context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource); ASSERT_EQ(static_cast<UINT>(mWindowWidth * 4), mappedSubresource.RowPitch); ASSERT_EQ(static_cast<UINT>(mWindowWidth * mWindowWidth * 4), mappedSubresource.DepthPitch); angle::GLColor *byteData = reinterpret_cast<angle::GLColor *>(mappedSubresource.pData); // Note that the texture is in BGRA format, although the GLColor struct is RGBA GLColor expectedTopLeftPixel = GLColor(0, 0, 255, 255); // Red GLColor expectedTopRightPixel = GLColor(0, 255, 0, 255); // Green GLColor expectedBottomLeftPixel = GLColor(255, 0, 0, 255); // Blue GLColor expectedBottomRightPixel = GLColor(0, 255, 255, 255); // Red + Green if (usingPresentPathFast) { // Invert the expected values GLColor tempTopLeft = expectedTopLeftPixel; GLColor tempTopRight = expectedTopRightPixel; expectedTopLeftPixel = expectedBottomLeftPixel; expectedTopRightPixel = expectedBottomRightPixel; expectedBottomLeftPixel = tempTopLeft; expectedBottomRightPixel = tempTopRight; } EXPECT_EQ(expectedTopLeftPixel, byteData[0]); EXPECT_EQ(expectedTopRightPixel, byteData[(mWindowWidth - 1)]); EXPECT_EQ(expectedBottomLeftPixel, byteData[(mWindowWidth - 1) * mWindowWidth]); EXPECT_EQ(expectedBottomRightPixel, byteData[(mWindowWidth - 1) * mWindowWidth + (mWindowWidth - 1)]); context->Unmap(cpuTexture, 0); SafeRelease(cpuTexture); SafeRelease(device); SafeRelease(context); }
~CDX11StateGuard() { ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); // Apply saved state pContext->OMSetBlendState( m_pBlendState, m_BlendFactor, m_SampleMask ); pContext->RSSetState( m_pRasterizerState ); pContext->IASetPrimitiveTopology( m_PrimitiveTopology ); pContext->IASetIndexBuffer( m_pIndexBuffer, m_IndexBufferFormat, m_IndexBufferOffset ); pContext->IASetInputLayout( m_pInputLayout ); pContext->IASetVertexBuffers( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, m_pVertexBuffers, m_pVertexBufferStrides, m_pVertexBufferOffsets ); pContext->VSSetShader( m_pVertexShader, m_ppVertexShaderClassInstances, m_VertexShaderClassInstancesCount ); pContext->PSSetShader( m_pPixelShader, m_ppPixelShaderClassInstances, m_PixelShaderClassInstancesCount ); pContext->PSSetSamplers( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, m_ppPixelShaderSamplers ); pContext->PSSetShaderResources( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, m_ppPixelShaderResources ); // Release references SAFE_RELEASE( m_pBlendState ); SAFE_RELEASE( m_pRasterizerState ); SAFE_RELEASE( m_pIndexBuffer ); SAFE_RELEASE( m_pInputLayout ); for ( UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i ) { SAFE_RELEASE( m_pVertexBuffers[i] ); } SAFE_RELEASE( m_pVertexShader ); for ( UINT i = 0; i < m_VertexShaderClassInstancesCount; ++i ) { SAFE_RELEASE( m_ppVertexShaderClassInstances[i] ); } SAFE_RELEASE( m_pPixelShader ); for ( UINT i = 0; i < m_PixelShaderClassInstancesCount; ++i ) { SAFE_RELEASE( m_ppPixelShaderClassInstances[i] ); } for ( UINT i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i ) { SAFE_RELEASE( m_ppPixelShaderSamplers[i] ); } for ( UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i ) { SAFE_RELEASE( m_ppPixelShaderResources[i] ); } }
void D11State::draw() { clock_t t = clock(); float elapsed = static_cast<float>(t - timeT) / CLOCKS_PER_SEC; ++frameCount; if (elapsed > OVERLAY_FPS_INTERVAL) { OverlayMsg om; om.omh.uiMagic = OVERLAY_MAGIC_NUMBER; om.omh.uiType = OVERLAY_MSGTYPE_FPS; om.omh.iLength = sizeof(OverlayMsgFps); om.omf.fps = frameCount / elapsed; sendMessage(om); frameCount = 0; timeT = t; } checkMessage(static_cast<unsigned int>(vp.Width), static_cast<unsigned int>(vp.Height)); if (a_ucTexture && pSRView && (uiLeft != uiRight)) { if (!bDeferredContext) { pOrigStateBlock->Capture(); pMyStateBlock->Apply(); } // Set vertex buffer UINT stride = sizeof(SimpleVertex); UINT offset = 0; pDeviceContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset); pDeviceContext->VSSetShader(pVertexShader, NULL, 0); pDeviceContext->GSSetShader(NULL, NULL, 0); pDeviceContext->PSSetShaderResources(0, 1, &pSRView); pDeviceContext->PSSetShader(pPixelShader, NULL, 0); pDeviceContext->DrawIndexed(6, 0, 0); if (bDeferredContext) { ID3D11CommandList *pCommandList; pDeviceContext->FinishCommandList(TRUE, &pCommandList); ID3D11DeviceContext *ctx = NULL; pDevice->GetImmediateContext(&ctx); ctx->ExecuteCommandList(pCommandList, TRUE); ctx->Release(); pCommandList->Release(); } else { pDeviceContext->Flush(); pMyStateBlock->Capture(); pOrigStateBlock->Apply(); } } }
void CCoherentViewListener::DrawFrameDX11SharedMemory( Coherent::UI::CoherentHandle handle, int width, int height ) { ID3D11Texture2D* pTexture = static_cast<ID3D11Texture2D*>( m_pTexture ); ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); D3D11_MAPPED_SUBRESOURCE mapped; HRESULT hr = pContext->Map( pTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped ); if ( FAILED( hr ) ) { return; } const size_t size = width * height * 4; void* pMapped = ::MapViewOfFile( handle, FILE_MAP_READ, 0, 0, size ); char* pSrc = static_cast<char*>( pMapped ); if ( pSrc == NULL ) { pContext->Unmap( pTexture, 0 ); return; } char* pDest = static_cast<char*>( mapped.pData ); // copy and convert from BGRA to RGBA int offsetSrc = 0; int offsetDst = 0; int rowOffset = mapped.RowPitch % width; for ( int row = 0; row < height; ++row ) { for ( int col = 0; col < width; ++col ) { pDest[offsetDst] = pSrc[offsetSrc + 2]; pDest[offsetDst + 1] = pSrc[offsetSrc + 1]; pDest[offsetDst + 2] = pSrc[offsetSrc]; pDest[offsetDst + 3] = pSrc[offsetSrc + 3]; offsetSrc += 4; offsetDst += 4; } offsetDst += rowOffset; } ::UnmapViewOfFile( pMapped ); pContext->Unmap( pTexture, 0 ); }
CDX11StateGuard() : m_VertexShaderClassInstancesCount(D3D11_SHADER_MAX_INTERFACES) , m_PixelShaderClassInstancesCount(D3D11_SHADER_MAX_INTERFACES) { ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); pContext->OMGetBlendState( &m_pBlendState, m_BlendFactor, &m_SampleMask ); pContext->RSGetState( &m_pRasterizerState ); pContext->IAGetPrimitiveTopology( &m_PrimitiveTopology ); pContext->IAGetIndexBuffer( &m_pIndexBuffer, &m_IndexBufferFormat, &m_IndexBufferOffset ); pContext->IAGetInputLayout( &m_pInputLayout ); pContext->IAGetVertexBuffers( 0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, m_pVertexBuffers, m_pVertexBufferStrides, m_pVertexBufferOffsets ); pContext->VSGetShader( &m_pVertexShader, m_ppVertexShaderClassInstances, &m_VertexShaderClassInstancesCount ); pContext->PSGetShader( &m_pPixelShader, m_ppPixelShaderClassInstances, &m_PixelShaderClassInstancesCount ); pContext->PSGetSamplers( 0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, m_ppPixelShaderSamplers ); pContext->PSGetShaderResources( 0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, m_ppPixelShaderResources ); }
StarObject* DX11Engine::createVideoRendererResources(IUnknown* pDeviceIn, const Filesystem* pFilesystem) const { std::unique_ptr<ID3D11DeviceContext, COMDeleter> pDC; ID3D11Device* pDevice = static_cast<ID3D11Device*>(pDeviceIn); pDevice->GetImmediateContext(ref(pDC)); std::unique_ptr<DX11VideoRendererResources> resources( new DX11VideoRendererResources(pDevice, pDC.get())); if (!resources) return nullptr; try { resources->create(*pFilesystem); } catch (...) { return nullptr; } return resources.release(); }
void CCoherentViewListener::DrawFrameDX11SharedTexture( Coherent::UI::CoherentHandle handle, int width, int height ) { if ( gCoherentUISystem == NULL ) { return; } void* pNativeTexture = gCoherentUISystem->GetNativeTextureFromSharedHandle( handle ); if ( pNativeTexture == NULL ) { return; } ID3D11Texture2D* pSourceResource = static_cast<ID3D11Texture2D*>( pNativeTexture ); ID3D11Texture2D* pDestResource = static_cast<ID3D11Texture2D*>( m_pTexture ); ID3D11DeviceContext* pContext = NULL; ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); pDevice->GetImmediateContext( &pContext ); pContext->CopySubresourceRegion( pDestResource, 0, 0, 0, 0, pSourceResource, 0, NULL ); }
void CCoherentViewListener::CreateShaderResourceViewForDX11Texture() { if ( gEnv->pRenderer->GetRenderType() != eRT_DX11 || m_pTexture == NULL ) { return; } ID3D11Texture2D* pTexture = static_cast<ID3D11Texture2D*>( m_pTexture ); ID3D11Device* pDevice = static_cast<ID3D11Device*>( gD3DDevice ); ID3D11DeviceContext* pContext = NULL; pDevice->GetImmediateContext( &pContext ); D3D11_TEXTURE2D_DESC texDesc; pTexture->GetDesc( &texDesc ); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MostDetailedMip = 0; pDevice->CreateShaderResourceView( pTexture, &srvDesc, &m_pTextureSRV ); }
HRESULT STDMETHODCALLTYPE D3D11SwapPresentHook(IDXGISwapChain *swap, UINT syncInterval, UINT flags) { if(lpCurrentSwap == NULL && !bTargetAcquired) { lpCurrentSwap = swap; SetupD3D11(swap); bTargetAcquired = true; } if(lpCurrentSwap == swap) { ID3D11Device *device = NULL; HRESULT chi; if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device))) { if(!lpCurrentDevice) { lpCurrentDevice = device; /*FARPROC curRelease = GetVTable(device, (8/4)); if(curRelease != newD3D11Release) { oldD3D11Release = curRelease; newD3D11Release = (FARPROC)DeviceReleaseHook; SetVTable(device, (8/4), newD3D11Release); }*/ } ID3D11DeviceContext *context; device->GetImmediateContext(&context); if(bCapturing && bStopRequested) { ClearD3D11Data(); bStopRequested = false; } if(!bHasTextures && bCapturing) { if(dxgiFormat) { if(!hwndReceiver) hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL); if(hwndReceiver) { BOOL bSuccess = DoD3D11Hook(device); if(bSuccess) { d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData); if(!d3d11CaptureInfo.mapID) { RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl; bSuccess = false; } } if(bSuccess) bSuccess = IsWindow(hwndReceiver); if(bSuccess) { bHasTextures = true; d3d11CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX; d3d11CaptureInfo.hwndSender = hwndSender; d3d11CaptureInfo.bFlip = FALSE; texData->texHandles[0] = sharedHandles[0]; texData->texHandles[1] = sharedHandles[1]; PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo); logOutput << "DoD3D11Hook: success"; } else { ClearD3D11Data(); } } } } if(bHasTextures) { LONGLONG frameTime; if(bCapturing) { if(texData) { if(frameTime = texData->frameTime) { LONGLONG timeVal = OSGetTimeMicroseconds(); LONGLONG timeElapsed = timeVal-lastTime; if(timeElapsed >= frameTime) { lastTime += frameTime; if(timeElapsed > frameTime*2) lastTime = timeVal; DWORD nextCapture = curCapture == 0 ? 1 : 0; ID3D11Resource *backBuffer = NULL; if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer))) { if(bIsMultisampled) context->ResolveSubresource(copyTextureGame, 0, backBuffer, 0, dxgiFormat); else context->CopyResource(copyTextureGame, backBuffer); ID3D10Texture2D *outputTexture = NULL; int lastRendered = -1; if(keyedMutexes[curCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0) lastRendered = (int)curCapture; else if(keyedMutexes[nextCapture]->AcquireSync(0, 0) == WAIT_OBJECT_0) lastRendered = (int)nextCapture; if(lastRendered != -1) { shareDevice->CopyResource(sharedTextures[lastRendered], copyTextureIntermediary); keyedMutexes[lastRendered]->ReleaseSync(0); } texData->lastRendered = lastRendered; backBuffer->Release(); } curCapture = nextCapture; } } } } else ClearD3D11Data(); } device->Release(); context->Release(); } } gi11swapPresent.Unhook(); HRESULT hRes = swap->Present(syncInterval, flags); gi11swapPresent.Rehook(); return hRes; }
void DoD3D11Capture(IDXGISwapChain *swap) { ID3D11Device *device = NULL; HRESULT chi; if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device))) { if(!lpCurrentDevice) { lpCurrentDevice = device; /*FARPROC curRelease = GetVTable(device, (8/4)); if(curRelease != newD3D11Release) { oldD3D11Release = curRelease; newD3D11Release = (FARPROC)DeviceReleaseHook; SetVTable(device, (8/4), newD3D11Release); }*/ } ID3D11DeviceContext *context; device->GetImmediateContext(&context); if(bCapturing && bStopRequested) { ClearD3D11Data(); bCapturing = false; bStopRequested = false; } if(!bCapturing && WaitForSingleObject(hSignalRestart, 0) == WAIT_OBJECT_0) { hwndOBS = FindWindow(OBS_WINDOW_CLASS, NULL); if(hwndOBS) bCapturing = true; } if(!bHasTextures && bCapturing) { if(dxgiFormat && hwndOBS) { BOOL bSuccess = DoD3D11Hook(device); if(bSuccess) { d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData); if(!d3d11CaptureInfo.mapID) { RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl; bSuccess = false; } } if(bSuccess) { bHasTextures = true; d3d11CaptureInfo.captureType = CAPTURETYPE_SHAREDTEX; d3d11CaptureInfo.bFlip = FALSE; texData->texHandle = (DWORD)sharedHandle; memcpy(infoMem, &d3d11CaptureInfo, sizeof(CaptureInfo)); SetEvent(hSignalReady); logOutput << "DoD3D11Hook: success" << endl; } else { ClearD3D11Data(); } } } if(bHasTextures) { LONGLONG timeVal = OSGetTimeMicroseconds(); //check keep alive state, dumb but effective if(bCapturing) { if((timeVal-keepAliveTime) > 3000000) { HANDLE hKeepAlive = OpenEvent(EVENT_ALL_ACCESS, FALSE, strKeepAlive.c_str()); if (hKeepAlive) { CloseHandle(hKeepAlive); } else { ClearD3D11Data(); bCapturing = false; } keepAliveTime = timeVal; } } LONGLONG frameTime; if(bCapturing) { if(texData) { if(frameTime = texData->frameTime) { LONGLONG timeElapsed = timeVal-lastTime; if(timeElapsed >= frameTime) { if(!IsWindow(hwndOBS)) { hwndOBS = NULL; bStopRequested = true; } if(WaitForSingleObject(hSignalEnd, 0) == WAIT_OBJECT_0) bStopRequested = true; lastTime += frameTime; if(timeElapsed > frameTime*2) lastTime = timeVal; DWORD nextCapture = curCapture == 0 ? 1 : 0; ID3D11Resource *backBuffer = NULL; if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer))) { if(bIsMultisampled) context->ResolveSubresource(copyTextureGame, 0, backBuffer, 0, dxgiFormat); else context->CopyResource(copyTextureGame, backBuffer); backBuffer->Release(); } curCapture = nextCapture; } } } } else ClearD3D11Data(); } device->Release(); context->Release(); } }
// void ovGetCamImageForUnityNative(void* pTexPtr_Left, void* pTexPtr_Right, int qt, int useAR) CSHARP_EXPORT void ovGetCamImageForUnityNative(void* pTexPtr_Left, void* pTexPtr_Right) { if (g_ovOvrvision == NULL) return; //Get image unsigned char* pLeft = g_ovOvrvision->GetCamImageBGRA(OVR::OV_CAMEYE_LEFT); unsigned char* pRight = g_ovOvrvision->GetCamImageBGRA(OVR::OV_CAMEYE_RIGHT); int length = g_ovOvrvision->GetCamWidth() * g_ovOvrvision->GetCamHeight() * g_ovOvrvision->GetCamPixelsize(); int offsetlen = g_ovOvrvision->GetCamPixelsize(); if (g_DeviceType == 2) { //Direct11 #if SUPPORT_D3D11 ID3D11DeviceContext* ctx = NULL; ID3D11Device* device = (ID3D11Device*)g_D3D11Device; device->GetImmediateContext(&ctx); D3D11_TEXTURE2D_DESC desc_left, desc_right; ID3D11Texture2D* d3dtex_left = (ID3D11Texture2D*)pTexPtr_Left; ID3D11Texture2D* d3dtex_right = (ID3D11Texture2D*)pTexPtr_Right; d3dtex_left->GetDesc(&desc_left); d3dtex_right->GetDesc(&desc_right); ctx->UpdateSubresource(d3dtex_left, 0, NULL, pLeft, g_ovOvrvision->GetCamWidth() * offsetlen, 0); ctx->UpdateSubresource(d3dtex_right, 0, NULL, pRight, g_ovOvrvision->GetCamWidth() * offsetlen, 0); ctx->Release(); #endif } else if (g_DeviceType == 1) { //DirectX9 #if SUPPORT_D3D9 IDirect3DTexture9* d3dtex_left = (IDirect3DTexture9*)pTexPtr_Left; IDirect3DTexture9* d3dtex_right = (IDirect3DTexture9*)pTexPtr_Right; D3DSURFACE_DESC desc_left, desc_right; d3dtex_left->GetLevelDesc(0, &desc_left); d3dtex_left->GetLevelDesc(0, &desc_right); D3DLOCKED_RECT lr; d3dtex_left->LockRect(0, &lr, NULL, 0); memcpy((unsigned char*)lr.pBits, pLeft, length); d3dtex_left->UnlockRect(0); d3dtex_right->LockRect(0, &lr, NULL, 0); memcpy((unsigned char*)lr.pBits, pRight, length); d3dtex_right->UnlockRect(0); #endif } else if (g_DeviceType == 18) { //DirectX12 #if SUPPORT_D3D12 #endif } else if (g_DeviceType == 0) { //OpenGL #if SUPPORT_OPENGL uintptr_t gltex_left = (uintptr_t)pTexPtr_Left; uintptr_t gltex_right = (uintptr_t)pTexPtr_Right; glBindTexture(GL_TEXTURE_2D, (GLuint)gltex_left); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_ovOvrvision->GetCamWidth(), g_ovOvrvision->GetCamHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, pLeft); glBindTexture(GL_TEXTURE_2D, (GLuint)gltex_right); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_ovOvrvision->GetCamWidth(), g_ovOvrvision->GetCamHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, pRight); #endif } else if (g_DeviceType == 17) { //OpenGLCore #if SUPPORT_OPENGL uintptr_t gltex_left = (uintptr_t)pTexPtr_Left; uintptr_t gltex_right = (uintptr_t)pTexPtr_Right; glBindTexture(GL_TEXTURE_2D, gltex_left); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_ovOvrvision->GetCamWidth(), g_ovOvrvision->GetCamHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pLeft); glBindTexture(GL_TEXTURE_2D, gltex_right); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_ovOvrvision->GetCamWidth(), g_ovOvrvision->GetCamHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pRight); #endif } }
bool D11State::init() { HRESULT hr; ID3D11Texture2D* pBackBuffer = NULL; hr = pSwapChain->GetBuffer(0, __uuidof(*pBackBuffer), (LPVOID*)&pBackBuffer); if (FAILED(hr)) { ods("D3D11: pSwapChain->GetBuffer failure!"); return false; } hr = pDevice->CreateDeferredContext(0, &pDeviceContext); // Depending on the device settings a deferred context may not be createable // for example if it is a SINGLETHREADED device. // (See http://msdn.microsoft.com/en-us/library/windows/desktop/ff476505%28v=vs.85%29.aspx) // We handle the expected failure and failure fallback in the same way - // by trying to use an immediate context. if (FAILED(hr) || !pDeviceContext) { ods("D3D11: Failed to create DeferredContext (0x%x). Getting ImmediateContext", hr); pDevice->GetImmediateContext(&pDeviceContext); D11CreateStateBlock(pDeviceContext, &pOrigStateBlock); D11CreateStateBlock(pDeviceContext, &pMyStateBlock); pOrigStateBlock->Capture(); bDeferredContext = false; } else { bDeferredContext = true; } D3D11_TEXTURE2D_DESC backBufferSurfaceDesc; pBackBuffer->GetDesc(&backBufferSurfaceDesc); ZeroMemory(&vp, sizeof(vp)); vp.Width = static_cast<float>(backBufferSurfaceDesc.Width); vp.Height = static_cast<float>(backBufferSurfaceDesc.Height); vp.MinDepth = 0; vp.MaxDepth = 1; vp.TopLeftX = 0; vp.TopLeftY = 0; pDeviceContext->RSSetViewports(1, &vp); hr = pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRTV); if (FAILED(hr)) { ods("D3D11: pDevice->CreateRenderTargetView failed!"); return false; } pDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); // Settings for an "over" operation. // https://en.wikipedia.org/w/index.php?title=Alpha_compositing&oldid=580659153#Description D3D11_BLEND_DESC blend; ZeroMemory(&blend, sizeof(blend)); blend.RenderTarget[0].BlendEnable = TRUE; blend.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blend.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blend.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blend.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; blend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; pDevice->CreateBlendState(&blend, &pBlendState); if (FAILED(hr)) { ods("D3D11: pDevice->CreateBlendState failed!"); return false; } pDeviceContext->OMSetBlendState(pBlendState, NULL, 0xffffffff); hr = pDevice->CreateVertexShader(g_vertex_shader, sizeof(g_vertex_shader), NULL, &pVertexShader); if (FAILED(hr)) { ods("D3D11: Failed to create vertex shader."); return false; } hr = pDevice->CreatePixelShader(g_pixel_shader, sizeof(g_pixel_shader), NULL, &pPixelShader); if (FAILED(hr)) { ods("D3D11: Failed to create pixel shader."); return false; } pTexture = NULL; pSRView = NULL; // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; hr = pDevice->CreateInputLayout(layout, ARRAY_NUM_ELEMENTS(layout), g_vertex_shader, sizeof(g_vertex_shader), &pVertexLayout); if (FAILED(hr)) { ods("D3D11: pDevice->CreateInputLayout failure!"); return false; } pDeviceContext->IASetInputLayout(pVertexLayout); D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DYNAMIC; bd.ByteWidth = VERTEXBUFFER_SIZE; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; bd.MiscFlags = 0; hr = pDevice->CreateBuffer(&bd, NULL, &pVertexBuffer); if (FAILED(hr)) { ods("D3D11: pDevice->CreateBuffer failure!"); return false; } DWORD indices[] = { 0,1,3, 1,2,3, }; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_IMMUTABLE; bd.ByteWidth = sizeof(DWORD) * 6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; bd.MiscFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = indices; hr = pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer); if (FAILED(hr)) { ods("D3D11: pDevice->CreateBuffer failure!"); return false; } // Set index buffer pDeviceContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0); // Set primitive topology pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); if (!bDeferredContext) { pMyStateBlock->Capture(); pOrigStateBlock->Apply(); } pBackBuffer->Release(); return true; }
HRESULT STDMETHODCALLTYPE SwapPresentHook(UINT syncInterval, UINT flags) { IDXGISwapChain *swap = (IDXGISwapChain*)this; if(lpCurrentSwap == NULL && !bTargetAcquired) { lpCurrentSwap = swap; SetupD3D11(swap); bTargetAcquired = true; } if(lpCurrentSwap == swap) { ID3D11Device *device = NULL; HRESULT chi; if(SUCCEEDED(chi = swap->GetDevice(__uuidof(ID3D11Device), (void**)&device))) { if(!lpCurrentDevice) { lpCurrentDevice = device; oldD3D11Release = GetVTable(device, (8/4)); newD3D11Release = ConvertClassProcToFarproc((CLASSPROC)&D3D11Override::DeviceReleaseHook); SetVTable(device, (8/4), newD3D11Release); } ID3D11DeviceContext *context; device->GetImmediateContext(&context); if(!bHasTextures && bCapturing) { if(dxgiFormat) { if(!hwndReceiver) hwndReceiver = FindWindow(RECEIVER_WINDOWCLASS, NULL); if(hwndReceiver) { D3D11_TEXTURE2D_DESC texDesc; ZeroMemory(&texDesc, sizeof(texDesc)); texDesc.Width = d3d11CaptureInfo.cx; texDesc.Height = d3d11CaptureInfo.cy; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = dxgiFormat; texDesc.SampleDesc.Count = 1; texDesc.Usage = D3D11_USAGE_STAGING; texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; bool bSuccess = true; UINT pitch; for(UINT i=0; i<2; i++) { HRESULT ching; if(FAILED(ching = device->CreateTexture2D(&texDesc, NULL, &d3d11Textures[i]))) { bSuccess = false; break; } if(i == 0) { ID3D11Resource *resource; if(FAILED(d3d11Textures[i]->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource))) { bSuccess = false; break; } D3D11_MAPPED_SUBRESOURCE map; if(FAILED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map))) { bSuccess = false; break; } pitch = map.RowPitch; context->Unmap(resource, 0); resource->Release(); } } if(bSuccess) { d3d11CaptureInfo.mapID = InitializeSharedMemory(pitch*d3d11CaptureInfo.cy, &d3d11CaptureInfo.mapSize, ©Data, textureBuffers); if(!d3d11CaptureInfo.mapID) bSuccess = false; } if(bSuccess) { bHasTextures = true; d3d11CaptureInfo.captureType = CAPTURETYPE_MEMORY; d3d11CaptureInfo.hwndSender = hwndSender; d3d11CaptureInfo.pitch = pitch; d3d11CaptureInfo.bFlip = FALSE; PostMessage(hwndReceiver, RECEIVER_NEWCAPTURE, 0, (LPARAM)&d3d11CaptureInfo); } else { for(UINT i=0; i<2; i++) { SafeRelease(d3d11Textures[i]); if(textureBuffers[i]) { free(textureBuffers[i]); textureBuffers[i] = NULL; } } } } } } if(bHasTextures) { if(bCapturing) { DWORD nextCapture = curCapture == 0 ? 1 : 0; ID3D11Texture2D *texture = d3d11Textures[curCapture]; ID3D11Resource *backBuffer = NULL; if(SUCCEEDED(swap->GetBuffer(0, IID_ID3D11Resource, (void**)&backBuffer))) { if(bIsMultisampled) context->ResolveSubresource(texture, 0, backBuffer, 0, dxgiFormat); else context->CopyResource(texture, backBuffer); backBuffer->Release(); ID3D11Texture2D *lastTexture = d3d11Textures[nextCapture]; ID3D11Resource *resource; if(SUCCEEDED(lastTexture->QueryInterface(__uuidof(ID3D11Resource), (void**)&resource))) { D3D11_MAPPED_SUBRESOURCE map; if(SUCCEEDED(context->Map(resource, 0, D3D11_MAP_READ, 0, &map))) { LPBYTE *pTextureBuffer = NULL; int lastRendered = -1; //under no circumstances do we -ever- allow a stall if(WaitForSingleObject(textureMutexes[curCapture], 0) == WAIT_OBJECT_0) lastRendered = (int)curCapture; else if(WaitForSingleObject(textureMutexes[nextCapture], 0) == WAIT_OBJECT_0) lastRendered = (int)nextCapture; if(lastRendered != -1) { SSECopy(textureBuffers[lastRendered], map.pData, map.RowPitch*d3d11CaptureInfo.cy); ReleaseMutex(textureMutexes[lastRendered]); } context->Unmap(resource, 0); copyData->lastRendered = (UINT)lastRendered; } resource->Release(); } } curCapture = nextCapture; } else ClearD3D11Data(); } device->Release(); context->Release(); } } gi11swapPresent.Unhook(); HRESULT hRes = swap->Present(syncInterval, flags); gi11swapPresent.Rehook(); return hRes; }
void D3D11Grab(ID3D11Texture2D *pBackBuffer) { D3D11_TEXTURE2D_DESC tex_desc; pBackBuffer->GetDesc(&tex_desc); ID3D11Device *pDev; pBackBuffer->GetDevice(&pDev); ID3D11DeviceContext * pDevContext; pDev->GetImmediateContext(&pDevContext); ID3D11Texture2D * pTexture; D3D11_MAPPED_SUBRESOURCE mappedTexture; tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; tex_desc.ArraySize = 1; tex_desc.MipLevels = 1; tex_desc.BindFlags = 0; tex_desc.SampleDesc.Count = 1; tex_desc.SampleDesc.Quality = 0; tex_desc.Usage = D3D11_USAGE_STAGING; tex_desc.MiscFlags = 0; HRESULT hr = pDev->CreateTexture2D(&tex_desc, NULL, &pTexture); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 pDev->CreateTexture2D 0x%x", hr); pDevContext->CopyResource(pTexture, pBackBuffer); D3D11_BOX box = {0, 0, tex_desc.Width, tex_desc.Height, 0, 1}; pDevContext->CopySubresourceRegion(pTexture, 0, 0, 0, 0, pBackBuffer, 0, &box); DxgiFrameGrabber *dxgiFrameGrabber = DxgiFrameGrabber::getInstance(); IPCContext *ipcContext = dxgiFrameGrabber->m_ipcContext; Logger *logger = dxgiFrameGrabber->m_logger; // __asm__("int $3"); if (S_OK != (hr = pDevContext->Map(pTexture, D3D11CalcSubresource(0, 0, 1), D3D11_MAP_READ, 0, &mappedTexture))) { logger->reportLogError(L"d3d11 couldn't map texture, hresult = 0x%x", hr); goto end; } ipcContext->m_memDesc.width = tex_desc.Width; ipcContext->m_memDesc.height = tex_desc.Height; ipcContext->m_memDesc.rowPitch = mappedTexture.RowPitch; ipcContext->m_memDesc.frameId++; // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 texture description. width: %u, height: %u, pitch: %u", tex_desc.Width, tex_desc.Height, mappedTexture.RowPitch); DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) { // __asm__("int $3"); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 writing description to mem mapped file"); memcpy(ipcContext->m_pMemMap, &ipcContext->m_memDesc, sizeof (ipcContext->m_memDesc)); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d11 writing data to mem mapped file"); PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc)); if (mappedTexture.RowPitch == tex_desc.Width * 4) { memcpy(pMemDataMap, mappedTexture.pData, tex_desc.Width * tex_desc.Height * 4); } else { UINT i = 0, cleanOffset = 0, pitchOffset = 0; while (i < tex_desc.Height) { memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(mappedTexture.pData, pitchOffset), tex_desc.Width * 4); cleanOffset += tex_desc.Width * 4; pitchOffset += mappedTexture.RowPitch; i++; } } ReleaseMutex(ipcContext->m_hMutex); SetEvent(ipcContext->m_hFrameGrabbedEvent); } else { logger->reportLogError(L"d3d11 couldn't wait mutex. errocode = 0x%x", errorcode); } pDevContext->Unmap(pTexture, D3D10CalcSubresource(0, 0, 1)); end: pTexture->Release(); pDevContext->Release(); pDev->Release(); }
/** * Handle Stereo Drawing. ***/ void* StereoPresenter::Provoke(void* pThis, int eD3D, int eD3DInterface, int eD3DMethod, DWORD dwNumberConnected, int& nProvokerIndex) { #ifdef _DEBUG_STP { wchar_t buf[128]; wsprintf(buf, L"[STP] ifc %u mtd %u", eD3DInterface, eD3DMethod); OutputDebugString(buf); } #endif // update our global time static float fGlobalTime = 0.0f; static DWORD dwTimeStart = 0; DWORD dwTimeCur = GetTickCount(); if (dwTimeStart == 0) dwTimeStart = dwTimeCur; fGlobalTime = (dwTimeCur - dwTimeStart) / 1000.0f; // only present accepted bool bValid = false; if (((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) || ((eD3DInterface == INTERFACE_IDIRECT3DDEVICE9) && (eD3DMethod == METHOD_IDIRECT3DDEVICE9_PRESENT))) bValid = true; if (!bValid) return nullptr; // clear all previous menu events ZeroMemory(&m_abMenuEvents[0], sizeof(VireioMenuEvent)* (int)VireioMenuEvent::NumberOfEvents); // main menu update ? if ((m_sMainMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sMainMenu.bOnChanged = false; // loop through entries for (size_t nIx = 0; nIx < m_sMainMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sMainMenu.asEntries[nIx].bOnChanged) { m_sMainMenu.asEntries[nIx].bOnChanged = false; // set new menu index.. selection to zero m_sMenuControl.nMenuIx = (INT)nIx; m_sMenuControl.unSelectionFormer = m_sMenuControl.unSelection = 0; } } } // sub menu update ? if ((m_sSubMenu.bOnChanged) && (!m_sMenuControl.eSelectionMovement)) { m_sSubMenu.bOnChanged = false; // exit ? if (m_sSubMenu.bOnExit) m_sMenuControl.nMenuIx = -1; // loop through entries for (size_t nIx = 0; nIx < m_sSubMenu.asEntries.size(); nIx++) { // entry index changed ? if (m_sSubMenu.asEntries[nIx].bOnChanged) { m_sSubMenu.asEntries[nIx].bOnChanged = false; // font ? if (nIx == ENTRY_FONT) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (SUCCEEDED(nHr)) { HRESULT nHr; // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font, make backup VireioFont* pcOldFont = m_pcFontSegeo128; m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = pcOldFont; } else { // set new font name m_strFontName = m_sSubMenu.asEntries[nIx].astrValueEnumeration[m_sSubMenu.asEntries[nIx].unValue]; // write to ini file char szFilePathINI[1024]; GetCurrentDirectoryA(1024, szFilePathINI); strcat_s(szFilePathINI, "\\VireioPerception.ini"); WritePrivateProfileStringA("Stereo Presenter", "strFontName", m_strFontName.c_str(), szFilePathINI); } } SAFE_RELEASE(pcDevice); SAFE_RELEASE(pcContext); } } } } // get xbox controller input XINPUT_STATE sControllerState; bool bControllerAttached = false; ZeroMemory(&sControllerState, sizeof(XINPUT_STATE)); if (XInputGetState(0, &sControllerState) == ERROR_SUCCESS) { bControllerAttached = true; } if (true) { #pragma region menu hotkeys static bool bReleased = true; static bool s_bOnMenu = false; // keyboard menu on/off event + get hand poses UINT uIxHandPoses = 0, uIxPoseRequest = 0; s_bOnMenu = GetAsyncKeyState(VK_LCONTROL) && GetAsyncKeyState(0x51); for (UINT unIx = 0; unIx < 32; unIx++) { // set menu bool event if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnBack) { // main menu ? exit if ((m_sMenuControl.nMenuIx == -1) && (!m_sMenuControl.eSelectionMovement)) s_bOnMenu = true; else m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; m_apsSubMenues[unIx]->bOnBack = false; } // hand poses ? if (m_apsSubMenues[unIx]->bHandPosesPresent) uIxHandPoses = unIx; if (m_apsSubMenues[unIx]->bHandPosesRequest) uIxPoseRequest = unIx; } } if ((m_apsSubMenues[uIxHandPoses]) && (m_apsSubMenues[uIxPoseRequest])) { // copy the hand pose data to the request node m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[0] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[0]; m_apsSubMenues[uIxPoseRequest]->sPoseMatrix[1] = m_apsSubMenues[uIxHandPoses]->sPoseMatrix[1]; m_apsSubMenues[uIxPoseRequest]->sPosition[0] = m_apsSubMenues[uIxHandPoses]->sPosition[0]; m_apsSubMenues[uIxPoseRequest]->sPosition[1] = m_apsSubMenues[uIxHandPoses]->sPosition[1]; } // static hotkeys : LCTRL+Q - toggle vireio menu // F12 - toggle stereo output if (GetAsyncKeyState(VK_F12)) { m_bHotkeySwitch = true; } else if (s_bOnMenu) { m_bMenuHotkeySwitch = true; } else if (m_bMenuHotkeySwitch) { m_bMenuHotkeySwitch = false; m_bMenu = !m_bMenu; for (UINT unIx = 0; unIx < 32; unIx++) { // set sub menu active if menu is active if (m_apsSubMenues[unIx]) m_apsSubMenues[unIx]->bIsActive = m_bMenu; } } else if (m_bHotkeySwitch) { if (m_eStereoMode) m_eStereoMode = VireioMonitorStereoModes::Vireio_Mono; else m_eStereoMode = VireioMonitorStereoModes::Vireio_SideBySide; m_bHotkeySwitch = false; } else bReleased = true; #pragma endregion #pragma region menu events // menu is shown ? if (m_bMenu) { // handle controller if (bControllerAttached) { if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_BACK) { m_abMenuEvents[VireioMenuEvent::OnExit] = TRUE; } if (sControllerState.Gamepad.wButtons & XINPUT_GAMEPAD_A) { m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; } if (sControllerState.Gamepad.sThumbLY > 28000) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (sControllerState.Gamepad.sThumbLY < -28000) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (sControllerState.Gamepad.sThumbLX > 28000) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (sControllerState.Gamepad.sThumbLX < -28000) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; } // loop through sub menues for (UINT unIx = 0; unIx < 32; unIx++) { // set bool events if (m_apsSubMenues[unIx]) { if (m_apsSubMenues[unIx]->bOnUp) m_abMenuEvents[VireioMenuEvent::OnUp] = TRUE; if (m_apsSubMenues[unIx]->bOnDown) m_abMenuEvents[VireioMenuEvent::OnDown] = TRUE; if (m_apsSubMenues[unIx]->bOnLeft) m_abMenuEvents[VireioMenuEvent::OnLeft] = TRUE; if (m_apsSubMenues[unIx]->bOnRight) m_abMenuEvents[VireioMenuEvent::OnRight] = TRUE; if (m_apsSubMenues[unIx]->bOnAccept) m_abMenuEvents[VireioMenuEvent::OnAccept] = TRUE; // clear events m_apsSubMenues[unIx]->bOnUp = false; m_apsSubMenues[unIx]->bOnDown = false; m_apsSubMenues[unIx]->bOnLeft = false; m_apsSubMenues[unIx]->bOnRight = false; m_apsSubMenues[unIx]->bOnAccept = false; m_apsSubMenues[unIx]->bOnBack = false; } } #pragma endregion #pragma region menu update/render // update UpdateMenu(fGlobalTime); // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; HRESULT nHr = S_OK; if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) nHr = GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext); else { if (m_ppcTexView11[0]) { if (*(m_ppcTexView11[0])) (*(m_ppcTexView11[0]))->GetDevice(&pcDevice); if (pcDevice) pcDevice->GetImmediateContext(&pcContext); else nHr = E_FAIL; if (!pcContext) nHr = E_FAIL; } else nHr = E_FAIL; } if (FAILED(nHr)) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // create the depth stencil... if D3D11 if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT) && (!m_pcDSGeometry11)) { ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); if (pcBackBuffer) { D3D11_TEXTURE2D_DESC sDesc; pcBackBuffer->GetDesc(&sDesc); pcBackBuffer->Release(); // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory(&descDepth, sizeof(descDepth)); descDepth.Width = sDesc.Width; descDepth.Height = sDesc.Height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; if (FAILED(pcDevice->CreateTexture2D(&descDepth, NULL, &m_pcDSGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil."); // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory(&descDSV, sizeof(descDSV)); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; if (FAILED(pcDevice->CreateDepthStencilView(m_pcDSGeometry11, &descDSV, &m_pcDSVGeometry11))) OutputDebugString(L"[STP] Failed to create depth stencil view."); } } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set the menu texture (if present) if (m_ppcTexViewMenu) { if (*m_ppcTexViewMenu) { // set render target ID3D11RenderTargetView* pcRTView = *m_ppcTexViewMenu; pcContext->OMSetRenderTargets(1, &pcRTView, NULL); // set viewport D3D11_VIEWPORT sViewport = {}; sViewport.TopLeftX = 0; sViewport.TopLeftY = 0; sViewport.Width = 1024; sViewport.Height = 1024; sViewport.MinDepth = 0.0f; sViewport.MaxDepth = 1.0f; pcContext->RSSetViewports(1, &sViewport); // clear render target...zero alpha FLOAT afColorRgba[4] = { 0.5f, 0.4f, 0.2f, 0.4f }; pcContext->ClearRenderTargetView(*m_ppcTexViewMenu, afColorRgba); } } else if ((eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); } // create the font class if not present nHr = S_OK; if (!m_pcFontSegeo128) { // get base directory std::string strVireioPath = GetBaseDir(); // add file path strVireioPath += "font//"; strVireioPath += m_strFontName; strVireioPath += ".spritefont"; OutputDebugStringA(strVireioPath.c_str()); // create font m_pcFontSegeo128 = new VireioFont(pcDevice, pcContext, strVireioPath.c_str(), 128.0f, 1.0f, nHr, 1); } if (FAILED(nHr)) { delete m_pcFontSegeo128; m_pcFontSegeo128 = nullptr; } // render text (if font present) if (m_pcFontSegeo128) { m_pcFontSegeo128->SetTextAttributes(0.0f, 0.2f, 0.0001f); // set additional tremble for "accepted" event float fDepthTremble = 0.0f; if (m_sMenuControl.eSelectionMovement == MenuControl::SelectionMovement::Accepted) { float fActionTimeElapsed = (fGlobalTime - m_sMenuControl.fActionStartTime) / m_sMenuControl.fActionTime; fDepthTremble = sin(fActionTimeElapsed*PI_F) * -3.0f; } m_pcFontSegeo128->ToRender(pcContext, fGlobalTime, m_sMenuControl.fYOrigin, 30.0f, fDepthTremble); RenderMenu(pcDevice, pcContext); } else OutputDebugString(L"Failed to create font!"); // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } #pragma endregion #pragma region draw stereo (optionally) // draw stereo target to screen (optionally) if ((m_eStereoMode) && (eD3DInterface == INTERFACE_IDXGISWAPCHAIN) && (eD3DMethod == METHOD_IDXGISWAPCHAIN_PRESENT)) { // DX 11 if ((m_ppcTexView11[0]) && (m_ppcTexView11[1])) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext))) { // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } // get the viewport UINT dwNumViewports = 1; D3D11_VIEWPORT psViewport[16]; pcContext->RSGetViewports(&dwNumViewports, psViewport); // backup all states D3DX11_STATE_BLOCK sStateBlock; CreateStateblock(pcContext, &sStateBlock); // clear all states, set targets ClearContextState(pcContext); // set first active render target - the stored back buffer - get the stored private data view ID3D11Texture2D* pcBackBuffer = nullptr; ((IDXGISwapChain*)pThis)->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pcBackBuffer); ID3D11RenderTargetView* pcView = nullptr; UINT dwSize = sizeof(pcView); pcBackBuffer->GetPrivateData(PDIID_ID3D11TextureXD_RenderTargetView, &dwSize, (void*)&pcView); if (dwSize) { pcContext->OMSetRenderTargets(1, (ID3D11RenderTargetView**)&pcView, m_pcDSVGeometry11); pcView->Release(); } else { // create render target view for the back buffer ID3D11RenderTargetView* pcRTV = nullptr; pcDevice->CreateRenderTargetView(pcBackBuffer, NULL, &pcRTV); if (pcRTV) { pcBackBuffer->SetPrivateDataInterface(PDIID_ID3D11TextureXD_RenderTargetView, pcRTV); pcRTV->Release(); } } pcContext->RSSetViewports(dwNumViewports, psViewport); pcBackBuffer->Release(); // clear the depth stencil pcContext->ClearDepthStencilView(m_pcDSVGeometry11, D3D11_CLEAR_DEPTH, 1.0f, 0); // create all bool bool bAllCreated = true; // create vertex shader if (!m_pcVertexShader11) { if (FAILED(CreateVertexShaderTechnique(pcDevice, &m_pcVertexShader11, &m_pcVertexLayout11, VertexShaderTechnique::PosUV2D))) bAllCreated = false; } // create pixel shader... TODO !! add option to switch output if (!m_pcPixelShader11) { if (FAILED(CreatePixelShaderEffect(pcDevice, &m_pcPixelShader11, PixelShaderTechnique::FullscreenSimple))) bAllCreated = false; } // Create vertex buffer if (!m_pcVertexBuffer11) { if (FAILED(CreateFullScreenVertexBuffer(pcDevice, &m_pcVertexBuffer11))) bAllCreated = false; } // create constant buffer if (!m_pcConstantBufferDirect11) { if (FAILED(CreateGeometryConstantBuffer(pcDevice, &m_pcConstantBufferDirect11, (UINT)sizeof(GeometryConstantBuffer)))) bAllCreated = false; } if (bAllCreated) { // left/right eye for (int nEye = 0; nEye < 2; nEye++) { // Set the input layout pcContext->IASetInputLayout(m_pcVertexLayout11); // Set vertex buffer UINT stride = sizeof(TexturedVertex); UINT offset = 0; pcContext->IASetVertexBuffers(0, 1, &m_pcVertexBuffer11, &stride, &offset); // Set constant buffer, first update it... scale and translate the left and right image D3DXMATRIX sScale; D3DXMatrixScaling(&sScale, 0.5f, 1.0f, 1.0f); D3DXMATRIX sTrans; if (nEye == 0) D3DXMatrixTranslation(&sTrans, -0.5f, 0.0f, 0.0f); else D3DXMatrixTranslation(&sTrans, 0.5f, 0.0f, 0.0f); D3DXMatrixTranspose(&sTrans, &sTrans); D3DXMATRIX sProj; D3DXMatrixMultiply(&sProj, &sTrans, &sScale); pcContext->UpdateSubresource((ID3D11Resource*)m_pcConstantBufferDirect11, 0, NULL, &sProj, 0, 0); pcContext->VSSetConstantBuffers(0, 1, &m_pcConstantBufferDirect11); // Set primitive topology pcContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // set texture pcContext->PSSetShaderResources(0, 1, m_ppcTexView11[nEye]); // set shaders pcContext->VSSetShader(m_pcVertexShader11, 0, 0); pcContext->PSSetShader(m_pcPixelShader11, 0, 0); // Render a triangle pcContext->Draw(6, 0); } } // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } } #pragma endregion } return nullptr; }
TextureClient* IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) { ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(); if (!device || aClient->GetForwarder()->GetCompositorBackendType() != LayersBackend::LAYERS_D3D11) { IDirect3DDevice9* d3d9device = gfxWindowsPlatform::GetPlatform()->GetD3D9Device(); if (d3d9device && aClient->GetForwarder()->GetCompositorBackendType() == LayersBackend::LAYERS_D3D9) { return GetD3D9TextureClient(aClient); } return nullptr; } if (mTextureClient) { return mTextureClient; } RefPtr<ID3D11DeviceContext> ctx; device->GetImmediateContext(byRef(ctx)); CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM, mData.mYSize.width, mData.mYSize.height, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; RefPtr<ID3D11Texture2D> textureY; HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = mData.mCbCrSize.width; newDesc.Height = mData.mCbCrSize.height; RefPtr<ID3D11Texture2D> textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCb)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); RefPtr<ID3D11Texture2D> textureCr; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureCr)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); { AutoLockTexture lockY(textureY); AutoLockTexture lockCb(textureCb); AutoLockTexture lockCr(textureCr); ctx->UpdateSubresource(textureY, 0, nullptr, mData.mYChannel, mData.mYStride, mData.mYStride * mData.mYSize.height); ctx->UpdateSubresource(textureCb, 0, nullptr, mData.mCbChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); ctx->UpdateSubresource(textureCr, 0, nullptr, mData.mCrChannel, mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height); } RefPtr<IDXGIResource> resource; HANDLE shareHandleY; textureY->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleY); HANDLE shareHandleCb; textureCb->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCb); HANDLE shareHandleCr; textureCr->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCr); mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), TextureFlags::DEFAULT, textureY, textureCb, textureCr, shareHandleY, shareHandleCb, shareHandleCr, GetSize(), mData.mYSize, mData.mCbCrSize); return mTextureClient; }
void CoherentGT::CoherentGTGem::Init() { ID3D11Device* pDevice = static_cast<ID3D11Device*>(gEnv->pRenderer->GetRendDevice()); //Init d3d stuff m_SwapChain = static_cast<IDXGISwapChain*>(gEnv->pRenderer->GetSwapChain()); HRESULT hr; m_width = gEnv->pRenderer->GetWidth(); m_height = gEnv->pRenderer->GetHeight(); pDevice->GetImmediateContext(&m_ImmediateContext); CryLogAlways("INIT COHERENT GT GEM"); Coherent::UIGT::SystemSettings settings; settings.DebuggerPort = 9999; m_UISystem = InitializeUIGTSystem(COHERENT_UI_GT_LICENSE, settings, Coherent::LoggingGT::Trace, &m_LogHandler); FileResourceHandler fileHandler; Coherent::UIGT::ViewInfo info; info.Width = m_width; info.Height = m_height; info.IsTransparent = true; info.ResourceHandlerInstance = &fileHandler; info.ViewListenerInstance = new SimpleViewListener(); m_Backend.reset(new renoir::Dx11Backend(static_cast<ID3D11Device*>(gEnv->pRenderer->GetRendDevice()), true)); string path; AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); if (fileIO) { const char* aliasPath = fileIO->GetAlias("@assets@"); if (aliasPath && aliasPath[0] != '\0') { path += aliasPath; } } path += "\\Shaders"; const char* dx11ShadersPath = path; static_cast<renoir::Dx11Backend*>(m_Backend.get())->InitializeStaticResources(dx11ShadersPath); uint32 flags = FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_DONT_RELEASE | FT_DONT_RESIZE; m_crytex = gEnv->pRenderer->EF_CreateTexture(m_width, m_height, 1, 0, eTF_R8G8B8A8, flags); m_UISystemRenderer = m_UISystem->CreateRenderer(m_Backend.get()); m_CurrentView = m_UISystem->CreateView(info, "http://www.liminalgames.com/ui/index.html"); int sampleCount = 1; auto tex = gEnv->pRenderer->EF_GetTextureByID(m_crytex); auto rtv = static_cast<ID3D11RenderTargetView*>(tex->GetTextureRTV()); m_stencilTexture = nullptr; m_stencilView = nullptr; D3D11_TEXTURE2D_DESC descDepth; std::memset(&descDepth, 0, sizeof(descDepth)); descDepth.Width = m_width; descDepth.Height = m_height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = sampleCount; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; ID3D11Texture2D *texture; if (FAILED(pDevice->CreateTexture2D(&descDepth, nullptr, &texture))) { CryLogAlways("FAILED TO CREATE TEX"); } D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; std::memset(&descDSV, 0, sizeof(descDSV)); descDSV.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; ID3D11DepthStencilView *dsv; if (FAILED(pDevice->CreateDepthStencilView( texture, &descDSV, &dsv))) { CryLogAlways("FAILED TO CREATE STENCIL VIEW"); } Coherent::UIGT::NativeRenderTarget rt = { nullptr, nullptr }; // Get a pointer to the native texture rt.Texture = (void*)rtv; rt.DepthStencilTexture = (void*)dsv; m_viewRenderer = m_UISystemRenderer->CreateViewRenderer( m_CurrentView, rt, m_width, m_height, sampleCount); gEnv->pGame->GetIGameFramework()->RegisterListener(this, "CoherentGT", FRAMEWORKLISTENERPRIORITY_HUD); }