DirectX 11:在运行简单的DirectX应用程序时运行时崩溃

DirectX 11:在运行简单的DirectX应用程序时运行时崩溃

问题描述:

我试图从基类继承一些公共全局变量,并成功地获得了启动并运行的窗口,并以简单的方式初始化了directx - 在它自己的类中,继承了全局变量如HWND hWndDirectX 11:在运行简单的DirectX应用程序时运行时崩溃

但是,当程序运行时,D3D11CreateDeviceAndSwapChain()失败。上进一步检查,调试器给出:

DXGI ERROR: IDXGIFactory::CreateSwapChain: No target window specified in DXGI_SWAP_CHAIN_DESC, and no window associated with owning factory. [ MISCELLANEOUS ERROR #6: ]

DXGI_SWAP_CHAIN_DESC结构如下:

SwapChainDesc.BufferCount = 1; 
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
SwapChainDesc.BufferDesc.Width = 1024; 
SwapChainDesc.BufferDesc.Height = 768; 
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 
SwapChainDesc.OutputWindow = hWnd; 
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; 
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 
SwapChainDesc.SampleDesc.Count = 4; 
SwapChainDesc.Windowed = TRUE; 
SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 

hWnd存储在:

class Infinity{ 
public: 
    Infinity(); 
    ~Infinity(); 
    HWND hWnd; 
}; 

和遗传这样:

class Direct3D : public Infinity{ 
public: 
    Direct3D(); 
    ~Direct3D(); 
    IDXGISwapChain   *Swapchain; //Display modes. 
    ID3D11Device   *Device; 
    ID3D11DeviceContext  *DeviceContext; 
    ID3D11RenderTargetView *RenderTargetView; 

    void D3D_Start(int width, int height); 
    void D3D_Render(); 
    void D3D_Terminate(); 
}Direct3D; 

在运行时检查SwapChainDesc.OutputWindow = hWnd;的值,它为空。 (0x00000000),我认为这就是Swapchain->GetBuffer失败的原因,因为D3D11CreateDeviceAndSwapChain需要工作HWND。如果这是真的,为什么ShowWindow()成功?

编辑:我还要补充一点,ShowWindow()是相似的类从class Infinity继承:

class Windows : public Infinity{ 
public: 
    Windows(); 
    ~Windows(); 
    bool DisplayWindow(int width, int height, HINSTANCE hInstance); 
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 
}Windows; 
+1

hWnd在您的代码中不是全局的,它是数据成员。 – NmdMystery 2014-08-29 18:54:34

+0

@NmdMystery在这个班级结构中,“hWnd”不应该是全球性的吗?这两个类都从'Infinity'继承, – 2014-08-29 19:01:39

+1

不,因为它是一个实例变量。所有实例变量都是对象的本地变量。如果您实例化一个Window类型的对象,然后是另一个Direct3D类型的对象,那么它们将分别拥有自己的hWnd实例。你可能想要做的就是制作hWnd'static',这样只有一个hWnd副本,并且所有的继承类都可以访问它(当然,如果你只打算制作一个窗口的话)。 – NmdMystery 2014-08-29 19:05:42

遵守以下代码:

class A { 
public: 
    int memA; 
    static int memB; 
}; 

int A::memB = 0; 

class B : public A {}; 

class C : public A {}; 

int main() { 
    A a; 
    B b; 
    C c; 

    a.memA = 4; 
    b.memA = 5; 
    c.memA = 6; 

    A::memB = 4; 
    B::memB = 5; 
    C::memB = 6; 

    printf("a.memA = %d\n", a.memA); 
    printf("b.memA = %d\n", b.memA); 
    printf("c.memA = %d\n", c.memA); 

    printf("A::memB = %d\n", A::memB); 
    printf("B::memB = %d\n", B::memB); 
    printf("C::memB = %d\n", C::memB); 

    return 0; 
} 

这段代码的输出是:

a.memA = 4 
b.memA = 5 
c.memA = 6 
A::memB = 6 
B::memB = 6 
C::memB = 6 

通过使成员为静态,您可以确保:A) re只是该成员的一个实例,B)所有子类都可以直接访问该成员(假设它不是私有的)。你的hWnd不是全球性的,因为你的代码被写入,但是使它成为静态的将会实现你想要的。

下面的代码做到这一点:

//header file 
class Infinity { 
public: 
    static HWND hWnd; 
}; 

//cpp file 
HWND Infinity::hWnd = NULL; 

你的Direct3D类将能够访问你的窗口类写入非空的hWnd。如果您打算创建一个窗口,这只是一个有效的解决方案 - 否则,您将不得不求助于两个类之间的更复杂的父子关系(可能不使用继承)。