初始化 D3D9 导致第 3 方库停止工作
首先,一般情况...通过 DLL 加载的第 3 方库会渲染为 HWND。它是简单的 2D 渲染,并没有以我所看到的方式直接使用 D3D - DLL 上的依赖关系显示了许多 D3DKMT 函数,如 D3DKMTCreateDevice
,但不是常规 D3D 调用,如 IDirect3D9::CreateDevice
。 当我调用 IDirect3D9::CreateDevice 时,第 3 方渲染变得混乱。它不会抱怨,只是将所有内容渲染为黑色矩形。我自己的渲染效果很好。
具体...第3方DLL是Mozilla XULRunner 1.9.x,它是FireFox的核心(不是具有硬件加速功能的2.0),包装在wxWidgets wxWebConnect库中。 wxWC 加载 XUL DLL 并提供 Web 浏览器 GUI 组件。
我有一个使用 wx & 的工作应用程序wxWebConnect 这里是编译好的 EXE 和代码: http://www.kirix.com/forums/viewtopic .php?f=25&t=911#p2605
这是我的真实代码,它与 wxWidgets 略有绑定,但不足以使其难以阅读 - 我从随机窗口获取 HWND 只是为了初始化D3D 但从不渲染它:
void MyFrame::OnD3DButton( wxCommandEvent &event )
{
static bool initialized = false;
static LPDIRECT3D9 mpD3D = NULL;
static LPDIRECT3DDEVICE9 mpD3DDevice=NULL;
if(!initialized)
{
wxButton *button=wxDynamicCast(event.GetEventObject(), wxButton);
HWND mHWnd = (HWND)button->GetHandle();
mpD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS md3dpp;
ZeroMemory( &md3dpp, sizeof(D3DPRESENT_PARAMETERS) );
md3dpp.Windowed = true;
md3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// triple buffer if VSync is on
md3dpp.BackBufferCount = 1;
md3dpp.EnableAutoDepthStencil = 0;
md3dpp.hDeviceWindow = mHWnd;
md3dpp.BackBufferWidth = 0;
md3dpp.BackBufferHeight = 0;
md3dpp.FullScreen_RefreshRateInHz = 0;
md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
md3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
md3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
md3dpp.MultiSampleQuality = 0;
HRESULT hr = mpD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,mHWnd,
D3DCREATE_MULTITHREADED|D3DCREATE_MIXED_VERTEXPROCESSING,&md3dpp,&mpD3DDevice);
if(FAILED(hr))
wxMessageBox(wxString("mpD3D->CreateDevice() FAILED"));
else
{
wxMessageBox(wxString("mpD3D->CreateDevice() SUCCEEDED"));
initialized = true;
}
}
}
First, the general situation... a 3rd-party library loaded through a DLL does rendering into a HWND. It's simple 2D rendering and is not directly using D3D in a way I can see - a dependency walk on the DLL shows lots of D3DKMT functions like D3DKMTCreateDevice
but not regular D3D calls like IDirect3D9::CreateDevice
.
When I call IDirect3D9::CreateDevice
, the 3rd-party rendering goes screwy. It doesn't complain, but simply renders everything as black rectangles. My own rendering works fine.
The specifics... the 3rd-party DLL is Mozilla XULRunner 1.9.x, which is the core of FireFox (not 2.0 which features hardware acceleration), wrapped in the wxWidgets wxWebConnect library. wxWC loads the XUL DLL and provides a web-browser GUI component.
I have a working app using wx & wxWebConnect here, a compiled EXE and the code:
http://www.kirix.com/forums/viewtopic.php?f=25&t=911#p2605
Here is my real-life code, it's slightly bound to wxWidgets but not enough to make it hard to read - I get a HWND from a random window simply to initialize D3D but never render to it:
void MyFrame::OnD3DButton( wxCommandEvent &event )
{
static bool initialized = false;
static LPDIRECT3D9 mpD3D = NULL;
static LPDIRECT3DDEVICE9 mpD3DDevice=NULL;
if(!initialized)
{
wxButton *button=wxDynamicCast(event.GetEventObject(), wxButton);
HWND mHWnd = (HWND)button->GetHandle();
mpD3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS md3dpp;
ZeroMemory( &md3dpp, sizeof(D3DPRESENT_PARAMETERS) );
md3dpp.Windowed = true;
md3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// triple buffer if VSync is on
md3dpp.BackBufferCount = 1;
md3dpp.EnableAutoDepthStencil = 0;
md3dpp.hDeviceWindow = mHWnd;
md3dpp.BackBufferWidth = 0;
md3dpp.BackBufferHeight = 0;
md3dpp.FullScreen_RefreshRateInHz = 0;
md3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
md3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
md3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
md3dpp.MultiSampleQuality = 0;
HRESULT hr = mpD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,mHWnd,
D3DCREATE_MULTITHREADED|D3DCREATE_MIXED_VERTEXPROCESSING,&md3dpp,&mpD3DDevice);
if(FAILED(hr))
wxMessageBox(wxString("mpD3D->CreateDevice() FAILED"));
else
{
wxMessageBox(wxString("mpD3D->CreateDevice() SUCCEEDED"));
initialized = true;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题可能是 CreateDevice 将修改 FPU 状态,除非您传递标志
D3DCREATE_FPU_PRESERVE
。当它咬我的时候,我花了很长时间才找到这个。The problem might be that CreateDevice will modify the FPU state unless you pass the flag
D3DCREATE_FPU_PRESERVE
. It took me a really long time to find this when it bit me.您是否使用与第 3 方 dll 使用的相同的 hwnd 创建 D3D 设备?
在这种情况下,也许第 3 方软件仍在绘制它的内容,但 direct3d 只是在其之上渲染,因此您只能看到 d3d 输出。
do you create the D3D Device with the same hwnd like the one the 3rd-party dll uses?
in this case maybe the 3rd-party software is still drawing it's stuff, but direct3d just renders on top of it, so you only see the d3d output.