您没有找到引用的原因GraphicsDevice.Begin/EndScene()是因为这些方法不存在.的GraphicsDevice类是用于封装由XNA框架的用户所需的图形功能的托管类; 它不是本机IDirect3DDevice9接口的一对一映射.
我假设通过查看源代码,你的意思是使用像Reflector这样的东西,我也假设你把代码看作C#代码.要记住的一件重要事情是XNA框架的大部分是用C++/CLI编写的,因此当反映到C#时,结果可能有些不可预测.
对于调用本地的具体情况IDirect3DDevice9::BeginScene()和IDirect3DDevice9::EndScene(),你需要深入一点.
以下所有内容均假设为XNA 4.0.3.1应该仍然相似.在Reflector中,您会注意到GraphicsDevice该类具有私有bool _insideScene.如果你对此进行分析,你会看到它设置在不同的位置,例如GraphicsDevice.DrawPrimitives()通话.此方法的C#反射应使用以下代码设置此成员:
if (!this._insideScene)
{
    **(((int*) this.pComPtr))[0xa4](this.pComPtr);
    this._insideScene = true;
}
Run Code Online (Sandbox Code Playgroud)
这里的关键是**(((int*) this.pComPtr))[0xa4](this.pComPtr);.如果您要编写C++/CLI程序集,请包含相应的DirectX头文件(d3d9.h)并调用(即)BeginScene()的实例,然后在C#中反汇编程序集,您将拥有与上述相同的行.这就是本机调用的IL映射回C#的方式,但是不可能在C#中编写该行并进行编译.IDirect3DDevice9pDevice->BeginScene()
代码行本质上是一个原始的虚方法调用.您可以在此处阅读有关虚拟方法表的更多信息,但是针对这种情况,它的基本内容如下所示:对象的虚拟表指针(依赖于编译器,但在这种情况下为true)是本机对象中的第一个元素.pComPtr是一个指向本机COM IDirect3DDevice9对象的不安全指针.因此,dereferencing pComPtr(*pComPtr)为您提供指向虚方法表的指针.这里的反汇编有点模棱两可,但IL很清楚.接下来发生的事情0xa4是添加到虚方法表指针.要理解这一点,请记住本机数组只是指向数组第一个元素的指针.对象的虚方法表是一个函数指针数组.0xa4是十进制的164,意味着指针向前移动164个字节.由于库是一个x86库,指针长度为4个字节.这意味着我们已经转移到虚方法表(164 / 4 = 41)中的第41个方法.如果您查看(部分DirectX SDK)中的IDirect3DDevice9接口声明d3d9.h,您将看到第41个方法BeginScene.然后取消引用此指针以提供实际BeginScene方法,然后调用(通常是隐藏的)this指针作为第一个(也是唯一的)参数(this本机调用是this.pComPtr指针的位置).
您可以在私有不安全GraphicsDevice.Present()方法中看到类似的代码,这次偏移到0xa8,或者函数42,即IDirect3DDevice9::EndScene().
因此,您可以看到GraphicsDevice正确确保BeginScene在完成任何绘制EndScene之前IDirect3DDevice9::Present()调用它,并在调用本机方法之前调用它,但它故意将此功能隐藏在XNA框架的用户中.