Document/View框架中初始化Direct3D

一般情况下,初始化Direct3D包含以下四个步骤:

1、获得IDirect3D9接口指针;

2、检查显卡是否支持硬件顶点处理;

3、定义一个D3DPRESENT _PARAMETERS变量,指定相关的显示特性;

4、创建IDirect3DDevice9对象,该对象指向一个代表图形设备的C++对象。

具体在文档/视图框架中初始化过程如下:

1、在View类中添加两个成员变量(m_pD3d应该不是必须的):

class CXXView : public CView
{
private:
    LPDIRECT3D9 m_pD3d;
    LPDIRECT3DDEVICE9 m_pD3dDevice;
protected: // create from serialization only
    CFirstView();
    DECLARE_DYNCREATE(CFirstView)
 
// Attributes
public:
    CFirstDoc* GetDocument() const;
...
};

2、进行初始化工作。可以首先将初始化的工作封装为一个View类的成员函数:

bool CXXView::D3dInit()
{
    HWND hwnd = GetSafeHwnd();
    CRect clientrect;
    GetClientRect(&clientrect);
    m_pD3d = Direct3DCreate9(D3D_SDK_VERSION);
    if(m_pD3d == NULL)
    {
        MessageBox("Fail to create D3d interface");
        return false;
    }
    D3DCAPS9 caps;
    m_pD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
    int vp = 0;
    if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
        vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    else
        vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    D3DPRESENT_PARAMETERS para;
    ZeroMemory(&para,sizeof(para));
     para.BackBufferWidth = clientrect.Width();
     para.BackBufferHeight = clientrect.Height();
     para.BackBufferFormat = D3DFMT_A8R8G8B8; //像素格式
     para.BackBufferCount = 1;
     para.MultiSampleType = D3DMULTISAMPLE_NONE;
     para.MultiSampleQuality = 0;
     para.SwapEffect = D3DSWAPEFFECT_DISCARD;
     para.hDeviceWindow = hwnd;
    para.Windowed = TRUE;
     para.EnableAutoDepthStencil = true;
     para.AutoDepthStencilFormat = D3DFMT_D24S8; // depth format
     para.Flags = 0;
     para.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
     para.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    
    HRESULT hr = m_pD3d->CreateDevice(D3DADAPTER_DEFAULT, 
                                        D3DDEVTYPE_HAL,
                                        hwnd, 
                                        vp, 
                                        &para, 
                                        &m_pD3dDevice);
    if(FAILED(hr))
    {
//         DWORD dw = GetLastError();
//         CString error;
//         error.Format("%u,%u",dw,hr);
//         MessageBox(error);
        MessageBox("Fail to create D3d device");
        return false;
    }
    return true;
}

3、重载OnInitialUpdate虚函数,在其中调用D3dInit:

void CXXView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
 
    // TODO: Add your specialized code here and/or call the base class
    if(!D3dInit())
        MessageBox("D3d initialization failed!");
}

4、在析构函数释放设备和D3d对象:

CXXView::~CXXView()
{
    if(m_pD3dDevice != NULL)
        m_pD3dDevice->Release();
    if(m_pD3d != NULL)
        m_pD3d->Release();
}

5、可以在OnPaint中测试一下:

void CXXView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CView::OnPaint() for painting messages
    if(m_pD3dDevice)
    {
        m_pD3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,0x00000000, 1.0f, 0);
        m_pD3dDevice->Present(0,0,0,0);
    }
}

posted on 2012-04-27 20:30  youthlion  阅读(530)  评论(0编辑  收藏  举报

导航