游戏开发论坛

 找回密码
 立即注册
搜索
查看: 11781|回复: 8

请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

[复制链接]

1

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2009-1-6 20:48:00 | 显示全部楼层 |阅读模式
申请了帐号一直潜水,今天遇到在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]希望大家能帮帮小弟

0

主题

769

帖子

1052

积分

金牌会员

Rank: 6Rank: 6

积分
1052
发表于 2009-1-7 17:50:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

对应错误编码是
D3DERR_INVALIDCALL
The method call is invalid. For example, a method's parameter may have an invalid value.
你里面有变量设错了
自己对下吧
头晕就不帮你查了

0

主题

769

帖子

1052

积分

金牌会员

Rank: 6Rank: 6

积分
1052
发表于 2009-1-7 17:55:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

貌似显卡驱动什么搞出毛病来也会这样
如果确定没设置错的话要不重装下驱动了

1

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
 楼主| 发表于 2009-1-7 18:48:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

谢谢无名剑,代码上我再好好检查下。今天重装了下系统,显卡驱动也换了,但还是SDK(August2007)里面的例子看不了,提示错误为“Thr Direct3D device has a non-zero reference cout,meaning some objects were not released.”还是和先前的一样。显卡驱动换了好几个GF8600GT版本的,郁闷

22

主题

309

帖子

353

积分

中级会员

Rank: 3Rank: 3

积分
353
QQ
发表于 2009-1-7 21:53:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

SDK不是越新越好,装个06年4月的试试
你确定hWnd是有效的?把出错时hWnd和m_D3DParam那几个参数的值贴上来瞧瞧...


貌似现在流行美术转程序?我也是美术转程序~~~公司还有几个美术和策划想学程序-_-!~~

72

主题

447

帖子

454

积分

中级会员

Rank: 3Rank: 3

积分
454
QQ
发表于 2009-1-8 16:09:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

楼主 的这个代码写了太多的辅助的东西了,你报错的原因是你的某一种特效设置你的显卡不支持。
直接运行一下SDK里面的例题看看吧~~
SDk目录\Samples\C++\Direct3D\Tutorials\Tut01_CreateDevice   这个看看再说

你的Microsoft DirectX 9.0 SDK Update (Summer 2003)这个安装版还有吗?分享一下吧!

-----------------------------------------------------------
欢迎游戏同仁来我的窝讨论游戏开发中遇到的问题!!
http://www.dingge.com/forum/index.asp?boardid=46

12

主题

46

帖子

46

积分

注册会员

Rank: 2

积分
46
发表于 2009-1-10 13:39:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

检查两个方面的东西,hWnd以及m_D3DParam,
下面是个简单例子,你可以比较一下,看看有什么区别,觉得主要是在m_D3DParam的参数设置上面出了问题?不过也有可能是hWnd.
        //First of all, create the main D3D object. If it is created successfully we
        //should get a pointer to an IDirect3D8 interface.
    g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
        if(g_pD3D == NULL)
        {
        return E_FAIL;
        }

    //Get the current display mode
    D3DDISPLAYMODE d3ddm;
    if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
        {
        return E_FAIL;
        }

        //Create a structure to hold the settings for our device
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));

        //Fill the structure.
        //We want our program to be windowed, and set the back buffer to a format
        //that matches our current display mode
    d3dpp.Windowed                        = TRUE;
    d3dpp.SwapEffect                = D3DSWAPEFFECT_COPY_VSYNC;
    d3dpp.BackBufferFormat        = d3ddm.Format;

        //Create a Direct3D device.
        if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)))
    {
        return E_FAIL;
    }

1

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
 楼主| 发表于 2009-1-11 00:55:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

谢谢各位老大的提示。貌似 D3DPRESENT_PARAMETERS 结构体里面的BackBufferFormat有问题,昨天抽空加班到半夜趁老大不注意看了下。在DirectX属性里的Direct3D选项里面,把Debuging全选了发现BackBufferFormat这个信息是错误。

这几天公司内部内讧,一团胡闹,短短2个月游戏都推翻了3次~~~实在很无语。一直没时间上来,哭啊

回神秘的猫:
其实我大学是学程序的,不过是师范类的计科专业。不务正业美术也自学了点点,以前跟老师做项目也是做UI设计,顺带着做下控件。因为手头没作品,之后客串做美工了。也就一个打杂的,2D和3D都做~~~~

回鼯鼠:
就是贪心了点,想能在更多不同配置的机子上显示出最佳的效果。刚和一个好朋友(原公司的3D模型师,现在在家做家庭煮男了^_^)聊QQ,居然异想天开要做个渲染高模的游戏图形引擎。
我的SDK一直都用我说的这个,不过这个版本的官网有下,如果没找到的话,我给你就是了。汗~~~不知道如何给你,可以联系我哈,QQ183301791、MSN&E_Mail:yang839@126.com,MSN上的少,没几个人哈,最好还是电邮或QQ。

回jolley
谢谢你的提醒,目前的判断和你的一样,是BackBufferFormat有问题,不过按照鼯鼠大哥和你的提示运行了下SDK里面的代码,莫名其妙的又出错了,但很奇怪的是论坛上翁云兵老大翻译的《Introduction.To.Direct3D9中文版(翁云兵版)》这个教材里面带的源码完全无错且无任何警告的运行成功了,并且《DirectX 8 教程》里面配套代码也可以任意修改参数能无错运行,太诡异了。以前的情况和现在的情况相反了,超级郁闷。这几天做场景和3D模型也没修改过什么,唯一就是安装3DS MAX8的时候Autodesk自己装Directx9.0c。

这几天被勾心斗角搞的想吐还遇上这些程序灵异事件,想死的心都有了。

12

主题

46

帖子

46

积分

注册会员

Rank: 2

积分
46
发表于 2009-1-11 14:42:00 | 显示全部楼层

Re:请教,LPDIRECT3DDEVICE9定义接口指针CreateDevice()失败的问题

建议更新dx sdk.是不是你的版本过旧了呀?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-20 12:43

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表