DirectX 11:运行简单的 DirectX 应用程序时运行时崩溃
Posted
技术标签:
【中文标题】DirectX 11:运行简单的 DirectX 应用程序时运行时崩溃【英文标题】:DirectX 11: Runtime crash when running simple DirectX application 【发布时间】:2014-08-29 18:40:46 【问题描述】:我尝试从基类继承一些公共全局变量,并成功启动并运行窗口,并以简单的方式类似地初始化了 Directx - 在它自己的类中,继承全局变量,例如 HWND hWnd
。
但是,当程序运行时,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;
【问题讨论】:
hWnd 在您的代码中不是全局变量,它是一个数据成员。 @NmdMysteryhWnd
不应该在这个类结构中充当全局吗?两个类都继承自Infinity
不,因为它是一个实例变量。所有实例变量都是对象的本地变量。如果您实例化一个 Window 类型的对象,然后实例化另一个 Direct3D 类型的对象,它们将各自拥有自己的 hWnd 实例。您可能想要做的是制作 hWnd static
,这样就只有一个 hWnd 副本,并且所有继承类都可以访问它(当然,如果您只打算制作一个窗口)。
嗯,我试过了,收到了LNK2001
,LNK1120
(Error 1 error LNK2001: unresolved external symbol "public: static struct HWND__ * Infinity::hWnd" (?hWnd@Infinity@@2PAUHWND__@@A) c:\Users\...\Win32Project3.obj Win32Project3
)只有1个窗口-
您还必须在您的 cpp 文件中的类之外声明它,如下所示:HWND Infinity::hWnd = NULL;
。但请注意,从长远来看,我的建议可能不是您想要的设计。
【参考方案1】:
观察以下代码:
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) 该成员只有一个实例,并且 B) 所有子类都可以直接访问该成员(假设它不是私有的)。您的 hWnd 不是全局的,因为您的代码是编写的,但是将其设为静态将完成您想要的。
下面的代码就是这样做的:
//header file
class Infinity
public:
static HWND hWnd;
;
//cpp file
HWND Infinity::hWnd = NULL;
您的 Direct3D 类将能够访问由您的 Window 类写入的非空 hWnd。如果您打算创建一个窗口,这仅是一种有效的解决方案 - 否则,您将不得不求助于两个类之间更复杂的父子关系(可能不使用继承)。
【讨论】:
以上是关于DirectX 11:运行简单的 DirectX 应用程序时运行时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Directx11学习笔记 封装一个简单的Dx11DemoBase
吃鸡出现运行引擎dx11 运行引擎需要dx11功能级别10.0怎么解决