首页 > 代码库 > Directx9.0 学习教程1 - 第一个程序

Directx9.0 学习教程1 - 第一个程序

在图书馆选了N本书,还是觉得直接讲代码的书更适合我,一个完整的列子加上些许注释,比那些一上来就是一大段一大段的文字阐述的教程容易懂的多。 

因此我的笔记也开始用这种方式记录。

写在开头:  dx(我对directx简称) dx的版本主要有9 和11这两种系列。 API和功能差异还是笔记大的。 但是手头dx9的书笔记齐全。 就开始看dx9 了。而且学习从来都是学习他的思想,尽管可能换版本要换配置环境,或者换api ,但是大概思想是不变的。学了总有好处。

下面是学习这本书的第一个列子。

说白了就是个vc++的小框架。然后有一点dx的代码。 但是这个小框架以后可以自己慢慢丰富。 可能对MFC抵触的童鞋觉得里面的win32 api晦涩难懂,但是完全没必要注意哪些细节,这个小框架只是为了显示一个窗口展示dx ,还有消息处理。所以会用就行了。

转自http://blog.csdn.net/cq361106306/article/details/39549091

先介绍下win32下dx主要工作流程:


1.winMain 函数

这个是整个工程的入口函数,看代码也是从这里开始看

//先定义窗口类
WNDCLASSEX wc={...} //细节不用管,你也记不住

//注册窗口类
RegisterClassEx(&wc);

//然后就是创建窗口类
HWND hwnd=CreateWindow(....)//里面的参数主要是窗口大小和标题,可以自己改改

//---------以上是win32窗口的东西
//---------以下就开始d3d的初始化了

//源代码里有很多if这些只看流程我就省略了

//首先把窗口传给D3D。
InitD3D(hwnd); //这个函数里面的东西在后面讲。先记住大概流程就行了

//然后装载模型
InitGeometry();//这个也后面讲

//初始化完了。当然就是显示咯
ShowWindow(hwnd,...);
UpdateWindow(hwnd);

//消息循环--这个是vc++的程序必须要弄的。反正就是一个循环不断的执行一些能改变窗口啊,变量啊之类的循环

while(msg.messge!=WM_QUIT)
{
	//执行系统消息
	..
	//执行D3D的渲染
	Render();//以后的列子都只需要在Render里面加东西了。所以其他函数都是框架的一部分啦。看不懂就算了。
}


上面就是整体流程了,是不是发现其实还是挺简单的。就是一堆初始化,然后就开始循环更新。

下面讲初始化的函数

//-----------------------------------------------------------------------------
// 函数:InitD3D()
// 功能:初始化 D3D 和 3D 设备
// 参数:初始化了两个全局变量 g_pD3D g_pd3dDevice
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
  {
    // 创建 3D 对象.
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )       return E_FAIL;
    // 告诉系统设置需要创建的参数,就是填充 D3DPRESENT_PARAMETERS 的参数
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof( d3dpp ));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    // 创建设备
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
      D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) )  return E_FAIL;
    return S_OK;
  }

//以上代码看着是不是很蛋疼,对啊非常蛋碎,反正就是一系列参数。先放着吧。

下面就是InitGeometry函数 主要就是设置效果文件 .fx后缀那个。

//-----------------------------------------------------------------------------
// 函数:InitGeometry()
// 功能:设置目录、装入模型、纹理、效果文件、传递效果参数到HLSL
// 参数:初始化了其他三个全局变量 g_pMesh g_pEffect g_pMeshTextures
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
  {
    HRESULT hr;
    // 设置目录
    TCHAR szAppPath[ MAX_PATH ];
    TCHAR szRcPath[ MAX_PATH ];
    GetCurrentDirectory( MAX_PATH, szAppPath );
    // 
    lstrcpy( szRcPath , szAppPath );
    lstrcat( szRcPath ,L"\\ResFile_1_Model" );
    SetCurrentDirectory( szRcPath );
        // 装入效果文件
    LPD3DXBUFFER pCode = NULL;
    if( FAILED( hr = D3DXCreateEffectFromFile( g_pd3dDevice, L"FileFX.fx", 
      NULL, NULL, 0, NULL, &g_pEffect, &pCode )))
      {
        LPVOID pBufErr = pCode->GetBufferPointer();
        char* ErrInfo = ( char* ) pBufErr;
        pCode->Release( );
        return hr;
      }
    if( FAILED( hr = g_pEffect->SetTechnique( "DefaultTech" ))) return hr ;
    //上面效果文件装载成功后,就要设置顶点结构的模型了 InitVB();
    if( FAILED( hr = InitVB())) return hr;
    // 可以正确返回了
    return S_OK;
  }

以上代码其实基本都固定不变的。因为每个列子都要用的。真正需要随时改的那就是模型和渲染逻辑了

回顾一下以上已经完成的是,窗口定义,窗口显示,初始化D3D,初始化.fx效果文件,初始化模型, 消息循环.

下面就是讲真正要做的东西。 显示一个三角形

顶点模型创建

// 函数:InitVB
// 功能:初始化 g_pVB
// 参数:无
//-----------------------------------------------------------------------------
HRESULT InitVB()
  {
    HRESULT hr;
    CUSTOMVERTEX vertices[] =
      {
        {  5.0f ,  0.0f , 0.0f , 1.0f , 0xffff0000  }, // x, y, z, rhw, color 红色
        {  0.0f  , 5.0f , 0.0f , 1.0f , 0xff00ff00  }, // 绿色
        { -5.0f ,  0.0f , 0.0f , 1.0f , 0xff0000ff  }, // 蓝色
        
      };
    if( FAILED( hr = g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ),
       0 , D3DFVF_CUSTOMVERTEX , D3DPOOL_DEFAULT , &g_pVB, NULL ))) return hr;
    VOID* pVertices;
    if( FAILED( hr = g_pVB->Lock( 0, sizeof( vertices ), ( void** )&pVertices, 0 )))    return hr;
    memcpy( pVertices, vertices, sizeof( vertices ));
    g_pVB->Unlock( );

    return S_OK;
  }

一切准备工作就完成了。然后就是渲染啦

主要是Render() 函数

VOID Render()
  {
    HRESULT hr;
    // 清除背景缓冲区的深度缓冲区
    hr = g_pd3dDevice->Clear( 0 , NULL , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 
      D3DXCOLOR( 0.0f , 0.25f , 0.25f , 0.55f ) , 1.0f , 0 );
    hr = g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
    hr = g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
    if( SUCCEEDED( g_pd3dDevice->BeginScene( )))
      {
        // 设置变换,实际上是设置实际矩阵绕 Y 轴旋转
        SetupMatrices( );
        // 按效果文件的设置渲染
        UINT iPass, cPasses;
        hr = g_pEffect->Begin( &cPasses, 0 );
        for ( iPass = 0; iPass < cPasses; iPass++ )
          {
            hr = g_pEffect->BeginPass( iPass );
            hr = g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST , 0 , 1 );
            hr = g_pEffect->EndPass();
          }
        hr = g_pEffect->End();
        hr = g_pd3dDevice->EndScene();
      }
    // 将渲染的结果切换到前景缓冲区
    hr = g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
  }
//-----------------------------------------------------------------------------
// 函数:SetupMatrices()
// 功能:将 4 个变量传递给效果文件,由效果文件来计算
// 参数:无,本模块涉及全局变量:效果文件接口
//-----------------------------------------------------------------------------
VOID SetupMatrices()
  {
    HRESULT hr;
    D3DXMATRIXA16 matWorld;
    float fTime = timeGetTime() / 1000.0f ;
    D3DXMatrixRotationY( &matWorld , fTime );
    //D3DXMatrixIdentity( &matWorld );
    hr = g_pEffect->SetFloat( "g_fTime" , fTime );
    // 世界矩阵
    hr = g_pEffect->SetMatrix( "g_matWorld" , &matWorld );
    // 观察矩阵
    D3DXVECTOR3 vEyePt( 15.0f , 3.0f , 0.0f );
    D3DXVECTOR3 vLookatPt( 0.0f, 3.0f, 0.0f );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
    D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
    hr = g_pEffect->SetMatrix( "g_matView" , &matView );
    // 投影矩阵
    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH( &matProj , D3DX_PI/4 , 64.0 / 41.0f , 1.0 , 100.0f );
    hr = g_pEffect->SetMatrix( "g_matProject" , &matProj );
  }

效果就是一个三角形不停的转啊转。



工程源码链接: http://pan.baidu.com/s/1sjI131j 密码: 8l7s

Directx9.0 学习教程1 - 第一个程序