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 dx11ShaderOverride::terminateKey(MHWRender::MDrawContext& context, const MString& /*key*/) { if (fShaderNode) { MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if (theRenderer) { dx11ShaderDX11Device* dxDevice = (dx11ShaderDX11Device*)theRenderer->GPUDeviceHandle(); if (dxDevice) { ID3D11DeviceContext* dxContext = NULL; dxDevice->GetImmediateContext(&dxContext); if (dxContext) { fShaderNode->restoreStates(dxContext, fStates); dxContext->VSSetShader(NULL, NULL, 0); dxContext->PSSetShader(NULL, NULL, 0); dxContext->GSSetShader(NULL, NULL, 0); dxContext->HSSetShader(NULL, NULL, 0); dxContext->DSSetShader(NULL, NULL, 0); dxContext->Release(); } } } } }
void ComplexTree::draw(ID3D11Device* device, const GameTime& gameTime) { ID3D11DeviceContext* deviceContext; device->GetImmediateContext(&deviceContext); ID3D11Buffer* buffers[2] = { trunkMesh.GetVB11(0, 0), instanceBuffer }; unsigned strides[2] = { trunkMesh.GetVertexStride(0,0), sizeof(Vector3) }; unsigned offsets[2] = {0}; deviceContext->IASetInputLayout(inputLayout); deviceContext->IASetVertexBuffers(0, 2, buffers, strides, offsets); deviceContext->IASetIndexBuffer(trunkMesh.GetIB11(0), trunkMesh.GetIBFormat11(0), 0); Camera& camera = vegetationRendering.getCamera(); const Light& light = vegetationRendering.getLight(); D3D11_VIEWPORT viewport; unsigned numViewports = 1; deviceContext->RSGetViewports(&numViewports, &viewport); evGSCulling->SetBool(vegetationRendering.isGSCullingEnabled()); evShowSavedCulling->SetBool(vegetationRendering.showSaved()); evSavedViewProjection->SetMatrix(vegetationRendering.getSavedViewMatrix() * vegetationRendering.getSavedProjectionMatrix()); evCameraPosition->SetFloatVector(camera.getPosition()); evLightVector->SetFloatVector(Vector3(light.Direction.x, light.Direction.y, light.Direction.z)); evAmbientLight->SetFloatVector(Vector3(light.Ambient.r, light.Ambient.g, light.Ambient.b)); evDiffuseLight->SetFloatVector(Vector3(light.Diffuse.r, light.Diffuse.g, light.Diffuse.b)); evSpecularLight->SetFloatVector(Vector3(light.Specular.r, light.Specular.g, light.Specular.b)); evShininess->SetFloat(TREE_SHININESS); evWorld->SetMatrix(world); evViewProjection->SetMatrix(camera.getView() * camera.getProjection(TREE_NEAR_PLANE, TREE_FAR_PLANE)); for(unsigned i = 0; i < trunkMesh.GetNumSubsets(0); ++i) { SDKMESH_SUBSET* subset = trunkMesh.GetSubset(0, i); //D3D11_PRIMITIVE_TOPOLOGY primitiveType = trunkMesh.GetPrimitiveType11((SDKMESH_PRIMITIVE_TYPE)subset->PrimitiveType); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST); SDKMESH_MATERIAL* material = trunkMesh.GetMaterial(subset->MaterialID); if(material) evTrunkTexture->SetResource(material->pDiffuseRV11); pass->Apply(0, deviceContext); deviceContext->DrawIndexedInstanced((unsigned)subset->IndexCount, drawInstanceCount, (unsigned)subset->IndexStart, (int)subset->VertexStart,0); //deviceContext->DrawIndexed((unsigned)subset->IndexCount, (unsigned)subset->IndexStart, (int)subset->VertexStart); } /*deviceContext->IASetInputLayout(inputLayoutLOD1); unsigned stride = sizeof(float) * 3; unsigned offset = 0; deviceContext->IASetVertexBuffers(0, 1, &instanceBuffer, &stride, &offset); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); evWorld->SetMatrix(Matrix::createScale(Vector3(9))); passLOD1->Apply(0, deviceContext); deviceContext->Draw(INSTANCE_COUNT, 0);*/ deviceContext->Release(); }
static void DoRendering (const float* worldMatrix, const float* identityMatrix, float* projectionMatrix, const MyVertex* verts) { // Does actual rendering of a simple triangle #if SUPPORT_D3D11 // D3D11 case if (s_DeviceType == kUnityGfxRendererD3D11 && EnsureD3D11ResourcesAreCreated()) { ID3D11DeviceContext* ctx = NULL; g_D3D11Device->GetImmediateContext (&ctx); ID3D11RenderTargetView* pCurrentRenderTarget; ID3D11DepthStencilView* pCurrentDepthStencil; // Get the current render targets ctx->OMGetRenderTargets(1, &pCurrentRenderTarget, &pCurrentDepthStencil); ctx->OMSetRenderTargets(1, &g_pD3D11RenderTargetView, nullptr); /* // update native texture from code D3D11_TEXTURE2D_DESC desc; g_TexturePointer->GetDesc(&desc); unsigned char* data = new unsigned char[desc.Width*desc.Height * 4]; FillTextureFromCode(desc.Width, desc.Height, desc.Width * 4, data); ctx->UpdateSubresource(g_TexturePointer, 0, NULL, data, desc.Width * 4, 0); delete[] data; */ const float CLEAR_CLR[4] = { 1, 1, 0, 1 }; // Yellow ctx->ClearRenderTargetView(g_pD3D11RenderTargetView, CLEAR_CLR); // Restore the original render target ctx->OMSetRenderTargets(1, &pCurrentRenderTarget, pCurrentDepthStencil); // update constant buffer - just the world matrix in our case ctx->UpdateSubresource (g_D3D11CB, 0, NULL, worldMatrix, 64, 0); // set shaders ctx->VSSetConstantBuffers (0, 1, &g_D3D11CB); ctx->VSSetShader (g_D3D11VertexShader, NULL, 0); ctx->PSSetShader (g_D3D11PixelShader, NULL, 0); // update vertex buffer ctx->UpdateSubresource (g_D3D11VB, 0, NULL, verts, sizeof(verts[0])*3, 0); // set input assembler data and draw ctx->IASetInputLayout (g_D3D11InputLayout); ctx->IASetPrimitiveTopology (D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); UINT stride = sizeof(MyVertex); UINT offset = 0; ctx->IASetVertexBuffers (0, 1, &g_D3D11VB, &stride, &offset); ctx->Draw (3, 0); ctx->Release(); } #endif }
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 TerrainController::init(ID3D11Device* device) { width = Config::getValue<int>(ConfigKeys::terrainWidth); length = Config::getValue<int>(ConfigKeys::terrainLength); position = Vector3(width / -2.0f, 0, length / -2.0f); bumpiness = Config::getValue<float>(ConfigKeys::terrainBumpiness); quality = Config::getValue<float>(ConfigKeys::terrainQuality); D3DX11_IMAGE_LOAD_INFO loadInfo; ZeroMemory( &loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO) ); loadInfo.Usage = D3D11_USAGE_STAGING; loadInfo.Format = DXGI_FORMAT_FROM_FILE; loadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_READ; ID3D11Texture2D *heightmapTexture, *normalmapTexture; D3DX11CreateTextureFromFile( device, L"Content/Textures/Terrain/Heightmap.png", &loadInfo, NULL, (ID3D11Resource**)(&heightmapTexture), NULL ); D3DX11CreateTextureFromFile( device, L"Content/Textures/Terrain/Normalmap.png", &loadInfo, NULL, (ID3D11Resource**)(&normalmapTexture), NULL ); heightmapTexture->GetDesc(&heightmapDesc); normalmapTexture->GetDesc(&normalmapDesc); std::vector<HeightmapFormat> hData = std::vector<HeightmapFormat>(heightmapDesc.Width * heightmapDesc.Height); std::vector<NormalmapFormat> nData = std::vector<NormalmapFormat>(normalmapDesc.Width * normalmapDesc.Height); ID3D11DeviceContext* deviceContext; device->GetImmediateContext(&deviceContext); D3D11_MAPPED_SUBRESOURCE heightmapData; deviceContext->Map(heightmapTexture, 0, D3D11_MAP_READ, 0, &heightmapData); memcpy((void*)&hData[0], heightmapData.pData, heightmapDesc.Width * heightmapDesc.Height * sizeof(HeightmapFormat)); deviceContext->Unmap(heightmapTexture, 0); D3D11_MAPPED_SUBRESOURCE normalmapData; deviceContext->Map(normalmapTexture, 0, D3D11_MAP_READ, 0, &normalmapData); memcpy((void*)&nData[0], normalmapData.pData, normalmapDesc.Width * normalmapDesc.Height * sizeof(NormalmapFormat)); deviceContext->Unmap(normalmapTexture, 0); heightData = HeightData(heightmapDesc.Width * heightmapDesc.Height); normalData = NormalData(normalmapDesc.Width * normalmapDesc.Height); std::transform(hData.begin(), hData.end(), heightData.begin(), &TerrainController::convertHeight); std::transform(nData.begin(), nData.end(), normalData.begin(), &TerrainController::convertNormal); heightmapTexture->Release(); normalmapTexture->Release(); deviceContext->Release(); }
static void SetDefaultGraphicsState () { #if SUPPORT_D3D11 // D3D11 case if (s_DeviceType == kUnityGfxRendererD3D11) { ID3D11DeviceContext* ctx = NULL; g_D3D11Device->GetImmediateContext (&ctx); ctx->OMSetDepthStencilState (g_D3D11DepthState, 0); ctx->RSSetState (g_D3D11RasterState); ctx->OMSetBlendState (g_D3D11BlendState, NULL, 0xFFFFFFFF); ctx->Release(); } #endif }
Profiler::Result Profiler::getResult(ID3D11Device* graphicsDevice, Game* game) { ID3D11DeviceContext* immediateContext; graphicsDevice->GetImmediateContext(&immediateContext); GPA_BeginSession(&sessionID); for (unsigned i = 0; i < numPasses; ++i) { GPA_BeginPass(); GPA_BeginSample(0); game->drawTerrain(graphicsDevice); GPA_EndSample(); GPA_EndPass(); } GPA_EndSession(); immediateContext->Release(); bool readyResult; do GPA_IsSessionReady(&readyResult, sessionID); while (!readyResult); do GPA_IsSampleReady(&readyResult, sessionID, 0); while (!readyResult); double primitivesIn; double pixelsPerTriangle; GPA_GetSampleFloat64(sessionID, 0, primitivesInCounterID, &primitivesIn); GPA_GetSampleFloat64(sessionID, 0, pixelsPerTriangleCounterID, &pixelsPerTriangle); Result result; result.primitiveCount = (unsigned)primitivesIn; result.pixelsPerTriangle = (float)pixelsPerTriangle; return result; }
void UnityTextureOutput::Write(const FrameData *frame) noexcept { // TODO: move this bit into constructor, if possible? ID3D11Texture2D* d3dtex = (ID3D11Texture2D*)texture_ptr_; ID3D11Device *g_D3D11Device; d3dtex->GetDevice(&g_D3D11Device); ID3D11DeviceContext* ctx = NULL; g_D3D11Device->GetImmediateContext(&ctx); D3D11_TEXTURE2D_DESC desc; d3dtex->GetDesc(&desc); auto linelength = frame->size.width * frame->size.depth; auto buffer = (eye_ == Eye::LEFT) ? frame->buffer_left.get() : frame->buffer_right.get(); // TODO: https://gamedev.stackexchange.com/questions/60668/how-to-use-updatesubresource-and-map-unmap ? ctx->UpdateSubresource(d3dtex, 0, NULL, buffer, linelength, 0); ctx->Release(); }
//! driver initialization void DirectX11Driver::Init() { super::Init(); UINT creationFlags = 0; #if defined(_DEBUG) creationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { //D3D_FEATURE_LEVEL_11_1, //D3D_FEATURE_LEVEL_11_0, //D3D_FEATURE_LEVEL_10_1, //D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 // max compatibility with Windows Phone 8 }; ID3D11Device* pDevice = NULL; ID3D11DeviceContext* pContext = NULL; DX_ASSERT(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &pDevice, &m_FeatureLevel, &pContext)); ID3D11Device1* pDevice1 = NULL; ID3D11DeviceContext1* pContext1 = NULL; DX_ASSERT(pDevice->QueryInterface(__uuidof(ID3D11Device1), (void**)&pDevice1)); DX_ASSERT(pContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void**)&pContext1)); m_Device = pDevice1; m_ImmediateContext = pContext1; pDevice->Release(); pContext->Release(); #if SHOOT_PLATFORM != SHOOT_PLATFORM_WP8 if(!m_RenderTargetView.Get()) { ResizeScreen(Size(int(m_ViewPortArea.Size().X), int(m_ViewPortArea.Size().Y))); } #endif }
std::vector<DXGI_SAMPLE_DESC> EnumAAModes(IDXGIAdapter* adapter) { std::vector<DXGI_SAMPLE_DESC> aa_modes; // NOTE: D3D 10.0 doesn't support multisampled resources which are bound as depth buffers AND shader resources. // Thus, we can't have MSAA with 10.0 level hardware. ID3D11Device* device; ID3D11DeviceContext* context; D3D_FEATURE_LEVEL feat_level; HRESULT hr = PD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &device, &feat_level, &context); if (FAILED(hr) || feat_level == D3D_FEATURE_LEVEL_10_0) { DXGI_SAMPLE_DESC desc; desc.Count = 1; desc.Quality = 0; aa_modes.push_back(desc); SAFE_RELEASE(context); SAFE_RELEASE(device); } else { for (int samples = 0; samples < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; ++samples) { UINT quality_levels = 0; device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, samples, &quality_levels); if (quality_levels > 0) { DXGI_SAMPLE_DESC desc; desc.Count = samples; for (desc.Quality = 0; desc.Quality < quality_levels; ++desc.Quality) aa_modes.push_back(desc); } } context->Release(); device->Release(); } return aa_modes; }
void Edo::GetD3D11DeviceAndSwapchainVTable(HWND window, uintptr_t** ppDeviceVTable, uintptr_t** ppContextVTable, uintptr_t** ppSwapchainVTable) { ID3D11Device* pDevice; ID3D11DeviceContext* pContext; IDXGISwapChain* pSwapchain; //Create dummy devices. CreateD3D11DummyDeviceAndSwapchain(window, &pDevice, &pContext, &pSwapchain); //Set the vtable pointers if(ppDeviceVTable) *ppDeviceVTable = (uintptr_t*)*(uintptr_t*)pDevice; if(ppContextVTable) *ppContextVTable = (uintptr_t*)*(uintptr_t*)pContext; if(ppSwapchainVTable) *ppSwapchainVTable = (uintptr_t*)*(uintptr_t*)pSwapchain; //Cleanup. pDevice->Release(); pContext->Release(); pSwapchain->Release(); }
void Terrain::draw(ID3D11Device* device, const GameTime& gameTime) { ID3D11DeviceContext* deviceContext; device->GetImmediateContext(&deviceContext); deviceContext->IASetInputLayout(inputLayout); deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); unsigned strides[2] = { sizeof(TerrainVertex), sizeof(TerrainInstance) }; unsigned offsets[2] = { 0, 0 }; ID3D11Buffer* buffers[2] = { vertexBuffer, instanceBuffer }; deviceContext->IASetVertexBuffers(0, 2, buffers, strides, offsets); deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0); Camera& camera = vegetationRendering.getCamera(); evWorld->SetMatrix(world); evViewProjection->SetMatrix(camera.getView() * camera.getProjection()); pass->Apply(0, deviceContext); deviceContext->DrawIndexedInstanced(4, INSTANCE_COUNT, 0, 0, 0); //deviceContext->DrawInstanced(4, INSTANCE_COUNT, 0, 0); deviceContext->Release(); }
void VegetationRendering::draw(ID3D11Device* device, const GameTime& gameTime) { ID3D11DeviceContext* deviceContext; device->GetImmediateContext(&deviceContext); D3D11_VIEWPORT viewport; unsigned numViewports = 1; deviceContext->RSGetViewports(&numViewports, &viewport); camera->setAspectRatio(viewport.Width / viewport.Height); deviceContext->RSSetState(rsCullBack); deviceContext->OMSetBlendState(bsDefault, Vector4(0,0,0,0), 0xFFFFFFFF); terrain->draw(device, gameTime); //tessellationTerrain->draw(device, gameTime); if (complexTreesEnabled) trunk->draw(device, gameTime); deviceContext->RSSetState(rsCullNone); if(treeModelsEnabled) { separateLeafModel->draw(device, gameTime); billboardLeafModel->draw(device, gameTime); } if (defaultTreesEnabled) { for(int i = 0; i < trunk->getDrawInstanceCount(); ++i) { Matrix trunkWorld = Matrix::createTranslation(trunk->getTreePositions()[i]); /*if(defaultDetailedEnabled) { defaultTrunkDetailedModel->setWorld(trunkWorld); defaultTrunkDetailedModel->draw(device, gameTime); } else {*/ defaultTrunkModel->setWorld(trunkWorld); defaultTrunkModel->draw(device, gameTime); //} } } if (complexGrassEnabled) complexGrass->draw(device, gameTime); if (defaultGrassEnabled) { for(int i = 0; i < complexGrass->getDrawInstanceCount(); ++i) { Matrix grassWorld = Matrix::createScale(complexGrass->getScale()) * Matrix::createTranslation(complexGrass->getGrassPatchPositions()[i]); if(defaultDetailedEnabled) { defaultGrassDetailedModel->setWorld(grassWorld); defaultGrassDetailedModel->draw(device, gameTime); } else { defaultGrassModel->setWorld(grassWorld); defaultGrassModel->draw(device, gameTime); } } } deviceContext->OMSetBlendState(bsAlphaToCoverage, Vector4(0,0,0,0), 0xFFFFFFFF); if (gsGrassEnabled) gsGrass->draw(device, gameTime); deviceContext->Release(); }
int main(int argc, char* argv[]) { // Parse the command line int realParams = 0; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { Usage(argv[0]); } else switch (++realParams) { case 1: default: Usage(argv[0]); } } if (realParams != 0) { Usage(argv[0]); } // Get an OSVR client context to use to access the devices // that we need. osvr::clientkit::ClientContext context( "org.opengoggles.exampleclients.TrackerCallback"); // Construct button devices and connect them to a callback // that will set the "quit" variable to true when it is // pressed. Use button "1" on the left-hand or // right-hand controller. osvr::clientkit::Interface leftButton1 = context.getInterface("/controller/left/1"); leftButton1.registerCallback(&myButtonCallback, &quit); osvr::clientkit::Interface rightButton1 = context.getInterface("/controller/right/1"); rightButton1.registerCallback(&myButtonCallback, &quit); // Create a D3D11 device and context to be used, rather than // having RenderManager make one for us. This is an example // of using an external one, which would be needed for clients // that already have a rendering pipeline, like Unity. ID3D11Device* myDevice = nullptr; // Fill this in ID3D11DeviceContext* myContext = nullptr; // Fill this in. // Here, we open the device and context ourselves, but if you // are working with a render library that provides them for you, // just stick them into the values rather than constructing // them. (This is a bit of a toy example, because we could // just let RenderManager do this work for us and use the library // it sends back. However, it does let us set parameters on the // device and context construction the way that we want, so it // might be useful. Be sure to get D3D11 and have set // D3D11_CREATE_DEVICE_BGRA_SUPPORT in the device/context // creation, however it is done). D3D_FEATURE_LEVEL acceptibleAPI = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL foundAPI; auto hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, &acceptibleAPI, 1, D3D11_SDK_VERSION, &myDevice, &foundAPI, &myContext); if (FAILED(hr)) { std::cerr << "Could not create D3D11 device and context" << std::endl; return -1; } // Put the device and context into a structure to let RenderManager // know to use this one rather than creating its own. osvr::renderkit::GraphicsLibrary library; library.D3D11 = new osvr::renderkit::GraphicsLibraryD3D11; library.D3D11->device = myDevice; library.D3D11->context = myContext; // Open Direct3D and set up the context for rendering to // an HMD. Do this using the OSVR RenderManager interface, // which maps to the nVidia or other vendor direct mode // to reduce the latency. osvr::renderkit::RenderManager* render = osvr::renderkit::createRenderManager(context.get(), "Direct3D11", library); if ((render == nullptr) || (!render->doingOkay())) { std::cerr << "Could not create RenderManager" << std::endl; return 1; } // Set up a handler to cause us to exit cleanly. #ifdef _WIN32 SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); #endif // Open the display and make sure this worked. osvr::renderkit::RenderManager::OpenResults ret = render->OpenDisplay(); if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) { std::cerr << "Could not open display" << std::endl; return 2; } if (ret.library.D3D11 == nullptr) { std::cerr << "Attempted to run a Direct3D11 program with a config file " << "that specified a different rendering library." << std::endl; return 3; } // Do a call to get the information we need to construct our // color and depth render-to-texture buffers. std::vector<osvr::renderkit::RenderInfo> renderInfo; context.update(); renderInfo = render->GetRenderInfo(); // Set up the vector of textures to render to and any framebuffer // we need to group them. std::vector<osvr::renderkit::RenderBuffer> renderBuffers; std::vector<ID3D11Texture2D*> depthStencilTextures; std::vector<ID3D11DepthStencilView*> depthStencilViews; for (size_t i = 0; i < renderInfo.size(); i++) { // The color buffer for this eye. We need to put this into // a generic structure for the Present function, but we only need // to fill in the Direct3D portion. // Note that this texture format must be RGBA and unsigned byte, // so that we can present it to Direct3D for DirectMode. ID3D11Texture2D* D3DTexture = nullptr; unsigned width = static_cast<int>(renderInfo[i].viewport.width); unsigned height = static_cast<int>(renderInfo[i].viewport.height); // Initialize a new render target texture description. D3D11_TEXTURE2D_DESC textureDesc = {}; textureDesc.Width = width; textureDesc.Height = height; textureDesc.MipLevels = 1; textureDesc.ArraySize = 1; // textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; textureDesc.SampleDesc.Count = 1; textureDesc.SampleDesc.Quality = 0; textureDesc.Usage = D3D11_USAGE_DEFAULT; // We need it to be both a render target and a shader resource textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; textureDesc.CPUAccessFlags = 0; textureDesc.MiscFlags = 0; // Create a new render target texture to use. hr = renderInfo[i].library.D3D11->device->CreateTexture2D( &textureDesc, NULL, &D3DTexture); if (FAILED(hr)) { std::cerr << "Can't create texture for eye " << i << std::endl; return -1; } // Fill in the resource view for your render texture buffer here D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc = {}; // This must match what was created in the texture to be rendered renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; // Create the render target view. ID3D11RenderTargetView* renderTargetView; //< Pointer to our render target view hr = renderInfo[i].library.D3D11->device->CreateRenderTargetView( D3DTexture, &renderTargetViewDesc, &renderTargetView); if (FAILED(hr)) { std::cerr << "Could not create render target for eye " << i << std::endl; return -2; } // Push the filled-in RenderBuffer onto the stack. osvr::renderkit::RenderBufferD3D11* rbD3D = new osvr::renderkit::RenderBufferD3D11; rbD3D->colorBuffer = D3DTexture; rbD3D->colorBufferView = renderTargetView; osvr::renderkit::RenderBuffer rb; rb.D3D11 = rbD3D; renderBuffers.push_back(rb); //================================================================== // Create a depth buffer // Make the depth/stencil texture. D3D11_TEXTURE2D_DESC textureDescription = {}; textureDescription.SampleDesc.Count = 1; textureDescription.SampleDesc.Quality = 0; textureDescription.Usage = D3D11_USAGE_DEFAULT; textureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL; textureDescription.Width = width; textureDescription.Height = height; textureDescription.MipLevels = 1; textureDescription.ArraySize = 1; textureDescription.CPUAccessFlags = 0; textureDescription.MiscFlags = 0; /// @todo Make this a parameter textureDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; ID3D11Texture2D* depthStencilBuffer; hr = renderInfo[i].library.D3D11->device->CreateTexture2D( &textureDescription, NULL, &depthStencilBuffer); if (FAILED(hr)) { std::cerr << "Could not create depth/stencil texture for eye " << i << std::endl; return -4; } depthStencilTextures.push_back(depthStencilBuffer); // Create the depth/stencil view description D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDescription = {}; depthStencilViewDescription.Format = textureDescription.Format; depthStencilViewDescription.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDescription.Texture2D.MipSlice = 0; ID3D11DepthStencilView* depthStencilView; hr = renderInfo[i].library.D3D11->device->CreateDepthStencilView( depthStencilBuffer, &depthStencilViewDescription, &depthStencilView); if (FAILED(hr)) { std::cerr << "Could not create depth/stencil view for eye " << i << std::endl; return -5; } depthStencilViews.push_back(depthStencilView); } // Create depth stencil state. // Describe how depth and stencil tests should be performed. D3D11_DEPTH_STENCIL_DESC depthStencilDescription = {}; depthStencilDescription.DepthEnable = true; depthStencilDescription.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDescription.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDescription.StencilEnable = true; depthStencilDescription.StencilReadMask = 0xFF; depthStencilDescription.StencilWriteMask = 0xFF; // Front-facing stencil operations depthStencilDescription.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDescription.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDescription.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDescription.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Back-facing stencil operations depthStencilDescription.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDescription.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDescription.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDescription.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; ID3D11DepthStencilState* depthStencilState; hr = renderInfo[0].library.D3D11->device->CreateDepthStencilState( &depthStencilDescription, &depthStencilState); if (FAILED(hr)) { std::cerr << "Could not create depth/stencil state" << std::endl; return -3; } // Register our constructed buffers so that we can use them for // presentation. if (!render->RegisterRenderBuffers(renderBuffers)) { std::cerr << "RegisterRenderBuffers() returned false, cannot continue" << std::endl; quit = true; } // Continue rendering until it is time to quit. while (!quit) { // Update the context so we get our callbacks called and // update tracker state. context.update(); renderInfo = render->GetRenderInfo(); // Render into each buffer using the specified information. for (size_t i = 0; i < renderInfo.size(); i++) { renderInfo[i].library.D3D11->context->OMSetDepthStencilState( depthStencilState, 1); RenderView(renderInfo[i], renderBuffers[i].D3D11->colorBufferView, depthStencilViews[i]); } // Send the rendered results to the screen if (!render->PresentRenderBuffers(renderBuffers, renderInfo)) { std::cerr << "PresentRenderBuffers() returned false, maybe because " "it was asked to quit" << std::endl; quit = true; } } // Close the Renderer interface cleanly. delete render; // Clean up after ourselves. myContext->Release(); myDevice->Release(); return 0; }
bool TestDX11Present() { HMODULE hD3D11 = LoadLibrary("d3d11.dll"); if (!hD3D11) { Msg("* DX11: failed to load d3d11.dll"); return false; } FuncPtrD3D11CreateDeviceAndSwapChain pD3D11CreateDeviceAndSwapChain = (FuncPtrD3D11CreateDeviceAndSwapChain)GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain"); if (!pD3D11CreateDeviceAndSwapChain) { Msg("* DX11: failed to get address of D3D11CreateDeviceAndSwapChain"); return false; } // Register class WNDCLASSEX wcex; ZeroMemory(&wcex, sizeof(wcex)); wcex.cbSize = sizeof( WNDCLASSEX ); wcex.lpfnWndProc = WndProc; wcex.hInstance = GetModuleHandle(NULL); wcex.lpszClassName = "TestDX11WindowClass"; if( !RegisterClassEx( &wcex ) ) { Msg("* DX11: failed to register window class"); return false; } // Create window HWND hWnd = CreateWindow( "TestDX11WindowClass", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL ); DXGI_SWAP_CHAIN_DESC sd; if (!hWnd) { Msg("* DX11: failed to create window"); return false; } HRESULT hr = E_FAIL; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = 800; sd.BufferDesc.Height = 600; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; D3D_FEATURE_LEVEL pFeatureLevels[] = {D3D_FEATURE_LEVEL_11_0}; D3D_FEATURE_LEVEL FeatureLevel; ID3D11Device* pd3dDevice = NULL; ID3D11DeviceContext* pContext = NULL; IDXGISwapChain* pSwapChain = NULL; hr = pD3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, pFeatureLevels, 1, D3D11_SDK_VERSION, &sd, &pSwapChain, &pd3dDevice, &FeatureLevel, &pContext ); if (FAILED(hr)) Msg("* D3D11: device creation failed with hr=0x%08x", hr); if (pContext) pContext->Release(); if (pSwapChain) pSwapChain->Release(); if (pd3dDevice) pd3dDevice->Release(); FreeLibrary(hD3D11); DestroyWindow(hWnd); return SUCCEEDED(hr); }
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 DXSample::initD3D11() { auto hwnd = Win32Application::hwnd(); // デバイス作成フラグ auto deviceFlag = 0; #ifdef _DEBUG deviceFlag |= D3D11_CREATE_DEVICE_DEBUG; #endif DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 }; swapChainDesc.OutputWindow = hwnd; swapChainDesc.BufferCount = 2; swapChainDesc.BufferDesc.Width = this->width(); swapChainDesc.BufferDesc.Height = this->height(); swapChainDesc.Windowed = true; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.Flags = 0; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; std::array<D3D_DRIVER_TYPE, 3> driverTypes = { { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE } }; std::array<D3D_FEATURE_LEVEL, 3> featureLevels = { { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 } }; HRESULT hr = E_FAIL; D3D_DRIVER_TYPE usedDriverType; ID3D11DeviceContext* pContext = nullptr; for (auto driverIndex = 0U; driverIndex < driverTypes.size(); driverIndex++) { usedDriverType = driverTypes[driverIndex]; hr = D3D11CreateDeviceAndSwapChain( NULL, usedDriverType, NULL, deviceFlag, &featureLevels[0], static_cast<UINT>(featureLevels.size()), D3D11_SDK_VERSION, &swapChainDesc, &this->mpSwapChain, &this->mpDevice, nullptr, &pContext ); if (SUCCEEDED(hr))break; } if (FAILED(hr)) { throw std::runtime_error("DX11の初期化に失敗しました。"); } this->mpImmediateContext = pContext; pContext->Release(); {//バックバッファのRenderTargetViewの作成 HRESULT hr = this->mpSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&this->mpBackBuffer); if (FAILED(hr)) { throw std::runtime_error("バックバッファーのリソース取得に失敗"); } this->mpDevice->CreateRenderTargetView(this->mpBackBuffer.Get(), nullptr, &this->mpBackBufferRTV); } { D3D11_TEXTURE2D_DESC desc = {}; desc.Width = this->width(); desc.Height = this->height(); desc.Format = DXGI_FORMAT_D32_FLOAT; desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; desc.ArraySize = 1; desc.SampleDesc.Count = 1; auto hr = this->mpDevice->CreateTexture2D(&desc, nullptr, &this->mpZBuffer); if (FAILED(hr)) { throw std::runtime_error("Zバッファー作成に失敗"); } hr = this->mpDevice->CreateDepthStencilView(this->mpZBuffer.Get(), nullptr, &this->mpZBufferDSV); if (FAILED(hr)) { throw std::runtime_error("ZバッファーのDepthStencilViewの作成に失敗"); } } D3D11_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; vp.Width = static_cast< float >(this->width()); vp.Height = static_cast< float >(this->height()); vp.MinDepth = 0.f; vp.MaxDepth = 1.f; this->mpImmediateContext->RSSetViewports(1, &vp); }
void ComplexTree::init(ID3D11Device* device) { ID3D11DeviceContext* deviceContext; device->GetImmediateContext(&deviceContext); HRESULT result = trunkMesh.Create(device, trunkPath, true); boundingBoxCenter = trunkMesh.GetMeshBBoxCenter(0); boundingBoxExtents = trunkMesh.GetMeshBBoxExtents(0); ID3DBlob* errorBlob; ID3DBlob* shaderBlob; result = D3DX11CompileFromFileA("Content/Effects/Trunk.fx", 0, 0, 0, "fx_5_0", 0, 0, 0, &shaderBlob, &errorBlob, 0); char* errorBuffer; if(errorBlob) { errorBuffer = (char*)errorBlob->GetBufferPointer(); } result = D3DX11CreateEffectFromMemory(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), 0, device, &effect); if(shaderBlob) shaderBlob->Release(); if(errorBlob) errorBlob->Release(); for(int i = 0; i < TREE_INSTANCE_COUNT; ++i) { treePositions[i].x = (rand() / (float)RAND_MAX) * TREE_BORDER - TREE_BORDER / 2.0f; treePositions[i].y = 0; treePositions[i].z = (rand() / (float)RAND_MAX) * TREE_BORDER - TREE_BORDER / 2.0f; } D3D11_BUFFER_DESC instanceBufferDesc; ZeroMemory(&instanceBufferDesc, sizeof(D3D11_BUFFER_DESC)); instanceBufferDesc.Usage = D3D11_USAGE_DEFAULT; instanceBufferDesc.ByteWidth = sizeof(treePositions); instanceBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; instanceBufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA instanceData; ZeroMemory(&instanceData, sizeof(D3D11_SUBRESOURCE_DATA)); instanceData.pSysMem = treePositions; device->CreateBuffer(&instanceBufferDesc, &instanceData, &instanceBuffer); technique = effect->GetTechniqueByName("Trunk"); techniqueLOD1 = effect->GetTechniqueByName("TrunkLOD1"); pass = technique->GetPassByIndex(0); passLOD1 = techniqueLOD1->GetPassByIndex(0); D3D11_INPUT_ELEMENT_DESC inputElementDescLOD0[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1} }; int inputElementCount = sizeof(inputElementDescLOD0) / sizeof(D3D11_INPUT_ELEMENT_DESC); D3DX11_PASS_DESC passDesc; pass->GetDesc(&passDesc); result = device->CreateInputLayout(inputElementDescLOD0, inputElementCount, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &inputLayout); D3D11_INPUT_ELEMENT_DESC inputElementDescLOD1[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0} }; inputElementCount = sizeof(inputElementDescLOD1) / sizeof(D3D11_INPUT_ELEMENT_DESC); passLOD1->GetDesc(&passDesc); device->CreateInputLayout(inputElementDescLOD1, inputElementCount, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &inputLayoutLOD1); CDXUTResourceCache& resourceCache = DXUTGetGlobalResourceCache(); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/rinde_bumpmap.dds", &bumpMap); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/rinde.dds", &alternativeTrunkTexture); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/trunk414_normalmap.dds", &normalMap); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/trunk414_front.dds", &billboardFront); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/trunk414_side.dds", &billboardSide); resourceCache.CreateTextureFromFile(device, deviceContext, L"Content/Textures/Trees/trunk414_top.dds", &billboardTop); evViewProjection = effect->GetVariableByName("ViewProjection")->AsMatrix(); evWorld = effect->GetVariableByName("World")->AsMatrix(); evTrunkTexture = effect->GetVariableByName("TrunkTexture")->AsShaderResource(); evBumpMap = effect->GetVariableByName("BumpMapTexture")->AsShaderResource(); evNormalMap = effect->GetVariableByName("NormalMapTexture")->AsShaderResource(); evBillboardTop = effect->GetVariableByName("BillboardTop")->AsShaderResource(); evBillboardSide = effect->GetVariableByName("BillboardSide")->AsShaderResource(); evBillboardFront = effect->GetVariableByName("BillboardFront")->AsShaderResource(); evEdgeFactor = effect->GetVariableByName("EdgeFactor")->AsScalar(); evInsideFactor = effect->GetVariableByName("InsideFactor")->AsScalar(); evMinDistance = effect->GetVariableByName("MinDistance")->AsScalar(); evMaxDistance = effect->GetVariableByName("MaxDistance")->AsScalar(); evBoundingBoxCenter = effect->GetVariableByName("BoundingBoxCenter")->AsScalar(); evBoundingBoxExtents = effect->GetVariableByName("BoundingBoxExtents")->AsScalar(); evGSCulling = effect->GetVariableByName("GSCulling")->AsScalar(); evShowSavedCulling = effect->GetVariableByName("ShowSavedCulling")->AsScalar(); evSavedViewProjection = effect->GetVariableByName("SavedViewProjection")->AsMatrix(); evCameraPosition = effect->GetVariableByName("CameraPosition")->AsVector(); evLightVector = effect->GetVariableByName("LightVector")->AsVector(); evAmbientLight = effect->GetVariableByName("AmbientLight")->AsVector(); evDiffuseLight = effect->GetVariableByName("DiffuseLight")->AsVector(); evSpecularLight = effect->GetVariableByName("SpecularLight")->AsVector(); evShininess = effect->GetVariableByName("Shininess")->AsScalar(); evBumpMap->SetResource(bumpMap); evTrunkTexture->SetResource(alternativeTrunkTexture); evNormalMap->SetResource(normalMap); evBillboardTop->SetResource(billboardTop); evBillboardFront->SetResource(billboardFront); evBillboardSide->SetResource(billboardSide); evEdgeFactor->SetFloat(TREE_TESSELLATION_FACTOR_EDGES); evInsideFactor->SetFloat(TREE_TESSELLATION_FACTOR_INSIDE); evMinDistance->SetFloat(TREE_MIN_DISTANCE); evMaxDistance->SetFloat(TREE_MAX_DISTANCE); evBoundingBoxCenter->SetFloatArray(boundingBoxCenter, 0, 3); evBoundingBoxExtents->SetFloatArray(boundingBoxExtents, 0, 3); deviceContext->Release(); }
/// Prepares DXGI and D3D11 data by trying to determine the module filepath /// and function offsets in memory. /// (This data can later be used for hooking / code injection.) /// /// Adjusts the data behind the global variables dxgi and d3d11. void PrepareDXGI11(IDXGIAdapter1* pAdapter, bool initializeDXGIData) { if (!dxgi || !d3d11 || !pAdapter) return; ods("D3D11: Preparing static data for DXGI and D3D11 Injection"); d3d11->wcFileName[0] = 0; d3d11->iOffsetAddRef = 0; d3d11->iOffsetRelease = 0; HMODULE hD3D11 = LoadLibrary("D3D11.DLL"); if (hD3D11 != NULL) { HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, NULL, NULL, 0); D3D11CreateDeviceAndSwapChainType pD3D11CreateDeviceAndSwapChain = reinterpret_cast<D3D11CreateDeviceAndSwapChainType>(GetProcAddress(hD3D11, "D3D11CreateDeviceAndSwapChain")); DXGI_SWAP_CHAIN_DESC desc; ZeroMemory(&desc, sizeof(desc)); RECT rcWnd; BOOL success = GetClientRect(hwnd, &rcWnd); if (success) { desc.BufferDesc.Width = rcWnd.right - rcWnd.left; desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top; ods("D3D11: Got ClientRect W %d H %d", desc.BufferDesc.Width, desc.BufferDesc.Height); desc.BufferDesc.RefreshRate.Numerator = 60; desc.BufferDesc.RefreshRate.Denominator = 1; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 2; desc.OutputWindow = hwnd; desc.Windowed = true; desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; IDXGISwapChain *pSwapChain = NULL; ID3D11Device *pDevice = NULL; D3D_FEATURE_LEVEL featureLevel; ID3D11DeviceContext *pDeviceContext = NULL; HRESULT hr = pD3D11CreateDeviceAndSwapChain(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &desc, &pSwapChain, &pDevice, &featureLevel, &pDeviceContext); if (FAILED(hr)) ods("D3D11: pD3D11CreateDeviceAndSwapChain failure!"); if (pDevice && pDeviceContext && pSwapChain) { // For VC++ the vtable is located at the base addr. of the object and each function entry is a single pointer. Since p.e. the base classes // of IDXGISwapChain have a total of 8 functions the 8+Xth entry points to the Xth added function in the derived interface. void ***vtbl = (void ***) pSwapChain; void *pPresent = (*vtbl)[8]; int offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pPresent), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D11", "Present"); if (offset >= 0) { if (initializeDXGIData) { dxgi->iOffsetPresent = offset; ods("D3D11: Successfully found Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent); } else { if (dxgi->iOffsetPresent == offset) { ods("D3D11: Successfully verified Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent); } else { ods("D3D11: Failed to verify Present offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetPresent); } } } void *pResize = (*vtbl)[13]; offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pResize), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D11", "ResizeBuffers"); if (offset >= 0) { if (initializeDXGIData) { dxgi->iOffsetResize = offset; ods("D3D11: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize); } else { if (dxgi->iOffsetResize == offset) { ods("D3D11: Successfully verified ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize); } else { ods("D3D11: Failed to verify ResizeBuffers offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetResize); } } } vtbl = (void ***) pDevice; void *pAddRef = (*vtbl)[1]; offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pAddRef), d3d11->wcFileName, ARRAY_NUM_ELEMENTS(d3d11->wcFileName), "D3D11", "AddRef"); if (offset >= 0) { d3d11->iOffsetAddRef = offset; ods("D3D11: Successfully found AddRef offset: %ls: %d", d3d11->wcFileName, d3d11->iOffsetAddRef); } void *pRelease = (*vtbl)[2]; offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pRelease), d3d11->wcFileName, ARRAY_NUM_ELEMENTS(d3d11->wcFileName), "D3D11", "Release"); if (offset >= 0) { d3d11->iOffsetRelease = offset; ods("D3D11: Successfully found Release offset: %ls: %d", d3d11->wcFileName, d3d11->iOffsetRelease); } } if (pDevice) pDevice->Release(); if (pDeviceContext) pDeviceContext->Release(); if (pSwapChain) pSwapChain->Release(); } else { FreeLibrary(hD3D11); } DestroyWindow(hwnd); } else { FreeLibrary(hD3D11); } }
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(); }
int _tmain(int /*argc*/, _TCHAR* /*argv[]*/) { // GROUP_SIZE_X defined in kernel.hlsl must match the // groupSize declared here. size_t const groupSize = 512; size_t const numGroups = 16; size_t const dimension = numGroups*groupSize; // Create a D3D11 device and immediate context. // TODO: The code below uses the default video adapter, with the // default set of feature levels. Please see the MSDN docs if // you wish to control which adapter and feature level are used. D3D_FEATURE_LEVEL featureLevel; ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, 0, D3D11_SDK_VERSION, &device, &featureLevel, &context); if (FAILED(hr)) { printf("D3D11CreateDevice failed with return code %x\n", hr); return hr; } // Create system memory and fill it with our initial data. Note that // these data structures aren't really necessary , it's just a demonstration // of how you can take existing data structures you might have and copy // their data to/from GPU computations. std::vector<float> x(dimension); std::vector<float> y(dimension); std::vector<float> z(dimension); float const a = 2.0f; for (size_t i = 0; i < dimension; ++ i) { x[i] = static_cast<float>(i); y[i] = 100 - static_cast<float>(i); } // Create structured buffers for the "x" and "y" vectors. D3D11_BUFFER_DESC inputBufferDesc; inputBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // The buffers are read-only by the GPU, writeable by the CPU. // TODO: If you will never again upate the data in a GPU buffer, // you might want to look at using a D3D11_SUBRESOURCE_DATA here to // provide the initialization data instead of doing the mapping // and copying that happens below. inputBufferDesc.Usage = D3D11_USAGE_DYNAMIC; inputBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; inputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; inputBufferDesc.StructureByteStride = sizeof(float); inputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* xBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &xBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // We can re-use inputBufferDesc here because the layout and usage of the x // and y buffers is exactly the same. ID3D11Buffer* yBuffer = nullptr; hr = device->CreateBuffer(&inputBufferDesc, NULL, &yBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for x buffer with return code %x\n", hr); return hr; } // Create shader resource views for the "x" and "y" buffers. // TODO: You can optionally provide a D3D11_SHADER_RESOURCE_VIEW_DESC // as the second parameter if you need to use only part of the buffer // inside the compute shader. ID3D11ShaderResourceView* xSRV = nullptr; hr = device->CreateShaderResourceView(xBuffer, NULL, &xSRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for x buffer with return code %x\n", hr); return hr; } ID3D11ShaderResourceView* ySRV = nullptr; hr = device->CreateShaderResourceView(yBuffer, NULL, &ySRV); if (FAILED(hr)) { printf("CreateShaderResourceView failed for y buffer with return code %x\n", hr); return hr; } // Create a structured buffer for the "z" vector. This buffer needs to be // writeable by the GPU, so we can't create it with CPU read/write access. D3D11_BUFFER_DESC outputBufferDesc; outputBufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; outputBufferDesc.Usage = D3D11_USAGE_DEFAULT; outputBufferDesc.CPUAccessFlags = 0; outputBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; outputBufferDesc.StructureByteStride = sizeof(float); outputBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* zBuffer = nullptr; hr = device->CreateBuffer(&outputBufferDesc, NULL, &zBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for z buffer with return code %x\n", hr); return hr; } // Create an unordered access view for the "z" vector. D3D11_UNORDERED_ACCESS_VIEW_DESC outputUAVDesc; outputUAVDesc.Buffer.FirstElement = 0; outputUAVDesc.Buffer.Flags = 0; outputUAVDesc.Buffer.NumElements = dimension; outputUAVDesc.Format = DXGI_FORMAT_UNKNOWN; outputUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; ID3D11UnorderedAccessView* zBufferUAV; hr = device->CreateUnorderedAccessView(zBuffer, &outputUAVDesc, &zBufferUAV); if (FAILED(hr)) { printf("CreateUnorderedAccessView failed for z buffer with return code %x\n", hr); return hr; } // Create a staging buffer, which will be used to copy back from zBuffer. D3D11_BUFFER_DESC stagingBufferDesc; stagingBufferDesc.BindFlags = 0; stagingBufferDesc.Usage = D3D11_USAGE_STAGING; stagingBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; stagingBufferDesc.StructureByteStride = sizeof(float); stagingBufferDesc.ByteWidth = sizeof(float) * dimension; ID3D11Buffer* stagingBuffer; hr = device->CreateBuffer(&stagingBufferDesc, NULL, &stagingBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for staging buffer with return code %x\n", hr); return hr; } // Create a constant buffer (this buffer is used to pass the constant // value 'a' to the kernel as cbuffer Constants). D3D11_BUFFER_DESC cbDesc; cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.Usage = D3D11_USAGE_DYNAMIC; cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cbDesc.MiscFlags = 0; // Even though the constant buffer only has one float, DX expects // ByteWidth to be a multiple of 4 floats (i.e., one 128-bit register). cbDesc.ByteWidth = sizeof(float)*4; ID3D11Buffer* constantBuffer = nullptr; hr = device->CreateBuffer( &cbDesc, NULL, &constantBuffer); if (FAILED(hr)) { printf("CreateBuffer failed for constant buffer with return code %x\n", hr); return hr; } // Map the constant buffer and set the constant value 'a'. D3D11_MAPPED_SUBRESOURCE mappedResource; context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* constants = reinterpret_cast<float*>(mappedResource.pData); constants[0] = a; constants = nullptr; context->Unmap(constantBuffer, 0); // Map the x buffer and copy our data into it. context->Map(xBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* xvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(xvalues, &x[0], sizeof(float)*x.size()); xvalues = nullptr; context->Unmap(xBuffer, 0); // Map the y buffer and copy our data into it. context->Map(yBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); float* yvalues = reinterpret_cast<float*>(mappedResource.pData); memcpy(yvalues, &y[0], sizeof(float)*y.size()); yvalues = nullptr; context->Unmap(yBuffer, 0); // Compile the compute shader into a blob. ID3DBlob* errorBlob = nullptr; ID3DBlob* shaderBlob = nullptr; hr = D3DX11CompileFromFile(L"kernel.hlsl", NULL, NULL, "saxpy", "cs_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &shaderBlob, &errorBlob, NULL); if (FAILED(hr)) { // Print out the error message if there is one. if (errorBlob) { char const* message = (char*)errorBlob->GetBufferPointer(); printf("kernel.hlsl failed to compile; error message:\n"); printf("%s\n", message); errorBlob->Release(); } return hr; } // Create a shader object from the compiled blob. ID3D11ComputeShader* computeShader; hr = device->CreateComputeShader(shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize(), NULL, &computeShader); if (FAILED(hr)) { printf("CreateComputeShader failed with return code %x\n", hr); return hr; } // Make the shader active. context->CSSetShader(computeShader, NULL, 0); // Attach the z buffer to the output via its unordered access view. UINT initCounts = 0xFFFFFFFF; context->CSSetUnorderedAccessViews(0, 1, &zBufferUAV, &initCounts); // Attach the input buffers via their shader resource views. context->CSSetShaderResources(0, 1, &xSRV); context->CSSetShaderResources(1, 1, &ySRV); // Attach the constant buffer context->CSSetConstantBuffers(0, 1, &constantBuffer); // Execute the shader, in 'numGroups' groups of 'groupSize' threads each. context->Dispatch(numGroups, 1, 1); // Copy the z buffer to the staging buffer so that we can // retrieve the data for accesss by the CPU. context->CopyResource(stagingBuffer, zBuffer); // Map the staging buffer for reading. context->Map(stagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); float* zData = reinterpret_cast<float*>(mappedResource.pData); memcpy(&z[0], zData, sizeof(float)*z.size()); zData = nullptr; context->Unmap(stagingBuffer, 0); // Now compare the GPU results against expected values. bool resultOK = true; for (size_t i = 0; i < x.size(); ++ i) { // NOTE: This comparison assumes the GPU produces *exactly* the // same result as the CPU. In general, this will not be the case // with floating-point calculations. float const expected = a*x[i] + y[i]; if (z[i] != expected) { printf("Unexpected result at position %lu: expected %.7e, got %.7e\n", i, expected, z[i]); resultOK = false; } } if (!resultOK) { printf("GPU results differed from the CPU results.\n"); OutputDebugStringA("GPU results differed from the CPU results.\n"); return 1; } printf("GPU output matched the CPU results.\n"); OutputDebugStringA("GPU output matched the CPU results.\n"); // Disconnect everything from the pipeline. ID3D11UnorderedAccessView* nullUAV = nullptr; context->CSSetUnorderedAccessViews( 0, 1, &nullUAV, &initCounts); ID3D11ShaderResourceView* nullSRV = nullptr; context->CSSetShaderResources(0, 1, &nullSRV); context->CSSetShaderResources(1, 1, &nullSRV); ID3D11Buffer* nullBuffer = nullptr; context->CSSetConstantBuffers(0, 1, &nullBuffer); // Release resources. Again, note that none of the error checks above // release resources that have been allocated up to this point, so the // sample doesn't clean up after itself correctly unless everything succeeds. computeShader->Release(); shaderBlob->Release(); constantBuffer->Release(); stagingBuffer->Release(); zBufferUAV->Release(); zBuffer->Release(); xSRV->Release(); xBuffer->Release(); ySRV->Release(); yBuffer->Release(); context->Release(); device->Release(); return 0; }
int main(int argc, char* argv[]) { options::option<bool> help("-h --help /?", "- Shows this help"); options::option<int> dimensions("--resolution", "<resolution> - Specifies texture resolution", { 128 }); options::option<float> scale("--scale", "<scale> - Specifies noise scale", { 8 } ); options::option<bool> gradients("--gradients", "- Store gradients in RGB channels (generates R8G8B8A8 textures instead of R8) - Note: gradients are fitted in [0-1]"); options::option<string> output("--output", 1, "<filename> - DDS destination texture"); options::option<bool> dumpAsFloat("--float", "- Use a floating-point texture format (default is R8/R8G8B8A8)"); auto cmdln = options::make_parser( help, dimensions, scale, gradients, output, dumpAsFloat ); cmdln.parse(argv, argv+argc); if (help || !output) { cout << "Generates tiling 3D textures filled with simplex noise. Options are :\n" << endl; cout << cmdln << endl; cout << "Example:" << endl; cout << " noise2dds --gradients --float --scale 16 --resolution 256 --output noise_256.dds" << endl; cout << "Will generate a texture with dimensions of 256x256x256, noise scale 16, with format DXGI_FORMAT_R32G32B32A32_FLOAT as noise_256.dds" << endl; return 0; } Volume<float> volume(dimensions(0), dimensions(0), dimensions(0), gradients ? 4 : 1); anl::CMWC4096 rnd; rnd.setSeedTime(); anl::CImplicitBasisFunction noise(anl::SIMPLEX, anl::QUINTIC); const float twopi = 2.f * 3.14159f; auto sampleNoise = [&](float x, float y, float z, int c) -> float { float dx = scale(0); float nx = cosf(x * twopi) * dx / twopi; float ny = cosf(y * twopi) * dx / twopi; float nz = cosf(z * twopi) * dx / twopi; float nw = sinf(x * twopi) * dx / twopi; float nu = sinf(y * twopi) * dx / twopi; float nv = sinf(z * twopi) * dx / twopi; float f = (float) noise.get(nx, ny, nz, nw, nu, nv) * 0.5f + 0.5f; return f; }; if (gradients) { float fmin = (std::numeric_limits<float>::max)(); float fmax = -(std::numeric_limits<float>::max)(); const float dx = 2.0f / 128.f; // 2.0f actually smoothes out the slight artifacts anl happens to have in its 6D simplex noise implementation volume.fill(0, [&](float x, float y, float z, int c) -> float { float m = (sampleNoise(x + dx, y, z, c) - sampleNoise(x - dx, y, z, c)) * 0.5f + 0.5f; fmin = (std::min)(m, fmin); fmax = (std::max)(m, fmax); return m; }); volume.fill(1, [&](float x, float y, float z, int c) -> float { float m = (sampleNoise(x, y + dx, z, c) - sampleNoise(x, y - dx, z, c)) * 0.5f + 0.5f; fmin = (std::min)(m, fmin); fmax = (std::max)(m, fmax); return m; }); volume.fill(2, [&](float x, float y, float z, int c) -> float { float m = (sampleNoise(x, y, z + dx, c) - sampleNoise(x, y, z - dx, c)) * 0.5f + 0.5f; fmin = (std::min)(m, fmin); fmax = (std::max)(m, fmax); return m; }); volume.fill(3, sampleNoise); // normalize gradients for (unsigned int n = 0; n < volume.Width*volume.Height*volume.Depth; n++) for (unsigned int c = 0; c < 3; c++) { float& f = volume.Data[n * 4 + c]; f = (f - fmin) / (fmax - fmin); } } else volume.fill(0, sampleNoise); // ID3D11Device* device; ID3D11DeviceContext* deviceContext; D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &deviceContext); if (dumpAsFloat) { volume.dump(output(0), gradients ? DXGI_FORMAT_R32G32B32A32_FLOAT : DXGI_FORMAT_R32_FLOAT, deviceContext); } else { Volume<byte> volumeByte(dimensions(0), dimensions(0), dimensions(0), gradients ? 4 : 1); volumeByte.fill([&](int x, int y, int z, int c) -> byte { return (byte) (volume.Data[(z * volume.Height * volume.Width + y * volume.Width + x) * volume.Channels + c] * 255.f); }); volumeByte.dump(output(0), gradients ? DXGI_FORMAT_R8G8B8A8_UNORM : DXGI_FORMAT_R8_UNORM, deviceContext); } deviceContext->Release(); device->Release(); return 0; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) { DXTInputHandlerDefault inputHandler; DXTWindowEventHandlerDefault eventHandler; DXTWindow window(hInstance, &inputHandler, &eventHandler); DXTRenderParams params; params.Extent = { 800, 600 }; params.UseVSync = true; params.Windowed = true; HRESULT result; result = window.Initialize(params, "DXT Example (DirectX 11)"); if (SUCCEEDED(result)) { ID3D11Device* device; ID3D11DeviceContext* context; IDXGISwapChain* swapChain; result = DXTInitDevice(params, &window, &swapChain, &device, &context); if (SUCCEEDED(result)) { eventHandler.SetSwapChain(swapChain); FLOAT clearColor[] = { 0.5f, 0.5f, 1.0f, 1.0f }; D3D11_INPUT_ELEMENT_DESC inputDesc[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(float) * 3, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(float) * 5, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT elementCount = 3; UINT stride = 8 * sizeof(FLOAT); UINT offset = 0; UINT indexCount = 0; FLOAT deltaTime = 0.016f; DXTSphericalCamera camera; DXTFirstPersonCameraController cameraController(&camera, &inputHandler); inputHandler.AddInputInterface(&cameraController); cameraController.Velocity = 40.0f; cameraController.RotationVelocity = 0.005f; camera.Position = DirectX::XMFLOAT3(20.0f, 20.0f, 20.0f); camera.LookAt(DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f)); ID3D11RenderTargetView* renderTargetView; ID3D11Texture2D* depthBuffer; ID3D11DepthStencilView* depthBufferView; ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; DXTBytecodeBlob vertexBytecode; ID3D11DepthStencilState* depthState; ID3D11RasterizerState* rasterizerState; ID3D11Buffer* vertexBuffer; ID3D11Buffer* indexBuffer; ID3D11InputLayout* inputLayout; ID3D11Buffer* transformBuffer; DXTCreateRenderTargetFromBackBuffer(swapChain, device, &renderTargetView); DXTCreateDepthStencilBuffer(device, params.Extent.Width, params.Extent.Height, DXGI_FORMAT_D24_UNORM_S8_UINT, &depthBuffer, &depthBufferView); DXTVertexShaderFromFile(device, "VertexShader.cso", &vertexShader, &vertexBytecode); DXTPixelShaderFromFile(device, "PixelShader.cso", &pixelShader); DXTCreateDepthStencilStateDepthTestEnabled(device, &depthState); DXTCreateRasterizerStateSolid(device, &rasterizerState); DXTLoadStaticMeshFromFile(device, "mesh.ase", DXTVertexAttributePosition | DXTVertexAttributeUV | DXTVertexAttributeNormal, DXTIndexTypeShort, &vertexBuffer, &indexBuffer, &indexCount); DXTCreateBuffer(device, sizeof(DirectX::XMFLOAT4X4) * 2, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE, D3D11_USAGE_DYNAMIC, &transformBuffer); device->CreateInputLayout(inputDesc, elementCount, vertexBytecode.Bytecode, vertexBytecode.BytecodeLength, &inputLayout); vertexBytecode.Destroy(); window.Present(false); while (!window.QuitMessageReceived()) { window.MessagePump(); if (inputHandler.IsKeyDown(VK_ESCAPE)) break; cameraController.Update(deltaTime); XMFLOAT4X4 ViewProj; XMFLOAT4X4 World; camera.GetViewProjectionMatrix(&ViewProj, params.Extent); XMStoreFloat4x4(&World, XMMatrixIdentity()); D3D11_MAPPED_SUBRESOURCE subres; context->Map(transformBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &subres); XMFLOAT4X4* ptr = (XMFLOAT4X4*)subres.pData; ptr[0] = World; ptr[1] = ViewProj; context->Unmap(transformBuffer, 0); D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (FLOAT)params.Extent.Width, (FLOAT)params.Extent.Height, 0.0f, 1.0f }; context->ClearRenderTargetView(renderTargetView, clearColor); context->ClearDepthStencilView(depthBufferView, D3D11_CLEAR_DEPTH, 1.0f, 0); context->OMSetDepthStencilState(depthState, 0); context->OMSetRenderTargets(1, &renderTargetView, depthBufferView); context->RSSetState(rasterizerState); context->RSSetViewports(1, &viewport); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, nullptr, 0); context->PSSetShader(pixelShader, nullptr, 0); context->VSSetConstantBuffers(0, 1, &transformBuffer); context->DrawIndexed(indexCount, 0, 0); swapChain->Present(1, 0); } swapChain->SetFullscreenState(false, nullptr); transformBuffer->Release(); depthBufferView->Release(); depthBuffer->Release(); inputLayout->Release(); vertexBuffer->Release(); indexBuffer->Release(); depthState->Release(); rasterizerState->Release(); vertexShader->Release(); pixelShader->Release(); renderTargetView->Release(); swapChain->Release(); context->Release(); device->Release(); } window.Destroy(); } }
void BBWin8Game::CreateD3dDevice(){ CoreWindow ^window=CoreWindow::GetForCurrentThread(); int width=DipsToPixels( window->Bounds.Width ); int height=DipsToPixels( window->Bounds.Height ); #if WINDOWS_8 switch( DisplayProperties::CurrentOrientation ){ case DisplayOrientations::Portrait: case DisplayOrientations::PortraitFlipped: std::swap( width,height ); break; } #endif UINT creationFlags=D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG creationFlags|=D3D11_CREATE_DEVICE_DEBUG; #endif #if WINDOWS_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; #elif WINDOWS_PHONE_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 }; #endif ID3D11Device *device; ID3D11DeviceContext *context; DXASS( D3D11CreateDevice( 0, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &_featureLevel, &context ) ); DXASS( device->QueryInterface( __uuidof( ID3D11Device1 ),(void**)&_d3dDevice ) ); DXASS( context->QueryInterface( __uuidof( ID3D11DeviceContext1 ),(void**)&_d3dContext ) ); device->Release(); context->Release(); //create swap chain if( _swapChain ){ DXASS( _swapChain->ResizeBuffers( 2,width,height,DXGI_FORMAT_B8G8R8A8_UNORM,0 ) ); }else{ #if WINDOWS_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=2; swapChainDesc.Scaling=DXGI_SCALING_NONE; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Flags=0; #elif WINDOWS_PHONE_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=1; swapChainDesc.Scaling=DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags=0; #endif IDXGIDevice1 *dxgiDevice; DXASS( _d3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ),(void**)&dxgiDevice ) ); IDXGIAdapter *dxgiAdapter; DXASS( dxgiDevice->GetAdapter( &dxgiAdapter ) ); IDXGIFactory2 *dxgiFactory; DXASS( dxgiAdapter->GetParent( __uuidof( IDXGIFactory2 ),(void**)&dxgiFactory ) ); DXASS( dxgiFactory->CreateSwapChainForCoreWindow( _d3dDevice,(IUnknown*)window,&swapChainDesc,0,&_swapChain ) ); DXASS( dxgiDevice->SetMaximumFrameLatency( 1 ) ); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); } // Create a render target view of the swap chain back buffer. // ID3D11Texture2D *backBuffer; DXASS( _swapChain->GetBuffer( 0,__uuidof( ID3D11Texture2D ),(void**)&backBuffer ) ); DXASS( _d3dDevice->CreateRenderTargetView( backBuffer,0,&_renderTargetView ) ); backBuffer->Release(); /* // Create a depth stencil view // D3D11_TEXTURE2D_DESC dsdesc; ZEROMEM( dsdesc ); dsdesc.Width=width; dsdesc.Height=height; dsdesc.MipLevels=1; dsdesc.ArraySize=1; dsdesc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT; dsdesc.SampleDesc.Count=1; dsdesc.SampleDesc.Quality=0; dsdesc.Usage=D3D11_USAGE_DEFAULT; dsdesc.BindFlags=D3D11_BIND_DEPTH_STENCIL; dsdesc.CpuAccessFlags=0; dsdesc.MiscFlags=0; ID3D11Texture2D *depthStencil; DXASS( _d3dDevice->CreateTexture2D( &dsdesc,0,&depthStencil ) ); DXASS( _d3dDevice->CreateDepthStencilView( depthStencil,0,&_depthStencilView ) ); depthStencil->Release(); */ D3D11_VIEWPORT viewport={ 0,0,width,height,0,1 }; _d3dContext->RSSetViewports( 1,&viewport ); }
// 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 } }
// Detour function that replaces the IDXGISwapChain::Present() API DllExport HRESULT __stdcall hook_DXGISwapChainPresent( IDXGISwapChain * This, UINT SyncInterval, UINT Flags ) { static int frame_interval; static LARGE_INTEGER initialTv, captureTv, freq; static int capture_initialized = 0; // int i; struct pooldata *data; struct vsource_frame *frame; // DXGI_SWAP_CHAIN_DESC pDESC; HRESULT hr = pDXGISwapChainPresent(This, SyncInterval, Flags); if(resolution_retrieved == 0) { if(DXGI_get_resolution(This) >= 0) { resolution_retrieved = 1; } return hr; } if(vsource_initialized == 0) { ga_error("video source not initialized.\n"); return hr; } This->GetDesc(&pDESC); pDXGI_FORMAT = pDESC.BufferDesc.Format; // extract screen format for sws_scale if(pDESC.BufferDesc.Width != game_width || pDESC.BufferDesc.Height != game_height) { ga_error("game width/height mismatched (%dx%d) != (%dx%d)\n", pDESC.BufferDesc.Width, pDESC.BufferDesc.Height, game_width, game_height); return hr; } // if (enable_server_rate_control && ga_hook_video_rate_control() < 0) return hr; if (dx_version == dx_none) { //bool check_result = FALSE; if (check_dx_device_version(This, IID_ID3D10Device)) { dx_version = dx_10; ga_error("[DXGISwapChain] DirectX 10\n"); } else if (check_dx_device_version(This, IID_ID3D10Device1)) { dx_version = dx_10_1; ga_error("[DXGISwapChain] DirectX 10.1\n"); } else if (check_dx_device_version(This, IID_ID3D11Device)) { dx_version = dx_11; ga_error("[DXGISwapChain] DirectX 11\n"); } } if (capture_initialized == 0) { frame_interval = 1000000/video_fps; // in the unif of us frame_interval++; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&initialTv); capture_initialized = 1; } else { QueryPerformanceCounter(&captureTv); } hr = 0; // d3d10 / d3d10.1 if (dx_version == dx_10 || dx_version == dx_10_1) { void *ppDevice; ID3D10Device *pDevice; //IUnknown *pDevice; if (dx_version == dx_10) { This->GetDevice(IID_ID3D10Device, &ppDevice); pDevice = (ID3D10Device *)ppDevice; } else if (dx_version == dx_10_1) { This->GetDevice(IID_ID3D10Device1, &ppDevice); pDevice = (ID3D10Device1 *)ppDevice; } else { OutputDebugString("Invalid DirectX version in IDXGISwapChain::Present"); return hr; } ID3D10RenderTargetView *pRTV = NULL; ID3D10Resource *pSrcResource = NULL; pDevice->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D10Texture2D* pSrcBuffer = (ID3D10Texture2D *)pSrcResource; ID3D10Texture2D* pDstBuffer = NULL; D3D10_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; desc.Usage = D3D10_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create texture2D"); //assert(exp_state == exp_none); } pDevice->CopyResource(pDstBuffer, pSrcBuffer); D3D10_MAPPED_TEXTURE2D mapped_screen; hr = pDstBuffer->Map(0, D3D10_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DstBuffer"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDstBuffer->Unmap(0); pDevice->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); // d11 } else if (dx_version == dx_11) { void *ppDevice; This->GetDevice(IID_ID3D11Device, &ppDevice); ID3D11Device *pDevice = (ID3D11Device*) ppDevice; This->GetDevice(IID_ID3D11DeviceContext, &ppDevice); ID3D11DeviceContext *pDeviceContext = (ID3D11DeviceContext *) ppDevice; ID3D11RenderTargetView *pRTV = NULL; ID3D11Resource *pSrcResource = NULL; pDeviceContext->OMGetRenderTargets(1, &pRTV, NULL); pRTV->GetResource(&pSrcResource); ID3D11Texture2D *pSrcBuffer = (ID3D11Texture2D *)pSrcResource; ID3D11Texture2D *pDstBuffer = NULL; D3D11_TEXTURE2D_DESC desc; pSrcBuffer->GetDesc(&desc); desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.Usage = D3D11_USAGE_STAGING; hr = pDevice->CreateTexture2D(&desc, NULL, &pDstBuffer); if (FAILED(hr)) { OutputDebugString("Failed to create buffer"); //assert(exp_state == exp_none); } pDeviceContext->CopyResource(pDstBuffer, pSrcBuffer); D3D11_MAPPED_SUBRESOURCE mapped_screen; hr = pDeviceContext->Map(pDstBuffer, 0, D3D11_MAP_READ, 0, &mapped_screen); if (FAILED(hr)) { OutputDebugString("Failed to map from DeviceContext"); //assert(exp_state == exp_none); } // copy image do { unsigned char *src, *dst; data = g_pipe[0]->allocate_data(); frame = (struct vsource_frame*) data->ptr; frame->pixelformat = PIX_FMT_BGRA; frame->realwidth = desc.Width; frame->realheight = desc.Height; frame->realstride = desc.Width<<2; frame->realsize = frame->realwidth * frame->realstride; frame->linesize[0] = frame->realstride;//frame->stride; // src = (unsigned char*) mapped_screen.pData; dst = (unsigned char*) frame->imgbuf; for (i = 0; i < encoder_height; i++) { CopyMemory(dst, src, frame->realstride/*frame->stride*/); src += mapped_screen.RowPitch; dst += frame->realstride;//frame->stride; } frame->imgpts = pcdiff_us(captureTv, initialTv, freq)/frame_interval; } while(0); // duplicate from channel 0 to other channels for(i = 1; i < SOURCES; i++) { int j; struct pooldata *dupdata; struct vsource_frame *dupframe; dupdata = g_pipe[i]->allocate_data(); dupframe = (struct vsource_frame*) dupdata->ptr; // vsource_dup_frame(frame, dupframe); // g_pipe[i]->store_data(dupdata); g_pipe[i]->notify_all(); } g_pipe[0]->store_data(data); g_pipe[0]->notify_all(); pDeviceContext->Unmap(pDstBuffer, 0); pDevice->Release(); pDeviceContext->Release(); pSrcResource->Release(); pSrcBuffer->Release(); pRTV->Release(); pDstBuffer->Release(); } return hr; }
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(); } }
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; }
/** * 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; }