//resize buffer void RenderEngine::resizeBuffer(LVLfloat2 size) { //resizes the whole buffer HRESULT result; ID3D11DeviceContext* con; m_d3dDevice->GetImmediateContext(&con); con->ClearState(); //release the current buffer m_backBufferTarget.clear(); //resize the buffer result = m_swapChain->ResizeBuffers(2, static_cast<UINT>(size.x), static_cast<UINT>(size.y), DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); if (FAILED(result)) { throw(std::runtime_error("buffer resize fail")); } //set the texture of the swap chain APT::StrongPointer<ID3D11Texture2D> backBufferTexture; backBufferTexture.setDeleteFunc([](ID3D11Texture2D*& p) { if (p) p->Release(); p = nullptr; }); result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferTexture.getPtrRef()); //error checking if (FAILED(result)) { throw(std::runtime_error("buffer resize fail")); } //create a render target with the backbuffer result = m_d3dDevice->CreateRenderTargetView(backBufferTexture.getPtr(), 0, &m_backBufferTarget.getPtrRef()); //release the texture backBufferTexture.clear(); //error checking if (FAILED(result)) { throw(std::runtime_error("buffer resize fail")); } ////set the output merger's render targets m_d3dContext->OMSetRenderTargets(1, &m_backBufferTarget.getPtrRef(), 0); //set the alpha blending float blendFactor[4] = { m_bgColor.x, m_bgColor.y, m_bgColor.z, 1.0f }; m_d3dContext->OMSetBlendState(m_alphaBlendState.getPtr(), blendFactor, 0xFFFFFFFF); }
/** * Handle OSVR direct mode. ***/ void* OSVR_DirectMode::Provoke(void* pThis, int eD3D, int eD3DInterface, int eD3DMethod, DWORD dwNumberConnected, int& nProvokerIndex) { if (eD3DInterface != INTERFACE_IDXGISWAPCHAIN) return nullptr; if (eD3DMethod != METHOD_IDXGISWAPCHAIN_PRESENT) return nullptr; if (!m_bHotkeySwitch) { if (GetAsyncKeyState(VK_F11)) { m_bHotkeySwitch = true; } return nullptr; } // Get an OSVR client context to use to access the devices // that we need. static osvr::clientkit::ClientContext m_pcClientContext = osvr::clientkit::ClientContext("com.mtbs3d.vireio.osvr.directmode"); if (m_pcRenderManager == nullptr) { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; switch (m_eMethod) { case OSVR_undefined: // TODO !! determine method by used DX version return nullptr; case OSVR_D3D11_use_Game_Device: if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext))) { OutputDebugString(L"OSVR-DirectMode: Failed to get d3d11 device + context"); return nullptr; } break; case OSVR_D3D11_own_Device: case OSVR_D3D10_own_Device: case OSVR_D3D9_own_Device: { // get game device + context if (m_eMethod == OSVR_DirectModeMethods::OSVR_D3D11_own_Device) { if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &m_pcGameDevice, &m_pcGameDeviceContext))) { OutputDebugString(L"OSVR-DirectMode: Failed to get d3d11 device + context"); return nullptr; } m_pcGameDevice->Release(); m_pcGameDeviceContext->Release(); } // Be sure to get D3D11 and have set // D3D11_CREATE_DEVICE_BGRA_SUPPORT in the device/context 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, &m_pcDevice, &foundAPI, &m_pcDeviceContext); if (FAILED(hr)) { OutputDebugString(L"Could not create D3D11 device and context"); return nullptr; } pcDevice = m_pcDevice; pcContext = m_pcDeviceContext; } break; default: break; } // Put the device and context into a structure to let RenderManager // know to use this one rather than creating its own. osvr::renderkit::GraphicsLibrary cLibrary; cLibrary.D3D11 = new osvr::renderkit::GraphicsLibraryD3D11; cLibrary.D3D11->device = pcDevice; cLibrary.D3D11->context = pcContext; if (m_eMethod == OSVR_DirectModeMethods::OSVR_D3D11_use_Game_Device) { if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } // 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. m_pcRenderManager = osvr::renderkit::createRenderManager(m_pcClientContext.get(), "Direct3D11", cLibrary); if ((m_pcRenderManager == nullptr) || (!m_pcRenderManager->doingOkay())) { // Error OutputDebugString(L"OSVR-DirectMode: [Error] No Render Manager available !"); } else { // Set callback to handle setting up rendering in a display m_pcRenderManager->SetDisplayCallback((osvr::renderkit::DisplayCallback)&OSVR_DirectMode::SetupDisplay); // Register callback to render things in world space. m_pcRenderManager->AddRenderCallback("/", (osvr::renderkit::RenderCallback)&OSVR_DirectMode::DrawWorld); // Open the display and make sure this worked. osvr::renderkit::RenderManager::OpenResults ret = m_pcRenderManager->OpenDisplay(); if (ret.status == osvr::renderkit::RenderManager::OpenStatus::FAILURE) { OutputDebugString(L"Could not open display"); } if (ret.library.D3D11 == nullptr) { OutputDebugString(L"Attempted to run a Direct3D11 program with a config file that specified a different renderling library."); } // Do a call to get the information we need to construct our // color and depth render-to-texture buffers. std::vector<osvr::renderkit::RenderInfo> asRenderInfo; m_pcClientContext.update(); asRenderInfo = m_pcRenderManager->GetRenderInfo(); // Create the sampler state D3D11_SAMPLER_DESC sSampDesc; ZeroMemory(&sSampDesc, sizeof(sSampDesc)); sSampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sSampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sSampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sSampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sSampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sSampDesc.MinLOD = 0; sSampDesc.MaxLOD = D3D11_FLOAT32_MAX; if (FAILED(asRenderInfo[0].library.D3D11->device->CreateSamplerState(&sSampDesc, &m_pcSamplerState))) OutputDebugString(L"Failed to create Sampler State."); } } else { // get device and context ID3D11Device* pcDevice = nullptr; ID3D11DeviceContext* pcContext = nullptr; switch (m_eMethod) { case OSVR_undefined: return nullptr; case OSVR_D3D11_use_Game_Device: if (FAILED(GetDeviceAndContext((IDXGISwapChain*)pThis, &pcDevice, &pcContext))) { OutputDebugString(L"OSVR-DirectMode: Failed to get d3d11 device + context"); // release frame texture+view if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } return nullptr; } break; case OSVR_D3D11_own_Device: case OSVR_D3D10_own_Device: case OSVR_D3D9_own_Device: pcDevice = m_pcDevice; pcContext = m_pcDeviceContext; break; default: break; } // backup device states, if game device is used D3DX11_STATE_BLOCK sStateBlock; if (m_eMethod == OSVR_DirectModeMethods::OSVR_D3D11_use_Game_Device) { // backup all states CreateStateblock(pcContext, &sStateBlock); // clear all states pcContext->ClearState(); } // Update the context so we get our callbacks called and // update tracker state. m_pcClientContext.update(); if (!m_pcRenderManager->Render()) { OutputDebugString(L"Render() returned false, maybe because it was asked to quit"); } // apply state block, if game device is used if (m_eMethod == OSVR_DirectModeMethods::OSVR_D3D11_use_Game_Device) { // set back device ApplyStateblock(pcContext, &sStateBlock); if (pcDevice) { pcDevice->Release(); pcDevice = nullptr; } if (pcContext) { pcContext->Release(); pcContext = nullptr; } } } return nullptr; }
/////////////////////////////////////////////////////////////////////////////////////////////////// /// CelShadeApp::CelShadeD3D /// /// @brief /// Render a cel-shading demo using Direct3D /// @return /// N/A /////////////////////////////////////////////////////////////////////////////////////////////////// void CelShadeApp::CelShadeD3D() { ID3D11DeviceContext* pContext = m_pDxData->pD3D11Context; ID3D11Device* pDevice = m_pDxData->pD3D11Device; D3DX11_IMAGE_LOAD_INFO imageLoadInfo; memset( &imageLoadInfo, 0, sizeof(D3DX11_IMAGE_LOAD_INFO) ); imageLoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE; imageLoadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM; DxTextureCreateInfo shadeTexInfo; memset(&shadeTexInfo, 0, sizeof(DxTextureCreateInfo)); shadeTexInfo.flags.RenderTarget = TRUE; shadeTexInfo.flags.ShaderInput = TRUE; shadeTexInfo.format = DXGI_FORMAT_R8G8B8A8_UNORM; shadeTexInfo.width = m_screenWidth; shadeTexInfo.height = m_screenHeight; DxTexture* pShadeTex = DxTexture::Create(pDevice, &shadeTexInfo); DxTextureCreateInfo edgeTexInfo; memset(&edgeTexInfo, 0, sizeof(DxTextureCreateInfo)); edgeTexInfo.flags.RenderTarget = TRUE; edgeTexInfo.flags.ShaderInput = TRUE; edgeTexInfo.format = DXGI_FORMAT_R8G8B8A8_UNORM; edgeTexInfo.width = m_screenWidth; edgeTexInfo.height = m_screenHeight; DxTexture* pEdgeTex = DxTexture::Create(pDevice, &edgeTexInfo); // Samplers ///////////////////////////////////////////////////////////////////////////// // SamplerState PointSampler : register(s0); D3D11_SAMPLER_DESC pointSamplerDesc; memset(&pointSamplerDesc, 0, sizeof(D3D11_SAMPLER_DESC)); pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; pointSamplerDesc.MinLOD = -FLT_MAX; pointSamplerDesc.MaxLOD = FLT_MAX; pointSamplerDesc.MipLODBias = 0.0f; pointSamplerDesc.MaxAnisotropy = 16; ID3D11SamplerState* pPointSampler = NULL; pDevice->CreateSamplerState(&pointSamplerDesc, &pPointSampler); // UINT numVertices = 0, numIndices = 0; VertexPTN* pVB = NULL; UINT* pIB = NULL; ImportPly("Content/dragon_vrip_res3.ply", numVertices, &pVB, numIndices, &pIB); //ImportPly("Content/bun_zipper_res4.ply", numVertices, &pVB, numIndices, &pIB); DxMeshCreateInfo meshCreateInfo = {0}; meshCreateInfo.indexCount = numIndices; meshCreateInfo.pIndexArray = pIB; meshCreateInfo.indexFormat = DXGI_FORMAT_R32_UINT; meshCreateInfo.pVertexArray = pVB; meshCreateInfo.vertexCount = numVertices; meshCreateInfo.vertexElementSize = sizeof(VertexPTN); DxMesh* pMesh = DxMesh::Create(pDevice, &meshCreateInfo); Plane p; DxMeshCreateInfo planeMeshInfo; memset(&planeMeshInfo, 0, sizeof(planeMeshInfo)); planeMeshInfo.pVertexArray = p.GetVB(); planeMeshInfo.vertexCount = p.NumVertices(); planeMeshInfo.vertexElementSize = sizeof(VertexPTN); DxMesh* pPlaneMesh = DxMesh::Create(pDevice, &planeMeshInfo); Cube c; DxMeshCreateInfo cubeMeshInfo; memset(&cubeMeshInfo, 0, sizeof(cubeMeshInfo)); cubeMeshInfo.pVertexArray = c.GetVB(); cubeMeshInfo.vertexCount = c.NumVertices(); cubeMeshInfo.vertexElementSize = sizeof(VertexPT); DxMesh* pCubeMesh = DxMesh::Create(pDevice, &cubeMeshInfo); D3D11_SUBRESOURCE_DATA cbInitData; memset(&cbInitData, 0, sizeof(D3D11_SUBRESOURCE_DATA)); // Camera Buffer CameraBufferData cameraData; memset(&cameraData, 0, sizeof(CameraBufferData)); DxBufferCreateInfo cameraBufferCreateInfo = {0}; cameraBufferCreateInfo.flags.cpuWriteable = TRUE; cameraBufferCreateInfo.elemSizeBytes = sizeof(CameraBufferData); cameraBufferCreateInfo.pInitialData = &cameraData; DxBuffer* pCameraBuffer = DxBuffer::Create(pDevice, &cameraBufferCreateInfo); // Shaders //////////////////////////////////////////////////////////////////////////////////// m_pPosTexTriVS = DxShader::CreateFromFile(pDevice, "PosTexTri", "Content/shaders/CelShade.hlsl", PosTexVertexDesc, PosTexElements); m_pPosTexNormVS = DxShader::CreateFromFile(pDevice, "PosTexNorm", "Content/shaders/CelShade.hlsl", PosTexNormVertexDesc, PosTexNormElements); m_pCelShadePS = DxShader::CreateFromFile(pDevice, "CelShade", "Content/shaders/CelShade.hlsl"); DxShader* pDetectEdges = DxShader::CreateFromFile(pDevice, "DetectEdges", "Content/shaders/CelShade.hlsl"); DxShader* pApplyTexPS = DxShader::CreateFromFile(pDevice, "ApplyTex", "Content/shaders/CelShade.hlsl"); DxShader* pCubeVS = DxShader::CreateFromFile(pDevice, "PosTex", "Content/shaders/CelShade.hlsl", PosTexVertexDesc, PosTexElements); DxShader* pCubePS = DxShader::CreateFromFile(pDevice, "CubePS", "Content/shaders/CelShade.hlsl"); //////////////////////////////////////////////////////////////////////////////////////// pContext->ClearState(); // SET RENDER STATE FLOAT clearColor[4]; clearColor[0] = 0.2f; clearColor[1] = 0.2f; clearColor[2] = 0.2f; clearColor[3] = 1.0f; D3D11_RASTERIZER_DESC shadeDesc; shadeDesc.FillMode = D3D11_FILL_SOLID; shadeDesc.CullMode = D3D11_CULL_BACK; shadeDesc.FrontCounterClockwise = FALSE; shadeDesc.DepthBias = 0; shadeDesc.DepthBiasClamp = 0.0f; shadeDesc.SlopeScaledDepthBias = 0; shadeDesc.DepthClipEnable = false; shadeDesc.ScissorEnable = false; shadeDesc.MultisampleEnable = false; shadeDesc.AntialiasedLineEnable = false; ID3D11RasterizerState* pShadeRS = NULL; pDevice->CreateRasterizerState(&shadeDesc, &pShadeRS); pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_pWindow->Show(); BOOL quit = false; FLOAT yRotationAngle = 0.0f; while (!quit) { ProcessUpdates(); BeginFrame(); CameraBufferData* pCameraData = NULL; // new frame, clear state pContext->ClearState(); pContext->RSSetViewports(1, &m_pDxData->viewport); pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); pContext->RSSetState(pShadeRS); pContext->PSSetSamplers(0, 1, &pPointSampler); pContext->OMSetRenderTargets(1, &m_pDxData->pAppRenderTargetView, m_pDxData->pAppDepthStencilTex->GetDepthStencilView()); pContext->ClearRenderTargetView(m_pDxData->pAppRenderTargetView, clearColor); pContext->ClearDepthStencilView(m_pDxData->pAppDepthStencilTex->GetDepthStencilView(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0); ///// Draw Mesh /////////////////////////////////////////////////////////////////////////// FLOAT viewRotationY = (GetMousePos().x - (m_screenWidth / 2.0f)) /(m_screenWidth / 2.0f); viewRotationY *= (3.14159f / 4.0f); FLOAT viewRotationZ = (GetMousePos().y - (m_screenHeight / 2.0f)) /(m_screenHeight / 2.0f); viewRotationZ *= (3.14159f / 4.0f); pCameraData = reinterpret_cast<CameraBufferData*>(pCameraBuffer->Map(pContext)); pCameraData->worldMatrix = XMMatrixScaling(25, 25, 25) * XMMatrixRotationY(yRotationAngle) * XMMatrixTranslation(m_pCamera->Position().x, m_pCamera->Position().y, m_pCamera->Position().z) ; // translate world +6 in Z to position camera -9 from world origin pCameraData->viewMatrix = m_pCamera->W2C(); pCameraData->projectionMatrix = m_pCamera->C2S(); pCameraBuffer->Unmap(pContext); pCameraBuffer->BindVS(pContext, 0); pMesh->Bind(pContext); m_pPosTexNormVS->Bind(pContext); m_pCelShadePS->Bind(pContext); pMesh->Draw(pContext); ///// Detect Edges /////////////////////////////////////////////////////////////////////////// ///// Draw Light Position //////////////////////////////////////////////////////////////////// //yRotationAngle = 0; pCameraData = reinterpret_cast<CameraBufferData*>(pCameraBuffer->Map(pContext)); pCameraData->worldMatrix = XMMatrixScaling(1, 1, 1); // XMMatrixRotationY(yRotationAngle); // XMMatrixTranslation(-10, 10, 10); // translate world +6 in Z to position camera -9 from world origin pCameraData->viewMatrix = XMMatrixTranslation(0, 0, 10) * m_pCamera->W2C(); pCameraData->projectionMatrix = m_pCamera->C2S(); pCameraBuffer->Unmap(pContext); pCameraBuffer->BindVS(pContext, 0); pCubeVS->Bind(pContext); pCubePS->Bind(pContext); pCubeMesh->Bind(pContext); pCubeMesh->Draw(pContext); ///// Draw UI //////////////////////////////////////////////////////////////////////////////// ///@todo Consider moving the following UI drawing to Draw2D() m_pUI->Begin(); // Draw UI stuff m_pUI->RenderRect(); m_pUI->RenderText(); m_pUI->End(); /// Blend UI onto final image DrawUI(); m_pDxData->pDXGISwapChain->Present(0,0); EndFrame(); Sleep(50); yRotationAngle += 3.14159f / 60.0f; } // Shader Resource Views pCameraBuffer->Destroy(); // Shaders m_pCelShadePS->Destroy(); m_pCelShadePS = NULL; m_pPosTexTriVS->Destroy(); m_pPosTexTriVS = NULL; m_pPosTexNormVS->Destroy(); m_pPosTexNormVS = NULL; pApplyTexPS->Destroy(); pApplyTexPS = NULL; pPlaneMesh->Destroy(); pPlaneMesh = NULL; // Samplers pPointSampler->Release(); // Rasterizer State pShadeRS->Release(); m_pDxData->pD3D11Context->ClearState(); m_pDxData->pD3D11Context->Flush(); }