DirectX 9.0 3D 游戏开发编程基础 学习笔记(一)

来源:互联网 发布:ubuntu 重置 编辑:程序博客网 时间:2024/05/16 13:56

 

 一个简单的例子Triangle

 

一般创建一个directX的程序需要四个步骤

 

// Step 1: Create the IDirect3D9 object.

IDirect3D9* d3d9 = 0;

d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

 

IDirect3D9是一个用来创建微软directX对象以及初始化环境的接口,主要的作用是枚举和获取设备的capabilities

类主要的成员函数有

IDirect3D9::GetDeviceCaps     //获取设备信息

IDirect3D9::CheckDeviceType   //是否支持硬件加速

IDirect3D9::GetAdapterCount   //获取系统适配器的数目

 

IDirect3D9的创建方法是调用Direct3DCreate9函数

 

// Step 2: Check for hardware vp.

D3DCAPS9 caps;

d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,deviceType, &caps);

 

int vp = 0;

if( caps.DevCaps &D3DDEVCAPS_HWTRANSFORMANDLIGHT )

       vp= D3DCREATE_HARDWARE_VERTEXPROCESSING;

else

       vp= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

 

这里就是调用上述步骤1IDirect3D9成员函数GetDeviceCaps来获取一个描述硬件的结构体D3DCAPS9。查看相关文档会发现,这是一个相当大的结构体,在这里我们只关心DWORDDevCaps这个成员,用来标示设备性能。在此处,检验当前该硬件是否支持硬件顶点计算。

 

// Step 3: Fill out theD3DPRESENT_PARAMETERS structure.

D3DPRESENT_PARAMETERS d3dpp;

       d3dpp.BackBufferWidth                 = width;

       d3dpp.BackBufferHeight                = height;

       d3dpp.BackBufferFormat               = D3DFMT_A8R8G8B8;

       d3dpp.BackBufferCount                 = 1;

       d3dpp.MultiSampleType                 = D3DMULTISAMPLE_NONE;

       d3dpp.MultiSampleQuality             = 0;

       d3dpp.SwapEffect                          = D3DSWAPEFFECT_DISCARD;

       d3dpp.hDeviceWindow                  = hwnd;

       d3dpp.Windowed                          = windowed;

       d3dpp.EnableAutoDepthStencil     = true;

       d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;

       d3dpp.Flags                                   = 0;

       d3dpp.FullScreen_RefreshRateInHz= D3DPRESENT_RATE_DEFAULT;

       d3dpp.PresentationInterval           = D3DPRESENT_INTERVAL_IMMEDIATE;

 

这里的主角就是D3DPRESENT_PARAMETERS结构体,用来进行参数的描述。可以看到诸如离屏帧缓冲的长宽、格式、数量以及多重采样、是否全屏等设置。

 

// Step 4: Create the device.

HRESULT hr = 0;

hr = d3d9->CreateDevice(

              D3DADAPTER_DEFAULT,// primary adapter

              deviceType,              // device type

              hwnd,                   // window associated with device

              vp,                     //vertex processing

           &d3dpp,                // present parameters

           device);

 

获得刚才设置的结构体后,最后便是创建Device的句柄了。

其中最值得一提的是out参数IDirect3DDevice9** device,这也是direct3D做基础图元绘制的接口,完成例如创建资源、shader等等工作。这个接口的函数也非常多,但在以后应用中都会遇到,是进行图形处理最重要的接口。

 

接着要重点解释的是IDirect3DVertexBuffer9这个接口,DX中要绘制的顶点和图元都是通过这样一个顶点缓存来传给GPU的。一个顶点缓存是一个包含顶点数据的连续空间。之所以用缓存而非数组来存储数据,是因为顶点缓存可以被放置在显存中。进行绘制时,使用显存的数据将比使用系统内存要快很多。

 

IDirect3DVertexBuffer9继承自IDirect3DResource9接口,在DX中,资源是指用来绘制的纹理和缓存,而应用程序需要创建、导入、复制或者使用这些资源,这些接口提供的正是这样的功能。

缓存(几何)资源:IDirect3DIndexBuffer9/IDirect3DVertexBuffer9直接继承自IDirect3DResource9接口;

纹理资源:IDirect3DCubeTexture9/IDirect3DTexture9/IDirect3DVolumeTexture9继承自IDirect3DBaseTexture9接口;

 

继承结构如下:

IDirect3DResource9

|-- IDirect3DBaseTexture9

  |-- IDirect3DCubeTexture9

  |-- IDirect3DTexture9

  |-- IDirect3DVolumeTexture9

|-- IDirect3DIndexBuffer9

|-- IDirect3DSurface9

|-- IDirect3DVertexBuffer9

|-- IDirect3DVolume9

 

IDirect3DResource9主要提供了查询和准备这些资源的统一接口方法

比如

IDirect3DResource9::SetPriority     //设置资源的优先级 

IDirect3DResource9::SetPrivateData  //设置应用程序的数据

 

而创建这些资源是通过IDirect3DDevice9的方法来实现

创建纹理资源:

IDirect3DDevice9::CreateCubeTexture

IDirect3DDevice9::CreateTexture

IDirect3DDevice9::CreateVolumeTexture

创建缓存资源:

IDirect3DDevice9::CreateIndexBuffer

IDirect3DDevice9::CreateVertexBuffer

 

现在就具体看下IDirect3DVertexBuffer9这个接口,用来操作顶点缓存。

函数有三个

Direct3DVertexBuffer9::GetDesc // 获取描述结构体

IDirect3DVertexBuffer9::Lock   // 锁定该缓存,只有锁定后,才能进行读写

IDirect3DVertexBuffer9::Unlock // 解锁

 

使用实例

IDirect3DVertexBuffer9*Triangle = 0; // vertex buffer to store

// Createthe vertex buffer.

Device->CreateVertexBuffer(

              3 * sizeof(Vertex),           // size in bytes

              D3DUSAGE_WRITEONLY,  // flags

              Vertex::FVF,               // vertex format

              D3DPOOL_MANAGED,    // managed memory pool

              &Triangle,                // return create vertex buffer

              0);                      // not used - set to 0

 

// Fillthe buffers with the triangle data.

Vertex*vertices;

Triangle->Lock(0,0, (void**)&vertices, 0);

 

vertices[0]= Vertex(-1.0f, 0.0f, 2.0f);

vertices[1] = Vertex( 0.0f,1.0f, 2.0f);

vertices[2] = Vertex( 1.0f,0.0f, 2.0f);

 

Triangle->Unlock();

 

在进行绘制时进行数据源的绑定就可以了

Device->SetStreamSource(0,Triangle, 0, sizeof(Vertex));

 

使用完进行释放

d3d::Release<IDirect3DVertexBuffer9*>(Triangle);

这个应该是继承自IUnknown接口相同的释放方法

 

其中还有一些IDirect3DDevice9的方法,记录下

IDirect3DDevice9::BeginScene

IDirect3DDevice9::DrawPrimitive

IDirect3DDevice9::EndScene

IDirect3DDevice9::SetTransform

IDirect3DDevice9::SetFVF

IDirect3DDevice9::Present

IDirect3DDevice9::SetRenderState

最后这个SetRenderState函数可以设置的东西也不少,下次有时间再继续研究吧

 

原创粉丝点击