Создание пакета игры DirectX универсальной платформы Windows (UWP)

Масштабные игры универсальной платформы Windows (UWP) (особенно те, которые поддерживают несколько языков и региональные ресурсы для них или включают дополнительные ресурсы высокого разрешения) могут легко раздуться до больших размеров. Из этой статьи вы узнаете, как настроить пакеты своего приложения таким образом, чтобы пользователи получали только необходимые им ресурсы.

Помимо модели пакета приложения Windows 10 поддерживает также пакеты приложений, которые включают два типа пакетов:

  • Пакеты приложения содержат исполняемые файлы и библиотеки для конкретных платформ. Как правило, игра UWP может содержать до трех пакетов приложений: по одному для архитектур ЦП x86, x64 и Arm. В этот пакет приложения должны быть включены все данные и код, относящиеся к соответствующей аппаратной платформе. Пакет приложения должен также включать все основные ресурсы, позволяющие запустить игру с базовым уровнем качества и производительности.
  • Пакеты ресурсов содержат дополнительные или расширенные данные, которые не зависят от платформы, например ресурсы игры (текстуры, сетки, звук и текст). У игры UWP может быть один или несколько пакетов ресурсов, включая пакеты для ресурсов и текстур высокого разрешения, ресурсов для уровня компонентов DirectX 11+ или ресурсов, которые требуются для определенного языка.

Дополнительные сведения о наборах приложения и пакетах приложения можно прочесть в разделе Определение ресурсов приложения.

Хотя все содержимое можно поместить в пакеты приложения, это неэффективно и делать этого не следует. Почему один и тот же большой файл текстуры реплицировался три раза для каждой платформы, особенно для платформ Arm, которые могут не использовать его? Стоит подумать о том, как свести к минимуму объем данных, скачиваемых клиентом, чтобы он мог раньше начать игру, сэкономить место на устройстве и избежать возможных затрат на оплату трафика.

Чтобы использовать эту функцию установщика приложений UWP, на ранних этапах разработки игры важно учитывать структуру каталогов, а также соглашения о наименовании приложения и пакета ресурсов. Благодаря этому инструменты и источник смогут правильно выводить их, что упростит упаковку. Следуйте правилам, указанным в данном документе, при разработке или настройке создания ресурсов и управлении инструментами и сценариями, а также при написании загружаемого кода или ссылочных ресурсов.

Зачем создавать пакеты ресурсов?

При создании приложений (особенно игр, которые могут продаваться в странах с разными языковыми стандартами или предназначаться для широкого спектра аппаратных платформ UWP) часто бывает необходимо включить несколько версий множества файлов для поддержки разных языковых стандартов или платформ. Например, если вы выпускаете игру в США и в Японии, вам может потребоваться один набор голосовых файлов на английском (en-us) и еще один — на японском (jp-jp). Или, если вы хотите использовать изображение в игре для устройств Arm, а также платформ x86 и x64, необходимо отправить один и тот же ресурс образа 3 раза, один раз для каждой архитектуры ЦП.

Кроме того, если в вашей игре много ресурсов высокого разрешения, которые неприменимы к платформам с более низкими уровнями компонентов DirectX, зачем включать их в базовый пакет приложения и заставлять пользователя скачивать большой объем компонентов, которые его устройство не может использовать? Отделив эти ресурсы высокого разрешения и поместив их в дополнительный пакет ресурсов, вы предоставите клиентам с устройствами, поддерживающими такие ресурсы, возможность получить их (возможно, по сети с платным трафиком). В то же время те, у кого нет устройств подобного класса, смогут быстрее получить свою игру и снизить затраты на трафик.

Существуют следующие кандидаты содержимого для пакетов игровых ресурсов:

  • международные ресурсы с определенными языковыми параметрами (локализованный текст, аудиозаписи или изображения);
  • ресурсы высокого разрешения для различных коэффициентов масштабирования устройства (1,0, 1,4 и 1,8);
  • ресурсы высокого разрешения для верхних функциональных уровней DirectX (9, 10 и 11).

Все они определяются в файле package.appxmanifest, который включен в состав проекта UWP и структуру каталогов вашего конечного пакета. Благодаря новому пользовательскому интерфейсу Visual Studio, если вы придерживаетесь процесса, описанного в данном документе, вам не нужно редактировать указанный файл вручную.

Важно Загрузка этих ресурсов и управление ими осуществляется с помощью API Windows.ApplicationModel.Resources*. Если вы используете эти API для ресурсов модели приложения при загрузке правильного файла для языковых параметров, коэффициента масштабирования или уровня компонентов DirectX, вам не нужно загружать свои ресурсы с помощью явных путей к файлам. Вместо этого вы предоставляете API ресурсов только с именем файла, относящегося к нужному ресурсу, и позволяете системе управления ресурсами получить правильный вариант ресурса для текущей платформы пользователя и конфигурации языковых параметров (которые можно указать как напрямую, так и с помощью тех же самых API).

Ресурсы для упаковки ресурсов указываются одним из двух способов.

  • Файлы ресурсов имеют одно и то же имя файла, и версии для пакета ресурсов размещаются в определенных именованных каталогах. Имена этих каталогов зарезервированы системой. Например, \en-us, \scale-140, \dxfl-dx11.
  • Файлы ресурсов хранятся в папках с произвольными именами, но имена файлов задаются с общей меткой, которая добавляется к строкам, зарезервированным системой, для обозначения языка или других квалификаторов. В частности, строки квалификатора прикрепляются к универсальному имени файла после символа подчеркивания ("_"). Например, \assets\menu_option1_lang-en-us.png, \assets\menu_option1_scale-140.png, \assets\coolsign_dxfl-dx11.dds. Вы также можете объединять эти строки. Например, \assets\menu_option1_scale-140_lang-en-us.png.

    Примечание При использовании в имени файла, а не только в имени каталога, квалификатор языка должен иметь вид "lang-tag<>", например "lang-en-us", как описано в разделе Настройка ресурсов для языка, масштаба и других квалификаторов.

Имена каталогов можно комбинировать, чтобы упаковка ресурсов стала более избирательной. Однако они не должны быть слишком длинными. Например, \en-us\menu_option1_lang-en-us.png является избыточным.

Вы можете указывать любые незарезервированные имена подкаталогов, которые должны быть включены в каталог ресурсов, если структуры всех каталогов ресурсов совпадают. Например, \dxfl-dx10\assets\textures\coolsign.dds. Когда вы загружаете ресурс или ссылаетесь на него, имя пути должно быть универсальным, без каких-либо квалификаторов языка, масштаба или уровня компонентов DirectX, вне зависимости от того, входят они в узлы папок или же в имена файлов. Например, чтобы ссылаться в коде на ресурс, один из вариантов которого — \dxfl-dx10\assets\textures\coolsign.dds, используйте \assets\textures\coolsign.dds. Аналогичным образом, чтобы ссылаться на ресурс с \images\background_scale-140.png варианта, используйте \images\background.png.

Ниже приводятся зарезервированные имена каталогов и префиксы для имен файлов с символом подчеркивания.

Тип ресурса Имя каталога для пакета ресурсов Суффикс имени файла для пакета ресурсов
Локализованные ресурсы Все возможные языки или сочетания языков и языковых стандартов для Windows 10. (Префикс квалификатора «lang-» в имени папки не обязателен.) Значение "_", за которым следует описатель языка, языкового стандарта или языкового стандарта. Например, "_en", "_us" или "_en-us" соответственно.
Ресурсы коэффициента масштабирования scale-100, scale-140, scale-180. Эти ресурсы относятся к коэффициентам масштабирования пользовательского интерфейса 1,0, 1,4 и 1,8 соответственно. "_", за которым следует "scale-100", "scale-140" или "scale-180".
Ресурсы уровня компонентов DirectX dxfl-dx9, dxfl-dx10 и dxfl-dx11. Эти ресурсы относятся к уровням компонентов DirectX 9, 10 и 11 соответственно. Символ "_", за которым следует "dxfl-dx9", "dxfl-dx10" или "dxfl-dx11".

 

Определение локализованных пакетов языковых ресурсов

Файлы с определенными языковыми параметрами размещаются в каталогах проекта, носящих название языка (например, «en»).

При настройке вашего приложения для поддержки ресурсов, локализованных на несколько языков, необходимо сделать следующее.

  • Создайте подкаталог приложения (или версию файла) для каждого языка и языковых параметров, которые вы будете поддерживать (например, en-us, jp-jp, zh-cn, fr-fr и так далее).

  • Во время разработки поместите копии ВСЕХ ресурсов (например, локализованные аудиофайлы, текстуры и графику меню) в подкаталог соответствующего языка, даже если они не отличаются для разных языков и языковых параметров. Чтобы добиться наилучшего взаимодействия с пользователем, позаботьтесь об уведомлении пользователя в том случае, если он не получил доступный пакет языковых ресурсов для своих языковых параметров при наличии последнего (или если он случайно удалил его после скачивания и установки).

  • Убедитесь, что каждый ресурс или файл строкового ресурса (RESW-файл) одинаково называется в каждом каталоге. Например, menu_option1.png должно иметь одинаковое имя в каталогах \en-us и \jp-jp, даже если содержимое файла предназначено для другого языка. В этом случае вы увидите их как \en-us\menu_option1.png и \jp-jp\menu_option1.png.

    Примечание При необходимости к имени файла можно добавить языковой стандарт и сохранить их в том же каталоге; например, \assets\menu_option1_lang-en-us.png, \assets\menu_option1_lang-jp-jp.png.

     

  • Используйте API в Windows.ApplicationModel.Resources и Windows.ApplicationModel.Resources.Core, чтобы указать и загрузить ресурсы с определенными языковым стандартом для своего приложения. Используйте также ссылки на ресурсы, которые не включают определенный языковой стандарт, поскольку эти API определяют правильный языковой стандарт на основе параметров пользователя и затем извлекают подходящий ресурс для пользователя.

  • В Microsoft Visual Studio 2015 выберите PROJECT-Store-Create>> App Package... и создайте пакет.

Определение пакетов ресурсов для коэффициентов масштабирования

В Windows 10 предусмотрены три коэффициента масштабирования пользовательского интерфейса: 1,0, 1,4 и 1,8. Коэффициенты масштабирования для каждого экрана задаются во время установки, исходя из ряда взаимосвязанных факторов: размера экрана, разрешения экрана и предполагаемого среднего расстояния между пользователем и экраном. Пользователь также может настраивать коэффициенты масштабирования, чтобы повысить удобочитаемость. Чтобы обеспечить наилучшее взаимодействие, ваша игра должна быть поддерживающей определение DPI и коэффициент масштабирования. Помимо прочего это означает, что нужно создавать версии критически важных визуальных ресурсов для каждого из трех коэффициентов масштабирования. Это также относится к взаимодействию с указателем и проверке наличия данных в кэше.

Настраивая свое приложение с целью поддержки пакетов ресурсов для различных коэффициентов масштабирования приложения UWP, необходимо сделать следующее.

  • Создайте подкаталог приложения (или версию файла) для каждого коэффициента масштабирования, который планируется поддерживать (scale-100, scale-140 и scale-180).

  • Во время разработки поместите копии ВСЕХ ресурсов, относящихся к коэффициентам масштабирования в каждый каталог ресурсов для коэффициента масштабирования, даже если они одинаковы для разных коэффициентов.

  • Убедитесь, что каждый ресурс одинаково называется в каждом каталоге. Например, menu_option1.png должны иметь одинаковое имя в каталогах \scale-100 и \scale-180, даже если содержимое файла отличается. В этом случае вы увидите их как \scale-100\menu_option1.png и \scale-140\menu_option1.png.

    Примечание Опять же, при необходимости можно добавить суффикс коэффициента масштабирования к имени файла и сохранить их в том же каталоге; например, \assets\menu_option1_scale-100.png, \assets\menu_option1_scale-140.png.

     

  • Используйте API в Windows.ApplicationModel.Resources.Core для загрузки ресурсов. Ссылки на ресурсы должны быть обобщенными (без суффиксов), без конкретных вариантов масштаба. Система извлечет соответствующий ресурс для дисплея и параметров пользователя.

  • В Visual Studio 2015 выберите PROJECT-Store-Create>> App Package... и создайте пакет.

Определение пакетов ресурсов для функциональных уровней DirectX

Уровни компонентов DirectX соотносятся с наборами компонентов GPU для прошлых и текущей версий DirectX (в частности, Direct3D). В их число входят спецификации и функциональные возможности модели шейдеров, поддержка языка программирования шейдеров, поддержка сжатия текстур и общие возможности графического конвейера.

В вашем базовом пакете приложения должны использоваться основные форматы сжатия текстур: BC1, BC2 или BC3. Эти форматы могут использоваться любым устройством UWP, от низкоуровневых платформ Arm до выделенных рабочих станций с несколькими GPU и мультимедийных компьютеров.

Поддержка формата текстур на уровне компонентов DirectX 10 или более поздней версии должна быть добавлена в пакет ресурсов для экономии места на локальном диске и пропускной способности загрузки. Это позволяет воспользоваться более современными схемами сжатия для уровня 11 (например, BC6H и BC7). (Дополнительные сведения см. в разделе Сжатие блока текстуры в Direct3D 11.) Эти форматы более эффективны для ресурсов с текстурами высокого разрешения, поддерживаемых современными GPU. Их использование улучшает внешний вид игры, повышает ее производительность и снижает требования к свободному дисковому пространству на современных платформах.

Функциональный уровень DirectX Поддерживаемое сжатие текстур
9 BC1, BC2, BC3
10 BC4, BC5
11 BC6H, BC7

 

Кроме того, каждый функциональный уровень DirectX поддерживает различные версии модели построителя текстуры. Скомпилированные ресурсы построителя текстуры можно создавать для каждого функционального уровня и включать в пакеты ресурсов для функционального уровня DirectX. Помимо этого, некоторые последние версии моделей построителя текстуры могут использовать такие ресурсы, как карты нормалей, которые не используются в более ранних версиях моделей построителя текстуры. Эти ресурсы, относящиеся к модели построителя текстуры, должны быть также включены в пакет ресурсов для функционального уровня DirectX.

Механизм ресурсов в основном имеет дело с форматами текстур, поддерживаемыми ресурсами. Поэтому он поддерживает только 3 общих функциональных уровня. Если вам нужны отдельные шейдеры для подуровневых (точечная версия), например DX9_1 и DX9_3, код управления ресурсами и отрисовки должен обрабатывать их явным образом.

Настраивая свое приложение с целью поддержки пакетов ресурсов для различных функциональных уровней DirectX, необходимо сделать следующее.

  • Создайте подкаталог приложения (или версию файла) для каждого функционального уровня DirectX, который планируется поддерживать (dxfl-dx9, dxfl-dx10 и dxfl-dx11).

  • Во время разработки поместите ресурсы, относящиеся к уровню компонентов, в каждый каталог ресурсов для уровня компонентов. В отличие от ситуации с языковыми стандартами и коэффициентами масштабирования, у вас могут быть различные ветви кода отрисовки для каждого уровня компонентов в игре. А если у вас есть текстуры, скомпилированные построители текстуры или другие ресурсы, которые применяются только на одном уровне компонентов или в подмножестве всех поддерживаемых уровней компонентов, поместите соответствующие ресурсы только в те каталоги, которые относятся к использующим их уровням компонентов. Если речь идет о ресурсах, которые загружаются для всех уровней компонентов, убедитесь, что в каждом каталоге ресурсов для уровня компонентов имеется одноименная версия ресурса. Например, для независимой текстуры уровня компонентов с именем "coolsign.dds" поместите версию, со сжатием BC3, в каталог \dxfl-dx9, а версию со сжатием BC7 — в каталог \dxfl-dx11.

  • Убедитесь, что каждый ресурс (если он доступен для нескольких уровней компонентов) имеет одно и то же имя в каждом каталоге. Например, у coolsign.dds должно быть одинаковое имя в каталогах \dxfl-dx9 и \dxfl-dx11, даже если содержимое файла отличается. В этом случае они будут отображаться как \dxfl-dx9\coolsign.dds и \dxfl-dx11\coolsign.dds.

    Примечание При необходимости можно добавить суффикс уровня компонентов к имени файла и сохранить их в том же каталоге. Например, \textures\coolsign_dxfl-dx9.dds, \textures\coolsign_dxfl-dx11.dds.

     

  • Объявите поддерживаемые уровни компонентов DirectX во время настройки графических ресурсов.

    D3D_FEATURE_LEVEL featureLevels[] = 
    {
      D3D_FEATURE_LEVEL_11_1,
      D3D_FEATURE_LEVEL_11_0,
      D3D_FEATURE_LEVEL_10_1,
      D3D_FEATURE_LEVEL_10_0,
      D3D_FEATURE_LEVEL_9_3,
      D3D_FEATURE_LEVEL_9_1
    };
    
    ComPtr<ID3D11Device> device;
    ComPtr<ID3D11DeviceContext> context;
    D3D11CreateDevice(
        nullptr,                    // Use the default adapter.
        D3D_DRIVER_TYPE_HARDWARE,
        0,                      // Use 0 unless it is a software device.
        creationFlags,          // defined above
        featureLevels,          // What the app will support.
        ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION,      // This should always be D3D11_SDK_VERSION.
        &device,                    // created device
        &m_featureLevel,            // The feature level of the device.
        &context                    // The corresponding immediate context.
    );
    
  • Используйте API в Windows.ApplicationModel.Resources.Core для загрузки ресурсов. Ссылки на ресурсы должны быть обобщенными (без суффиксов), без уровня компонентов. Однако в отличие от языка и масштаба, система не определяет автоматически оптимальный уровень компонентов для определенного экрана. Это должны определить вы сами на основе логики кода. После этого используйте API, чтобы информировать ОС о предпочитаемом уровне компонентов. Тогда система сможет извлечь подходящий ресурс на основе этого предпочтения. Вот пример кода, который показывает, как сообщить приложению о текущем уровне компонентов DirectX для платформы:

    // Set the current UI thread's MRT ResourceContext's DXFeatureLevel with the right DXFL. 
    
    Platform::String^ dxFeatureLevel;
        switch (m_featureLevel)
        {
        case D3D_FEATURE_LEVEL_9_1:
        case D3D_FEATURE_LEVEL_9_2:
        case D3D_FEATURE_LEVEL_9_3:
            dxFeatureLevel = L"DX9";
            break;
        case D3D_FEATURE_LEVEL_10_0:
        case D3D_FEATURE_LEVEL_10_1:
            dxFeatureLevel = L"DX10";
            break;
        default:
            dxFeatureLevel = L"DX11";
        }
    
        ResourceContext::SetGlobalQualifierValue(L"DXFeatureLevel", dxFeatureLevel);
    

Примечание

В коде загрузите текстуру непосредственно по имени (или по пути ниже каталога уровня компонентов). Не включайте имя каталога или суффикс уровня компонентов. Например, загрузите "textures\coolsign.dds", а не "dxfl-dx11\textures\coolsign.dds" или "textures\coolsign_dxfl-dx11.dds".

  • Теперь используйте ResourceManager , чтобы найти файл, соответствующий текущему уровню компонентов DirectX. ResourceManager возвращает элемент ResourceMap, запрашиваемый в методе ResourceMap::GetValue (или ResourceMap::TryGetValue) и предоставленный объект ResourceContext. В результате этого возвращается ResourceCandidate, который максимально соответствует уровню компонентов DirectX, указанному путем вызова SetGlobalQualifierValue.

    // An explicit ResourceContext is needed to match the DirectX feature level for the display on which the current view is presented.
    
    auto resourceContext = ResourceContext::GetForCurrentView();
    auto mainResourceMap = ResourceManager::Current->MainResourceMap;
    
    // For this code example, loader is a custom ref class used to load resources.
    // You can use the BasicLoader class from any of the 8.1 DirectX samples similarly.
    
    
    auto possibleResource = mainResourceMap->GetValue(
        L"Files/BumpPixelShader.cso",
        resourceContext
    );
    Platform::String^ resourceName = possibleResource->ValueAsString;
    
  • В Visual Studio 2015 выберите PROJECT-Store-Create>> App Package... и создайте пакет.

  • Убедитесь, что вы включили пакеты приложений в настройках манифеста package.appxmanifest.