Ejemplo n.º 1
0
static bool grabFrameD3D11(IDXGISwapChain *swap)
{
  ID3D11Device *device = 0;
  ID3D11DeviceContext *context = 0;
  ID3D11Texture2D *tex = 0, *captureTex = 0;

  if (FAILED(swap->GetBuffer(0, IID_ID3D11Texture2D, (void**)&tex)))
    return false;

  D3D11_TEXTURE2D_DESC desc;
  tex->GetDevice(&device);
  tex->GetDesc(&desc);

  // re-creating the capture staging texture each frame is definitely not the most efficient
  // way to handle things, but it frees me of all kind of resource management trouble, so
  // here goes...
  desc.MipLevels = 1;
  desc.ArraySize = 1;
  desc.SampleDesc.Count = 1;
  desc.SampleDesc.Quality = 0;
  desc.Usage = D3D11_USAGE_STAGING;
  desc.BindFlags = 0;
  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  desc.MiscFlags = 0;

  if(FAILED(device->CreateTexture2D(&desc,0,&captureTex)))
    printLog("video/d3d11: couldn't create staging texture for gpu->cpu download!\n");
  else
    setCaptureResolution(desc.Width,desc.Height);

  device->GetImmediateContext(&context);
  context->CopySubresourceRegion(captureTex,0,0,0,0,tex,0,0);

  D3D11_MAPPED_SUBRESOURCE mapped;
  bool grabOk = false;

  if(captureTex && SUCCEEDED(context->Map(captureTex,0,D3D11_MAP_READ,0,&mapped)))
  {
    switch(desc.Format)
    {
    case DXGI_FORMAT_R8G8B8A8_UNORM:
      blitAndFlipRGBAToCaptureData((unsigned char *) mapped.pData,mapped.RowPitch);
      grabOk = true;
      break;

    default:
      printLog("video/d3d11: unsupported backbuffer format, can't grab pixels!\n");
      break;
    }

    context->Unmap(captureTex,0);
  }

  tex->Release();
  if(captureTex) captureTex->Release();
  context->Release();
  device->Release();

  return grabOk;
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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();
}
Ejemplo n.º 10
0
	//! 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
	}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
    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, &copyData, 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;
    }
Ejemplo n.º 18
0
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();
}
Ejemplo n.º 20
0
/// 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);
	}
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
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();
	}
}
Ejemplo n.º 25
0
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 );
}
Ejemplo n.º 26
0
// 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
	}
}
Ejemplo n.º 27
0
// 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;
}
Ejemplo n.º 28
0
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();
    }
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
/**
* 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;
}