//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;
}
Exemple #3
0
///////////////////////////////////////////////////////////////////////////////////////////////////
/// 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(); 
}