一个简单的例子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;
这里就是调用上述步骤1中IDirect3D9成员函数GetDeviceCaps来获取一个描述硬件的结构体D3DCAPS9。查看相关文档会发现,这是一个相当大的结构体,在这里我们只关心DWORD DevCaps这个成员,用来标示设备性能。在此处,检验当前该硬件是否支持硬件顶点计算。
// Step 3: Fill out the D3DPRESENT_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
// Create the 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
// Fill the 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函数可以设置的东西也不少,下次有时间再继续研究吧