Xna框架问题

Xna框架问题,xna,directx,Xna,Directx,我在看Xna Framework游戏类的源代码,特别是它如何进行Draw调用,我可以在中看到对GraphicsDevice.Present()的调用 GraphicsDeviceManager.EndDraw(),但找不到对GraphicsDevice.BeginScene()或 GraphicsDevice.EndScene(),甚至不在GraphicsDevice类本身中。任何人都知道他们是如何处理这种情况的。您没有找到对GraphicsDevice.Begin/EndScene()的引用的

我在看Xna Framework游戏类的源代码,特别是它如何进行Draw调用,我可以在中看到对GraphicsDevice.Present()的调用 GraphicsDeviceManager.EndDraw(),但找不到对GraphicsDevice.BeginScene()或
GraphicsDevice.EndScene(),甚至不在GraphicsDevice类本身中。任何人都知道他们是如何处理这种情况的。

您没有找到对
GraphicsDevice.Begin/EndScene()
的引用的原因是这些方法不存在。
GraphicsDevice
类是一个托管类,用于封装XNA框架用户所需的图形功能;它不是本机
IDirect3DDevice9
接口的一对一映射

我假设通过查看源代码,您的意思是使用类似Reflector的东西,我还假设您将代码视为C代码。需要记住的一件事是,XNA框架的大部分是用C++/CLI编写的,因此,当反映到C#时,结果可能有些不可预测

对于调用本机
IDirect3DDevice9::BeginScene()
IDirect3DDevice9::EndScene()
的特定情况,您需要深入研究一下

以下所有假设均为XNA 4.0。3.1仍应类似。在Reflector中,您会注意到
GraphicsDevice
类有一个私有
bool
\u insideScene
。如果您对此进行分析,您将在不同的位置看到它的设置,例如
GraphicsDevice.DrawPrimitives()
调用。此方法的C#反射应使用以下代码设置此成员:

if (!this._insideScene)
{
    **(((int*) this.pComPtr))[0xa4](this.pComPtr);
    this._insideScene = true;
}
这里的关键行是
**((int*)this.pComPtr))[0xa4](this.pComPtr)。如果您要编写一个C++/CLI程序集,包括适当的DirectX头(
d3d9.h
)并在
IDirect3DDevice9
(即
pDevice->BeginScene()
)的实例上调用
BeginScene()
),然后在C#中反汇编程序集,您将有一行与上面相同的代码。这就是本机调用的IL映射回C#的方式,但不可能用C#编写该行并编译它

代码行本质上是一个原始的虚拟方法调用。您可以阅读有关虚拟方法表的更多信息,但在这种情况下,其要点如下:对象的虚拟表指针(依赖于编译器,但在这种情况下为true)是本机对象中的第一个元素
pComPtr
是指向本机COM
IDirect3DDevice9
对象的不安全指针。因此,取消引用
pComPtr
*pComPtr
)将为您提供指向虚拟方法表的指针。disassembly在这里有点模棱两可,但IL是相当清楚的。接下来将
0xa4
添加到虚拟方法表指针。要理解这一点,请记住本机数组只是指向数组第一个元素的指针。对象的虚拟方法表是一个函数指针数组
0xa4
是十进制的164,表示指针向前移动了164字节。由于该库是x86库,指针的长度为4字节。这意味着我们已经移动到虚拟方法表中的第41个方法(
164/4=41
)。如果查看
d3d9.h
(DirectX SDK的一部分)中的
IDirect3DDevice9
接口声明,您将看到第41个方法是
BeginScene
。然后取消对该指针的引用以给出实际的
BeginScene
方法,然后调用该指针作为第一个(也是唯一一个)参数传入(通常隐藏的)
This
指针(其中本机调用的
This
This.pComPtr
指针)

您可以在private unsafe
GraphicsDevice.Present()
方法中看到类似的代码,这次偏移为
0xa8
,或者偏移为函数42,即
IDirect3DDevice9::EndScene()


因此,您可以正确地看到
GraphicsDevice
确保在完成任何绘图之前调用了
BeginScene
,并且在调用本机
IDirect3DDevice9::Present()
方法之前调用了
EndScene
,但它故意对XNA框架的用户隐藏了此功能。

,问题是什么?不精确,就是这样。我想问你一些事情,我正在尝试在C++中组装一个游戏编程框架,但是我喜欢XNA的工作方式,所以我所做的就是尝试在我的框架中编写相同的功能。这是否错误,是否有任何法律影响?是的,我正在使用DotNetReflector