2017-08-08 49 views
1

自从上次提出问题以来,我已经取得了相当大的进展。我现在有一个非常酷的版本,现在有一个山地和湖泊的地形网格: LakeAndMountainsD3D11CreateDeviceAndSwapChain在不同的计算机上使用S_False失败

我做了一个发布版本,调试它,现在它在我的电脑上工作得很好。我可以将应用程序文件夹移到我的电脑上,然后运行.exe文件而不会出现问题。但是,当我将应用程序目录复制到另一台计算机(以及我的朋友的计算机)时,它会在D3D11CreateDeviceAndSwapChain步骤中以S_False的HR进行失败。

对于我的其他计算机和我的朋友的计算机,它只会在调用create函数后触发if(失败(hr)),并且它表示dev/devcon/swapchain全部为NULL。因为它们全都为空,所以当它从交换链中碰到该函数时,它会因访问冲突错误而崩溃。

我搜索了几天寻找解决方案,但我还没有看到一个有S_FALSE发生。我尝试了一些更直接的答案,但没有得到任何答案。所有电脑在64位操作系统上都运行64位,全部都是DirectX12,都是高端游戏PC,而我的另一台电脑实际上也有VS2017CE以及C++游戏编程,但它们都在这方面仍然失败。我真的很感激,如果任何人都可以给我一些指导,从哪里开始解释为什么发布版本在我的电脑上运行,而不是在其他人的电脑上运行。这里是它被初始化代码,以及用于窗口创建的代码(代码摘录只是职能的相关部分):

的WinMain:

// the entry point for any Windows program 
int WINAPI WinMain(HINSTANCE hInstance, 
HINSTANCE hPrevInstance, 
LPSTR lpCmdLine, 
int nCmdShow) 
{ 
//MessageBox(NULL, "Start of WinMain", "WinMain", 0); 
// the handle for the window, filled by a function 
HWND hWnd; 
// this struct holds information for the window class 
WNDCLASSEX wc; 

//Screen size variables 
long screenWidth = 1280; 
long screenHeight = 720; 
UINT screenWidthUINT = 1280; 
UINT screenHeightUINT = 720; 

// clear out the window class for use 
ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

// fill in the struct with the needed information 
wc.cbSize = sizeof(WNDCLASSEX); 
wc.style = CS_HREDRAW | CS_VREDRAW; 
wc.lpfnWndProc = WindowProc; 
wc.hInstance = hInstance; 
wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
//wc.hbrBackground = (HBRUSH)COLOR_WINDOW; 
wc.lpszClassName = "WindowClass1"; 

// register the window class 
RegisterClassEx(&wc); 

RECT wr = { 0, 0, screenWidth, screenHeight }; // set the size, but not the position 
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); // adjust the size 

// create the window and use the result as the handle 
hWnd = CreateWindowEx(NULL, 
    "WindowClass1", 
    "Game", 
    WS_OVERLAPPEDWINDOW, 
    0, // x-position of the window 
    0, // y-position of the window 
    wr.right - wr.left, // width of the window 
    wr.bottom - wr.top, // height of the window 
    NULL, 
    NULL, 
    hInstance, 
    NULL); 

// display the window on the screen 
ShowWindow(hWnd, nCmdShow); 
//MessageBox(NULL, "called ShowWindow", "WinMain", 0); 

/***************************************** 
// GAME ENGINE INITIALIZATION 
******************************************/ 
//Need to initialize the graphics engine. This passes the window pointer through the 
//game engine to the D3D engine so it knows what window to look at. 
//MessageBox(NULL, "Calling InitGraphics", "WinMain", 0); 
InitGraphics(hWnd); 

InitGraphics:

//DEVICE CREATION 
#include Windows.h 
#include <windowsx.h> 
#include <d3d11.h> 
#include <DirectXMath.h> 
#include <D3Dcompiler.h> 
#include <dxgi.h> 

#pragma comment(lib, "d3d11.lib") 
#pragma comment(lib, "dxgi.lib") 
#pragma comment(lib, "d3dcompiler.lib") 

#include "DirectXDeviceEngine.h" 

using namespace DirectX; 

InitGraphics(HWND hWnd) 
{ 
//call at start to initialize D3DX 
if (hWnd == NULL) 
{ 
    MessageBox(NULL, "hWnd was NULL", "DirectXDeviceEngine", 0); 
} 

HRESULT hr; 
//initialize swap chain 
//Describe our Buffer 
DXGI_MODE_DESC bufferDesc; 

ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); 

bufferDesc.Width = winWidth; 
bufferDesc.Height = winHeight; 
bufferDesc.RefreshRate.Numerator = 60; 
bufferDesc.RefreshRate.Denominator = 1; 
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 

// create a struct to hold information about the swap chain 
DXGI_SWAP_CHAIN_DESC scd; 

// clear out the struct for use 
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); 

// fill the swap chain description struct 
scd.BufferCount = 1;         // one back buffer 
scd.BufferDesc = bufferDesc; 
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;  // how swap chain is to be used 
scd.OutputWindow = hWnd;        // the window to be used 
scd.SampleDesc.Count = 4;        // how many multisamples 
scd.SampleDesc.Quality = 1; 
scd.Windowed = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // windowed/full-screen mode 
scd.Flags = 0; 

// create a device, device context and swap chain using the information in the scd struct 
dev = NULL; 
devcon = NULL; 
swapchain = NULL; 

hr = D3D11CreateDeviceAndSwapChain(
    NULL, //null 
    D3D_DRIVER_TYPE_HARDWARE, //driver type 
    NULL, //handle to a software rasterizer, should be null if driver type isn't software 
    NULL, //UINT device creation flags, can be ORed together 
    NULL, //D3D Feature level, when NULL defaults to 11.0-9.1 feature levels 
    NULL, //the number of elements in the D3D feature level array 
    D3D11_SDK_VERSION, //set to D3D11_SDK_VERSION 
    &scd, //reference to the swap chain desc 
    &swapchain, //reference to the pointer to the swap chain 
    &dev, //reference to the pointer to the device 
    NULL, //returns a reference to the first supported element in the feature level array 
    &devcon); //reference to the pointer to the device context 
if (FAILED(hr)) 
{ 
    //CODE FALLS INTO THIS BLOCK ON OTHER COMPUTER 
    MessageBox(NULL, "Create Device and SwapChain FAILED", "DirectXDeviceEngine", 0); 
    if (swapchain == NULL) 
    { 
     MessageBox(NULL, "swapchain was NULL", "DirectXDeviceEngine", 0); 
    } 
    if (dev == NULL) 
    { 
     MessageBox(NULL, "dev was NULL", "DirectXDeviceEngine", 0); 
    } 
    if (devcon == NULL) 
    { 
     MessageBox(NULL, "devcon was NULL", "DirectXDeviceEngine", 0); 
    } 
} 
//prepare buffers 
// get the address of the back buffer 
ID3D11Texture2D *pBackBuffer; 
//VVVV CODE THEN CRASHES ON NEXT LINE BECAUSE SWAPCHAIN IS NULL VVVV 
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); 

在此先感谢。

----更新2017/09/08 ----- 所以我换了一些代码,但我仍然在其他计算机上得到错误。目前的代码如下所示:

//call at start to initialize D3DX 
if (&hWnd == NULL) 
{ 
    MessageBox(NULL, "hWnd was NULL", "DirectXDeviceEngine", 0); 
} 

HRESULT hr; 

// create a device, device context and swap chain using the information in the scd struct 
dev = NULL; 
devcon = NULL; 
swapchain = NULL; 

D3D_FEATURE_LEVEL lvl[] = { 
    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 }; 

DWORD createDeviceFlags = 0; 
hash ifdef _DEBUG 
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; 
hash endif 

D3D_FEATURE_LEVEL fl; 
hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 
    createDeviceFlags, lvl, _countof(lvl), 
    D3D11_SDK_VERSION, &dev, &fl, &devcon); 
if (hr == E_INVALIDARG) 
{ 
    hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 
     createDeviceFlags, &lvl[1], _countof(lvl) - 1, 
     D3D11_SDK_VERSION, &dev, &fl, &devcon); 
} 
if (FAILED(hr)) 
{ 
    MessageBox(NULL, "Create Device Failed", "DirectXDeviceEngine", 0); 
} 

IDXGIDevice * dxgiDevice = 0; 
dev->QueryInterface(__uuidof(IDXGIDevice), (void **)& dxgiDevice); 

IDXGIAdapter * dxgiAdapter = 0; 
dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)& dxgiAdapter); 

IDXGIFactory * dxgiFactory = 0; 
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)& dxgiFactory); 

//initialize swap chain 
//Describe our Buffer 
DXGI_MODE_DESC bufferDesc; 

ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); 

/*bufferDesc.Width = winWidth; 
bufferDesc.Height = winHeight; 
bufferDesc.RefreshRate.Numerator = 60; 
bufferDesc.RefreshRate.Denominator = 1; 
*/ 
bufferDesc.Width = 0; 
bufferDesc.Height = 0; 
bufferDesc.RefreshRate.Numerator = 0; 
bufferDesc.RefreshRate.Denominator = 1; 
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 

// create a struct to hold information about the swap chain 
DXGI_SWAP_CHAIN_DESC scd; 

// clear out the struct for use 
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); 

// fill the swap chain description struct 
scd.BufferCount = 1;         // one back buffer 
scd.BufferDesc = bufferDesc; 
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;  // how swap chain is to be used 
scd.OutputWindow = hWnd;        // the window to be used 
scd.SampleDesc.Count = 4;        // how many multisamples 
scd.SampleDesc.Quality = 1; 
scd.Windowed = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // windowed/full-screen mode 
scd.Flags = 0; 

hr = dxgiFactory->CreateSwapChain(dev, &scd, &swapchain); 
if (FAILED(hr)) 
{ 
//fails here 
    MessageBox(NULL, "Create Swap Chain Failed", "DirectXDeviceEngine", 0); 
} 

if (dxgiDevice != NULL) 
{ 
    dxgiDevice->Release(); 
} 
if (dxgiAdapter != NULL) 
{ 
    dxgiAdapter->Release(); 
} 
if (dxgiFactory != NULL) 
{ 
    dxgiFactory->Release(); 
} 

//prepare buffers 
// get the address of the back buffer 
ID3D11Texture2D *pBackBuffer; 
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); 

因此,仍然有一些奇怪的东西发生在这里,我没有得到。如果有人有一个如何正确使用FindClosestMatchingMode的例子,我真的很感激它。

虽然还有一件非常奇怪的事情。当我在我的笔记本电脑上的调试器中,变量hWnd有一个值,但编译器说它是未使用的,并且不能显示它的值。这是正常的,或者这可能是问题的根源,因为交换链描述中使用了hWnd? hWnd如何在其他计算机上坏而未使用,但不在我的桌面上?

再次感谢。

+0

看起来像失败了,因为在调用D3D11CreateDeviceAndSwapChain时没有指定有效的创建标志。如果您查看此枚举D3D11_CREATE_DEVICE_FLAG,它没有任何值等于0:https://msdn.microsoft.com/en-us/library/windows/desktop/ff476107(v=vs.85)。aspx如果你没有使用延迟设备上下文,那么至少指定D3D11_CREATE_DEVICE_SINGLETHREADED,可能会解决你的问题 – Asesh

+0

我刚刚尝试过,但我得到了同样的错误,S_FALSE在hr中返回而没有附加信息。这很奇怪,因为发布版本在我的电脑上运行得很好,但是当我将它移动到另一台计算机上时却不行。这也很奇怪,因为我可以将发布文件夹移动到其他地方,并且它仍然可以正常工作。 – GaleRazorwind

+0

对于创建标志,0是一个有效的值,尽管你不应该将“NULL”用于值为0的东西。这当然是为什么C++ 11强烈鼓励使用“nullptr”而不是传统的''NULL''会产生非指针用法的错误/警告。 –

回答

0

所以我最终找到了问题的原因。出于某种原因,计数4质量1 MSAA不适用于另一台计算机。当我将它设置为1/0时,它运行完美。我需要研究如何正确枚举MSAA的东西,以便可以根据计算机进行调整。

相关问题