|
|
申请了帐号一直潜水,今天遇到在D3D中CreateDevice()总是失败,没人帮忙解决,所以只好上来求救各位了。小弟在一家游戏公司做美工,利用休息时间写D3D图形引擎,在初始化D3D设备的时候前面其他前面步骤都顺利但是到CreateDevice()的时候就不能通过,向程序组那边请教未果(他们很排斥底层开发)。之前也写过一些D3D小程序,本次用类封装的时候就出错。
不废话了,先?下我的平台
硬件
Dual E2160 (1.80G)CPU、 2G内存、GeForce 8600GT(512现存,美工配置最好^_^)
软件
Microsoft Visual Studio 2005 Team Edition for Software Developers
Microsoft DirectX 9.0 SDK Update (Summer 2003)
部份代码
//类定义
class D3D
{
public:
D3D(void);
bool InitGraphicsDevice(HWND hWnd, UINT nWidth, UINT nHeight, bool bWindowed) throw (EXC_GraphicsException);// 初始化D3D设备
private:
// 成员变量定义
LPDIRECT3D9 m_pD3D;
LPDIRECT3DDEVICE9 m_pd3dDevice;
D3DCAPS9 m_D3DCaps;
D3DPRESENT_PARAMETERS m_D3DParam;
HRESULT m_hr;
};
//方法
D3D(void)//构造函数
:m_pD3D(NULL)
,m_pd3dDevice(NULL)
,m_nScreenDepth(32)
,m_BackGroundColor(0xff000000)
,m_bZBuffer(false)
{}
//---------------------------------
// 初始化D3D设备
//---------------------------------
bool D3D::InitGraphicsDevice(HWND hWnd, UINT nWidth, UINT nHeight, bool bWindowed)
throw (EXC_GraphicsException)
{
ASSERT(NULL != hWnd && NULL == m_pD3D);
//创建Direct3D设备
if (NULL == (m_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
return false;
}
//获取显卡具体属性
D3DADAPTER_IDENTIFIER9 AddID;
m_pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &AddID);
//获取显示模式
D3DDISPLAYMODE DisplayMode;
m_hr = m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DisplayMode);
if (FAILED(m_hr))
{
throw JHXH_GraphicsException("不能确定桌面显示方式!", m_hr);
}
//获取桌面显示位深
UINT nModes = 0;
UINT i = 0;
D3DFORMAT Formatfs = D3DFMT_UNKNOWN;
//32位
if (32 == m_nScreenDepth)
{
nModes = m_pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
for (UINT i = 0; i < nModes; i++)
{
m_pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_A8R8G8B8, i, &DisplayMode);
if (DisplayMode.Width != nWidth || DisplayMode.Height != nHeight )
{
continue;
}
Formatfs = DisplayMode.Format;
break;
}
}
else if (16 == m_nScreenDepth) //16位
{
D3DFORMAT tempFormat = D3DFMT_R5G6B5;
if (!nModes)
{
nModes = m_pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X1R5G5B5);
tempFormat = D3DFMT_X1R5G5B5;
}
for (UINT i = 0; i < nModes; i++)
{
m_pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, tempFormat, i, &DisplayMode);
if (DisplayMode.Width != nWidth || DisplayMode.Height != nHeight)
{
continue;
}
Formatfs = DisplayMode.Format;
break;
}
}
else if (D3DFMT_UNKNOWN == Formatfs)
{
return false;
}
//创建设备支持结构体
ZeroMemory(&m_D3DParam, sizeof(m_D3DParam));
// 检查显卡是否支持抗锯齿
// 自动计算显卡支持抗锯齿等级
for (int i = 16; i >= 1; i--)
{
D3DMULTISAMPLE_TYPE Samples;
DWORD dwQuality;//抗齿质量
......//太长了绝对?]问题,所以省略
dwQuality = i;//抗齿质量
if (SUCCEEDED(m_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL , DisplayMode.Format, true, Samples, NULL)))
{
m_D3DParam.MultiSampleType = Samples;
m_D3DParam.MultiSampleQuality = dwQuality;
break;
}
else
{
if (0 == i)
{
m_D3DParam.MultiSampleType = D3DMULTISAMPLE_NONE;
m_D3DParam.MultiSampleQuality = 0;
}
}
}//End for(;;)
// 判断是窗口还是全屏,以此来填充设备结构体
if (true == bWindowed )//窗口
{
m_D3DParam.Windowed = true;
m_D3DParam.BackBufferFormat = DisplayMode.Format;
}
else //全屏
{
m_D3DParam.Windowed = false;
m_D3DParam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
m_D3DParam.BackBufferFormat = Formatfs;
}
m_D3DParam.BackBufferCount = 1;
m_D3DParam.BackBufferWidth = nWidth;
m_D3DParam.BackBufferHeight = nHeight;
m_D3DParam.hDeviceWindow = hWnd;
m_D3DParam.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_D3DParam.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
m_D3DParam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (m_bZBuffer)//Z缓冲
{
m_D3DParam.EnableAutoDepthStencil = true;
m_D3DParam.AutoDepthStencilFormat = D3DFMT_A8R8G8B8;
}
ZeroMemory(&m_D3DCaps, sizeof(m_D3DCaps));
if (FAILED(m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_D3DCaps)))
{
throw EXC_GraphicsException("GetDeviceCaps_ERROR", hr);
return false;
}
int VP = 0;
if (m_D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
VP = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
VP = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
//以下就是出问题的地方
if (m_hr = (m_D3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, VP, &m_D3DParam, &m_pd3dDevice)))
{
throw EXC_GraphicsException("CreateDevice_ERROR", m_hr);//抛出异常错误代码-2005530516
return false;
}
return true;
}
以上就是相关代码(又臭又长),在CreateDevice()之前均正确无误,调试的时候抛出异常代码为-2005530516,逐步断点调试发现m_pd3dDevice的值为0x00000000。通过注释其他函数的办法逐步排除其他参数干扰,通过自己编写的记录消息发现是m_pd3dDevice存在问题,现在初步定位在该长指针出问题,但是不知道如何修改。指针初始化我?]看出问题原因所在。现在DirectInput和DirectSound部份均正常,就D3D不能实现类封装了。通过定义全局变量该指针的方式还是不能解决问题。我在观摩了上百份别人的源代码后问题依旧,所以只好上来求救各位高手了。
如果不是代码问题,软硬件应该?]问题的,显卡驱动是官网下的最新驱动(换了N次驱动),不过有个奇怪的问题就是DirectSDK上的例子除了我现在用的外任何版本(9.0以上)都不能运行,公司主程(很排斥底层开发和C++)?是显卡驱动、DirectX问题 [em17]实在很无语,我电脑上上G的源码实例以及国内外的各种开源游戏引擎(C++)通过更错、该配置信息后均能运行。C++是我知道点Java语法皮毛后自己反推过来自学的、Windows编程也就在MSDN帮助下调用几个API函数(看不懂MFC [em7])。因为我是利用自己休息时间自己写着玩的,要绕开这个问题不用类封装来实现功能很简单,我也做到了,但我现在就想知道错在哪里,原因是什么。为了这个问题整个进度停了两周的时间了 [em17]希望大家能帮帮小弟 |
|