使用MFC做D3D的框架

转载请注明出处http://www.cnblogs.com/CAION/p/3192111.html

(程序运行时是和其他程序挺像 = =,但我保证这是原创的)

1.将D3D的初始化,渲染等等一些行为封装为图形(Graph)类

代码如下(这里使用绘制旋转的茶壶作为例子),头文件

#pragma once
#include <d3d9.h>
#include <d3dx9.h>

class Graphi
{
public:
    Graphi(void);
    ~Graphi(void);

    bool Initialize(int,int,HWND);
    void Shutdown();

    bool Setup();
    bool Update();
    bool Render();
private:
    float GetDeltaTime();
private:
    LPDIRECT3D9             m_pD3d;  //Direct3D对象
    LPDIRECT3DDEVICE9       m_pd3dDevice; //Direct3D设备对象
    ID3DXMesh*                m_Teapot;    //

private:
    int m_Width,m_Height;
    D3DXMATRIX m_world;
};

CPP文件

#include "StdAfx.h"
#include "Graphi.h"
#include "MMSystem.h"

Graphi::Graphi(void)
{
    m_pD3d = NULL;  //Direct3D对象
    m_pd3dDevice = NULL;
    m_Teapot = NULL;

    //
    m_Width = 0;
    m_Height = 0;
}


Graphi::~Graphi(void)
{
    Shutdown();
}

bool Graphi::Initialize(int Width,int Height,HWND hWnd)
{
    //创建Direct3D对象, 该对象用来创建Direct3D设备对象
    if( NULL == ( m_pD3d = Direct3DCreate9( D3D_SDK_VERSION ) ) )
        return false;

    //设置D3DPRESENT_PARAMETERS结构, 准备创建Direct3D设备对象
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    

    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

    //创建Direct3D设备对象
     m_pD3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
        &d3dpp, &m_pd3dDevice ) ;
    
     //
     m_Width = Width;
     m_Height = Height;

    return true;
}

bool Graphi::Setup()
{
    D3DXCreateTeapot(m_pd3dDevice,&m_Teapot,0);

    D3DXVECTOR3 position(0.0f, 0.0f, -3.0f);
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXMATRIX V;
    D3DXMatrixLookAtLH(&V, &position, &target, &up);
    m_pd3dDevice->SetTransform(D3DTS_VIEW, &V);

    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
        &proj,
        D3DX_PI * 0.5f, // 90 - degree
        (float)m_Width / (float)m_Height,
        1.0f,
        1000.0f);
    m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj);

    m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
return true;
}

void Graphi::Shutdown()
{
    //释放Direct3D设备对象
    if( m_pd3dDevice != NULL) 
        m_pd3dDevice->Release();

    //释放Direct3D对象
    if( m_pD3d != NULL)
        m_pD3d->Release();

    //释放mesh对象
    if( m_Teapot != NULL)
        m_Teapot->Release();
}

float Graphi::GetDeltaTime()
{
    static float lastTime = (float)timeGetTime();  
    // Compute time now.  
    float currentTime = (float)timeGetTime();  
    // Compute the difference: time elapsed in seconds.  
    float deltaTime = (currentTime - lastTime) * 0.001f;  
    // Last time is now current time.  
    lastTime = currentTime;  

    return deltaTime;
}

bool Graphi::Render()
{
    
    //清空后台缓冲区
    m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );


    m_pd3dDevice->BeginScene();
    
    //在此在后台缓冲区绘制图形
    m_Teapot->DrawSubset(0);
    
    m_pd3dDevice->EndScene();
    

    //将在后台缓冲区绘制的图形提交到前台缓冲区显示
    m_pd3dDevice->Present( NULL, NULL, NULL, NULL );

    return true;
}

bool Graphi::Update()
{
    D3DXMATRIX Ry;
    static float y = 0.0f;
    D3DXMatrixRotationY(&Ry, y);
    m_world = Ry;

    float deltaTime = GetDeltaTime();

    y += deltaTime;
    if(y >= 6.28f)
        y = 0.0f;

    
    m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_world);

    return true;
}

2.在VS2010中新建MFC工程,选择基于对话框创建

3.为对话框添加一个Static控件,并把控件ID改成IDC_3DVIEW。添加控件变量m_3dview

4.重载WM_KICKIDLE消息。(关于WM_KICKIDLE消息了解更多,http://hi.baidu.com/cherven23/item/ac0d59f539a137793c198b00

5.完成回调函数WM_KICKIDLE的回调函数OnKickIdle()。

LRESULT CD3D_MFCDlg::OnKickIdle(WPARAM wParam,LPARAM lParam)
{
    m_d3dGraphi->Update();
    m_d3dGraphi->Render();
    return 1;
}

6.在初始化对话框的函数中,添加初始化D3D代码

BOOL CD3D_MFCDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);            // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO: 在此添加额外的初始化代码
    CRect rect; 
    GetWindowRect(&rect);
    m_3dview.GetWindowRect( &rect );

    //初始化图形代码
    HWND hWnd;
    hWnd = m_3dview.m_hWnd;
    m_d3dGraphi = new Graphi();
    m_d3dGraphi->Initialize(rect.Width(),rect.Height(),hWnd);
    m_d3dGraphi->Setup();

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

7.编译运行

image

附:源代码下载http://download.csdn.net/detail/ok123zxx/5759675

原文地址:https://www.cnblogs.com/CAION/p/3192111.html