std::shared_ptr<IDXGISwapChain3> CreateSwapChain( ID3D12Device * device, ID3D12CommandQueue * commandQueue, const HWND* hWnd, DXGI_SWAP_CHAIN_DESC* swapChainDesc)
	{
		IDXGISwapChain* swapChain;
		IDXGISwapChain3* swapChain3;

		DXGI_SWAP_CHAIN_DESC defaultDesc = {};
		if (!swapChainDesc)
		{
			defaultDesc.BufferCount = 2;
			defaultDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
			defaultDesc.BufferDesc.Width = 1200;
			defaultDesc.BufferDesc.Height = 900;
			defaultDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
			defaultDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
			defaultDesc.OutputWindow = *hWnd;
			defaultDesc.SampleDesc.Count = 1;
			defaultDesc.Windowed = TRUE;
			swapChainDesc = &defaultDesc;
		}

		DirectX::ThrowIfFailed(CreateFactory()->CreateSwapChain(
			commandQueue,
			swapChainDesc,
			&swapChain
			));
		swapChain->QueryInterface(IID_PPV_ARGS(&swapChain3));
		swapChain->Release();
		return std::shared_ptr<IDXGISwapChain3>(swapChain3, ReleaseIUnknown);
	}
Beispiel #2
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();
}
//this function is exported and only called by CE when inside CE
void GetAddresses(void)
{
	//create window and create a d3ddevice for dx9, dx10 and dx11H
	OutputDebugStringA("GetAddresses()");

	HRESULT hr=S_OK;
	HWND x=0;
    WNDCLASSEXW wcex;

	ZeroMemory(&wcex, sizeof(wcex));

	wcex.cbSize = sizeof( WNDCLASSEX );
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = DefWindowProc;//WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	
	wcex.hInstance = GetModuleHandle(0);
	wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
	wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"BLA";
	if( !RegisterClassExW( &wcex ) )
		OutputDebugStringA("Failure\n");


	// Create window   
	RECT rc = { 0, 0, 640, 480 };
	AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
	x = CreateWindowW( L"BLA", L"BLA",
						   WS_OVERLAPPEDWINDOW,
						   CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, GetModuleHandle(0),
						   NULL );

	if (x)
	{

		DXGI_SWAP_CHAIN_DESC sd;
		
		ZeroMemory( &sd, sizeof( sd ) );
		sd.BufferCount = 1;
		sd.BufferDesc.Width = 640;
		sd.BufferDesc.Height = 480;
		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 = x;
		sd.SampleDesc.Count = 1;
		sd.SampleDesc.Quality = 0;
		sd.Windowed = TRUE;

		IDXGISwapChain *pSwapChain;
		ID3D10Device *pd3dDevice;
		ID3D11Device *pd3dDevice11;
		ID3D11DeviceContext *pd3dDevice11Context;
		D3D_FEATURE_LEVEL fl;


		HMODULE d3d11dll=LoadLibraryA("D3D11.dll");

		if (d3d11dll)
		{
			d3d11create=(D3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(d3d11dll, "D3D11CreateDeviceAndSwapChain");
			hr=d3d11create( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &sd, &pSwapChain, &pd3dDevice11, &fl, &pd3dDevice11Context);

			if (SUCCEEDED(hr))
			{	
				//get the present function of the swapchain
				uintptr_t *a=(uintptr_t *)*(uintptr_t *)pSwapChain;

	
				a=(uintptr_t *)*(uintptr_t *)pd3dDevice11Context;
				shared->d3d11_drawindexed=a[12]; //DrawIndexed();  //v
				shared->d3d11_draw=a[13]; //Draw();  //v
				shared->d3d11_drawindexedinstanced=a[20];
				shared->d3d11_drawinstanced=a[21];
				shared->d3d11_drawauto=a[38];   //v
				

				//now cleanup
				pSwapChain->Release();
				pd3dDevice11Context->Release();
				pd3dDevice11->Release();
			}		
		}
		else
			OutputDebugStringA("D3D11.dll not loaded");


		HMODULE d3d10dll=LoadLibraryA("D3D10.dll");

		if (d3d10dll)
		{
			d3d10create=(D3D10CREATEDEVICEANDSWAPCHAIN)GetProcAddress(d3d10dll, "D3D10CreateDeviceAndSwapChain");
			hr=d3d10create( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &sd, &pSwapChain, &pd3dDevice );

			if (SUCCEEDED(hr))
			{	
				//get the present function of the swapchain
				uintptr_t *a=(uintptr_t *)*(uintptr_t *)pSwapChain;

				shared->dxgi_present=a[8]; //8th element is Present()		
				shared->dxgi_resizebuffers=a[13]; 
			
							

				a=(uintptr_t *)*(uintptr_t *)pd3dDevice;
				shared->d3d10_drawindexed=a[8]; //DrawIndexed();  //v
				shared->d3d10_draw=a[9]; //Draw();  //v
				shared->d3d10_drawindexedinstanced=a[14];
				shared->d3d10_drawinstanced=a[15];
				shared->d3d10_drawauto=a[28];   //v
				
				//pd3dDevice->DrawIndexedInstanced(0,0,0,0,0);


				//now cleanup
				pSwapChain->Release();	
				pd3dDevice->Release();
			}		
		}
		else
			OutputDebugStringA("D3D10 dll not loaded");

		//now the same for d3d9 to get the present function of d3d9device
		HMODULE d3d9dll=LoadLibraryA("D3D9.dll");
		

		if (d3d9dll)
		{
			D3DCreate9=(DIRECT3DCREATE9)GetProcAddress(d3d9dll, "Direct3DCreate9");		
			if (D3DCreate9)
			{
				IDirect3D9 *d3d9=D3DCreate9(D3D_SDK_VERSION);
				IDirect3DDevice9 *d3d9device;		

				if (d3d9)
				{
					D3DPRESENT_PARAMETERS d3dpp; 
					ZeroMemory( &d3dpp, sizeof(d3dpp) );
					d3dpp.Windowed   = TRUE;
					d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;

					hr=d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, x, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3d9device);
					if (SUCCEEDED(hr))
					{
						if (d3d9device)
						{
							//get present address
							uintptr_t *a=(uintptr_t *)*(uintptr_t *)d3d9device;

							shared->d3d9_present=a[17]; //17th element is Present()	
							shared->d3d9_reset=a[16]; //16th element is reset

							shared->d3d9_drawprimitive=a[81];
							shared->d3d9_drawindexedprimitive=a[82];
							shared->d3d9_drawprimitiveup=a[83];
							shared->d3d9_drawindexedprimitiveup=a[84];
							shared->d3d9_drawrectpatch=a[115];
							shared->d3d9_drawtripatch=a[116];												

							//d3d9device->Present(NULL,NULL,0,NULL);
							d3d9device->Release();

							OutputDebugStringA("Success: Fetched the Direct3D9 method addresses");
						}
						else
							OutputDebugStringA("d3d9device is NULL");

					}
					else
						OutputDebugStringA("FAILED d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, x, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3d9device);");

					d3d9->Release();
				}
				else
					OutputDebugStringA("D3DCreate9 failed");
			}
			else
				OutputDebugStringA("Direct3DCreate9 not found");


		}
		else
		  OutputDebugStringA("D3D9 dll not loaded");

		DestroyWindow(x);	
	}

}
Beispiel #4
0
HRESULT DXManager::CreateSwapChain()
{
	HRESULT hr = S_FALSE;

	DXGI_SWAP_CHAIN_DESC swapChainDesc;
	ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

	// Set the swap chain to use double buffering.
	swapChainDesc.BufferCount = 2;
	// Set the height and width of the back buffers in the swap chain.
	swapChainDesc.BufferDesc.Height = m_WindowHeight;
	swapChainDesc.BufferDesc.Width = m_WindowWidth;
	// Set a regular 32-bit surface for the back buffers.
	swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	// Set the usage of the back buffers to be render target outputs.
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	// Set the swap effect to discard the previous buffer contents after swapping.
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
	// Set the handle for the window to render to.
	swapChainDesc.OutputWindow = m_hWnd;
	// Set to full screen or windowed mode.
	if (m_FullScreen)
		swapChainDesc.Windowed = false;
	else
		swapChainDesc.Windowed = true;
	// Set the refresh rate of the back buffer.
	if (m_VSYNC)
	{
		swapChainDesc.BufferDesc.RefreshRate.Numerator = m_Numerator;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = m_Denominator;
	}
	else
	{
		swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
	}
	// Turn multisampling off.
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	// Set the scan line ordering and scaling to unspecified.
	swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	// Don't set the advanced flags.
	swapChainDesc.Flags = 0;

	IDXGISwapChain* swapChain;
	ZeroMemory(&swapChain, sizeof(IDXGISwapChain));

	hr = m_Factory->CreateSwapChain(m_CommandQueue, &swapChainDesc, &swapChain);
	if (FAILED(hr))
		return hr;

	hr = swapChain->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&m_SwapChain);
	if (FAILED(hr))
		return hr;

	D3D12_DESCRIPTOR_HEAP_DESC renderTargetViewHeapDesc;
	ZeroMemory(&renderTargetViewHeapDesc, sizeof(D3D12_DESCRIPTOR_HEAP_DESC));

	renderTargetViewHeapDesc.NumDescriptors = 2;
	renderTargetViewHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
	renderTargetViewHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

	hr = m_Device->CreateDescriptorHeap(&renderTargetViewHeapDesc, __uuidof(ID3D12DescriptorHeap), (void**)&m_RenderTargetViewHeap);
	if (FAILED(hr))
		return hr;

	D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle;
	ZeroMemory(&renderTargetViewHandle, sizeof(D3D12_CPU_DESCRIPTOR_HANDLE));
	renderTargetViewHandle = m_RenderTargetViewHeap->GetCPUDescriptorHandleForHeapStart();

	unsigned int renderTargetViewDescriptorSize = 0;
	renderTargetViewDescriptorSize = m_Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

	hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D12Resource), (void**)&m_BackBufferRenderTarget[0]);
	if (FAILED(hr))
		return hr;

	m_Device->CreateRenderTargetView(m_BackBufferRenderTarget[0], NULL, renderTargetViewHandle);

	renderTargetViewHandle.ptr += renderTargetViewDescriptorSize;

	hr = m_SwapChain->GetBuffer(1, __uuidof(ID3D12Resource), (void**)&m_BackBufferRenderTarget[1]);
	if (FAILED(hr))
		return hr;

	m_Device->CreateRenderTargetView(m_BackBufferRenderTarget[1], NULL, renderTargetViewHandle);

	m_BufferIndex = m_SwapChain->GetCurrentBackBufferIndex();

	swapChain->Release();

	return hr;
}
Beispiel #5
0
/// Prepares DXGI and D3D10 data by trying to determining 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 d3d10.
void PrepareDXGI10(IDXGIAdapter1 *pAdapter, bool initializeDXGIData) {

	if (!dxgi || !d3d10 || !pAdapter)
		return;

	ods("D3D10: Preparing static data for DXGI and D3D10 Injection");

	d3d10->wcFileName[0] = 0;
	d3d10->iOffsetAddRef = 0;
	d3d10->iOffsetRelease = 0;

	HMODULE hD3D10 = LoadLibrary("D3D10.DLL");

	if (hD3D10 != NULL) {

		HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
								  CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
								  NULL, NULL, 0);

		D3D10CreateDeviceAndSwapChainType pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CreateDeviceAndSwapChainType>(GetProcAddress(hD3D10, "D3D10CreateDeviceAndSwapChain"));

		DXGI_SWAP_CHAIN_DESC desc;
		ZeroMemory(&desc, sizeof(desc));

		RECT rcWnd;
		GetClientRect(hwnd, &rcWnd);
		desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
		desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;

		ods("D3D10: 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;
		ID3D10Device *pDevice = NULL;
		HRESULT hr = pD3D10CreateDeviceAndSwapChain(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &desc, &pSwapChain, &pDevice);
		if (FAILED(hr))
			ods("D3D10: pD3D10CreateDeviceAndSwapChain failure!");

		if (pDevice && 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), "D3D10", "Present");
			if (offset >= 0) {
				if (initializeDXGIData) {
					dxgi->iOffsetPresent = offset;
					ods("D3D10: Successfully found Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
				} else {
					if (dxgi->iOffsetPresent == offset) {
						ods("D3D10: Successfully verified Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
					} else {
						ods("D3D10: 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), "D3D10", "ResizeBuffers");
			if (offset >= 0) {
				if (initializeDXGIData) {
					dxgi->iOffsetResize = offset;
					ods("D3D10: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
				} else {
					if (dxgi->iOffsetResize == offset) {
						ods("D3D10: Successfully verified ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
					} else {
						ods("D3D10: 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), d3d10->wcFileName, ARRAY_NUM_ELEMENTS(d3d10->wcFileName), "D3D10", "AddRef");
			if (offset >= 0) {
				d3d10->iOffsetAddRef = offset;
				ods("D3D10: Successfully found AddRef offset: %ls: %d", d3d10->wcFileName, d3d10->iOffsetAddRef);
			}

			void *pRelease = (*vtbl)[2];
			offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pRelease), d3d10->wcFileName, ARRAY_NUM_ELEMENTS(d3d10->wcFileName), "D3D10", "Release");
			if (offset >= 0) {
				d3d10->iOffsetRelease = offset;
				ods("D3D10: Successfully found Release offset: %ls: %d", d3d10->wcFileName, d3d10->iOffsetRelease);
			}
		}

		if (pDevice)
			pDevice->Release();
		if (pSwapChain)
			pSwapChain->Release();
		DestroyWindow(hwnd);
	} else {
		FreeLibrary(hD3D10);
	}
}
Beispiel #6
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);
}
Beispiel #7
0
result_t app_init_swapchain(struct app_swapchain* sc, HWND hwnd, uint width, uint height,
    uint refresh_rate, int fullscreen, int vsync)
{
    ASSERT(g_app);

    HRESULT dxhr;
    IDXGISwapChain* swapchain;
    ID3D11Texture2D* backbuffer;
    ID3D11RenderTargetView* rtv;
    ID3D11Texture2D* depthstencil = NULL;
    ID3D11DepthStencilView* dsv = NULL;
    struct app_win* app = g_app;

    DXGI_SWAP_CHAIN_DESC d3d_desc;
    memset(&d3d_desc, 0x00, sizeof(d3d_desc));

    if (width == 0 || height == 0)  {
        RECT wrc;
        ::GetClientRect(hwnd, &wrc);
        width = wrc.right - wrc.left;
        height = wrc.bottom - wrc.top;
    }

    d3d_desc.BufferDesc.Width = width;
    d3d_desc.BufferDesc.Height = height;
    d3d_desc.BufferDesc.RefreshRate.Numerator = refresh_rate;
    d3d_desc.BufferDesc.RefreshRate.Denominator = 1;
    d3d_desc.BufferDesc.Format = DEFAULT_DISPLAY_FORMAT;
    d3d_desc.SampleDesc.Count = 1;
    d3d_desc.SampleDesc.Quality = 0;
    d3d_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    d3d_desc.BufferCount = BACKBUFFER_COUNT;
    d3d_desc.Windowed = fullscreen ? FALSE : TRUE;
    d3d_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    d3d_desc.Flags = fullscreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0;
    d3d_desc.OutputWindow = hwnd;

    dxhr = app->dxgi_factory->CreateSwapChain(app->dev, &d3d_desc, &swapchain);
    if (FAILED(dxhr))   {
        err_print(__FILE__, __LINE__, "swapchain creation failed");
        return NULL;
    }

    /* get BackBuffer and Create RenderTargetView from it */
    if (FAILED(swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer)))    {
        swapchain->Release();
        return RET_FAIL;
    }

    if (FAILED(app->dev->CreateRenderTargetView(backbuffer, NULL, &rtv)))  {
        backbuffer->Release();
        swapchain->Release();
        return RET_FAIL;
    }

    /* depth/stencil */
    D3D11_TEXTURE2D_DESC ds_desc;
    memset(&ds_desc, 0x00, sizeof(ds_desc));
    ds_desc.ArraySize = 1;
    ds_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    ds_desc.Format = DXGI_FORMAT_R24G8_TYPELESS;
    ds_desc.MipLevels = 1;
    ds_desc.SampleDesc.Count = 1;
    ds_desc.Width = width;
    ds_desc.Height = height;

    if (FAILED(app->dev->CreateTexture2D(&ds_desc, NULL, &depthstencil)))  {
        backbuffer->Release();
        swapchain->Release();
        return RET_FAIL;
    }

    D3D11_DEPTH_STENCIL_VIEW_DESC ds_view;
    memset(&ds_view, 0x00, sizeof(ds_view));
    ds_view.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    ds_view.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    if (FAILED(app->dev->CreateDepthStencilView(depthstencil, &ds_view, &dsv)))    {
        depthstencil->Release();
        backbuffer->Release();
        swapchain->Release();
        return RET_FAIL;
    }

    sc->sc = swapchain;
    sc->backbuff = backbuffer;
    sc->depthbuff = depthstencil;
    sc->dsv = dsv;
    sc->rtv = rtv;
    sc->fullscreen = fullscreen;

    return RET_OK;
}
Beispiel #8
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();
	}
}
Beispiel #9
0
extern "C" __declspec(dllexport) void __cdecl PrepareDXGI() {
	// This function is called by the Mumble client in Mumble's scope
	// mainly to extract the offsets of various functions in the IDXGISwapChain
	// and IDXGIObject interfaces that need to be hooked in target
	// applications. The data is stored in the dxgi shared memory structure.

	if (! dxgi)
		return;

	ods("Preparing static data for DXGI Injection");

	dxgi->wcDXGIFileName[0] = 0;
	dxgi->wcD3D10FileName[0] = 0;
	dxgi->iOffsetPresent = 0;
	dxgi->iOffsetResize = 0;
	dxgi->iOffsetAddRef = 0;
	dxgi->iOffsetRelease = 0;

	OSVERSIONINFOEXW ovi;
	memset(&ovi, 0, sizeof(ovi));
	ovi.dwOSVersionInfoSize = sizeof(ovi);
	GetVersionExW(reinterpret_cast<OSVERSIONINFOW *>(&ovi));
	if ((ovi.dwMajorVersion >= 7) || ((ovi.dwMajorVersion == 6) && (ovi.dwBuildNumber >= 6001))) { // Make sure this is vista or greater as quite a number of <=WinXP users have fake DX10 libs installed
		HMODULE hD3D10 = LoadLibrary("D3D10.DLL");
		HMODULE hDXGI = LoadLibrary("DXGI.DLL");

		if (hDXGI != NULL && hD3D10 != NULL) {
			CreateDXGIFactoryType pCreateDXGIFactory = reinterpret_cast<CreateDXGIFactoryType>(GetProcAddress(hDXGI, "CreateDXGIFactory"));
			ods("Got %p", pCreateDXGIFactory);
			if (pCreateDXGIFactory) {
				HRESULT hr;
				IDXGIFactory * pFactory;
				hr = pCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));
				if (pFactory) {
					HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
					                          CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
					                          NULL, NULL, 0);

					IDXGIAdapter *pAdapter = NULL;
					pFactory->EnumAdapters(0, &pAdapter);

					D3D10CreateDeviceAndSwapChainType pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CreateDeviceAndSwapChainType>(GetProcAddress(hD3D10, "D3D10CreateDeviceAndSwapChain"));

					IDXGISwapChain *pSwapChain = NULL;
					ID3D10Device *pDevice = NULL;

					DXGI_SWAP_CHAIN_DESC desc;
					ZeroMemory(&desc, sizeof(desc));

					RECT rcWnd;
					GetClientRect(hwnd, &rcWnd);
					desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
					desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;

					ods("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;

					hr = pD3D10CreateDeviceAndSwapChain(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &desc, &pSwapChain, &pDevice);

					if (pDevice && pSwapChain) {
						HMODULE hRef;
						// 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];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pPresent, &hRef)) {
							ods("DXGI: Failed to get module for Present");
						} else {
							GetModuleFileNameW(hRef, dxgi->wcDXGIFileName, 2048);
							unsigned char *b = (unsigned char *) pPresent;
							unsigned char *a = (unsigned char *) hRef;
							dxgi->iOffsetPresent = b-a;
							ods("DXGI: Successfully found Present offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetPresent);
						}

						void *pResize = (*vtbl)[13];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pResize, &hRef)) {
							ods("DXGI: Failed to get module for ResizeBuffers");
						} else {
							wchar_t buff[2048];
							GetModuleFileNameW(hRef, buff, 2048);
							if (wcscmp(buff, dxgi->wcDXGIFileName) == 0) {
								unsigned char *b = (unsigned char *) pResize;
								unsigned char *a = (unsigned char *) hRef;
								dxgi->iOffsetResize = b-a;
								ods("DXGI: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetResize);
							}
						}

						vtbl = (void ***) pDevice;

						void *pAddRef = (*vtbl)[1];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pAddRef, &hRef)) {
							ods("D3D10: Failed to get module for AddRef");
						} else {
							GetModuleFileNameW(hRef, dxgi->wcD3D10FileName, 2048);
							unsigned char *b = (unsigned char *) pAddRef;
							unsigned char *a = (unsigned char *) hRef;
							dxgi->iOffsetAddRef = b-a;
							ods("D3D10: Successfully found AddRef offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetAddRef);
						}

						void *pRelease = (*vtbl)[2];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pRelease, &hRef)) {
							ods("D3D10: Failed to get module for Release");
						} else {
							wchar_t buff[2048];
							GetModuleFileNameW(hRef, buff, 2048);
							if (wcscmp(buff, dxgi->wcD3D10FileName) == 0) {
								unsigned char *b = (unsigned char *) pRelease;
								unsigned char *a = (unsigned char *) hRef;
								dxgi->iOffsetRelease = b-a;
								ods("D3D10: Successfully found Release offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetRelease);
							}
						}
					}

					if (pDevice)
						pDevice->Release();
					if (pSwapChain)
						pSwapChain->Release();
					DestroyWindow(hwnd);

					pFactory->Release();
				}
			}
		}
	} else {
		ods("No DXGI pre-Vista");
	}
}