本帖最后由 十二 于 2011-2-25 19:19 编辑
Directx9的的调用并不像普通的程序那么显性用LordPE打开任何一个Dx9程序一般都能看到输入表会导入d3d9.dll的Direct3DCreate9函数,d3d9.dll下一般只有这一个函数导入,这里出现一个疑问Directx提供那么丰富的功能一个函数去实现显然是扯淡的。Directx采用了COM接口,所以函数以方法的形式封装在接口中,得到这些方法的实现显然是对Directx更深了解的过程。
下面将已调试作为探索,展开对Directx初始化的讨论。
首先当程序准备初始化Directx的时候会调用Direct3DCreate9,下面是Direct3DCreate9的原型。
函数原型:Direct3DCreate9(D3D_SDK_VERSION)
该函数的参数必须是D3D_SDK_VERSION,只有如此方能保证应用程序使用正确的头文件,如果该函数调用失败,将返回一个NULL指针
该函数的返回值是一个指向接口IDirect3D9的指针
能看到该函数只有有一个参数D3D_SDK_VERSION这个参数并不重要,值得注意的是该函数会返回一个IDirect3D9接口的指针。
可以在1L的附件d3d9.rar中找到此接口的定义。
- DECLARE_INTERFACE_(IDirect3D9, IUnknown)
- {
- /*** IUnknown methods ***/
- STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDirect3D9 methods ***/
- STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
- STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
- STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier) PURE;
- STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter,D3DFORMAT Format) PURE;
- STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
- STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;
- STDMETHOD(CheckDeviceType)(THIS_ UINT iAdapter,D3DDEVTYPE DevType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) PURE;
- STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;
- STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels) PURE;
- STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
- STDMETHOD(CheckDeviceFormatConversion)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SourceFormat,D3DFORMAT TargetFormat) PURE;
- STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps) PURE;
- STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
- STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) PURE;
- };
复制代码 此定义中应该值得注意的是CreateDevice这个方法。当然你要是对其他方法感兴趣可以在OD中跟踪Direct3DCreate9返回的指针(EAX中的值)找到该方法的确切位置,或者查找MSDN。
CreateDevice方法的的原型
http://baike.baidu.com/view/3887791.htm
此方法的地6个参数会得到IDirect3DDevice9接口的指针。但是在我机器上OD实际是第7个参数。第一个参数为Direct3DCreate9返回的指针。
方法依旧在1L附件的d3d9.rar中找到IDirect3DDevice9接口的定义,可以看到很多方法实现了很多功能,代码过多这里不贴。
这样你就可以在OD中跟踪Directx的详细实现方法。
大部分流程是用CreateVertexBuffer方法来创建Vextex Buffer
CreateVertexBuffer方法的倒数第二个参数指向一IDirect3DVertexBuffer9接口。
IDirect3DVertexBuffer9接口定义如下
- #undef INTERFACE
- #define INTERFACE IDirect3DVertexBuffer9
- DECLARE_INTERFACE_(IDirect3DVertexBuffer9, IDirect3DResource9)
- {
- /*** IUnknown methods ***/
- STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDirect3DResource9 methods ***/
- STDMETHOD(GetDevice)(THIS_ IDirect3DDevice9** ppDevice) PURE;
- STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE;
- STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE;
- STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE;
- STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE;
- STDMETHOD_(DWORD, GetPriority)(THIS) PURE;
- STDMETHOD_(void, PreLoad)(THIS) PURE;
- STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE;
- STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) PURE;
- STDMETHOD(Unlock)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE;
- };
复制代码
这里你就能看到一些Dx在定义定点前必用的方法函数Lock和Unlock了
同理你还可以用OD来跟踪SetStreamSource方法SetFVF以及DrawPrimitive来看到具体的画法流程。
这样你就不难理解为什么DX只导入一个函数就能实现那么多功能了。
部分资料来源百度,和各大论坛。
|