DirectX. Использование возможностей ОС по выводу графики
Работа с интерфейсами
DirectX основан на технологии COM (Component Object Model - Компонентная Модель Объектов) . Возможно, эта технология имеет ряд преимуществ и упрощает жизнь разработчику подобных продуктов, в данном случае тем, кто разрабатывал DirectX, однако для пользователей это означает дополнительное изучение порядка работы с такой моделью.
Основная идея COM заключается в работе с указателями на виртуальную таблицу функций. В терминологии DirectX вместо слова функция используется понятие интерфейс и методы. Приблизительная схема организации таких таблиц изображена на рисунке:
Из рисунка видно, что имеется указатель на таблицу интерфейсов, каждая ячейка которой в свою очередь содержит указатели на методы того или иного интерфейса в отдельности. Очевидно, что вызов нужного метода напрямую невозможен. Только произведя некоторые манипуляции с указателем, появляется возможность до него добраться. Порядок таких манипуляций можно описать следующими действиями:
1. Создать объект
2. Получить указатель на соответствующий интерфейс этого объекта.
3. Используя данный указатель вызвать нужный метод.
Создав один раз объект, и получив указатель на нужный интерфейс, можно сколь угодно вызывать необходимые методы.
Если в языке C++ данный механизм реализован в таком виде:
// Создали объект и получили указатель на интерфейс IDirect3D9
pd3d9 = Direct3DCreate9 (D3D_SDK_VERSION);
// Вызвали метод CreateDevice
pd3d9 -> CreateDevice (arg1, arg2, arg3, arg4, arg5, arg6, arg7);
То в ассемблере это будет выглядеть так:
invoke Direct3DCreate9, D3D_SDK_VERSION ; Создали объект
mov pd3d9, eax ; получили указатель
push arg7
push arg6
push arg5
push arg4
push arg3
push arg2
push arg1
push pd3d9
mov eax, pd3d9
mov eax, [eax]
call dword ptr [eax+3Ch]
Смысл команд, приведенных выше, сводится к занесению данных для метода CreateDevice в стек; получению указателя на таблицу методов, используя указатель на интерфейс; и вызов самого метода CreateDevice. При этом число 3Ch является просто-напросто порядковым номером CreateDevice в таблице указателей на методы, умноженным на четыре.
Подобные операции с вычислением истинного адреса метода способны отбить желание работать на ассемблере с COM моделью. Избежать этого можно используя макрос d3d9.
Программа, которая совершает то же самое, что и указанная выше, но уже с использованием такого макроса:
invoke Direct3DCreate9, D3D_SDK_VERSION ; Создали объект
mov pd3d9, eax ; получили указатель
d3d9 CreateDevice, pd3d9, Arg1, ... , Arg7
Макрос автоматически выполняет всю рутинную работу за нас, и вызов метода выглядит почти также как вызов обычной функции API Windows. [5]
Макросы d3dev9, d3dxmesh тем же образом позволяют обращаться к методам соответствующих классов.