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); }
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); } }
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; }
/// 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); } }
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); }
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; }
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(); } }
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"); } }