Xna Framework Вопрос - PullRequest
       7

Xna Framework Вопрос

0 голосов
/ 22 августа 2011

Я смотрел на исходный код класса Xna Framework Game, в частности, как он выполняет вызовы Draw, я мог видеть вызов GraphicsDevice.Present () в GraphicsDeviceManager.EndDraw (), но я не смог найти вызовы GraphicsDevice.BeginScene () или GraphicsDevice.EndScene (), даже не в самом классе GraphicsDevice. Кто-нибудь знает, как они справляются с этой ситуацией.

1 Ответ

7 голосов
/ 22 августа 2011

Причина, по которой вы не нашли ссылок на 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;
}

Ключевая строка здесь - **(((int*) this.pComPtr))[0xa4](this.pComPtr);.Если бы вы написали сборку C ++ / CLI, включили соответствующие заголовки DirectX (d3d9.h) и вызвали BeginScene() в экземпляре IDirect3DDevice9 (то есть pDevice->BeginScene()), а затем разобрали вашу сборку в C #, вы бы получилилиния, идентичная вышеупомянутой.Вот как IL для нативного вызова отображается обратно в C #, , но невозможно написать эту строку в C # и скомпилировать ее .

Строка кода по сути является необработанной виртуальнойвызов метода.Вы можете прочитать более подробную информацию о таблицах виртуальных методов здесь , но для этой ситуации необходимо следующее: указатель виртуальной таблицы объекта (зависимый от компилятора, но истинный в этой ситуации) первый элементв родном объекте.pComPtr - это небезопасный указатель на собственный объект COM IDirect3DDevice9.Следовательно, разыменование pComPtr (*pComPtr) дает указатель на таблицу виртуальных методов.Разборка здесь немного неоднозначна, но ИЛ довольно ясен.Далее происходит добавление 0xa4 к указателю таблицы виртуальных методов.Чтобы понять это, помните, что собственные массивы - это просто указатель на первый элемент массива.Таблица виртуальных методов объекта - это массив указателей на функции.0xa4 - 164 в десятичном виде, что означает, что указатель перемещается на 164 байта вперед.Поскольку библиотека является библиотекой x86, указатели имеют длину 4 байта.Это означает, что мы перешли к 41-му методу в таблице виртуальных методов (164 / 4 = 41).Если вы посмотрите на объявление интерфейса IDirect3DDevice9 в d3d9.h (часть DirectX SDK), вы увидите, что 41-й метод - BeginScene.Этот указатель затем разыменовывается, чтобы получить фактический метод BeginScene, а затем вызывается, передавая (обычно скрытый) указатель this в качестве первого (и единственного) параметра (где this для собственного вызова - this.pComPtrуказатель).

Подобный код можно увидеть в закрытом небезопасном методе GraphicsDevice.Present(), на этот раз со смещением 0xa8 или в функции 42, равной IDirect3DDevice9::EndScene().

Поэтому выможно увидеть, что GraphicsDevice правильно гарантирует, что BeginScene был вызван до того, как будет выполнено любое рисование, и EndScene вызывается до того, как вызывается собственный метод IDirect3DDevice9::Present(), но он намеренно скрывает эту функциональность от пользователей платформы XNA.

...