十二 发表于 2011-2-23 13:24:53

Directx 接口与方法

本帖最后由 十二 于 2011-2-25 19:22 编辑



D3D9 所有COM接口和方法,调试的时候COM接口不透明。


Direct3DCreate9获得IDirect3D9接口指针,其他接口指针获得方法类似。

紅魔の月時計 发表于 2011-2-23 14:07:49

貌似和顯卡之類有關(?)

十二 发表于 2011-2-25 19:17:53

本帖最后由 十二 于 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只导入一个函数就能实现那么多功能了。

部分资料来源百度,和各大论坛。


htylanicer 发表于 2011-2-25 20:52:58

12大神触是也!

pa001024 发表于 2011-3-5 15:47:31

吐槽向。。。

十二 发表于 2011-3-13 10:59:09

directsound 接口与方法

天使怪盗Dick 发表于 2011-3-13 23:01:54

DX果然是浮云……浮云……触死我了

神符影之歌 发表于 2011-3-15 12:49:06

忙里偷闲回来看看,发现十二君又发有好物在这里呐

十二 发表于 2011-3-17 17:57:24

回复 神符影之歌 的帖子

算不上神马好物

#7
其实多翻翻MSDN和推推度娘一点也不触全是浮云+998

#4
喝茶君饶命

十二 发表于 2011-4-15 11:21:51



补一个 DirectInput的头文件和几个DX助手函数:

DirectInputCreate、DirectSoundCreate、Direct3DCreate。

Direct3DCreate获取IDirect3D接口指针。
DirectSoundCreate获取IDirectSound接口指针。
DirectInputCreate获取IDirectInput接口指针。

CoCreateInstance 下的CLSID值HEX下前64bit为反着的- =、后64bit为正着的- = 好囧。






页: [1] 2
查看完整版本: Directx 接口与方法