2014-08-29 191 views
0

我試圖從基類繼承一些公共全局變量,併成功地獲得了啓動並運行的窗口,並以簡單的方式初始化了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

回答

0

遵守以下代碼:

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。如果您打算創建一個窗口,這只是一個有效的解決方案 - 否則,您將不得不求助於兩個類之間的更復雜的父子關係(可能不使用繼承)。

相關問題