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

时间: 2024-11-06 08:14:45

Directx9.0 学习教程1 - 第一个程序的相关文章

Directx9.0 学习教程2 - 使用DXUT框架

DXUT框架是 samples例子的一个公共框架.非常方便的把很多本来需要复杂.而且重复的操作,都封装了起来. 使用步骤非常简单 C:\Program Files\Microsoft DirectX SDK (June 2010)\Samples\SampleBrowser 在SDK安装目录下面  有一个SampleBrowser文件.打开 然后根据自己的版本,选择如上, EmptyProject工程 然后 InstallProject 自动安装完成后.打开工程.Clean一下工程 ,防止缓存出

Directx9.0 学习教程5 光照

光照 1.      首先需要定义这样的顶点结构 struct CUSTOMVERTEX { D3DXVECTOR3position; // 顶点 D3DXVECTOR3normal; // 法向量 }; // Custom flexible vertex format (FVF). #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL) 2. 然后创建一个圆柱体顶点模型 // Create the vertex buffer. if( FA

Directx9.0 学习教程3 -图形学之创建点 线 三角形 等

1.首先 介绍点的表示方法 struct CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, { 0.0, 5.0, 0.0}, { 5.0, -5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0}, {20.0, 5.0, 0.0} }; 点的渲染方法--D3DPT_POINTLIST 主要是这个. 点列表 // // It is assumed th

Directx9.0 学习教程4 - 坐标系以及变换知识小记

坐标系 左图是左手坐标系    右图是右手坐标系 Direct3d用的是左手坐标系 顶点和法向 光栅化 变换 1世界变换 2观察变换 D3DXMATRIX out; D3DXVECTOR3 eye(2,3,3); D3DXVECTOR3 at(0,0,0); D3DXVECTOR3 up(0,1,0); D3DXMatrixLookAtLH(&out,&eye, &at, &up); 3.投影矩阵 他们的作用是 世界矩阵把 local坐标变为世界坐标 观察矩阵把世界坐标变为

ICE学习第二步-----从第一个程序了解ICE(HelloWorld)

ICE(Internet Communications Engine)是一种面向对象的中间件平台,主要用于网络通讯.它为面向对象的“客户端-服务器”模型的应用提供了一组很好的工具和API接口.目前在全世界被应用于很多项目之中.ICE中间件号称标准统一,开源,跨平台,跨语言,分布式,安全,服务透明,负载均衡,面向对象,性能优越,防火期穿透,通讯屏蔽.因此相比Corba,DCOM,SOAP,J2EE等的中间件技术,自然是集众多优点于一身,而却没有他们的缺点. 这次编写的小程序主要流程很简单,就是客户

Arduino可穿戴教程之第一个程序——选择端口(三)

Arduino可穿戴教程之第一个程序--选择端口(三) 2.4.4  选择端口 在选择了板子之后,我们就需要选择板子连接到电脑的端口了.它也在"工具"菜单中设置,如图2.42所示. 注意:COM1端口通常是主板自带的串行端口,所以它通常不是LilyPad所在的端口.端口的编号并不是固定的,在Windows操作系统下,编号可以在设备管理器中看到,如图2.43所示. 在Linux操作系统下,端口的命名方式与Windows是不同的,如图2.44所示. 在Linux操作系统下,可以通过dmes

DirectX11 学习笔记1 - 第一个程序

为了加快学习速度,和使程序更加容易理解.  我把sampler tutorial里面的一个例子 的固定代码和经常改动的代码经过简单的类的封装了一下. 以后学习的时候就可以只在另一个文件写render渲染代码和fx着色器代码了 D3DBase.h  基本框架代码 #include <windows.h> #include <d3d11.h> #include <d3dx11.h> #include <d3dcompiler.h> #include <xn

Python的学习之旅———第一个程序

基本上学习语言第一个程序都是打印"hello world".Python实现这个操作,就跟说话一样. print('hello world') 我们可以直接进入解释器的交互模式,有点事调试方便,但是永久保存代码,还可以用脚本文件的方式,有点是可以保存代码.通常定义文本以.py作为结尾. 也可以去安装JetBrains PyCharm 2017 IDE (集成开发环境IDE,Integrated Development Environment ),用他来编写调试更爽.可以极大的提高开发效

c#学习笔记之第一个程序“Hello world”

看到“Hello world”的时候想起了一个笑话:一个退休多年的程序员决定练习书法,他拿起毛笔挥毫泼墨写下一行大字——”Hello world“.虽然是一个笑话,但是还感觉有一丝程序员调侃自己的味道.的确,当学习一门新语言的时候,是要从最简单的”hello world“学起. 第一步:当然是安装visual studio,选择新建--项目--Visual c#--控制台应用程序 第二步:因为有一些代码是VS自己生成的,只需要在Main中写下向控制台显示”hello world“即可 执行程序,