DirectX и Windows Runtime Component в WinRT

169

Механизм Р/Invoke хорошо подходит для обращения к различным функциям «плоского» Win32 API, но работа с DirectX — совсем другое дело. Работать с DirectX средствами P/Invoke неудобно, и это лучше всего делать из кода C++. Если вы хотите использовать DirectX из программы C#, напишите на C++ обертку Windows Runtime Component, содержащую весь код DirectX, после чего обратитесь к этой библиотеке из программы C#. Для небольших подмножеств DirectX вы можете сделать это самостоятельно; также можно воспользоваться более серьезными решениями — например, распространяемой с открытым кодом библиотекой SharpDX.

Логично спросить, не обманываете ли вы себя, работая с DirectX из программы C# через библиотеку-обертку? Одна из основных причин использования DirectX — быстродействие, которое часто определяется не только быстродействием самой библиотеки DirectX (не зависящим от языка, из которого она используется), но и быстродействием кода приложения. Код приложения обычно работает быстрее, если он написан на C++ вместо C# (несмотря на то, что C# ускоряет программирование и снижает количество ошибок). А это значит, что приложения DirectX можно полностью или частично писать на C++.

Библиотека DirectXWrapper, представленная далее, в высшей степени тривиальна. Я намеренно ограничил ее тремя конкретными задачами: получением списка шрифтов, установленных в системе, получением метрик конкретного шрифта и рисованием линий на объекте SurfaceImageSource. Объект SurfaceImageSource фактически представляет собой растровое изображение; просто вам не придется самостоятельно реализовать алгоритмы рисования линий.

Чтобы создать эту библиотеку в Visual Studio, я создал новое решение и проект с именем DirectXWrapper. В левом столбце диалогового окна New Project был выбран проект приложения Windows Store на C++. В центральной части диалогового окна я выбрал шаблон Windows Runtime Compoment. Такие библиотеки Windows 8 могут быть запрограммированы на одном языке (в данном случае C++), а работать с ними могут любые приложения Windows Store, включая написанные на C#, Visual Studio и JavaScript.

Из-за этой гибкости для библиотек Windows Runtime Component устанавливаются очень жесткие ограничения. Они не могут делать то, что не поддерживается хотя бы одним из этих языков. Важнейшие ограничения библиотек Windows Runtime Component:

Проекту DirectXWrapper необходимы ссылки на библиотеки C++, не включаемые по умолчанию. В окне Solution Explorer щелкните правой кнопкой на имени проекта и выберите команду Properties. На экране появляется диалоговое окно свойств DirectXWrapper. В верхней части окна расположено поле со списком Platform; выберите в нем вариант All Platforms. В левой части диалогового окна выберите Configuration Properties, Linker и Input. Открывшийся список начинается с поля Additional Dependencies. Щелкните на этом поле и выберите команду Edit. На экране появляется диалоговое окно Additional Dependencies. Добавьте в список три библиотеки DirectX:

Добавление библиотек в проект классов C++

Первые две библиотеки предназначены соответственно для вывода двумерной и трехмерной графики на SurfaceImageSource. Третья библиотека предназначена для Direct Write.

Библиотеке DirectXWrapper также необходим доступ к заголовочным файлам, связанным с этими библиотеками. Я включил необходимые заголовочные файлы в файл pch.h (precompiled headers, то есть «предварительно откомпилированные заголовки»):

#pragma once

#include <collection.h>
#include <ppltasks.h>
#include <wrl.h>
#include <d2d1_1.h>
#include <d3d11_1.h>
#include <dwrite.h>
#include <windows.ui.xaml.media.dxinterop.h>

Заголовочный файл wrl.h (сокращение от «Windows Runtime Library») содержит определения, необходимые для использования COM в приложениях Windows 8. В заголовочном файле windows.ui.xaml.media.dxinterop.h находится объявление интерфейса ISurfaceImageSourceNative, необходимого для использования класса SurfaceImageSource. Мы реализуем части этого проекта в последующих статьях, чтобы более подробно ознакомиться с работой с DirectX через C++.

Пройди тесты
Лучший чат для C# программистов