Quantcast
Channel: Статьи Intel Developer Zone
Viewing all 357 articles
Browse latest View live

Преобразование пользовательского интерфейса: проектирование интерфейса будущего (1 из 5) Технология Intel® RealSense™ для разработчиков игр

$
0
0

Download PDF

Способы нашего взаимодействия с играми (и способы взаимодействия игр с нами) постоянно изменяются по мере появления новых технологий и новых возможностей. В отрасли компьютерных игр всегда быстро применяли потенциал новых интерактивных технологий. Развитие новых видов интерфейсов идет постоянно, и разработчики игр готовятся осваивать новые интересные идеи и технологии. Одна из таких перспективных технологий — Intel® RealSense™, сочетающая трехмерную камеру и усовершенствованное распознавание речи. С помощью Intel® RealSense™ SDK (бета-версия) разработчики только начинают изучать потенциал этой технологии для создания увлекательных игр, намного опережающих классические аппаратные контроллеры по возможностям интерактивности.

Эта статья (первая в серии из пяти статей о компьютерных системах с использованием перцептивных вычислений и о технологии Intel RealSense) содержит рассказ наших разработчиков, благодаря которым эта технология и увидела свет.

Изменение облика воображаемого мира

«Управление с помощью жестов интересно нам для создания ощущения преобразования и возможности использовать тактильные взаимодействия между вами и экраном компьютера», — говорит Робин Ханике из компании Funomena, описывая готовящуюся к выпуску игру на основе технологии Intel RealSense.

Funomena

Будучи убежденным сторонником положительного влияния игр, Ханике приняла участие в основании компании Funomena в 2013 году. Одна из целей этой компании состоит в изучении пределов эмоционального взаимодействия между игроками и технологиями. «В нашей игре персонаж идет по пути преобразования индивидуальности. На концепцию игры серьезно повлияло искусство оригами. Нам нравится, что камера может обнаруживать мельчайшее изменение положения рук игрока». Высокая точность отслеживания жестов расширяет возможности ввода. Технология Intel RealSense дает играм возможность очень точно реагировать на то, как именно игроки будут двигаться перед камерой. «Мы можем использовать эту информацию, чтобы игроки могли обращаться с объек­тами в реальном времени».

Эта игра пока не представлена для открытого ознакомления, но известно, она опирается на высокую точность камеры Intel® RealSense™ 3D для распознавания жестов; игроки будут напрямую взаимо­дей­ствовать с игровым миром, по-новому изучать загадки и головоломки в игре. «Нас всегда интересовала возможность расширить границы того, что может выразить игра. Мы создаем то, что бросает вызов вашим ощущениям, но при этом активно принимаем вашу реакцию как игрока. Вам понадобится в буквальном смысле собственными руками раскрывать загадки этого мира одну за другой и изменять каждый уровень в соответствии с вашим пониманием того, как должен выглядеть результат», — заявила Ханике.

Основы движения

Израильская компания Side-Kick Games уже несколько лет работает с контроллерами на основе распознавания движений, включая двухмерные веб-камеры (с помощью промежуточных систем PointGrab*, XTR* и EyeSight*), Kinect* и PrimeSense*. Благодаря накопленным знаниям внедрение технологии Intel RealSense оказалось весьма несложным процессом.

«Мы построили в наших играх уровень для контроллера движений, поэтому у нас много интерфейсов для обработки сигналов от промежуточных систем и стандартный интерфейс для управления движениями, — поясняет Таль Равив, операционный директор компании. — С помощью этой инфраструктуры и нашего опыта в области управления движением переход на технологию Intel RealSense с управления движением всем телом как на большом, так и на маленьком расстоянии прошел довольно гладко. Интерфейс технологии Intel RealSense очень прост и обладает отличными возможностями для отслеживания. По сравнению с другими технологиями пришлось преодолевать намного меньше затруднений».

В перспективной игре Warrior Wave компании Side-Kick игроки используют движения рук, чтобы укрыть солдат и защитить их от противника. Разработчики использовали разные функции технологии Intel RealSense в соответствии с игровым контекстом. «Мы используем два типа элементов управления. Первая часть — «силуэт». Это часть SDK, которая позволяет игре «видеть» руку, но не «знает», как она устроена (ладонь, пальцы). Отслеживаемая часть SDK — «скелет», она дает информацию о структуре руки (расположение каждого кончика пальца и середины ладони), — продолжает Равив. — Базовая механика игры работает с «силуэтом», но другие компоненты, такие как меню, работают со «скелетом».

Warrior Wave

Компания Side-Kick Games также заботится о том, чтобы технология Intel RealSense применялась в подходящем для нее контексте. Другие технологии используются в игре Warrior Waveвместе с ней для достижения оптимального удобства. «Игроки используют сенсорный экран для переходов по меню и включения различных функций, поскольку этот метод наиболее интуитивен. Управление движением применяется в игре для достижения более глубокого погружения в ее атмосферу, поскольку игрок не привязан к традиционной клавиатуре и мыши, — поясняет Равив. — Такое сочетание оптимально для игроков. В будущем сочетание голосового управления и управления движением будет играть более важную роль в пользовательском интерфейсе, но основное преимущество управления движением сейчас раскрывается в самой игре».

Выполнение приказов

Команда разработчиков Iridium Studios использует и управление движениями, и распознавание речи Intel RealSense для создания более реалистичного интерфейса для создаваемой игры There Came an Echo. в жанре стратегии реального времени. «В прошлом, управляя в стратегии в реальном времени небольшой группой боевых единиц, обычно мы использовали мышь, — говорит Джейсон Вишнов, основатель компании Iridium. — Но в реальном мире мы же не рисуем в воздухе воображаемый прямоугольник вокруг группы людей, чтобы заставить их идти. С людьми нужно общаться, а для этого мы используем жесты и голос».

В игре There Came an Echoголосовые команды крайне важны для реалистичного игрового процесса с высокой степенью вовлечения. Использование точных голосовых команд создает весьма интересный игровой процесс, более похожий на реальную жизнь. Впрочем, для Джейсона не менее важны и преимущества распознавания речи для игрового сюжета. «Мы потратили немало времени и сил на создание сценария и формирование персонажей, подобных обычным людям, каждый с настоящей мотивацией, настоящим страхом и изъянами характера. Распознавание речи помогает игроку лучше понять игровых персонажей, их характеры и роли в сценарии», — говорит Вишнов.

There Camean Echo

Возможности распознавания движений камерой Intel RealSense 3D сами по себе позволяют отдавать неголосовые команды в обстановке тактического боя, имитируемого в игре. «Некоторые жесты руками, используемые в войсках, можно связать напрямую с игровыми командами, и это очень интересно. Например, можно отдать команду впередили цель, сжав кулак, можно управлять движением солдат, поднимая руку - это очень здорово», — говорит Вишнов.

Впрочем, помимо точности самой технологии, ее удобство во многом зависит от контекста, в котором находится игрок. «Если просто взять и применить в игре набор жестов (не потому что это там нужно, а просто потому что у вас есть такая возможность), то игроки будут путаться, теряться и утрачивать ощущение связи с игрой, — говорит Вишнов. — Очень важно добиться того, чтобы жесты были правильными и естественными».

Измерение пульса

Одним из проектов, способных служить примером детализации и точности трехмерной камеры Intel RealSense, является приключенческая игра Nevermind с расширенной биологической обратной связью. В этой игре, которая будет выпущена компанией Flying Mollusk, игрок действует в качестве оператора «нейрозонда», способного путешествовать по разуму жертв психологических травм, решать головоломки и преодолевать защитные механизмы мозга, чтобы восстанавливать психическое здоровье пострадавших. Игра определяет стрессовое состояние игрока с помощью технологии биологической обратной связи. При обнаружении стресса среда динамически реагирует на страх игрока; по мере усиления беспокойства уровни стресса становятся все более сложными. Напротив, если игрок расслабляется, игра Nevermindприобретает более мягкий характер. За счет этого игра Nevermindпомогает игрокам внимательнее отслеживать свое стрессовое состояние и справляться с ним как в игре, так и в реальном мире.

Nevermind

«Меня всегда интересовали возможности биологической обратной связи в играх», — говорит Эрин Рейнольдс, творческий директор компании Flying Mollusk. Она с 2009 года изучает вопросы применения биологической обратной связи для построения более тесной взаимосвязи между игроком и игрой. Существовали разные варианты биологической обратной связи, но ни один из них не был достаточно пригоден для большинства потребителей. Технология Intel RealSense меняет такое положение.

«Камера Intel RealSense 3D может измерять пульс, а мы с этой помощью определяем стресс и страх игрока. На этом построена вся игра Nevermind , — говорит Эрин. — До этого игрокам в Nevermindприходилось надевать под одежду нагрудный ремень с датчиком пульса. А теперь, благодаря камере, они могут просто сесть за компьютер и играть. Так гораздо удобнее и интуитивнее».

Способность камеры Intel RealSense 3D измерить пульс, просто «глядя» на голову человека, открывает целый мир возможностей, поражающих воображение Эрин Рейнольдс. «Это означает, что разработчики могут сделать биологическую обратную связь важной частью своей продукции, будь то игры, медицинские системы или приложения для связи, — говорит она. — Все это чрезвычайно увлекательные возможности».

«Еще одна функция биологической обратной связи камеры — определение эмоций. Эта возможность очень нравится разработчикам, у нее огромный потенциал, чтобы изменить подход к тому, как мы будем играть в игры в будущем», — добавляет Чак Мак-Фадден, продукт-менеджер Intel, отвечающий за технологию Intel RealSense.

Новый уровень

Использование технологии Intel RealSense зависит от определенных нужд игры по созданию требуемых ощущений у игроков. Об этом свидетельствуют разные подходы этих разработчиков. Другие возможные области использования технологии Intel RealSense только открываются. «Мы проводим «хакатоны» и игровые конференции с использованием наших технологий, мы путешествуем по всему миру и общаемся с разработчиками игр, — говорит Мак-Фадден. — Мы даем разработчикам код и камеру Intel RealSense 3D и даем им полную свободу для творчества».

Корпорация Intel также проводит конкурс Intel® RealSense™ App challenge 2014 (по словам Мак-Фаддена, с миллионными призами), целью которого является поощрение изобретатели самых удачных, необычных и творческих идей использования новой технологии. «В числе предложенных были и такие идеи, которые лично я и представить бы себе не мог, например новый способ играть на музыкальных инструментах, — говорит Мак-Фадден. — Очень интересно наблюдать, как технология Intel RealSense выходит на новый уровень».

«Как разработчики, мы больше не загнаны в жесткие рамки соглашений тридцатилетней давности о том, как должен быть устроен интерфейс, — говорит Рейнольдс, подчеркивая преимущества технологии Intel RealSense. — Мы получили возможность увидеть нужды современного общества и изменить способ взаимодействия с компьютерами».

«Не знаю, сколько людей уже пользуются преимуществами этой новой технологии, — говорит Ханике о новых возможностях организации пользовательского интерфейса с помощью новой технологии Intel RealSense. — Мы на рубеже. Мы можем определять, какими будут эти интерфейсы, каким будет будущее. Мы можем задать контекст, создать эмоциональную связь с пользователями и вывести их из привычной зоны комфорта, — заключает Ханике. — Мы заставляем их привыкнуть к будущему».

Ресурсы и дополнительные сведения

Изучить технологию Intel® RealSense™, узнать о бета-версии Intel® RealSense™ SDK для Windows и заказать набор разработчика можно здесь.

Прочтите мнение о том, почему технология Intel RealSenseтак важна

Парить в воздухе без контроллера можно тут

Ваш проект готов к демонстрации? Станьте участником программы Intel® Software Innovator. Эта программа поддерживает разработчиков передовых проектов, дает возможность выступить с рассказом о своем проекте и устроить демонстрацию

Приступите к работе в центре ресурсов для разработчиков

 


Использование сенсорных жестов для управления параметрами физики в Unity* 3D с TouchScript

$
0
0

Download PDF

Автор: Линн Томпсон

При разработке игр и программ моделирования может понадобиться предоставить пользователям возможность управления ресурсами, которые используются в моделировании физики. Из этой статьи вы узнаете, как разрабатывать сцены Unity* 3D с настроенными сенсорными жестами для изменения физических характеристик используемых ресурсов, включая расположение, размер, массу и скорость. Эти изменения можно использовать для улучшения пользовательского интерфейса моделирования или для повышения эстетического качества сцены. В данном примере показана среда Unity 3D под управлением Windows* 8 в качестве удобной платформы для управления физическими характеристиками в играх и программах моделирования с помощью сенсорных жестов.

Настройка сцены Unity 3D

Я настроил геометрию этой сцены в Autodesk 3ds Max*. Я применил к поверхности волновой модификатор и модификатор изгиба; с одной стороны поверхности находится зеленая башня. Эту сцену я экспортировал из Autodesk 3ds Max в формате FBX, а затем импортировал в Unity 3D (см. рис. 1). Измененная поверхность с изгибом и волнами влияет на движение других ресурсов, добавляемых на сцену во время выполнения.

 


Примечание. Убедитесь, что геометрические объекты, импортируемые из сторонних приложений, не содержат настолько много фрагментов поверхностей, что движок Unity 3D будет перегружен или просто перестанет работать. В определенных средах разработки может указываться максимальное допустимое количество вершин и треугольников на каждый импортированный ресурс. Ресурсы в этом примере не используют никакие материалы, шейдеры и текстуры, но если такие ресурсы используются, следует учитывать их влияние на производительность целевой платформы разработки.


 


Рисунок 1. Башня с одной стороны поверхности, применены модификаторы изгиба и волн

Кроме того, с геометрией «отображение во время выполнения» импортированы сферы, которые не отображаются во время выполнения. Эти сферы я разместил над волнообразными выступами (см. рис. 2).

Рисунок 2. Поверхность с волнами, сферы не отрисовываются во время выполнения

Я использую расположение этих сфер в качестве места, откуда сферы будут попадать в сцену. Эти сферы я добавил программно, поэтому добавить их физические свойства нужно тоже програм­мно. Я делаю это с помощью следующего кода (обратите внимание, что имена 17 создающихся сфер - TargetSpawn[000 - 016]):


	int spawnPoint = 1;
	string spawnPointString = "";
	Vector3 spawnPosition = new Vector3(0.0f,0.0f,0.0f);
	Quaternion spawnRotation = new Quaternion(0.0f,0.0f,0.0f,0.0f);
	float spawnTime = 0.0f;


	void Update ()
	{



		spawnTime += Time.deltaTime;
		if(spawnTime > 1.0f)
		{
			spawnTime = 0.0f;

			if(spawnPoint == 17){spawnPoint = 1;}

			if(spawnPoint < 10){spawnPointString = "TargetSpawn00" + spawnPoint;}
			else{spawnPointString = "TargetSpawn0" +  spawnPoint;}

			GameObject spawnPointGO = GameObject.Find(spawnPointString);
			spawnPosition = spawnPointGO.transform.position;

			GameObject targetSphere = (GameObject)Instantiate
			 (GameObject.CreatePrimitive (PrimitiveType.Sphere),
			spawnPosition,spawnRotation);

			Color randomColor = new
			 Color(Random.value,Random.value,Random.value,1.0f);
			targetSphere.renderer.material.color = randomColor;


			targetSphere.collider.tag = "targetSphere";

			targetSphere.transform.localScale = new Vector3(10.0f,10.0f,10.0f);
			targetSphere.AddComponent ("Rigidbody");
			targetSphere.AddComponent ("GenericPan");
			targetSphere.AddComponent ("PanGesture");
			Destroy (targetSphere,60.0f);

			spawnPoint += 1;

		}
	}




При реализации приведенного выше сценария волнообразная основа заполняется твердыми физическими сферами, которые исчезают через 60 секунд (обратите внимание на вызов функции Destroy в предпоследней строке сценария). Можно настроить время до разрушения создаваемых сфер (в моем случае оно равно 60 секундам) на основе возможностей целевой платформы и нужных характеристик сцены. Башня в конце сцены настроена так, чтобы стрелять по капсулам, если они оказываются слишком близко. Эта башня не настроена для упреждающего сопровождения сфер и обычно промахивается (см. рис. 3).

Рисунок 3. Башня стреляет капсулами по создающимся твердым сферам

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

Прокрутка

IВ предыдущем разделе я программно применил сценарий GenericPan к созданным сферам.
Этот сценарий GenericPan позволяет пользователям передвигать сферу с помощью жеста прокрутки. Хотя сфера перемещается, преобразование ее локального расположения изменяется в функции Update сценария. Объект по-прежнему является частью физического моделирования при жесте прокрутки, он может взаимодействовать с другими объектами сцены. Я также применил жест GenericPan к прямоугольной задней стенке в сцене, чтобы с помощью стенки можно было передвигать сферы внутри выемки платформы. Можно переносить заднюю стенку, чтобы поместить ее перед башней и защитить, таким образом, созданные сферы от попадания выпускаемых башней капсул. Вот полный код сценария:


using TouchScript.Events;
using TouchScript.Gestures;
using UnityEngine;
using System;
using System.Collections;


public class GenericPan : MonoBehaviour
{
	private Vector3 targetPan;
	private Vector3 startPos;
	private float panSpeed;
	private float panFrac;
	private bool panning;


	void Start ()
	{
		startPos = targetPan = transform.localPosition;
		panSpeed = 10.0f;
		panFrac = 10.0f;
		panning = false;
		GetComponent<PanGesture>().StateChanged += onPanStateChanged;

	}

	void Update ()
	{

		if(panning)
		{
			//this.rigidbody.velocity = transform.forward * Vector3.Magnitude (transform.localPosition - targetPan);


			panFrac = panSpeed * Time.deltaTime;
        	transform.localPosition = Vector3.Lerp(transform.localPosition, targetPan, panFrac);
			panning = false;
		}
	}

	private void onPanStateChanged(object sender, GestureStateChangeEventArgs e)
    {
        switch (e.State)
        {
            case Gesture.GestureState.Began:
            case Gesture.GestureState.Changed:
                var target = sender as PanGesture;
                Debug.DrawRay(transform.position, target.WorldTransformPlane.normal);
                Debug.DrawRay(transform.position, target.WorldDeltaPosition.normalized);

                var local = new Vector3(transform.InverseTransformDirection(target.WorldDeltaPosition).x, transform.InverseTransformDirection(target.WorldDeltaPosition).y, transform.InverseTransformDirection(target.WorldDeltaPosition).z);
                targetPan += transform.InverseTransformDirection(transform.TransformDirection(local));
				panning = true;
                //if (transform.InverseTransformDirection(transform.parent.TransformDirection(targetPan - startPos)).y < 0) targetPan = startPos;
                break;
        }

    }

}



Обратите внимание, что в функции onPanStateChangedпеременная Vector3 localиспользует все три оси, тогда как в других моделях пользовательского интерфейса я использовал только оси x- и y-. Можно настроить нужным образом функциональность и других атрибутов, включая скорость прокрутки. При перемещении задней стенки для защиты сфер от выпускаемых башней капсул не так просто правильно разместить эту стенку. Нужно изменить переменную Vector3 localв отдельном сценарии, чтобы задняя стенка защищала сферы от попадания капсул из башни.

Касание

Далее для изменения физических характеристик я настроил жест касания. Я программно добавил этот жест к сферам во время их создания с помощью следующего кода:


targetSphere.AddComponent ("GenericTap");
targetSphere.AddComponent ("TapGesture");

Сценарий GenericTapвыполняет все модификации твердых тел в функции onTapи не использует функцию Update. Функция onTapувеличивает размер сферы в 2 раза при каждом ее касании пользователем. Я добавил это поведение, чтобы отслеживать сферы на сцене и удобнее наблюдать за их поведением. Каждый раз, когда пользователь касается сферы, ее физическая масса увеличивается в 10 раз. Результат виден на рис. 4: попадание выпущенных башней капсул не приводит к перемещению крупной сферы, которой пользователь коснулся 2 или 3 раза, тогда как другие сферы с легкостью перемещаются при попаданиях.


Рисунок 4. Попадание капсул не приводит к перемещению сферы с увеличенными размером и массой

Код сценария GenericTapвыглядит так:


using UnityEngine;
using System.Collections;
using TouchScript.Events;
using TouchScript.Gestures;


public class GenericTap: MonoBehaviour {

	private Vector3 startScale;

	void Start ()
	{

	startScale = transform.localScale;
	if (GetComponent<TapGesture>() != null) GetComponent<TapGesture>().StateChanged += onTap;


	}

	void Update ()
	{

	}

	private void onTap(object sender, GestureStateChangeEventArgs 	gestureStateChangeEventArgs)
    	{
        if (gestureStateChangeEventArgs.State == Gesture.GestureState.Recognized)
		{
            		transform.rigidbody.mass *= 10;
			transform.localScale *= 2.0f;
		}
	}

}



Этот сценарий прост: масса и размер сферы дискретно изменяются при выполнении жеста касания. В более сложной игровой среде жест касания может запускать последовательность событий, где масса и размер будут последовательно увеличиваться за определенное время и в зависимости от других элементов моделируемой сцены. Еще одно возможное улучшение состоит в использовании метода Time.deltaTimeдля настройки последовательности жестов для снижения массы и размера двойными касаниями.

Нажатие и отпускание

Затем я настраиваю жест «нажатие и отпускание», чтобы увеличить скорость движения созданных сфер в зависимости от времени между нажатием и отпусканием. Эта функциональность также добавляется программным образом во время создания:


			targetSphere.AddComponent ("PressGesture");
			targetSphere.AddComponent ("ReleaseGesture");
			targetSphere.AddComponent ("GenericPressRelease");

Я настраиваю сценарий GenericPressReleaseдля переключения двух логических переменных в функциях onPressи onRelease. Первая логическая переменная отслеживает, как изменилась скорость в последнем цикле жеста «нажатие и отпускание», чтобы в текущем цикле применить противоположное изменение. Вторая логическая переменная отслеживает, задействован ли сценарий в цикле жеста «нажатие и отпускание». Если да, то в зависимости от этого увеличивается или уменьшается скорость поступательного движения сферы. Для этого я использую параметр rigidbody.velocityсозданной сферы. Я использую переменную времени, чтобы регулировать величину изменения скорости поступательного движения. Результат таков: скорость движения сферы вперед увеличивается каждый нечетный раз, когда сфера получает жест «нажатие и отпускание», и уменьшается каждый четный раз при получении этого жеста. Код жеста «нажатие и отпускание» таков:


using UnityEngine;
using System.Collections;
using TouchScript.Events;
using TouchScript.Gestures;


public class GenericPressRelease : MonoBehaviour {

	private Vector3 startScale;
	private float velocityMult;
	private bool pressed;
	private bool currentlyIncreasing;
	private float timeSinceChanged;

	void Start ()
	{

	startScale = transform.localScale;
	velocityMult = 10.0f;
	pressed = false;
	currentlyIncreasing = true;
	timeSinceChanged = 0.0f;
	if (GetComponent<PressGesture>() != null) GetComponent<PressGesture>().StateChanged += onPress;
    if (GetComponent<ReleaseGesture>() != null) GetComponent<ReleaseGesture>().StateChanged += onRelease;

	}

	void Update ()
	{
		timeSinceChanged += Time.deltaTime;
		if(timeSinceChanged >= 0.25 && currentlyIncreasing && velocityMult <= 100 && pressed)
		{
			velocityMult += 10.0f;
			rigidbody.velocity = transform.forward * velocityMult;
			timeSinceChanged = 0.0f;
		}
		if(timeSinceChanged >= 0.25 && !currentlyIncreasing && velocityMult >= 0 && pressed)
		{
			velocityMult += -10.0f;
			rigidbody.velocity = transform.forward * velocityMult;
			timeSinceChanged = 0.0f;
		}

	}

	private void onPress(object sender, GestureStateChangeEventArgs gestureStateChangeEventArgs)
    {
        if (gestureStateChangeEventArgs.State == Gesture.GestureState.Recognized)
		{
			pressed = true;
		}
	}
	private void onRelease(object sender, GestureStateChangeEventArgs gestureStateChangeEventArgs)
    {
        if (gestureStateChangeEventArgs.State == Gesture.GestureState.Recognized)
		{
			pressed = false;
			currentlyIncreasing = !currentlyIncreasing;
		}
    }

}



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

Другие физические свойства

Я использовал жесты, показанные в этой статье, для управления такими характеристиками ресурсов сцены Unity 3D, как расположение, размер, масса и скорость движения. Другие параметры твердых тел, которыми удобно управлять с помощью жестов, — угловая скорость, сопротивление движению и центр масс. Можно связать эти параметры твердых тел, управляемые с помощью жестов, с существующими параметрами, такими как цвет и текстура. Также есть возможность создавать собственные переменные для моделирования физики твердых тел. Пример — переменная hitDamage, которая увеличивается при каждом касании; при обнаружении попадания из объекта вычитается определенное количество «здоровья».

Заключение

IЯ создал и запустил пример физического моделирования с твердыми телами, приведенный в этой статье, с помощью Unity 3D под управлением Windows 8 на ультрабуке. Я настроил наибольшее время жизни выпускаемых башней снарядов и создаваемых сфер для этой платформы. В результате моделирование должным образом реагировало на запрограммированные сенсорные жесты. Время жизни актива — всего один из параметров, которые нужно учитывать при изменении физических характеристик. При этом приложение не должно давать пользователю возможности приведения физического моделирования в состояние, из-за которого снизится производительность и скорость реагирования всего приложения. Для этого проще всего ограничить минимальные и максимальные значения всех изменяемых физических характеристик. Если учитывать вопросы производительности, Windows 8 на ультрабуках является жизнеспособной платформой для разработки моделей Unity 3D с изменением характеристик ресурсов сцены при физическом моделировании.

Другие материалы:

Об авторе

Линн Томпсон — специалист в области ИТ, более 20 лет проработавший в области компьютеризации предпринимательской и производственной сфер. Одной из первых его работ стало использование САПР для создания и редактирования чертежей контрольных приборов для энергосистем. Тогда же он получил степень бакалавра электротехники в Университете Небраски (г. Линкольн). В эпоху бума доткомов Линн занимался системным администри­рованием операционных систем, баз данных и приложений на различных платформах в одном из ИТ-интеграторов. Позже, после «краха доткомов», он участвовал во множестве проектов в роли ИТ-консультанта. Линн работал с компаниями, работающими в сфере легкой промыш­ленности, а также в нефтегазовой и оборонной индустрии. Сейчас он вновь вернулся к своей специальности и работает инженером-энергетиком. Линн получил магистерскую степень инженера со специализацией в области управления техническими системами (также в Университете Небраски).

 

Образец кода: приложение для генерации случайных чисел

$
0
0

Download as PDF

Download sample code

Кристофер Бёрд, специалист по разработке программного обеспечения 

Первоисточник приложения:
Intel SSG

Введение

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

Эта статья представляет краткий обзор API случайных чисел и демонстрирует, как использовать разные API для генерации случайных чисел на Android OS.

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

Код с пояснениями

Существует 4 пути для генерации случайных чисел на Android.

  • java.util.random
  • java.security.SecureRandom
  • /dev/urandom
  • OpenSSL* API

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

java.util.random

Использование Java API случайных чисел – очень простое. Вызов Random.nextInt() вернет 4-байтное случайное значение (с возможными значениями 2^32). Этот API будет хорошо работать в случаях, где вы не полагаетесь на истинно случайные числа. 

for (int i = 0; i < lastVal; i += 2) {
	dataRandomPoints[i] = (rand.nextInt() % widget_width);
	dataRandomPoints[i+1] = (rand.nextInt() % widget_height);

}

java.security.SecureRandom

SecureRandom напоминает java.util.Random тем, что с вызовом SecureRandom.nextInt() вы получаете 4-байтное случайное значение. SecureRandom считается криптографически сильным, хотя разработчикам стоит быть в курсе последних рекомендаций о том, что они наполняют SecureRandom байтами из /dev/urandom прежде, чем генерировать случайные числа. В представленном ниже примере нет привязки к /dev/urandom.

SecureRandom srand = new SecureRandom();
shouldDraw = (srand.nextInt() % randomMod );

/dev/urandom

Системы, управляемые посредством Linux (включая Android), имеют специальный файл, созданный ядром, который может устанавливать случайные числа в приложения. Являясь наиболее медленным из 4-х внедрений, /dev/urandom генерирует криптографически безопасные значения с высоким уровнем энтропии путем включения шума из разных частей операционной системы (к примеру, драйверов устройств) в  ГСЧ. Мы можем получить случайное число напрямую из ядра путем считывания с файла /dev/urandom. /dev/urandom даст доступ к ГСЧ с аппаратной поддержкой, если таковое доступно.

unsigned int cKeyBuffer[keysize];
memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize);

FILE *fin;
strcpy(filein, "/dev/urandom");
fin = fopen(filein, "rb");

if (fin != NULL) {
	fread(cKeyBuffer, sizeof(int), keysize, fin);
	fclose (fin);
}

OpenSSL API

Мы также можем использовать OpenSSL API для получения случайных чисел в нативном C-коде. Вы можете увидеть, как OpenSSL заполняется байтами из dev/urandom и затем может быть использован для генерации криптографически безопасных случайных чисел. OpenSSL даст доступ к ГСЧ с аппаратной поддержкой, если таковое доступно.

int seedbytes = 1024;
unsigned int cKeyBuffer[keysize];
memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize);

if (!opensslIsSeeded) {

	if (!RAND_load_file("/dev/urandom", seedbytes)) {
		__android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to seed OpenSSL RNG");
		return jKeyBuffer;
	}

	opensslIsSeeded = 1;
}

if (!RAND_bytes((unsigned char *)cKeyBuffer, keysize * sizeof(int))) {
	__android_log_print(ANDROID_LOG_ERROR, TAG, "Faled to create OpenSSSL random integers: %ul", ERR_get_error);
}

Выводы

Внедряя код по образу представленного образца, вы сможете быстро освоить использование четырех путей по генерации случайных чисел.

Об авторе

Кристофер Бёрд является членом Intel Software and Solutions Group (SSG), подразделения Developer Relations и команды Intel® Atom™ High Touch Software Enabling.

Статьи и информация по теме:

Предупреждение

ИНФОРМАЦИЯ В ЭТОМ ДОКУМЕНТЕ ПРЕДОСТАВЛЯЕТСЯ В ОТНОШЕНИИ ПРОДУКТОВ INTEL. ЛИЦЕНЗИЯ, ЯВНАЯ ИЛИ ПОДРАЗУМЕВАЕМАЯ, ПРЕДУСМОТРЕННАЯ ПРОЦЕССУАЛЬНЫМ ПОРЯДКОМ ИЛИ ИНЫМ СПОСОБОМ, НА ЛЮБЫЕ ПРАВА НА ИНТЕЛЛЕКТУАЛЬНУЮ СОБСТВЕННОСТЬ НЕ ПРЕДОСТАВЛЯЮТСЯ ЭТИМ ДОКУМЕНТОМ. ЗА ИСКЛЮЧЕНИЕМ СЛУЧАЕВ, ПРЕДУСМОТРЕННЫХ УСЛОВИЯМИ И СРОКАМИ INTEL ПО ПРОДАЖЕ ПОДОБНЫХ ПРОДУКТОВ, INTEL НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ И ОТКАЗЫВАЕТСЯ ОТ ЛЮБЫХ ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ В ОТНОШЕНИИ ПРОДАЖИ И/ИЛИ ИСПОЛЬЗОВАНИЯ ПРОДУКТОВ INTEL, ВКЛЮЧАЯ ОБЯЗАТЕЛЬСТВА ИЛИ ГАРАНТИИ, ОТНОСЯЩИЕСЯ К ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ, ЛИКВИДНОСТИ, ИЛИ НАРУШЕНИЯ КАКИХ-ЛИБО ПАТЕНТОВ, АВТОРСКИХ ПРАВ ИЛИ ИНЫХ ПРАВ ИНТЕЛЛЕКТУАЛЬНОЙ СОБСТВЕННОСТИ.

ЕСЛИ ИНОЕ НЕ СОГЛАСОВАНО КОМПАНИЕЙ INTEL В ПИСЬМЕННОЙ ФОРМЕ, ПРОДУКТЫ INTEL НЕ ПРЕДНАЗНАЧЕНЫ ДЛЯ ЛЮБОГО ИСПОЛЬЗОВАНИЯ, КОТОРОЕ ПРИ НАЛИЧИИ СБОЯ В РАБОТЕ ПРОДУКТА INTEL МОЖЕТ СПРОВОЦИРОВАТЬ ТРАВМИРОВАНИЕ И СМЕРТЕЛЬНЫЙ ИСХОД.

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

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

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

Копии документов, имеющих порядковый номер и на которые ссылается данный документ, а также иные материалы Intel можно получить, позвонив по тел. 1-800-548-4725 или на сайте: http://www.intel.com/design/literature.htm

 

Программное обеспечение и рабочая нагрузка, используемые в тестах производительности, могли быть оптимизированы для обеспечения высокой производительности только на микропроцессорах Intel. Тесты производительности, такие как SYSmark* и MobileMark*, проводятся с использованием конкретных компьютерных систем, компонентов, программного обеспечения, операций и функций. Любое изменение любого из этих факторов может привести к варьированию результатов. Вам стоит обратиться к другим источникам информации и тестам производительности для содействия  в оценке принятия решения о покупке, включая аспект производительности этого продукта в совместной работе с другими продуктами.

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

Intel, логотип Intel и Atom являются товарными знаками Корпорации Intel в США и/или других странах.

Copyright © 2014 Корпорации Intel. Все права защищены.

*Другие наименования и торговые марки могут быть собственностью других людей. 

 

Автоматическое тестирование Android с UiAutomator

$
0
0

Я хочу рассказать вам о замечательном инструменте для автоматического тестирования пользовательского интерфейса в приложениях Android - UiAutomator. Вы можете найти всю актуальную документацию здесь:  http://developer.android.com/tools/help/uiautomator/index.htmlи http://developer.android.com/tools/testing/testing_ui.html

У UiAutomator есть свои плюсы и минусы.

Преимущества:

  • Он может быть использован на дисплеях устройств с различным разрешением.
  • События можно привязывать к элементам управления Android UI. К примеру, кликайте на кнопку с текстом «Ок» вместо того, чтобы кликать по расположению координат (x=450, y=550).
  • Инструмент может воспроизводить сложную последовательность действий пользователя.
  • Он всегда выполняет одну и ту же последовательность действий, позволяя нам собирать данные о производительности на разных устройствах.
  • Он может многократно выполняться на различных устройствах без изменения Java-кода.
  • Может использовать аппаратные кнопки на устройствах.

Недостатки:

  • Его сложно использовать с OpenGL- и HTML5-приложениями, поскольку они не имеют компонентов Android UI.
  • Время, затрачиваемое на написание JavaScript.

Разработка скрипта

Чтобы познакомить вас с работой  UiAutomator, я хочу продемонстрировать простую программу. Это стандартное Android-приложение для месседжинга, которое может отсылать SMS-сообщения на любой телефонный номер.

Вот короткое описание действий, которые мы осуществили:

  1. Найти и запустить приложение
  2. Создать и отправить SMS-сообщения

Как видите, это очень просто.

Подготовка к тесту

Для анализа интерфейса будем использовать uiautomatorviewer.

Uiautomatorviewer показывает разделенный скриншот всех компонентов UI в Node Detail, чтобы вы могли видеть их разнообразные свойства. Там же в свойствах вы можете найти искомый элемент.

Настройка среды разработки

Если вы используете Eclipse*:

  1. Создайте новый Java-проект в Eclipse. Мы назовем наш проект: SendMessage.
  2. Клик правой кнопкой на вашем проекте в ProjectExplorerи затем клик на Properties.
  3. В Propertiesвыберите JavaBuildPath  и добавьте требуемые библиотеки:

 

Если вы пользуетесь иной средой разработки, убедитесь что файлы android.jar и uiautomator.jar добавлены в настройки проекта. 

Кликните AddLibrary JUnit  и там выберите JUnit3, чтобы добавить поддержку для JUnitКликните Add External JARs ...В <android-sdk>/platforms/directory выберите последнюю версию SDK. Также в этой директории выберите файлы uiautomator.jar и android.jar

Создание скрипта

Создайте проект в ранее созданном новом файле с классом Java. Назовите его SendMessage. Этот класс унаследован из класса UiAutomatorTestCase. Используя Ctrl + Shift + o (для Eclipse), добавьте требуемые библиотеки.

Создайте три функции для тестирования этого приложения:

  1. Найти и запустить приложение
  2. Отправить SMS-сообщения
  3. Выйти в главное меню приложения

Создайте функцию, от которой будут запускаться все эти опции, – своего рода основную функцию:

public void test() {
	// Here will be called for all other functions
	}

Функция поиска и запуска приложения

Эта функция крайне проста. Мы нажимаем кнопку Домой, открываем меню и ищем значок приложения. Нажимаем и запускаем его.

private void findAndRunApp() throws UiObjectNotFoundException {
		// Go to main screen
		getUiDevice().pressHome();
		// Find menu button
		UiObject allAppsButton = new UiObject(new UiSelector()
		.description("Apps"));
		// Click on menu button and wait new window
		allAppsButton.clickAndWaitForNewWindow();
		// Find App tab
		UiObject appsTab = new UiObject(new UiSelector()
		.text("Apps"));
		// Click on app tab
		appsTab.click();
		// Find scroll object (menu scroll)
		UiScrollable appViews = new UiScrollable(new UiSelector()
		.scrollable(true));
		// Set the swiping mode to horizontal (the default is vertical)
		appViews.setAsHorizontalList();
		// Find Messaging application
		UiObject settingsApp = appViews.getChildByText(new UiSelector()
		.className("android.widget.TextView"), "Messaging");
		// Open Messaging application
		settingsApp.clickAndWaitForNewWindow();

		// Validate that the package name is the expected one
	    UiObject settingsValidation = new UiObject(new UiSelector()
	    .packageName("com.android.mms"));
	    assertTrue("Unable to detect Messaging",
	    		settingsValidation.exists());
	}

Все наименования классов, текст на кнопках и пр. - из uiautomatorviewer.

Посылка SMS-сообщения

Эта функция находит и нажимает кнопку создания нового сообщения, вводит телефонный номер адресата и нажимает кнопку отправки. Телефонный номер и текст проходят через параметры функции:

private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
		// Find and click New message button
		UiObject newMessageButton = new UiObject(new UiSelector()
		.className("android.widget.TextView").description("New message"));
		newMessageButton.clickAndWaitForNewWindow();

		// Find to box and enter the number into it
		UiObject toBox = new UiObject(new UiSelector()
		.className("android.widget.MultiAutoCompleteTextView").instance(0));
		toBox.setText(toNumber);
		// Find text box and enter the message into it
		UiObject textBox = new UiObject(new UiSelector()
		.className("android.widget.EditText").instance(0));
		textBox.setText(text);

		// Find send button and send message
		UiObject sendButton = new UiObject(new UiSelector()
		.className("android.widget.ImageButton").description("Send"));
		sendButton.click();
	}

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

Чтобы добавить возможность передавать параметры в скрипт, мы можем точно определить число адресатов и сами сообщения. Функция test() устанавливает параметры по умолчанию, и если какими-либо из параметров были отправленные через командную строку сообщения, заменой параметрам по умолчанию были бы:

// Default parameters
		String toNumber = "123456";
		String text = "Test message";

		String toParam = getParams().getString("to");
		String textParam = getParams().getString("text");
if (toParam != null) {
// Remove spaces
			toNumber = toParam.trim();
		}
		if (textParam != null) {
			text = textParam.trim();
		}

Таким образом, мы сможем передавать параметры из командной строки скрипта, используя ключ –e, имя параметра и значение. К примеру, мое приложение отсылает номер для отправки " 777777 »:-e to 777777

Есть и некоторые подвохи. К примеру, данное приложение не понимает некоторые символы, и происходит сбой. Вот некоторые из этих символов: space, &, <, > , (,) , ", ' , а также некоторые символы Unicode. При внедрении в скрипт я заменил эти символы текстовой строкой, например пробел : blogspaceblog. Получается, когда скрипт запускает UiAutomator, мы используем скрипт, который будет обрабатывать наши входные параметры. Мы добавляем в функцию test(), проверку наличия опций, парсим параметры и заменяем их реальными символами. Ниже представлен образец кода, наглядно демонстрирующий всё, что мы ввели ранее:

if (toParam != null) {
			toParam = toParam.replace("blogspaceblog", "");
			toParam = toParam.replace("blogamperblog", "&");
			toParam = toParam.replace("bloglessblog", "<");
			toParam = toParam.replace("blogmoreblog", ">");
			toParam = toParam.replace("blogopenbktblog", "(");
			toParam = toParam.replace("blogclosebktblog", ")");
			toParam = toParam.replace("blogonequoteblog", "'");
			toParam = toParam.replace("blogtwicequoteblog", """);
			toNumber = toParam.trim();
		}
		if (textParam != null) {
			textParam = textParam.replace("blogspaceblog", "");
			textParam = textParam.replace("blogamperblog", "&");
			textParam = textParam.replace("bloglessblog", "<");
			textParam = textParam.replace("blogmoreblog", ">");
			textParam = textParam.replace("blogopenbktblog", "(");
			textParam = textParam.replace("blogclosebktblog", ")");
			textParam = textParam.replace("blogonequoteblog", "'");
			textParam = textParam.replace("blogtwicequoteblog", """);
			text = textParam.trim();
		}

Выход в главное меню приложения

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

private void exitToMainWindow() {
		// Find New message button
		UiObject newMessageButton = new UiObject(new UiSelector()
		.className("android.widget.TextView").description("New message"));

		// Press back button while new message button doesn't exist
		while(!newMessageButton.exists()) {
			getUiDevice().pressBack();
		}
	}

Исходный код

Вот и наш код:

package blog.send.message;
import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;

public class SendMessage extends UiAutomatorTestCase {
	public void test() throws UiObjectNotFoundException {
		// Default parameters
		String toNumber = "123456";
		String text = "Test message";

		String toParam = getParams().getString("to");
		String textParam = getParams().getString("text");
		if (toParam != null) {
			toParam = toParam.replace("blogspaceblog", "");
			toParam = toParam.replace("blogamperblog", "&");
			toParam = toParam.replace("bloglessblog", "<");
			toParam = toParam.replace("blogmoreblog", ">");
			toParam = toParam.replace("blogopenbktblog", "(");
			toParam = toParam.replace("blogclosebktblog", ")");
			toParam = toParam.replace("blogonequoteblog", "'");
			toParam = toParam.replace("blogtwicequoteblog", """);
			toNumber = toParam.trim();
		}
		if (textParam != null) {
			textParam = textParam.replace("blogspaceblog", "");
			textParam = textParam.replace("blogamperblog", "&");
			textParam = textParam.replace("bloglessblog", "<");
			textParam = textParam.replace("blogmoreblog", ">");
			textParam = textParam.replace("blogopenbktblog", "(");
			textParam = textParam.replace("blogclosebktblog", ")");
			textParam = textParam.replace("blogonequoteblog", "'");
			textParam = textParam.replace("blogtwicequoteblog", """);
			text = textParam.trim();
		}
		findAndRunApp();
	    	sendMessage(toNumber, text);
	    	exitToMainWindow();
	}
	// Here will be called for all other functions
	private void findAndRunApp() throws UiObjectNotFoundException {
		// Go to main screen
		getUiDevice().pressHome();
		// Find menu button
		UiObject allAppsButton = new UiObject(new UiSelector()
		.description("Apps"));
		// Click on menu button and wait new window
		allAppsButton.clickAndWaitForNewWindow();
		// Find App tab
		UiObject appsTab = new UiObject(new UiSelector()
		.text("Apps"));
		// Click on app tab
		appsTab.click();
		// Find scroll object (menu scroll)
		UiScrollable appViews = new UiScrollable(new UiSelector()
		.scrollable(true));
		// Set the swiping mode to horizontal (the default is vertical)
		appViews.setAsHorizontalList();
		// Find Messaging application
		UiObject settingsApp = appViews.getChildByText(new UiSelector()
		.className("android.widget.TextView"), "Messaging");
		// Open Messaging application
		settingsApp.clickAndWaitForNewWindow();

		// Validate that the package name is the expected one
	    UiObject settingsValidation = new UiObject(new UiSelector()
	    .packageName("com.android.mms"));
	    assertTrue("Unable to detect Messaging",
	    		settingsValidation.exists());
	}

	private void sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
		// Find and click New message button
		UiObject newMessageButton = new UiObject(new UiSelector()
		.className("android.widget.TextView").description("New message"));
		newMessageButton.clickAndWaitForNewWindow();

		// Find to box and enter the number into it
		UiObject toBox = new UiObject(new UiSelector()
		.className("android.widget.MultiAutoCompleteTextView").instance(0));
		toBox.setText(toNumber);
		// Find text box and enter the message into it
		UiObject textBox = new UiObject(new UiSelector()
		.className("android.widget.EditText").instance(0));
		textBox.setText(text);

		// Find send button and send message
		UiObject sendButton = new UiObject(new UiSelector()
		.className("android.widget.ImageButton").description("Send"));
		sendButton.click();
	}

	private void exitToMainWindow() {
		// Find New message button
		UiObject newMessageButton = new UiObject(new UiSelector()
		.className("android.widget.TextView").description("New message"));

		// Press back button while new message button doesn't exist
		while(!newMessageButton.exists()) {
			getUiDevice().pressBack();
			sleep(500);
		}
	}
}

Компиляция и выполнение тестирования UiAutomator

  1. Чтобы сгенерировать файлы конфигурации для экспериментальной сборки, выполните следующую команду из командной строки:
    <android-sdk>/tools/androidсоздать uitest-проект -n<name> -<target-id> -p<path>
    где <
    name>- это имя проекта, который был создан для тестирования UiAutomator (в нашем случае: SendMessage), <target-id>- выбор устройства и AndroidAPILevel (вы можете получить перечень установленных устройств с помощью команды <android-sdk> / tools / androidlisttargets), и <path> это путь к директории, где содержится проект.
  2. Вы должны экспортировать переменную среды ANDROID_HOME:
    • На Windows:
      установите ANDROID_HOME=<путь_к_вашему_sdk>
    • На UNIX:
      экспортируйте ANDROID_HOME=<путь_к_вашему_sdk>
  3. Откройте директорию с файлом проекта build.xml, который был создан на этапе 1, и выполните команду: antbuild
  4. Скопируйте скомпилированный файл JAR на устройство, используя adb push:
    adbpush<путь_к_output_jar> /data/local/tmp/
    В нашем случае это:

    adbpush<project_dir>/bin/SendMessage.jar /data/local/tmp/
  5. И выполните скрипт:
    adb shell uiautomator runtest /data/local/tmp/SendMessage.jar –c blog.send.message.SendMessage

Об авторе

Егор Чураев (egor.churaev@intel.com) – Стажер по программному обеспечению

Дополнительные материалы:

Real-time End-to-End H.265/HEVC Solution for Intel® Architecture-based Platforms

$
0
0

Contents

1. Abstract
2. Introduction
  2.1 Video Codec and H.265/HEVC
  2.2 HEVC Performance Issues
  2.3 The Current Solution of H.265/HEVC Investigation
3. Optimized Real-time Solution on IA-based Platforms
  3.1 Real-time HEVC Encoder Solution Based on Intel® Xeon™ Processor
    3.1.1 Intel SIMD Vectorization Tuning for HEVC Encoding Functions
    3.1.2 Thread Concurrency and Core Scalability Tuning
    3.1.3 Further Tuning with SMT/HT
  3.2 High Performance H.265/HEVC Decoder on Intel® Core™ Processor-based Platforms
    3.2.1 Optimization and Performance Analysis of Strongene HEVC Decoder
    3.2.2 Comparison of Intel SSE-Optimized Strongene HEVC Decoder with Open Source Alternatives and Future Optimization Opportunities
  3.3 Optimizing H.265/HEVC Decoder on Intel® Atom™ Processor-based Platforms
    3.3.1 Optimized by YASM & Intel® C++ Compiler
    3.3.2 Optimized with Intel® Streaming SIMD Extensions (Intel® SSE) Instructions
    3.3.3 Optimized by Intel® Threading Building Blocks (Intel® TBB) Tool
    3.3.4 H.265/HEVC Decoder Performance Comparison
4. Summary
5. Other related articles
Reference
About the Authors

1. Abstract

The International Telecommunication Union (ITU) announced the new video codec standard: High Efficiency Video Coding (HEVC)/H.265, which claims to be about 50 percent more efficient than the current H.264/MPEG-4 standard. However, the complexity of the algorithm and data structure of H.265 is more than 4 times the H.264. That means the H.265 based codec will require more computing resource/power than its predecessor. In this paper, we will investigate the HEVC codec characters and optimize the CPU-based software video trans-coding technologies, which provide the best video quality and the most flexible programming model. Our end-to-end solution can maximize Intel® Architecture (IA) platforms’ capabilities for the HEVC codec and achieve real-time performance.

2. Introduction

Video coding standards have evolved primarily through the development of the well-known ITU-T and ISO/IEC standards. The ITU-T produced H.261 and H.263, ISO/IEC produced MPEG-1 and MPEG-4 Visual, and the two organizations jointly produced the H.262/MPEG-2 Video and H.264/MPEG-4 Advanced Video Coding (AVC) standards [1].

H.265/HEVC (High-Efficiency Video Coding), introduced last year, is the latest video codec standard developed by ISO / IEC and ITU-T, aimed to maximize compression capability and reduce data loss. H.265/HEVC doubles the compression ratio compared to the previous H.264/AVC standard, but has the same subjective quality. HEVC technology helps online video providers to provide high-quality video with less bandwidth, making it the next video codec revolution.

2.1 Video Codec and H.265/HEVC

HEVC proposes several new video coding syntax architectures and algorithms to obtain the highly efficient coding standard[1][2]:

a) Random Access and Bitstream Splicing Features
The new design supports special features to enable random access and bitstream splicing. In H.264/MPEG-4 AVC, a bitstream must always start with an IDR access unit, but in HEVC, random access is supported.

b) Coding Tree Units Structure
A picture is partitioned into coding tree units (CTUs), each containing luma coding tree blocks (CTBs) and chroma CTBs. The value of L may be equal to 16, 32, or 64 as determined by an encoded syntax element specified in the sequence parameter set (SPS). The CTU contains a quadtree syntax that allows for splitting the coding blocks (CBs) to a selected appropriate size based on the signal characteristics of the region that is covered by the CTB. All previous video coding standards just used the fixed array size of 16×16 luma samples, but HEVC supports variable-sized CTBs selected according to the needs of encoders in terms of memory and computational requirements.

c) Tree-Structured Partitioning Into Transform Blocks and Units
A CB can be recursively partitioned into transform blocks (TBs). The partitioning is signaled by a residual quadtree. In contrast to previous standards, the HEVC design allows a TB to span across multiple prediction blocks (PBs) for interpicture-predicted coding units (CUs) to maximize the potential coding efficiency benefits of the quadtree-structured TB partitioning.

d) Intrapicture Prediction
Directional prediction with 33 different directional orientations is defined for (square) Transform Block (TB) sizes from 4×4 up to 32×32. The possible prediction directions are all 360’ directions. HEVC supports various intrapicture predictive coding methods referred to as Intra_Angular, Intra_Planar, and Intra_DC.

This advanced coding standard demands extremely high processing capabilities from both client devices and backend trans-coding servers.

2.2 HEVC Performance Issues

The current HEVC Test Model (HM) project[6] only implements the major functionalities of this standard; the real performance is still far from production and real deployment. The project’s two major drawbacks are:

  • No parallel scheme
  • Poor vectorization tuning


Figure 1. HM Project Profiling – Thread Concurrency


Figure 2. HM Project Profiling – Hot Code

This HEVC encoder consumes over 100 times more CPU resources than the H.264 on the server side, and over 10 times more on the client side.

2.3 The Current Solution of H.265/HEVC Investigation

The H.265/HEVC codec has drawn the interest of many worldwide groups/agencies to optimize the performance and lead to actual deployment. Several open source projects are:

  • OpenHEVC (HM10.0 compatible, decoder optimization)
    https://github.com/OpenHEVC/openHEVC
  • x265 (compatible with HM, parallel & SIMD optimization)
    http://code.google.com/p/x265/
    https://bitbucket.org/multicoreware/x265/wiki/Home

We ran a 720p 24 FPS video to evaluate the performance of the x.265 encoder on an Intel® Xeon® processor-based platform (E5-2680 @ 2.70GHz, 8*2 physical cores, codenamed Sandy Bridge). The implementers of this codec did lots of work to optimize the original standard for both task and data parallelism; however, from our benchmarking it can only use 6 cores in a system with 32 logical cores (SMT ON). Thus, it does not maximize computing resource utilization on current multi-core platforms.


Figure 3. X.265 Project CPU Usage


Figure 4. X.265 Project with Intel® SIMD Tuning

In the x.265 project, Intel® SSE instructions were utilized for vectorization tuning, which contributes to over 70% performance speedup. With further Intel® C Compiler compiling optimization, we get 2x speedup1 on the IA platform. However the encoder performance here still has big gap with the real-time encoder deployment, especially for HD 1080p videos.

In the PRC, more than 20 multimedia ISVs are pursuing the available HEVC solution and platform to save online video service costs and maintain high quality.


Figure 5. Online Video Market in the PRC

3. Optimized Real-time Solution on IA-based Platforms

Strongene is a Chinese company focusing on kernel video coding technology. It provides advanced H.265/HEVC encoder/decoder codecs that have been adopted by Xunlei online video service. Its encoder/decoder solution has been integrated with open source FFMPEG for ISVs to use. We worked with Strongene to optimize the H.265/HEVC encoder and decoder on platforms with Intel® Xeon® processors, Intel® Core™ processors, and Intel® Atom™ processors using new IA-based platform technologies, to achieve a real-time, end-to-end, HEVC codec solution.

3.1 Real-time HEVC Encoder Solution Based on Intel® Xeon™ Processor

Our video encoding application is a standard CPU and memory-intensive workload that requires high capabilities of the server platform, such as core computing efficiency, reliability, and stability. The computing of H.265/HEVC codec is 4 times more complex than the previous H.264/MPEG. It raises unprecedented processing requirements for the backend server platform. In this section, we will introduce major IA-based technologies that helped Strongene HEVC codec to reach the 1080p real-time encoding standard.

3.1.1 Intel SIMD Vectorization Tuning for HEVC Encoding Functions

Most of the time-consuming video and image processing functions are the block-based data intensive computing, which can be optimized using the Intel® SIMD (Single Instruction Multi Data) vectorization instructions. Intel SIMD instructions process multi set data within one single CPU cycle, which greatly improves the data throughput and execution efficiency. Intel SIMD has been widely supported, evolving from MMX, Intel® SSE, Intel® Advanced Vector Extensions (Intel® AVX), to Intel® Advanced Vector Extensions 2 (Intel® AVX2) for different x86 platform generations.

In the Strongene encoding codec, observed from the profiling data, all the major hot functions can be vectorized using Intel Intel SSE instructions, such as low-complexity, motion-compensated frame interpolation; transpose-free integer transform; butterfly Hadamard transform; and the least-memory-redundancy SAD/SSD calculation. We enabled the Intel SSE instructions in the Intel Xeon processor-based platform, as shown in Figure 6.


Figure 6. Sample of Enabling Intel® SIMD/SSE Instructions in Stongene Codec

With those Intel SIMD programming models and paradigms, Strongene rewrote all the hot functions in the encoding codec to obtain the maximum performance increase. Figure 7 is our profiling data in a standard 1080p HEVC encoding scenario, which shows 60% of the hot functions are running in Intel SIMD instructions.


Figure 7. Profiling Results of Strogene Encoding Functions

Intel AVX2 instructions with 256b int computing will double the performance of previous 128b Intel SSE code. Intel AVX2 will be supported on the Intel Xeon processor-based platform (codenamed Haswell) platform due to be launched in 2014. We take a common 64*64 block SAD computing as an example to test the intrinsic performance of Intel AVX2:

Table 1. Intel® SSE and Intel® AVX2 Implementation Results

CPU CycleoriginalIntel® SSEIntel® AVX2
run 198877977679
run 2984631092690
run 398152978679
run 498003943679
run 598118954678
avg.98322.6988.8681
speedup1.0099.44144.38

As shown in Table 1, in this function, the Intel SSE and Intel AVX2 instructions can boost the performance by 100 times, and the Intel AVX2 code further provides performance improvement of more than 40% over Intel SSE2. We can expect further performance improvement when upgrading the Intel SSE code to Intel AVX2 on the to-be-released Haswell platform.

3.1.2 Thread Concurrency and Core Scalability Tuning

As we have seen in Section 2.3, most current implementations do not utilize all the cores on multi-core platforms. Based on the latest Intel Xeon multi-core architecture, with the parallelism dependency between HEVC, CTB-based algorithms clarified, Strongene proposes to replace the original OWF (Overlapped Wave-Front) and WPP (Wave-front Parallel Processing) methods with the Inter-Frame Wave-front (IFW) parallel framework, then develop a three-level thread management scheme to guarantee that the IFW can fully utilize all the CPU cores to accelerate the HEVC encoding process. With this new parallelism framework, on an Ivy Bridge platform (Intel Xeon processor E5-2697 @2.70GHz, 12*2 physical cores, SMT OFF), the Strongene codec can utilize computing resources of 18-24 physical cores, achieving pretty good thread concurrency.


Figure 8. Thread Concurrency and CPU Utilization in Strongene Encoding Codec

With the new WHP parallelism framework and fully implemented Intel SIMD instructions on the task level and data level respectively, the Strongene encoding codec accomplished tremendous performance speedup on x86 processors for 1080p video sequences, leveraged all cores computing capabilities successfully as shown in the figure 8.

3.1.3 Further Tuning with SMT/HT

Simultaneous Multithreading (SMT), also called Hyper-threading (HT) technology, is widely supported in all IA-based platforms. It allows the operating system to address two virtual or logical cores for each physical core and share the resources between them when possible. The main function of hyper-threading is to decrease the number of dependent instructions on the pipeline. It offers performance benefits when CPU cores are fully running at a high level, but not all applications can benefit, such as those that do not utilize all the cores. In these cases SMT technology will introduce task/thread switching overhead. Therefore, we turned off the SMT in the Strongene encoding codec platform and obtained the HEVC 1080p video real-time encoding standard on the Ivy Bridge platform (Intel Xeon processor E5-2697 v2), as highlighted in yellow in the following table.

Table 2. Strongene HEVC Encoding Performance on Intel® Xeon® Processor-based Platform3

PlatformResolutionBitrate (kbps)FPSCPU UsageEncoding- modeSMT
WSM E7-8837
@2.67GHz
(8*8c)
720p8008.215cultrafastOFF
16002.618cultraslowOFF
1080p15003.627cultrafastOFF
30001.423cultraslowOFF
4k50001.219cultrafastOFF
100000.521cultraslowOFF
IVY E5-2697 v2
@2.70GHz
(2*12c)
720p10001140% 14cultraslowON
720p10004660% 16cultrafastON
1080p15002170% 16cultrafastON
1080p15002580% 18cultrafastOFF
IVB E7-4890
@2.80GHz
(4*15c)
1080p20002219cultrafastON
1080p80006.1115cultraslowON
4k80007.0229cultrafastON
4k80003.2823cultraslowON

After achieving tremendous performance improvements, we further evaluated the Strongene HEVC encoding codec capability on the Ivy Bridge platform, focusing on the bandwidth and quality issues.

Table 3. H.264 and H.265 Codec Performance Comparison

File: BQTerrance_1920x1080_60.yuv
Resolution: 1920x1080 Size: 1869Mbyte, 622080 kbps
Platform: E5-2697 v2 @2.70GHz, RAM 64GB DDR3-1867, QPI 8.0 GT /s OS/SW: Red Hat 6.4, kernel 2.6.32, gcc v4.4.7, ffmpeg v2.0.1, Lentoid HEVC Encoder r2096 linux
CodecSize (byte)Bitrate (kbps)PSNR_Y/U/V (db)
H.264122546964078.132.311/39.369/42.043
H.26562156152064.2834.016/39.822/42.141

From Table 3, we can see that H.265/HEVC codec saves 50% bandwidth4 while maintaining the same video quality.

3.2 High Performance H.265/HEVC Decoder on Intel® Core™ Processor-based Platforms

The Strongene HEVC/H.265 decoder is an optimized H.265 decoder that provides good performance with relatively low computation requirements. The high efficiency of the Strongene HEVC decoder is achieved by a fully parallelized architecture design and Wavefront Parallel Processing (WPP) implementation. Also, Intel SIMD instructions available on Intel Core processor-based platforms, such as Intel SSE2, Intel SSSE3, and Intel SSE4, are utilized to accelerate various decoding blocks and unleash the power of underlying Intel architecture. With the benefits of these features, the Strongene HEVC decoder is able to achieve real-time 4K decoding with mainstream CPU and up to 200 FPS decoding rate for 1080p video streams.

3.2.1 Optimization and Performance Analysis of Strongene HEVC Decoder

Multithreading optimization in the Strongene HEVC decoder is achieved through WPP and frame layer parallelism. WPP is a feature introduced in HEVC to allow for parallel processing by dividing a slice into several rows of Coding Tree Units (CTUs) and then allocating each row to a thread (each row can be processed once the CTUs in the preceding row for reference are decoded). Frame layer parallelism implemented in the Strongene HEVC decoder utilizes the hierarchy structure introduced in the HEVC standard by the fact that B frames can be referenced by other B frames to construct a hierarchy referencing architecture. For example, if Group of Pictures (GOP) equals 8, the sequence can be encoded as follows:


Figure 9. One of the Possible Encoded Frame Structures (Display Order) to Utilize Frame Layer Parallelism for GOP = 8

In this case, B1 uses 2 P frames as reference in the first stage. In the second stage, the two B2 frames use a P frame and a B1 frame as reference. Therefore, these two B2 frames can be processed in parallel. In the third stage, the four B3 frames use either a P frame and a B2 frame, or a B1 frame and a B2 frame as reference. As a result, the four B3 frames can also be processed in parallel. If a larger GOP is used, the frame layer parallelism can be further improved given that the number of threads in the HEVC decoder is sufficient to support the B frame decoding concurrently. The Strongene HEVC decoder is well-organized to achieve the maximum level of parallelism through multithread decoding and WPP in order to boost the decoding speed.

Here is the maximum decoding frame rate of Strongene HEVC decoder before (Table 4) and after (Table 5) Intel SSE optimization on a Sandy Bridge platform5, running on 1080p and 4K sequences with different numbers of threads enabled.

Table 4. Decoding Rate of Strongene HEVC Decoder Before Intel SSE Optimization (Lentoid C) on 1080p and 4K Video Streams with Different Numbers of Threads Enabled

 1080p 1.2Mbps4K 5.6Mbps
Decoding Rate w/o
Rendering (FPS)
Average CPU
Utilization
Decoding Rate w/o
Rendering (FPS)
Average CPU
Utilization
1 thread25.3325%6.8525%
2 thread43.0349%11.847%
4 thread51.7993%14.1386%
8 thread53.198%15.0399%

Table 5. Decoding Rate of Strongene HEVC Decoder After Intel SSE Optimization (v2.0.1.14) on 1080p and 4K Video Streams with Different Numbers of Threads Enabled

 1080p 1.2Mbps4K 5.6Mbps
Decoding Rate w/o
Rendering (FPS)
Average CPU
Utilization
Decoding Rate w/o
Rendering (FPS)
Average CPU
Utilization
1 thread7525%2125%
2 thread12045%3340%
4 thread14070%3663%
8 thread15498%4096%

We can see from the above data that a ~3x performance gain can be obtained for 1080p streams and ~2.6x for 4K streams after Intel SSE optimization5 on the Sandy Bridge platform. Also, multi-threading design in the Strongene HEVC decoder contributes to a significant performance boost compared to single-thread mode: ~2x decoding frame rate is achieved if the number of simultaneous decoding threads is increased from 1 to 8. In terms of the overall performance, it shows that even on the dual-core Sandy Bridge mobile platform, the Strongene HEVC decoder with Intel SSE optimization is capable of decoding 4K streams in real-time with less than 40% CPU utilization, which is definitely one of the best HEVC software decoders available in the industry. For 1080p streams with bit-rates ranging from 1Mbps to 3Mbps (general bit rate setting for 1080p videos streaming over the Internet), real-time decoding can be achieved with less than 20% CPU utilization.

3.2.2 Comparison of Intel SSE-Optimized Strongene HEVC Decoder with Open Source Alternatives and Future Optimization Opportunities

The performance of the Strongene HEVC decoder can be further examined through comparison with some well-known open source implementations such as HM and FFMPEG. In the following charts, decoding rates for different HEVC decoders are compared by using video streams with various levels of resolution, frame, and bit rate.

 HM10.0: HEVC reference decoder HM10.0
 FFMPEG: FFMPEG 2.1 HEVC decoder running on single thread
 FFMPEG 4 threads: FFMPEG 2.1 HEVC decoder running on 4 threads
 Lentoid C: Strongene HEVC decoder before SSE optimization running on single thread
 Lentoid SIMD: Strongene HEVC decoder after SSE optimization running on single thread (v2.0.1.16)
 Lentoid SIMD 4 threads: Strongene HEVC decoder after SSE optimization running on 4 threads (v2.0.1.16)


Figure 10. H.265 Decoding Frame Rate of 4K Videos for Various Decoders and Configurations


Figure 11. H.265 Decoding Frame Rate of Class A Videos for Various Decoders and Configurations


Figure 12. H.265 Decoding Frame Rate of Class B Videos for Various Decoders and Configurations


Figure 13. H.265 Decoding Frame Rate of Class C Videos for Various Decoders and Configurations


Figure 14. H.265 Decoding Frame Rate of Class E Videos for Various Decoders and Configurations


Figure 15. H.265 Decoding Frame Rate of Class F Videos for Various Decoders and Configurations

Regarding the performance data on different classes of videos, the Strongene HEVC decoder after Intel SSE optimization was able to achieve a ~10x speed boost6 compared to the HM10 decoder. The performance gain is even larger for lower bit-rate streams. However, the acceleration ratio of Intel SSE optimization (Lentoid SIMD 4 threads / Lentoid C) decreases when the bit rate increases due to the fact that Intel SIMD instructions are more effective on modules that can be parallelized such as Motion Compensation instead of those that can’t be parallelized (CABAC, IDCT, and deblocking). The phenomenon can be explained in more detail if we look at the VTune™ Amplifier XE hotspot functions before and after Intel SSE optimization:


Figure 16. Hotspot Functions of the Strongene HEVC Decoder Before Intel SSE Optimization (Lentoid C 8 Threads) Running on 4K 5.6Mbps Workload from the Perspective of the VTune™ Amplifier


Figure 17. Hotspot Functions of Strongene HEVC Decoder After SSE Optimization (Lentoid SIMD 8 Threads) Running on 4K 5.6Mbps Workload from the Perspective of the VTune™ Amplifier

In Figure 16, we found that most of the hotspots in Lentoid C decoder were in the Motion Compensation (MC) module since MC has to be done for each CTB and requires extensive computation resources. However, MC can be parallelized in the CTB level, so it can achieve the highest acceleration ratio after Intel SSE optimization:

  ∑∀i,i∈CTBsMC Acceleration Ratioi× Numbers of pixels in i  
Numbers of luma and chroma pixels in a frame
MC Acceleration Ratioavg

As the bit rate increases, many more computation resources are spent on CABAC, IDCT, and deblocking in order to decode and process video data, which leads to a lower Intel SSE acceleration ratio for these modules. That’s why hotspot functions have been shifted from MC to IDCT and deblocking modules after Intel SSE optimization, as shown in Figure 17.

Besides, we can see from the CPU concurrency in VTune that, when running the Intel SSE optimized decoder in 8 threads on 4K 5.6Mbps stream, at least 3 logical CPUs are running for 74% of the decoding time, only 1 or 2 logical CPUs are running for 26% of the time due to workload imbalance among B frames.


Figure 18. CPU Usage Histogram

For hotspot analysis, all the top five hot functions are actually compute-bound instead of memory-bound, which implies that these functions can be further optimized through Intel AVX and Intel AVX2 instructions.


Figure 19. Top Hotspots

3.3 Optimizing H.265/HEVC Decoder on Intel® Atom™ Processor-based Platforms

Watching video is the top usage for mobile devices. Multimedia processing is computing intensive and has a big impact on battery life and user experience. The LCD resolution on mobile devices has improved, from 480p to 720p, to now 1080p. End users want to watch high quality videos, but for online video providers, such as Youku, iQiyi and LeTV, purchasing the network bandwidth becomes increasingly expensive every year.

In 2013 Intel introduced the new 4th generation Intel Atom processor-based platforms (code-named Bay Trail), powered by 22nm Silvermont Architecture. The details of this architecture are shown below:


Figure 20. Bay Trail Platform Introduction

We used Intel VTune tools to debug the Strongene H.265/HEVC decoder. Then we optimized it using the toolsets as explained in the next three subsections. We obtained extreme decoding speed and low CPU occupancy on Intel Atom processor-based platforms.

3.3.1 Optimized by YASM & Intel® C++ Compiler

Instead of compiling the optimized ASM assembly codes in open source FFMPEG with the default Android* compiler, we used YASM and the Intel® C++ Compiler.

YASM is a complete rewrite of the NASM assembler under the “new” BSD License, which can reuse the Intel SIMD-optimized ASM assembly code for x86 platforms. Developers can download and install the YASM compiler from http://yasm.tortall.net. To use it, modify the configure.sh file to enable the YASM and ASM options before compiling FFMPEG, as shown below:


Figure 21. Modify the FFMPEG Configure File

We also encouraged the ISVs to use the Intel C++ Compiler to compile the native code.

3.3.2 Optimized with Intel® Streaming SIMD Extensions (Intel® SSE) Instructions

Debugging with Intel VTune tools, we found that the Strongene codec only used C code to realize YUV2RGB, making the performance less than optimal.

Intel Atom processor-based platforms support Intel SSE instruction codes, which includes MMX, MMXEXT, Intel SSE, Intel SSE2, Intel SSE3, Intel SSSE3, and Intel SSE4. Enabling Intel SSE code in open source FFMPEG can highly improve the YUV2RGB performance.

We open the Intel SSSE3 compiler option in the FFMPEG using MMX EXT code as shown in the code snippet below.


Figure 22. Enable Intel® SSE Code in the FFMPEG

The Bay Trail platform can support Intel SSE 4.1 instructions, which were used to optimize the H.265/HEVC decoder for better performance.

3.3.3 Optimized by Intel® Threading Building Blocks (Intel® TBB) Tool

When we ran the VTune tool, we found that the Strongene codec created four threads. However, the fastest thread had to wait for the slowest thread, creating idle cores.

Intel SSE can only work on a single core if used alone. Using Intel TBB together with Intel SSE can make the code run on multi-cores, improving performance.

We modified the multi-thread code to perform multi-tasks, then used Intel TBB to allocate the task to the idle cores in order to fully utilize the multi-cores.

Intel TBB can be downloaded from http://threadingbuildingblocks.org/download.


Figure 23. YUV to RGB Comparison Data

Optimization by Intel TBB can get up to 2.6x performance improvement7.

3.3.4 H.265/HEVC Decoder Performance Comparison

OpenGL* was also enabled for rendering because, through testing, we found that optimization by YASM and the Intel C++ Compiler improved performance up to 1.5x, optimization by Intel SSE improved performance up to 6x compared to C code, and optimization by Intel® TBB improved performance up to 2.6x8.

We used Intel® Graphics Performance Analyzers (Intel® GPA) to test the refresh rate when playing video. When tested with the optimized H.265/HEVC decoder on the Bay Trail tablet, the refresh rate can reach 90 FPS (frames per second) when playing the HEVC 1080p video, while the Clover Trail+ tablet can reach 40 FPS.


Figure 24. Performance Comparison on Clover Trail+/ Bay Trail tablets

If we set the refresh rate to 24 FPS on the Bay Trail tablet, when playing the 1080p video, the CPU workload is less than 25%. So we readily recommend the Strongene HEVC decoder solution to the popular online video providers in the PRC for commercial use.

4. Summary

H.265/HEVC will likely be the most popular video standard in the coming decade. Lots of the media applications and products are currently pursuing the HEVC support. In this paper, we implemented a CPU-based, real-time, end-to-end HEVC solution on Intel platforms with new IA platform technologies. Our Intel processor-based advanced solution has been deployed in Xunlei[4] online video services and products, and will definitely accelerate H.265/HEVC technology production and deployment.

5. Other related articles

  1. http://software.intel.com/en-us/articles/optimizing-h265hevc-decoder-on-intel-atom-processor-based-platforms
  2. http://software.intel.com/en-us/articles/real-time-cpu-based-h265hevc-encoding-solution-with-intel-platform-technology-1

Reference

[1] Overview of the High Efficiency Video Coding (HEVC) Standard, IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY, VOL. 22, NO. 12, DECEMBER 2012.
[2] High Efficiency Video Coding (HEVC) text specification draft 10, JCTVC-L1003_v34
[3] http://www.strongene.com/en/homepage.jsp
[4] http://yasm.tortall.net
[5] http://threadingbuildingblocks.org
[6] http://hevc.hhi.fraunhofer.de/

About the authors

  1. Yang Lu is a senior application engineer in the Intel® Software and Solutions Group (SSG), Developer Relations Division, Intel® Xeon® Processor Cloud Platform Enabling team. She has been working at Intel 8 years, working closely with the Asia-Pacific Tier I ISVs enabling Intel architecture technologies.
  2. Finn Wong is a senior application engineer in the Intel Software and Solutions Group (SSG), Developer Relations Division, Intel® Core™ Processor Client Enabling team. His research interests include video coding, digital image processing, computer vision and power optimization.
  3. Songyue Wang is a senior application engineer in the Intel Software and Solutions Group (SSG), Developer Relations Division, Intel® Atom™ Processor Mobile Enabling Team. Songyue is responsible for Android app enabling on Intel Atom processors. He focuses on optimizing multimedia performance on the Bay Trail platform, working closely with the most popular online video providers in the PRC region to enable the H.265/HEVC encoder and decoder solution and Intel® Wireless Display differentiation features on Android for x86 platforms.

 

1 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Xeon® processor E5-2680@2.70GHz with 32GB DDR3-1333 RAM, video trans-coding workload on HEVC codec, by YANG LU. For more information, go to http://www.intel.com/performance

2 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Xeon® processor E5-2697 v2 @2.70GHz with 64GB DDR3-1867 RAM, video trans-coding workload on StrongeneHEVC codec, by YANG LU. For more information, go to http://www.intel.com/performance

3 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Xeon® processor E5-2697 v2 @2.70GHz with 64GB DDR3-1867 RAM, video trans-coding workload on Strongene HEVC codec, by YANG LU. For more information, go to http://www.intel.com/performance

4 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Xeon® processor E5-2697 v2 @2.70GHz with 64GB DDR3-1867 RAM, video trans-coding workload on Strongene HEVC codec, by YANG LU. For more information, go to http://www.intel.com/performance

5 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Core™ processor i5-2520M-based PC with 4GB RAM and Windows* 7 OS, Decoding Frame Rate and CPU Utilization, Finn Wong]. For more information, go to http://www.intel.com/performance

6 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Core™ processor i7-2600-based PC with 8GB RAM and Windows* 7 OS, Decoding Frame Rate for Various Decoders and Configurations, Finn Wong]. For more information, go to http://www.intel.com/performance

7 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Atom™ processor Bay Trail tablet FFRD8 with 2GB RAM and Android 4.2, Decoding Frame Rate, Songyue Wang]. For more information, go to http://www.intel.com/performance

8 Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark* and MobileMark*, are measured using specific computer systems, components, software, operations and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Configurations: Intel® Atom™ processor Bay Trail tablet FFRD8 with 2GB RAM and Android 4.2, Decoding Frame Rate, Songyue Wang]. For more information, go to http://www.intel.com/performance

Intel® RealSense™. Работа с потоками необработанных данных

$
0
0

Download PDF

1. Введение

Разработчикам, которые интересуются возможностями, доступными при внедрении управления без помощи контроллеров в своих приложениях, достаточно ознакомиться с Intel RealSense SDK, сопутствующими примерами и ресурсами в Интернете. Если вы «погрузитесь» в это решение, то обнаружите широкий набор функций, позволяющих создавать совершенно новые, великолепные интерфейсы с использованием новых технологий.

В этой статье мы поговорим о потоках различных необработанных данных, о доступе к ним и о способах их использования. За счет прямого доступа к необработанным данным мы не только сможем работать с метаданными, но и получим самый быстрый способ определять, что делает пользователь в реальном мире.

В этой статье в качестве камеры Intel RealSense мы использовали трехмерную камеру Bell Cliff, которая выдает несколько потоков данных — от традиционного цветного изображения RGB до данных о глубине и картинки с инфракрасной камеры. Каждый из этих потоков ведет себя по-своему, но об этом мы подробнее поговорим ниже. Ознакомившись с этой статьей, вы узнаете, какие потоки доступны и когда работать с ними.

Для понимания представленных материалов полезно (но необязательно) знать C++ для ознакомления с примерами кода и иметь общее представление о технологии Intel RealSense (или о ее более ранней версии — Intel® Perceptual Computing SDK).

2. Почему это важно

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

Итак, первый вопрос: «Что нужно вашему приложению и можно ли выполнить эти требования с помощью модулей алгоритмов Intel RealSense SDK?». Если нужен указатель на экране, отслеживающий перемещение руки, для этого может оказаться достаточно модуля отслеживания руки или пальцев. Чтобы быстро определить, соответствует ли доступная функциональность вашим нуждам, можно использовать примеры в составе SDK. Если таких возможностей недостаточно, то можно приступить к планированию использования потоков необработанных данных.

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

Еще пример: предположим, что вы создаете приложение, которое обнаруживает и распознает язык жестов и преобразует его в текст для передачи в телеконференции. Текущая функциональность Intel RealSense SDK поддерживает отслеживание рук и пальцев (но только в одиночных жестах) и не имеет целенаправленной поддержки распознавания языка жестов. Единственное решение в таких случаях — разработка собственной системы распознавания жестов, которая сможет быстро преобразовывать жесты в последовательность положений пальцев и рук, а с помощью системы шаблонов будет распознавать знаки и восстанавливать текст. Единственный доступный в настоящее время способ достижения этого результата — доступ к потоку необработанных данных с помощью высокоскоростной записи и преобразование значения на лету.

Возможность написания кода для восполнения пробела между существующей и нужной функциональностью крайне важна, и она обеспечивается в Intel RealSense SDK.

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

3. Потоки

Лучший способ узнать о потоках данных — самостоятельно ознакомиться с ними. Для этого нужно запустить пример Raw Streams, находящийся в папке bin установленного экземпляра Intel Realsense SDK.

\Intel\RSSDK\bin\win32\raw_streams.exe

Пример снабжен полным исходным кодом и проектом, который нам очень пригодится. Если запустить исполняемый файл и нажать копку START при запуске приложения, вы получите цветной поток RGB, как показано на рис. 1.

Рисунок 1. Типичный цветной поток RGB

Помахав самому себе ручкой, нажмите кнопку STOP, откройте меню Depth и выберите 640x480x60. Снова нажмите кнопку START.


Рисунок 2. Отфильтрованный поток данных глубины с камеры Intel® RealSense™ 3D.

Как видно на рис. 2, это изображение значительно отличается от цветного потока RGB. Вы видите черно-белое изображение, представляющее расстояние каждого пикселя до камеры. Светлые пиксели ближе, а темные — дальше; черные либо считаются фоном, либо не распознаны достоверно.

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


Рисунок 3. Ночное видение. Камера Intel® RealSense™ 3D выдает поток необработанного видеоизображения, снятого в инфракрасном спектре.

Последний тип потока может быть неизвестен прежним разработчикам Intel Perceptual Computing SDK, но на рис. 3 видно, что в меню IR можно получить с камеры изображение, снятое в инфракрасном диапазоне. Это поток необработанных данных, его скорость чтения намного превышает частоту обновления типовых мониторов.

 

Можно инициализировать все или любые из этих потоков для их одновременного чтения по мере потребностей приложения; для каждого потока можно выбрать требуемое разрешение и частоту обновления. Важно отметить, что итоговая кадровая скорость входящих потоков будет зависеть от доступной пропускной способности. Например, если попытаться инициализировать поток RGB при 60 кадрах в секунду, поток глубины при 120 кадрах в секунду и ИК-поток при 120 кадрах в секунду и передавать все эти потоки с единой синхронизацией, будет доступна лишь наименьшая скорость обновления (60 кадров в секунду), и только если с такой работой справится система.

Образец с необработанными потоками пригоден для начала работы, но не позволяет сочетать потоки, поэтому его следует использовать только для ознакомления с типами, разрешениями и скоростями обновления, доступными для вашей камеры. Помните, что пакет Intel RealSense SDK предназначен для работы с различными типами трехмерных камер, поэтому разрешение образца может быть недоступным на других камерах. Поэтому не следует жестко задавать разрешение в коде приложений.

4. Создание потоков и доступ к данным

Просмотреть полный исходный код примера с необработанными потоками можно, открыв следующий проект в Visual Studio*.

\Intel\RSSDK\sample\raw_streams\raw_streams_vs20XX.sln

В примере содержится простой пользовательский интерфейс и полный набор параметров, поэтому код не очень легко читается. Имеет смысл убирать добавочный код и оставлять только необходимые строки кода, служащие для того, чтобы создавать, обрабатывать и удалять поток, полученный с камеры. Ниже приведен код, представляющий собой «очищенную» версию приведенного выше проекта, но в этом коде сохранены все необходимые компоненты даже для простейших приложений Intel RealSense.

Первые две важные функции — это инициализация камеры Intel RealSense 3D и ее высвобождение по завершении работы программы. Это видно в приведенном ниже коде, а подробные сведения о вызываемых функциях будут приведены ниже.


int RSInit ( void )
{
	InitCommonControls();
	g_session=PXCSession::CreateInstance();
	if (!g_session) return 1;
	g_bConnected = false;
	g_RSThread = CreateThread(0,0,ThreadProc,g_pGlob->hWnd,0,0);
	Sleep(6000);
	if ( g_bConnected==false )
		return 1;
	else
		return 0;
}

void RSClose ( void )
{
	g_bConnected = false;
	WaitForSingleObject(g_RSThread,INFINITE);
}


Здесь мы имеем функции верхнего уровня для любого приложения, предназначенного для необработанных данных: создание экземпляра сеанса и потока для выполнения кода, обрабатывающего поток, затем высвобождение потока с помощью глобального флага g_bConnected. Рекомендуется использовать потоки ЦП при работе с потоками данных, поскольку это даст возможность основному приложению работать с любой требуемой кадровой скоростью, независимо от кадровой скорости камеры. Кроме того, это помогает распределить нагрузку на ЦП среди нескольких ядер, благодаря чему повышается общая производительность приложения.

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


static DWORD WINAPI ThreadProc(LPVOID arg)
{
	CRITICAL_SECTION g_display_cs;
	InitializeCriticalSection(&g_depthdataCS);
	HWND hwndDlg=(HWND)arg;
	PopulateDevices(hwndDlg);
	PXCCapture::DeviceInfo dinfo=GetCheckedDevice(hwndDlg);
	PXCCapture::Device::StreamProfileSet profiles=GetProfileSet(hwndDlg);
	StreamSamples((HWND)arg,&dinfo,&profiles,
		false, false, false,
		g_file
		);

	ReleaseDeviceAndCaptureManager();
	g_session->Release();
	DeleteCriticalSection(&g_depthdataCS);
	return 0;
}

Для работы с потоком данных важно создать «главный раздел» в коде. Если не сделать это в многопоточной среде, то два потока теоретически смогут записывать данные в одну и ту же глобальную переменную одновременно, что нежелательно.

Для тех, кто не знаком с многопоточностью, эта функция вызывается и не завершается, пока для главного потока (создавшего этот поток) для параметра g_bConnected не будет установлено значение false. Главный вызов функции здесь — StreamSamples, а остальной код выше и ниже служит лишь для входа и выхода. Первая интересующая нас функция — PopulateDevices, она практически идентична такой же функции в проекте raw_streams. Она заполняет список g_devices именами всех доступных устройств. Если вы используете камеру Intel RealSense 3D на ультрабуке, то есть вероятность, что у вас будет два устройства (второе — встроенная камера ультрабука). Обратите внимание на следующие строки.


static const int ID_DEVICEX=21000;
static const int NDEVICES_MAX=100;
int c = ID_DEVICEX;
g_session->CreateImpl<PXCCapture>(g_devices[c],&g_capture);
g_device=g_capture->CreateDevice((c-ID_DEVICEX)%NDEVICES_MAX);

Код, константы и глобальные функции скопированы из первоначального кода, их можно еще более сократить. Важнейшие вызовы здесь — Createlmpl и CreateDevice. В результате указатель камеры Intel RealSense 3D теперь хранится в g_device.

При наличии действующего указателя на устройство остальной код инициализации работает без проблем. Функция StreamProfileSet является оболочкой для этого кода.

g_device->QueryDeviceInfo(&dinfo);

Функция StreamProfileSet отвечает за сбор всех типов потоков и разрешений, которые нужно инициализировать, она может быть простой или сложной, исходя из потребностей. В целях совместимости с камерами настоятельно рекомендуется перечислить доступные разрешения и типы в списке вместо жесткого кодирования фиксированных настроек.


PXCCapture::Device::StreamProfileSet GetProfileSet(HWND hwndDlg)
{
	PXCCapture::Device::StreamProfileSet profiles={};
	if (!g_device) return profiles;

	PXCCapture::DeviceInfo dinfo;
	g_device->QueryDeviceInfo(&dinfo);
	for (int s=0, mi=IDXM_DEVICE+1;s<PXCCapture::STREAM_LIMIT;s++)
	{
		PXCCapture::StreamType st=PXCCapture::StreamTypeFromIndex(s);
		if (!(dinfo.streams&st)) continue;

		int id=ID_STREAM1X+s*NPROFILES_MAX;
		int nprofiles=g_device->QueryStreamProfileSetNum(st);
		for (int p=0;p<nprofiles;p++)
		{
			if ( st==PXCCapture::StreamType::STREAM_TYPE_COLOR ) continue;
			if ( st==PXCCapture::StreamType::STREAM_TYPE_IR ) continue;
			if ( st==PXCCapture::StreamType::STREAM_TYPE_DEPTH && p==2 )
						{
				PXCCapture::Device::StreamProfileSet profiles1={};
				g_device->QueryStreamProfileSet(st, p, &profiles1);
				profiles[st]=profiles1[st];
						}
		}
		mi++;
	}

	return profiles;
}


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

Итоговая функция и центральный блок кода для доступа к данным потока — StreamSamples. Если убрать код безопасности и комментарии, код будет выглядеть так:


void StreamSamples(HWND hwndDlg, PXCCapture::DeviceInfo *dinfo, PXCCapture::Device::StreamProfileSet *profiles, bool synced, bool isRecord, bool isPlayback, pxcCHAR *file)
{
	PXCSenseManager *pp=g_session->CreateSenseManager();
	pp->QueryCaptureManager()->FilterByDeviceInfo(dinfo);
	for (PXCCapture::StreamType st=PXCCapture::STREAM_TYPE_COLOR;st!=PXCCapture::STREAM_TYPE_ANY;st++)
	{
		PXCCapture::Device::StreamProfile &profile=(*profiles)[st];
		if (!profile.imageInfo.format) continue;
		pp->EnableStream(st,profile.imageInfo.width, profile.imageInfo.height, profile.frameRate.max);
	}
	pp->QueryCaptureManager()->FilterByStreamProfiles(profiles);
	MyHandler handler(hwndDlg);
	if (pp->Init(&handler)>=PXC_STATUS_NO_ERROR)
	{
		pp->QueryCaptureManager()->QueryDevice()->SetMirrorMode(PXCCapture::Device::MirrorMode::MIRROR_MODE_DISABLED);
		g_bConnected = true;
		for (int nframes=0;g_bConnected==true;nframes++)
		{
			pxcStatus sts2=pp->AcquireFrame(synced);
			if (sts2<PXC_STATUS_NO_ERROR && sts2!=PXC_STATUS_DEVICE_LOST) break;
			if (sts>=PXC_STATUS_NO_ERROR)
			{
				PXCCapture::Sample *sample = (PXCCapture::Sample*)pp->QuerySample();

				short invalids[1];
				invalids[0] = pp->QueryCaptureManager()->QueryDevice()->QueryDepthSaturationValue();
				invalids[1] = pp->QueryCaptureManager()->QueryDevice()->QueryDepthLowConfidenceValue();

				PXCImage::ImageInfo dinfo=sample->depth->QueryInfo();
				PXCImage::ImageData ddata;
				if (sample->depth->AcquireAccess(	PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_DEPTH,&ddata)>=PXC_STATUS_NO_ERROR)
				{
					EnterCriticalSection(&g_depthdataCS);
					memset ( g_depthdata, 0, sizeof(g_depthdata) );
					short *dpixels=(short*)ddata.planes[0];
					int dpitch = ddata.pitches[0]/sizeof(short);
					for (int y = 0; y < (int)dinfo.height; y++)
					{
						for (int x = 0; x < (int)dinfo.width; x++)
						{
							short d = dpixels[y*dpitch+x];
							if (d == invalids[0] || d == invalids[1]) continue;
							g_depthdata[x][y] = d;
						}
					}
					LeaveCriticalSection(&g_depthdataCS);
					g_bDepthdatafilled = true;
				}
				sample->depth->ReleaseAccess(&ddata);
			}
			pp->ReleaseFrame();
		}
	}
	pp->Close();
	pp->Release();
}

На первый взгляд, здесь многовато кода, но, если разобраться, вы увидите, что это просто несколько вызовов настройки, условный цикл и заключительная чистка перед возвращением к функции ThreadProc, вызвавшей этот код. Основная используемая переменная называется pp, это указатель диспетчера Intel RealSense SDK для наших основных действий. Примечание. Как было сказано выше, для повышения удобочитаемости кода из него удалено отслеживание ошибок, но на практике не следует создавать код, исходящий из того, что все без исключения вызовы Intel RealSense SDK будут успешными.

Первый фрагмент кода, который будет включать интересующие нас потоки, выглядит так:

pp->EnableStream(st,profile.imageInfo.width, profile.imageInfo.height, profile.frameRate.max);

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


MyHandler handler(hwndDlg);
if (pp->Init(&handler)>=PXC_STATUS_NO_ERROR

Класс MyHandler определен в исходном проекте raw_streams и происходит от класса PXCSenseManager: Handler. В случае успеха вы узнаете, что камера включена и передает поток данных.

Теперь нужно запустить условный цикл, который будет работать до тех пор, пока какое-либо внешнее воздействие не изменит условие цикла. В этом цикле мы будем получать данные потока последовательно по одному кадру. Для этого используется команда AcquireFrame.


	for (int nframes=0;g_bConnected==true;nframes++)
	{
		pxcStatus sts2=pp->AcquireFrame(synced);

Пока g_bConnected имеет значение true, мы будем делать это как можно быстрее в отдельном потоке, созданном для этой цели. Для получения фактических данных требуется еще несколько строк кода:


	PXCCapture::Sample *sample = (PXCCapture::Sample*)pp->QuerySample();

	short invalids[1];
	invalids[0] = pp->QueryCaptureManager()->QueryDevice()->QueryDepthSaturationValue();
	invalids[1] = pp->QueryCaptureManager()->QueryDevice()->QueryDepthLowConfidenceValue();

	PXCImage::ImageInfo dinfo=sample->depth->QueryInfo();
	PXCImage::ImageData ddata;
	if (sample->depth->AcquireAccess(	PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_DEPTH,&ddata)>=PXC_STATUS_NO_ERROR)

Первая команда получает от диспетчера образец указателя и использует его для получения указателя на фактические данные в памяти с помощью последней команды AcquireAccess. Код выполняет два запроса, чтобы узнать у диспетчера, какие значения соответствуют «насыщенному» пикселю и «недостоверному» пикселю. Оба этих условия могут возникнуть при получении данных глубины с камеры. Их следует игнорировать при интерпретации возвращенных данных. Основной результат этого кода: структура данных ddata теперь заполнена информацией, которая позволит нам получить прямой доступ к данным глубины (в этом примере). Изменив соответствующие параметры, можно получить доступ к данным потоков COLOR и IR, если они включены.

На этом фрагмент кода, относящийся к Intel RealSense SDK, завершен (от первого вызова инициализации до получения указателя на данные потока). Остальной код будет несколько привычнее для разработчиков, обладающих опытом создания программ для обработки изображений.


		EnterCriticalSection(&g_depthdataCS);
		memset ( g_depthdata, 0, sizeof(g_depthdata) );
		short *dpixels=(short*)ddata.planes[0];
		int dpitch = ddata.pitches[0]/sizeof(short);
		for (int y = 0; y < (int)dinfo.height; y++)
		{
			for (int x = 0; x < (int)dinfo.width; x++)
			{
				short d = dpixels[y*dpitch+x];
				if (d == invalids[0] || d == invalids[1]) continue;
				g_depthdata[x][y] = d;
			}
		}
		LeaveCriticalSection(&g_depthdataCS);

Обратите внимание, что важный объект сеанса, созданный ранее, используется для блокировки нашего потока, чтобы никакой другой поток не мог получить доступ к нашим глобальным переменным. Это делается для того, чтобы можно было написать глобальный массив и быть уверенным в том, что на работу не будет влиять код из другой части приложения. Если проследить вложенные циклы, вы увидите, что после блокировки потока мы очищаем глобальный массив g_depthdata и заполняем его значениями из упомянутой выше структуры ddata, которая содержит указатель на данные глубины. Во вложенных циклах мы также сравниваем значение пикселей глубины с двумя недопустимыми значениями, которые мы задали раньше с помощью вызовов QueryDepthSaturationValue и QueryDepthLowConf idenceValue.

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

5. Что делать с данными потока

Итак, теперь вы знаете, как получить поток данных с камеры Intel RealSense 3D, и, наверное, интересуетесь, что делать с этими данными. Разумеется, можно просто вывести эти данные на экран и полюбоваться изображением, но вскоре потребуется преобразовать эти данные в полезную информацию и обработать ее в вашем приложении.

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

Найти ближайшую точку

Рекомендуется найти ближайшую к камере точку объекта, находящегося перед ней. При этом вы только что передали данные глубины из потока данных в глобальный массив в потоке ЦП. Можно создать вложенный цикл для проверки каждого значения в массиве:


short bestvalue = 0;
int bestx = 0;
int besty = 0;
for ( int y = 0; y < (int)dinfo.height; y++)
{
	for ( int x = 0; x < (int)dinfo.width; x++)
	{
		short thisvalue = g_depthdata[x][y];
		if ( thisvalue > bestvalue )
		{
			bestvalue = thisvalue;
			bestx = x;
			besty = y;
		}
	}
}

Каждый раз при обнаружении более близкого значения оно заменяет текущее наилучшее значение, при этом записываются координаты по осям X и Y. К тому моменту, когда цикл обойдет каждый пиксель в данных глубины, в итоговых переменных BESTX и BESTY будут храниться координаты данных глубины для ближайшей к камере точки.

Игнорировать объекты на заднем плане

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


short newshape[dinfo.height][dinfo.width];
memcpy(newshape,0,sizeof(newshape));
for ( int y = 0; y < (int)dinfo.height; y++)
{
	for ( int x = 0; x < (int)dinfo.width; x++)
	{
		short thisvalue = g_depthdata[x][y];
		if ( thisvalue>32000 && thisvalue<48000 )
		{
			newshape[x][y] = thisvalue;
		}
	}
}

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

6. Подсказки и советы

Что следует делать

  • Если вы работаете с примерами впервые и используете ультрабук со встроенной камерой, то приложение может использовать эту встроенную камеру вместо камеры Intel RealSense. Убедитесь, что камера Intel RealSense правильно подключена и что ваше приложение использует устройство Intel® RealSense™ 3D camera. Для получения дополнительных сведений о том, как найти список устройств, см. ссылки на g_devices в этой статье.
  • Всегда старайтесь использовать многопоточные вычисления в приложении Intel RealSense: в этом случае приложение не будет «привязано» к кадровой скорости потока камеры Intel RealSense 3D, а на многоядерных системах будет достигнута более высокая производительность.

Чего не следует делать

  • Не задавайте жестко в коде параметры устройства или профиля при инициализации потоков, поскольку будущие камеры Intel RealSense 3D могут не поддерживать заданные вами параметры. Всегда следует перечислять доступные устройства и профили и использовать условия поиска, чтобы найти нужное.
  • Избегайте ненужной передачи данных во вторичные массивы, поскольку при каждом таком цикле расходуется немало ресурсов ЦП и памяти. Старайтесь, чтобы анализ данных был как можно ближе к первоначальной операции чтения данных..

7. Заключение

Знание того, как получить поток необработанных данных с камеры Intel RealSense 3D, поможет расширить возможности этой технологии и создавать современные решения. Мы уже видели великолепные приложения с управлением без помощи рук, созданные первыми разработчиками в этой области, но это лишь малая часть всех возможностей новых технологий.

Многие пользователи по-прежнему относятся к компьютерам как к устройствам, на которые следует активно воздействовать, чтобы они работали, но теперь компьютеры получили «зрение» и могут наблюдать за всеми нашими движениями. Не подсматривать, прошу заметить, а просто наблюдать, чтобы в нужный момент прийти на помощь. Согласно поговорке в стране слепых одноглазый станет королем. Разве неверно, что мы живем в мире, населенном «слепыми» компьютерами? Представьте, какая произойдет революция, если один из них в не столь отдаленном будущем «прозреет»? Будучи разработчиками, мы являемся архитекторами этой революции, вместе мы можем создать совершенно новую парадигму, в которой компьютеры видят своих операторов и стараются им помогать.

Об авторе

В свободное от написания статей время Ли Бэмбер (Lee Bamber) руководит британской компанией The Game Creators (http://www.thegamecreators.com), которая специализируется на разработке и распространении средств создания компьютерных игр. Эта компания ведет свою историю с 1999 года. Среди плодов работы этой компании вместе с окружающим ее разработчиком игр — множество популярных брендов, в том числе Dark Basic, FPS Creator, а также App Game Kit (AGK).

Ли ведет хронику своей повседневной работы разработчика вместе со снимками экрана и видеороликами: http://fpscreloaded.blogspot.co.uk

Планирование оптимизации с Unity*

$
0
0

By John Wesolowski

Загрузки

How To Plan Optimizations with Unity* [PDF 2.15MB]


Аннотация

Unity содержит ряд настроек и инструментов, позволяющих добиться плавной работы графики в играх. Для этого проекта мы отобрали те из них, с которыми могут возникнуть сложности, и проанализировали их влияние на производительность игр на ГП Intel®.

Мы рассматриваем использование Unity с точки зрения разработчика игр. Мы стремились найти области снижения производительности, а затем определить, как улучшить работу приложений с помощью встроенных в Unity средств. Одно из преимуществ Unity состоит в возможности быстрого создания контента, но для того, чтобы добиться производительности, особенно на мобильных устройствах и планшетах, разработчику потребуется тщательно спланировать использование встроенных механизмов оптимизации производительности. В этой статье новым и существующим пользователям Unity предлагаются советы по повышению производительности при создании уровней и игр, а также описываются новые способы создания содержимого.


Введение

Создавать игры с использованием Unity относительно просто. В Unity имеется магазин, где можно приобретать различные элементы, такие как модели, готовые сценарии, демо или даже полные игры. Для тестирования я работал с существующей игрой, чтобы определить, в каких областях можно добиться повышения производительности, а в каких — нет. Я использовал техническое демо Unity под названием Boot Camp (ее можно бесплатно загрузить в магазине ресурсов), чтобы оценить сложность проблемы.

Для создания игровых параметров и запуска всех сцен я использовал Unity 3.0. Тестирование проводилось на компьютере с процессором Intel® Core 3-го поколения с ГП Intel® HD Graphics 4000. Результаты тестирования неприменимы к мобильным устройствам.

Quality Manager

В Unity доступны дополнительные параметры рендеринга для игр: меню Edit->Project Settings->Quality (рис. 1). Это настраиваемые параметры рендеринга, которые можно настроить индивидуально. В Unity содержится встроенная документация, поясняющая параметры качества и их настройку с помощью API сценариев Unity.

Рисунок 1. Доступ к тегам и слоям осуществляется через меню Edit->Project Settings->Tag inspector

Для изыскания возможностей оптимизации в Unity я решил попробовать изменить настройки качества, чтобы понять, что при этом можно выиграть или потерять, хотя я не тестировал все доступные параметры.

Качество текстур

В Quality Settings Inspector есть раскрывающееся меню, где можно выбрать разрешение рендеринга для текстур. Можно выбрать разрешение 1/8, ¼, ½ или полное разрешение. Для оценки прироста или снижения производительности при разном разрешении текстур я измерил кадровую скорость тестовой сцены при всех доступных в Unity настройках качества по умолчанию (Fastest, Fast, Good и пр.), изменяя только качество текстур перед каждым измерением.

На рис. 2 и 3 показано сравнение между сценами с 1/8 разрешения текстур и с полным разрешением текстур.

Рисунок 2. Сцена Unity* Boot Camp с разрешением 1/8

Рисунок 3. Сцена Unity* Boot Camp с полным разрешением

Мы измерили кадровую скорость (в кадрах в секунду) с помощью Intel® Graphics Performance Analyzers (Intel® GPA) после изменения разрешения текстур. При уровне качества Fantastic (таблица 1) видно, что производительность не слишком заметно изменилась при изменении размера текстур.

Таблица 1. Изменение кадровой скорости при переключении между различным качеством текстур в Unity

На компьютерах с ГП Intel®производительность теоретически не изменяется в зависимости от размера текстур, но следует учитывать и другие факторы, такие как общий объем памяти устройства и использование памяти приложением.

Shadow Distance

Shadow Distance — это параметр, определяющий глубину отбраковки, используемую для теней игровых объектов. Если игровой объект находится в пределах заданного расстояния от камеры, то тени этого объекта отрисовы­ваются, если же объект находится дальше этого расстояния, то тени такого объекта не отображаются (исключаются из отрисовки).

В зависимости от используемых параметров тени могут отрицательно повлиять на производительность, поскольку их расчет и отрисовка являются ресурсоемкими операциями. Тестирование влияния параметра Shadow Distance

  • Создайте тестовую сцену.
  • Задайте для этой сцены параметры качества Unity по умолчанию.
  • Постепенно увеличивайте значение параметра Shadow Distance и измеряйте кадровую скорость с помощью Intel GPA.
  • Выберите другое значение качества по умолчанию в Unity и повторите измерение кадровой скорости.

В этом тесте уровни качества Fastest и Fast не использовались, поскольку в этих режимах тени отключены.


Рисунок 4. Этот параметр доступен в меню Inspector: Edit->Project Settings->Quality

Рисунок 5. Техническое демо Unity* Boot Camp

Таблица 2. Изменение кадровой скорости при изменении значения параметра Shadow Distance в технической демонстрации Unity* Boot Camp

Тени значительно влияют на производительность. Тест показал, что кадровая скорость упала почти вдвое при переключении расстояния с 0 до 50 в режиме Simple. Важно учитывать, действительно ли видны игровые объекты, и убедиться, что ненужные тени не отрисовываются. Глубину отбраковки теней можно настра­ивать с помощью сценариев Unity для различных ситуаций. Мы проверили только воздействие глубины отбраковки теней, но аналогичные изменения производи­тельности могут возникать и при настройке других параметров качества теней.

Слои

Всем игровым объектам в Unity при создании назначается слой. Изначально всем объектам назначается слой по умолчанию, как показано на рис. 6, но можно создать собственные уникальные слои. Это можно сделать двумя способами. Можно просто щелкнуть поле Layer и выбрать Add New Layer. Также можно использовать меню Edit->Project Settings->Tags.

Рисунок 6. Меню Layer в окне Inspector игрового объекта

Рисунок 7. Tag Manager в окне Inspector

В окне Inspector (рис. 7) можно создать новый слой и указать, к какому номеру слоя он должен принадлежать. При использовании обоих методов открывается одно и то же окно Tag Manager. После создания слоя можно назначать этому слою игровые объекты, выбирая нужный слой в окне параметров в окне Inspector игрового объекта в поле Layer. Таким способом можно группировать объекты на одних и тех же слоях, чтобы затем обрабатывать их вместе. Помните о том, что такое слои, и как их создавать и настраивать, когда я буду рассказывать о некоторых других функциях слоев в этой статье.

Расстояния отбраковки слоев

Камера не будет отрисовывать игровые объекты, находящиеся за пределами плоскости отсечения в Unity. С помощью сценариев Unity можно задать для определенных слоев более короткое расстояние до плоскости отсечения.

Рисунок 8. Образец сценария из документации Unity с изменением расстояния отбраковки слоев

Настройка более короткого расстояния отбраковки для игровых объектов требует некоторой работы. Сначала нужно разместить объекты на слое. Затем нужно написать сценарий, чтобы изменить расстояние отбраковки этого конкретного слоя, и назначить сценарий камере. Образец сценария на рис. 8 показывает, как создается массив 32 значений с плавающей запятой, соответствующий 32 доступ­ным слоям, которые можно создать с помощью меню Edit->Project Settings->Tags. Если изменить значение индекса в этом массиве и присвоить его camera.layerCullDistances, то для соответствующего слоя изменится расстояние отбраковки. Если не назначить число индексу, то соответствующий слой будет использовать дальнюю плоскость отсечения камеры.

Для тестирования производительности layerCullDistances я создал три сцены, заполненные объектами низкой, средней и высокой сложности. В этих сценах идентичные игровые объекты собраны вместе и расположены в ряд с постепенным удалением от камеры. Я использовал Intel GPA для измерения кадровой скорости при постепенном увеличении расстояния отбраковки слоя, добавляя по группе объектов при каждом измерении (т. е. одна группа объектов при первом измерении, 6 групп объектов при шестом измерении).

На рисунках 9, 10 и 11 показаны сцены, которые я использовал для тестирования с объектами разных типов.

Сапоги: полигонов — 278, вершин — 218

Рисунок 9. Тестовая сцена с сапогами — объектами с низким числом полигонов и вершин

Динозавры: полигонов — 4398, вершин — 4400

Рисунок 10. Тестовая сцена с динозаврами — объектами со средним числом полигонов и вершин

Самолеты: полигонов — 112 074, вершин — 65 946

Рисунок 11. Тестовая сцена с самолетами — объектами с большим числом полигонов и вершин

В таблицах 3, 4 и 5 показано изменение кадровой скорости во всех тестовых сценах.


Таблица 3. Данные, полученные в сцене с сапогами (рис. 9)

Таблица 4. Данные, полученные в сцене с динозаврами (рис. 10)

Таблица 5. Данные, полученные в сцене с самолетами (рис. 11)

Таблица 6. Данные всех тестовых сцен в режиме Fantastic

Эти данные показывают повышение производительности, которого можно добиться с помощью функции layerCullDistances в Unity

В таблице 6 показано, как производительность изменяется при увеличении количества объектов на экране, особенно если это сложные объекты. С точки зрения разработчика игр, правильное использование layerCullDistances позволяет значительно повысить производительность. Например, для маленьких объектов со сложной моделью, расположенных дальше от камеры, можно настроить отрисовку только при достаточном приближении, когда эти объекты уже можно различить. При планировании и создании уровней разработчику следует учитывать сложность моделей и видимость объектов, расположенных на большом расстоянии от камеры. Заблаговременное планирование позволяет добиться лучших результатов при использовании layerCullDistances.

Камера

Я изучил возможности работы с камерой в Unity и ее настройки. Я попробовал выбрать различные параметры, поработал с другими компонентами и дополнениями.


Рисунок 12. Меню Inspector, открывающееся после выбора камеры

При создании новой сцены по умолчанию появляется только один игровой объект камеры под названием Main Camera. Чтобы добавить еще одну камеру, сначала создайте пустой игровой объект: Game Object->Create Empty. Затем выберите этот пустой объект и добавьте компонент камеры: Components->Rendering->Camera.

Камеры в Unity поддерживают широкие возможности настройки, как показано на рис. 12. Вот какие настройки я рассмотрел: Rendering Path и HDR.

Render Path

С помощью параметра Render Path можно указать в Unity, как обрабатывать рендеринг света и теней в игре. В Unity поддерживаются три типа рендеринга, вот они в порядке от наиболее ресурсоемкого к наименее ресурсоемкому: Deferred (отложенная, только в Unity Pro), Forward (заблаговременная) и Vertex Lit (освещение вертексов). В каждом случае тени и свет обрабатываются немного иначе, и для их обработки требуется разный объем ресурсов ЦП и ГП. Важно понимать, для какой платформы и для какого оборудования ведется разработка, чтобы выбрать соответствующий рендерер. Если выбрать рендерер, который не поддерживается графическим адаптером, Unity автоматически переключится на менее ресурсоемкий способ рендеринга.

Рисунок 13. Окно Player Settings Inspector

Настроить значение Rendering Path можно двумя способами. Первый способ:
Edit->Project Settings->Player (рис. 13). Раскрывающийся список Rendering Path находится на вкладке Others Settings. Второй способ: с помощью окна пользовательского интерфейса Camera Inspector (рис. 14). Если выбрать любой параметр, отличный от Use Player Settings, настройки по умолчанию будут заменены, но только для данной камеры. Поэтому можно использовать разные камеры с различными настройками буфера рендеринга для света и теней.

Рисунок 14. Раскрывающийся список при выборе параметра Rendering Path в окне Camera

Разработчики должны знать, каким образом действуют различные режимы рендеринга освещения, входящие в состав Unity. В разделе справочных материалов в конце этого документа приводятся ссылки на документацию по Unity. Убедитесь, что вы точно знаете целевую аудиторию своей игры и платформу, на которой потенциальные пользователи будут играть в эту игру. Это поможет вам выбрать соответствующий способ рендеринга для данной платформы. Например, если игра содержит несколько источников света и графических эффектов, использующих отложенный рендеринг, то на компьютерах с маломощным графическим адаптером играть в такую игру будет попросту невозможно. Если ваша целевая аудитория включает любителей казуальных игр, устройства которых не обладают высокой вычислительной мощью, то также могут возникнуть проблемы. Разработчики должны знать целевую платформу, для которой предназначена их игра, и соответственным образом выбирать способ рендеринга и обработки освещения в игре.

HDR (High Dynamic Range)

При обычном рендеринге значения красного (R), зеленого (G) и синего (B) цветов каждого пикселя представлены десятичным числом, значение которого составляет от 0 до 1. Если ограничить диапазон значений для этих цветов, освещение будет выглядеть нереалистично. Чтобы добиться более естественного освещения, в Unity можно включить расширенный динамический диапазон (HDR). В этом случае значения R, G и B каждого пикселя могут выходить за пределы обычного диапазона. HDR создает буфер изображения, поддерживающий значения вне диапазона от 0 до 1, и выполняет постобработку графических эффектов, таких как размытие и блики. После вычисления эффектов постобработки значения R, G и B в буфере изображения сбрасываются до значений в пределах диапазона от 0 до 1 технологией построения карт оттенков Unity. Если построение карт оттенков не выполняется при использовании HDR, то пиксели могут оказаться за пределами допустимого диапазона, из-за чего некоторые цвета сцены могут выглядеть неправильно по сравнению с остальными.

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

Если сцена обрабатывается с помощью отложенного рендеринга, а камере присвоены графические эффекты, то следует включить HDR. На рис. 15 сравнивается количество вызовов рендеринга для сцены с эффектами и отложенным рендерингом при включенном и отключенном HDR. Без HDR количество вызовов рендерингазначительно выше, чем при использовании HDR, если сцена содержит эффекты. На рис. 15 количество вызовов рендеринга представлено отдельными синими полосками, а высота каждой полоски соответствует величине нагрузки каждого вызова на ГП.


Рисунок 15. Измерение, проведенное с помощью Intel® Graphics Performance Analyzers, показывает, что при отключенном HDR выполняется свыше 2000 вызовов рендеринга, тогда как при включенном HDR — немногим более 900 вызовов рендеринга.

Ознакомьтесь с документацией Unity по HDR, чтобы понять, как работает эта функциональность. Также нужно знать, в каких случаях следует применять расширенный динамический диапазон, чтобы получить за счет этого прирост производительности, а в каких случаях это не имеет смысла.

Графические эффекты

В Unity Pro содержится ряд графических эффектов, которыеулучшают вид сцены. Чтобы добавить компонент Image Effects после создания проекта, используйте меню Assets->Import Package->Image Effects. После импорта можно добавить эффект к камере двумя способами. Щелкните игровой объект камеры, в окне камеры выберите Add Component, а затем Image Effects. Также можно щелкнуть объект камеры в меню, выбрав Component->Image Effect.

Рассеянное затенение в экранном пространстве — SSAO

 

Рассеянное затенение в экранном пространстве (SSAO) — это графический эффект в составе пакета Image Effect в Unity Pro. На рис. 16 показано различие между включенным и отключенным SSAO. Изображения выглядят схоже, но производительность существенно различается. У сцены без SSAO кадровая скорость составила 32 кадра в секунду, а с SSAO — 24 кадра в секунду, то есть на 25 % ниже.


Рисунок 16. Сравнение одного и того же уровня с отключенным SSAO (сверху) и с включенным SSAO (снизу)

Будьте осторожны при добавлении графических эффектов, поскольку они могут отрицательно повлиять на производительность. При подготовке этого документа мы тестировали только SSAO, но следует ожидать схожих результатов и при использовании других эффектов.

Исключение заслоненных объектов

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

Заслоняющий объект — объект, помеченный как заслоняющий, выступает в качестве преграды: все загороженные им объекты, помеченные как заслоняемые, не отрисовываются.

Заслоняемый объект — если пометить объект таким образом, он не будет отрисовываться в Unity, если его загораживает заслоняющий объект.

Например, если пометить все объекты, находящиеся внутри дома, как заслоняемые, то сам дом можно пометить как заслоняющий. Если игровой персонаж будет находиться снаружи этого дома, то все объекты внутри дома, помеченные как заслоняемые, не будут отрисовываться. При этом ускоряется обработка на ЦП и ГП.

Использование и настройка исключения заслоненных объектов задокументированы в Unity. Ссылку на информацию по настройке см. в разделе справочных материалов.

Для демонстрации изменения производительности (в зависимости от исключения заслоненных объектов) я создал сцену, где на переднем плане находится стена, а за ней — объекты со сложными моделями. Я измерил кадровую скорость сцены с исключением заслоненных объектов, а затем без него. На рис. 17 показана сцена с разной кадровой скоростью.


Рисунок 17. На изображении слева исключение заслоненных объектов отключено, отрисовываются все объекты, расположенные за стеной, поэтому кадровая скорость составляет 31 кадр в секунду. На изображении справа исключение заслоненныхобъектов включено, объекты, заслоненные стеной, не отрисовываются, поэтому скорость возросла до 126 кадров в секунду.

Исключение заслоненных объектов должно быть настроено разработчиками вручную. Не следует забывать об исключении заслоненных объектов при проектировании игр, поскольку это снижает требования к оборудованию и позволяет повысить производительность.

Уровень детализации (LOD)

С помощью уровня детализации (LOD) можно присвоить одному игровому объекту несколько моделей разной сложности и переключаться между ними в зависимости от расстояния между объектом и камерой. Это может быть выгодно с точки зрения производительности для сложных игровых объектов, находящихся далеко от камеры. С помощью уровня детализации можно автоматически упрощать модели. Сведения об использовании и настройке уровня детализации см. в документации Unity. Ссылка приведена в разделе справочных материалов.

Для тестирования прироста производительности при изменении уровня детализации я создал сцену с группой домов, которым присвоено 3 разные модели. Расположив камеру в одном и том же месте, я измерил кадровую скорость сцены с домами при использовании самой сложной модели. Затем я изменил расстояние детализации, чтобы задействовать модели с меньшей степенью детализации, и провел измерение еще раз. Я проделал эту процедуру для трех уровней моделей и записал полученные данные в таблице 5.

На рис. 18, 19 и 20 показаны три разных уровня сложности моделей с указанием количества полигонов и вершин в каждой модели.

 

Наилучшее качество — уровень детализации 0

Здание А

Вершин — 7065

Полигонов – 4999

Здание Б

Вершин — 5530

Полигонов – 3694

Рисунок 18. Уровень детализации 0. Это наивысший уровень детализации, на котором используются самые сложные модели

 

Среднее качество — уровень детализации 1

Здание А

Вершин — 6797

Полигонов — 4503

Здание Б

Полигонов — 5476

Вершин — 3690

Рисунок 19. Уровень детализации 1. Этот уровень находится на одну ступень ниже по шкале детализации, на нем используются модели средней сложности

   

Низкое качество — уровень детализации 2

Здание А

Вершин — 474

Полигонов – 308

Здание Б

Полигонов – 450

Вершин — 320

Рисунок 20. Уровень детализации 2. Это последний уровень детализации, здесь используются наименее сложные модели

Переключаясь между разными уровнями детализации, я измерял кадровую скорость для сравнения (таблица 7).

Таблица 7. Сравнение кадровой скорости при разных уровнях детализации

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

Пакетная обработка

Избыточное количество вызовов рендеринга может привести к чрезмерной нагрузке на ЦП и снижению производительности. Чем больше на экране объектов, тем больше вызовов рендеринга нужно сделать. В Unity поддерживается так называемая пакетная обработка, позволяющая поместить несколько игровых объектов в один вызов рендеринга. Статическая пакетная обработка предназначена для статических объектов, а динамическая — для движущихся объектов. Динамическая пакетная обработка выполняется автоматически при выполнении всех требований (см. документацию по пакетной обработке), а статическую пакетную обработку требуется задавать вручную.


Существуют определенные требования для совместного рендеринга объектов и для динамической, и для статической пакетной обработки. Все эти требования перечислены в документе по пакетной обработке, ссылка на который приведена в разделе справочных материалов.


Для тестирования прироста производительности при статической пакетной обработке я создал сцену со сложными игровыми объектами в виде самолетов (рис. 21) и измерил кадровую скорость с пакетной обработкой и без нее (таблица 8).

 

Рисунок 21. Статическая пакетная обработка тестовой сцены с очень сложными моделями самолета


Таблица 8. Разница в кадровой скорости и количестве вызовов рендерингапри включенной и отключенной статической пакетной обработке (рис. 21)

В Unity поддерживается два типа пакетной обработки, динамическая и статическая. Для получения наибольшего преимущества от пакетной обработки старайтесь объединить как можно больше объектов в пакет для одного вызова рендеринга. Сведения о том, какие объекты подходят для динамической или статической пакетной обработки, см. в документации Unity.

Заключение

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

Справочные материалы

Документация по параметрам качества:

http://docs.unity3d.com/Documentation/Components/class-QualitySettings.html

API сценариев для параметров качества:
http://docs.unity3d.com/Documentation/ScriptReference/QualitySettings.html

Техническая демонстрация Boot Camp:
http://u3d.as/content/unity-technologies/bootcamp/28W

Документация по уровню детализации:
http://docs.unity3d.com/Documentation/Manual/LevelOfDetail.html

Документация по исключению скрытых частей:
http://docs.unity3d.com/Documentation/Manual/OcclusionCulling.html

Документация по пакетной обработке:
http://docs.unity3d.com/Documentation/Manual/DrawCallBatching.html

Документация по параметру Rendering Path:
http://docs.unity3d.com/Documentation/Manual/RenderingPaths.html

Intel GPA:
http://software.intel.com/en-us/vcsource/tools/intel-gpa

Other Related Content and Resources

Unity MultiTouch Source (finally)
http://software.intel.com/en-us/blogs/2013/05/01/the-unity-multi-touch-source-finally

Implementing Multiple Touch Gestures Using Unity3D With Touchscript
http://software.intel.com/en-us/articles/implementing-multiple-touch-gestures-using-unity-3d-with-touchscript

Multithreading Perceptual Computing Applications in Unity3D
http://software.intel.com/en-us/blogs/2013/07/26/multithreading-perceptual-computing-applications-in-unity3d

Unity3D Touch GUI Widgets
http://software.intel.com/en-us/articles/unity-3d-touch-gui-widgets

Об авторе

Джон Весоловски, стажер

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

Вне работы мне всегда нравилось играть в Halo* 2 с друзьями через Интернет, но, поскольку в Майкрософт отключили Xbox LIVE* для игр для первой консоли Xbox*, мы с друзьями играем в Halo 2 по локальной сети, когда собираемся вместе. Еще мне нравится играть в покер и запускать воздушные змеи. Сейчас я учусь в университете штата Калифорния в Монтерей-Бэй, моя специальность — компьютерные науки и информационные технологии.

Примечания

ИНФОРМАЦИЯ В ДАННОМ ДОКУМЕНТЕ ПРИВЕДЕНА ТОЛЬКО В ОТНОШЕНИИ ПРОДУКТОВ INTEL. ДАННЫЙ ДОКУМЕНТ НЕ ПРЕДОСТАВЛЯЕТ ЯВНОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ЛИЦЕНЗИИ, ЛИШЕНИЯ ПРАВА ВОЗРАЖЕНИЯ ИЛИ ИНЫХ ПРАВ НА ИНТЕЛЛЕКТУАЛЬНУЮ СОБСТВЕННОСТЬ. КРОМЕ СЛУЧАЕВ, УКАЗАННЫХ В УСЛОВИЯХ И ПРАВИЛАХ ПРОДАЖИ ТАКИХ ПРОДУКТОВ, INTEL НЕ НЕСЕТ НИКАКОЙ ОТВЕТСТВЕННОСТИ И ОТКАЗЫВАЕТСЯ ОТ ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ В ОТНОШЕНИИ ПРОДАЖИ И/ИЛИ ИСПОЛЬЗОВАНИЯ СВОИХ ПРОДУКТОВ, ВКЛЮЧАЯ ОТВЕТСТВЕННОСТЬ ИЛИ ГАРАНТИИ ОТНОСИТЕЛЬНО ИХ ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ, ОБЕСПЕЧЕНИЯ ПРИБЫЛИ ИЛИ НАРУШЕНИЯ КАКИХ-ЛИБО ПАТЕНТОВ, АВТОРСКИХ ПРАВ ИЛИ ИНЫХ ПРАВ НА ИНТЕЛЛЕКТУАЛЬНУЮ СОБСТВЕННОСТЬ.

КРОМЕ СЛУЧАЕВ, СОГЛАСОВАННЫХ INTEL В ПИСЬМЕННОЙ ФОРМЕ, ПРОДУКТЫ INTEL НЕ ПРЕДНАЗНАЧЕНЫ ДЛЯ ИСПОЛЬЗОВАНИЯ В СИТУАЦИЯХ, КОГДА ИХ НЕИСПРАВНОСТЬ МОЖЕТ ПРИВЕСТИ К ТРАВМАМ ИЛИ ЛЕТАЛЬНОМУ ИСХОДУ.

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

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

Перед размещением заказа получите последние версии спецификаций в региональном офисе продаж Intel или у местного дистрибьютора.

Копии документов с порядковым номером, ссылки на которые содержатся в этом документе, а также другую литературу Intel можно получить, позвонив по телефону
1-800-548-47-25 либо на сайте http://www.intel.com/design/literature.htm

Программное обеспечение и нагрузки, использованные в тестах производительности, могли быть оптимизированы для достижения высокой производительности на микропроцессорах Intel. Тесты производительности, такие как SYSmark* и MobileMark*, проводятся на определенных компьютерных системах, компонентах, программах, операциях и функциях. Любые изменения любого из этих элементов могут привести к изменению результатов. При выборе приобретаемых продуктов следует обращаться к другой информации и тестам производительности, в том числе к тестам производительности определенного продукта в сочетании с другими продуктами.

Данный документ и описываемое в нем программное обеспечение предоставляются по лицензии и могут использоваться и распространяться только согласно условиям лицензии.

Intel и эмблема Intel являются товарными знаками корпорации Intel в США и в других странах. © Intel Corporation, 2014. Все права защищены.

* Прочие наименования и товарные знаки могут быть собственностью третьих лиц.

Интерактивные технологии открывают новые возможности в обучении

$
0
0

Преобразование пользовательского интерфейса: проектирование интерфейса будущего (3 из 5)

Различия между реальным и виртуальным миром исчезают, когда технология Intel® RealSense™ применяется в интерактивном обучении

Автор: Джон Тиррел

Сенсорное управление и управление жестами, распознавание изображений и дополненная реальность — все эти технологии используются в множестве образовательных приложений и игр, они объединяют виртуальный мир с реальным совершенно невероятным образом. Доступные и совершенные технологии, такие как Intel® RealSense™, развивают эти изменения, и с каждой новой возможностью устройств границы между реальным миром и виртуальным миром становятся все более размытыми. В результате можно создать мир для игр и обучения, где разница между реальным и виртуальным будет несущественной.

Компании 3D4Medical, PlayTalesи Scholasticвходят в число первых разработчиков, внедряющих технологию IntelRealSenseв области развлекательного обучения и образования. Эти компании работали в сотрудничестве с Intelв ходе освоения новых технологий и решения связанных с ними проблем. Приложения и продукты этих компаний открывают новую страницу интерактивных решений для детей и взрослых.

Интерактивные медицинские решения

Интерактивное обучение охватывает гораздо более обширную область, чем интерактивные приложения для детей. Ирландская компания 3D4Medicalсоздает межплатформенные приложения для анатомии, здравоохранения и фитнеса, а также медицинские справочники. Четвертая версия программы Essential Anatomy* компании 3D4Medical (см. рис. 1) в настоящее время лидирует по продажам среди медицинских приложений для Windows*, Android* и iOS*.

 

Рисунок 1. Снимок экрана приложения EssentialAnatomy

Разработчики изучают возможности применения технологии IntelRealSenseтаким образом, чтобы соответствовать строгим требованиям, предъявляемым к приложениям в медицинской области. Сергей Буштырков, менеджер по разработке программного обеспечения в компании 3D4Medical, предложил использовать Intel® RealSenseSDKс подключаемым модулем Unity, чтобы проще было достичь нужных результатов при моделировании конечностей в виртуальном пространстве.

«Камера Intel® RealSense™ 3Dи IntelRealSenseSDKпредоставляют информацию, но для создания высококачественного коммерческого приложения нужно больше, чем просто данные, — поясняет Сергей. — Нам был нужен трехмерный движок для создания привлекательного изображения, поэтому мы используем Unityдля создания среды и управления руками».

Еще один уровень важности в медицинском приложении — точность, с которой распознаются отдельные конечности и суставы. Группа разработчиков под руководством Буштрыкова в настоящее время работает над анатомически точным распознаванием рук, превосходящим потребности большинства приложений с управлением жестами. «Камера снимает некоторое количество точек на руках и оцифровывает их, — говорит Буштырков. — Этот поток данных представляет собой набор координат и углов поворота для каждой из 22 отслеживаемых точек руки» (см. рис. 2).

Рисунок 2. Точки руки, отслеживаемые камерой IntelRealSense 3D

Преобразование необработанных данных в точную модель виртуальной руки — сложный процесс, причем дополнительные усилия требуются для высокого уровня детализации, необходимой для медицинского приложения. «Мы развиваем технологию, создавая очень качественные модели человеческих рук, адаптируя их к информации, которую мы получаем с камеры IntelRealSense 3D, приводя их в движение и координируя их.

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

Компания 3D4Medicalвыбрала технологию IntelRealSenseв качестве основы для своей долгосрочной работы и стремится всегда быть на переднем крае новых технологий. «С точки зрения компаний, работающих в нашей области, мы находимся на переднем крае технологий во многих областях, — подчеркивает Найл Джонстон, вице-президент компании 3D4Medicalпо развитию бизнеса. — Мы работаем с этой технологией с самых первых этапов разработки, и это прекрасная возможность как следует изучить ее потенциал».

В гостях у сказки

Испанская компания PlayTalesначала продавать интерактивные книги в магазине AppleAppStoreв начале 2012 года и быстро стала лидером рынка в этой области. Компания разрабатывает продукты на основе глобальных франшиз, таких как «Гарфилд», «Улица Сезам» и TheLittlePrince, а также на базе собственной интеллектуальной собственности, например, My NewBaby*. Виртуальный магазин PlayTales, в котором представлено свыше 200 наименований на семи языках, быстро превратился в желанный источник интерактивных сказок для родителей и детей во всем мире.

Разработчики планируют интегрировать технологию IntelRealSenseв новую интерактивную книгу Wizard of Oz*и в учебное научное приложение ProfessorGarfield* (рис. 3). «Когда мы узнали о новой технологии Intel, мы немедленно стали размышлять над тем, что мы сможем предлагать покупателям с точки зрения интерфейса, трехмерной графики и взаимодействия», — говорит Энрике Тапиас, директор компании PlayTales.

Рисунок 3. Ребенок рукой управляет бабочками в приложении ProfessorGarfield

Технология IntelRealSenseеще не была выпущена, когда компании PlayTalesпредставилась возможность, выходящая за рамки обычной реализации новой технологии в своих продуктах. Речь идет о сотрудничестве обеих компаний. «Пока мы работали над приложением, корпорация Intelодновременно разрабатывала IntelRealSenseSDK. Нам пришлось приспосабливаться к этому, — говорит Пабло Бенитес, директор компании PlayTales. — Очень хорошо, что мы можем первыми тестировать новые возможности, мы наблюдаем развитие и приложения, и SDK, и в результате получаем великолепные возможности, улучшающие взаимодействие с нашей программой. Нам очень понравился режим распознавания контура, поскольку он отслеживает силуэт ближайшего к камере объекта. Этот режим мы используем, чтобы перенести руки пользователя в наш трехмерный мир в играх, где мы отображаем представление руки. Благодаря этому пользователи могут, к примеру, «собирать воду», сложив руки ковшиком, или выбирать направление полета бабочек, указывая пальцами».

Изменение в поведении

Работа с технологией IntelRealSenseприносит компании PlayTalesощутимые преимущества. «Мы осваиваем технологию, которая будет широко использоваться на рынке в ближайшие годы. Это важно для нас, — говорит Тапиас. — Кроме того, мы исследуем возможности интерфейса с точки зрения детей. Мы тестируем удобство пользовательского интерфейса и получаем помощь со стороны фокус-групп Intelдля тестирования нашего содержимого и реализации технологии IntelRealSense».  «При тестировании приложений Wizard of Oz и ProfessorGarfield, мы обнаружили, что у детей возникают затруднения с пониманием принципа глубины при взаимодействии с новыми трехмерными мирами, — добавляет Бенитес. — Кроме того, они часто уходили из поля зрения камеры. Поэтому мы применили пошаговые инструкции, учебные материалы и оповещения, чтобы пояснить детям, куда они могут двигаться и как это следует делать».

Компания PlayTalesиспользует эту информацию для разработки нынешних и будущих продуктов по мере изменения ожиданий покупателей. «Поведение детей изменяется очень быстро, причем благодаря предлагаемым им технологиям и устройствам, — говорит Тапиас. — Мне кажется, что у детей больше вариантов использовать IntelRealSense. Это уже не просто обучение или чтение, это взаимодействие с содержимым, например, управление движением бабочек в проекте ProfessorGarfield».

Тапиас и его команда понимают огромный потенциал, раскрываемый технологией IntelRealSense, но уверены, что реализацию этой технологии необходимо тщательно контролировать, дорабатывать до возможного совершенства и до полного соответствия контексту использования, будь то обучение или развлечения. Для Тапиаса прогноз на будущее выглядит весьма оптимистично: «Технология IntelRealSense— одна из самых важных для нас в течение следующего года, причем не только для стационарных компьютеров и ноутбуков, но и для устройств, которыми пользуются дети, то есть для планшетов и смартфонов».

Фантастика Scholastic

Компания Scholasticобладает заслуженной репутацией в области развлекательных решений для детей. На счету этой компании — книги, телепередачи (некоторые из них удостоены премии «Эмми»), видеоигры и интерактивные учебные продукты для различных платформ. «Мы создаем содержимое, соединяя темы и персонажей наших брендов с технологией, — говорит Дженнифер Контруччи, директор по производству цифрового содержимого в компании ScholasticMedia. — Мы стараемся использовать технологию, потому что она работает, а не в качестве дополнения».

Многие бренды этой компании стали привычными в среде детских материалов в США и в других странах, например, бренды CliffordtheBigRedDog*и MagicSchoolBus*. Технология IntelRealSenseиспользуется в серии I Spy*этой компании: этот бренд был запущен в 1992 году для детских книг, а сейчас это интерактивная игровая среда.

Рисунок 4. Снимок экрана приложения I SpyPirateShip

ISpyPirateShip* (рис. 4) — новинка в семействе брендов, предназначенная для переносных моноблоков AIOи трансформеров. «В приложении используется множество возможностей IntelRealSense, в том числе жесты, распознавание сжатого кулака и раскрытой ладони, отслеживание точке на лице, — говорит Контруччи. — В игре вы увидите полный спектр новых возможностей».

Дети и камеры

Одна из задач в игре I SpyPirateShipзаключается в том, чтобы смотреть в телескоп, установленный на марсовой площадке корабля, и находить объекты, скрытые среди звезд (рис. 5). При реализации технологии IntelRealSenseдля отслеживания движения головы пользователей, осматривающих небо, разработчики столкнулись с интересными проблемами.

Рисунок 5. Вид из телескопа, приложение I SpyPirateShip

«Дети двигаются быстро и резко, поэтому нам не удавалось всегда распознавать направление их взгляда, — поясняет Контруччи. — Мы переделали программу для отслеживания реперных точек. Теперь игра находит на лице определенные точки, например кончик носа, что дает гораздо лучший эффект».

Когда пользователь находит какой-либо объект, он сообщает это программе тем, что просто останавливается на найденном объекте: эта, казалось бы, простая модель взаимодействия очень хорошо воспринимается аудиторией. «Для детей это совершенно волшебные ощущения, им кажется, что они действительно находятся на кораблей, и могут физически воздействовать на окружающий мир», — говорит Контруччи.

Для Контруччи наибольшим потенциалом обладает способность приложения определять, когда лицо пользователя останавливается в определенном положении. «У такого подхода много других сценариев применения, — продолжает она. — Например, если ребенок рассматривает электронную книгу и останавливается на картинке со львом, программа может отреагировать на это, сказать, как называется это животное и дать его описание. Таким образом, дети получают справку на лету».

Социальное обучение

Орнит Гросс, руководитель продукции Intelв области игр и образования, дает совершенно однозначный ответ на вопрос о том, полезна ли интерактивность для учебного процесса. «Если сделать учебный материал увлекательным, живым и веселым, это поможет его лучше запомнить. Это, безусловно, помогает в обучении.

Когда мы начали осваивать эту область, мы узнали, что для успешного изучения требуется сочетание широкого набора факторов, — говорит Орнит. — Один из них — это взаимодействие, будь то с учителем, с другом или с приложением. Интерактивность делает процесс получения знаний более глубоким».

Технология IntelRealSenseявляется настоящим произведением искусства с точки зрения интерактивности, но этим все не ограничивается. «Второй фактор — социальный. Вы не просто учитесь, а учитесь в составе группы, — поясняет Орнит. — Это направление заслуживает дальнейшей разработки, мы будем этим заниматься в новом поколении наших решений. Здесь все дело в том, что работает модель взаимодействия одного со многими, а не одного с одним, если мы учимся вместе с моим другом».

Полный вперед!

Технология IntelRealSenseподтверждает свои преимущества для групп разработчиков, решивших внедрить ее: она фундаментально изменяет подход к взаимодействию пользователей с компьютерами и мобильными устройствами. Искренний интерес разработчиков к новой технологии стал заслуженной наградой для Орнита и его команды. «Меня удивило, что разработчики, поняв, что IntelRealSenseSDKдает и высокоуровневые, и низкоуровневые данные, начали сами писать код для взаимодействия, используя все APISDK. Например, SDKотслеживает на лице 78 реперных точек и распознает разные мимические черты, например, открытие или закрытие глаза, открытый рот и так далее. Эти возможности были объединены, чтобы SDKмог распознать, когда пользователь начинает корчить рожи. Еще один пример — распознавание жестов руки. IntelRealSenseSDKотслеживает 22 точки суставов руки и жест сведения пальцев. Разработчик объединил эти API, доступные в SDK, и получил совершенно уникальный жест складывания пальцев, который разработали специально для главного персонажа в игре».

Как известно, технология — это только начало. Гораздо важнее содержимое. Контруччи подводит краткий итог мотивации Scholasticв отношении освоения возможностей технологии IntelRealSense: «Многие считают, что управление жестами получит крайне широкое распространение не только потому, что ребенок хочет взаимодействовать с компьютером именно так, а потому, что это естественное действие. Когда мы выпустили I SpyPirateShipдля тестирования этого естественного взаимодействия с участием детей, для них это были совершенно новые ощущения. И это было очень интересно».

Ресурсы 

Изучить технологию Intel RealSense, узнать о бета-версии Intel RealSense SDK для Windows и заказать набор разработчика можно здесь.

В будущем камера Intel RealSense 3D будет встраиваться в ноутбуки, моноблоки и планшеты. Посмотрите, как компания  faceshiftиспользует эту камеру для управления аватарами на 16 планшетах для создания «виртуальных селфи».

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

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

Узнайте, как технология Intel RealSense стирает границы между личным общением и общением на расстоянии. Прочтите статью  здесь.

Intel и Intel RealSense являются товарными знаками корпорации Intel в США и в других странах.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.


Уход из плоскости. Трехмерная съемка и демонстрация

$
0
0

Преобразование пользовательского интерфейса. Проектирование интерфейса будущего (4 из 5).

Уход из плоскости. Трехмерная съемка и демонстрация

Download PDF

Оглядитесь по сторонам. В нашем трехмерном мире мы можем видеть объекты с любого ракурса, определять их размер, понимать, насколько близко или далеко они находятся по отношению к другим объектам. Но в том, что касается съемки и демонстрации этих объектов другим, мы часто применяем двухмерные неподвижные изображения или двухмерное видео. Причина проста: съемка трехмерного изображения была чрезвычайно сложным и дорогостоящим процессом, который был доступен лишь опытным профессионалам и самым «подкованным» энтузиастам таких решений.

Но появившиеся недавно новые технологии меняют эту картину. Достаточно незначительных усилий, чтобы покупатели могли на планшетах видеть, как они будут выглядеть в разных моделях виртуальных очков. Аналогичные приложения для Android* и iOS* позволяют покупателям просматривать и взаимодействоватьс виртуальной мебелью, одеждой, тканями, игрушками и т. д. В большинстве случаев трехмерные образцы товаров, используемые в этих приложениях, ограничиваются заранее подготовленным содержимым, которое было создано профессионалами.

Но камеры Intel® RealSense™ 3D будут способны уже скоро сделать возможности трехмерного сканирования, печати и демонстрации доступными для широкого круга пользователей. Используя отслеживание рук и пальцев, голосовые команды, распознавание лица и функции дополненной реальности, обеспечиваемые технологией Intel® RealSense™, пользователи смогут естественным образом взаимодействовать с реальными и виртуальными объектами и печатать их трехмерные модели. Возможны самые разные сценарии использования — от профессионального (продажи, медицина, дизайн, образование) до развлекательного (игры, создание фильмов, социальное общение).

Компании 3D Systems, Autodesk и DotProduct первыми осваивают новые возможности, располагая обширным опытом создания и печати трехмерного содержимого. Они внедряют технологию Intel RealSense для того, чтобы сделать возможности трехмерной съемки и отображения доступными для широкой аудитории.

Трехмерное изображение и печать

Компания 3D Systems, которую основал Чак Халл, изобретатель трехмерной печати, с 1986 года обслуживает заказчиков в таких отраслях, как автомобильная промышленность, аэрокосмическая промышленность, промышленное проектирование и медицина. В настоящее время компания занимается популяризацией трехмерной печати.   «Камера Intel RealSense 3D — естественный выбор, — говорит Пинь Фу (Ping Fu), директор компании 3D Systems. — Два года назад большинство трехмерных сканеров стоило от 10 000 до 50 000 долларов США. С помощью камер Intel RealSense 3D пользователи получат доступ к трехмерным сканерам, встроенным в их ПК, трансформеры, моноблоки, ультрабуки и планшеты».

Компания 3D Systems разрабатывает два настольных приложения, которые будут использовать технологию Intel RealSense на ПК: 3DMe* и SENSE*. Оба эти приложения созданы с помощью Intel® RealSense™ SDK 2014.

Приложение 3DMe дает возможность любому пользователю дать свое собственное лицо любимому игровому персонажу, например баскетболисту из НБА, Боргу из «Звездного пути», сноубордисту, принцессе и так далее (рис. 1). После съемки персонаж можно напечатать на трехмерном принтере, анимировать или показать друзьям по социальным сетям.

3DMe Armor Pic

Рисунок 1. Лицо пользователя сканируется в персонаж с помощью приложения 3DMe*

SENSE — это программа для сканирования объектов. «Можно отсканировать вашу голову, все тело или какие-либо объекты, например вашу любимую игрушку, а затем напечатать их трехмерную модель или экспортировать, — поясняет Пинь Фу. — Естественным примером использования служат игры. Разработчики и конструкторы могут применять эту возможность для создания эталонных моделей с высокой степенью детализации для сложных конструкций, обычные пользователи могут сканировать свои любимые вещи, делиться ими с друзьями и печатать на трехмерных принтерах».

Сценарии использования трехмерной печати индивидуальных отсканированных объектов весьма разнообразны. «Производители кукол хотят создавать лица кукол индивидуально, такими же, как лица девочек, — говорит Пинь Фу. — Спортсмены по заслугам оценят шлемы, которые идеально подойдут под индивидуальную форму головы. Пользователи могут сканировать свои кисти и руки, чтобы с легкостью получать отливки, устраняющие неудобства и туннельный синдром».

Приложения 3DMe и SENSE производят съемку объектов (рис. 2) в виде редактируемых трехмерных моделей вместе с картой текстур и информацией о цвете. Пользователи 3DMe будут переадресованы на cubify.com для печати человекоподобных моделей; пользователи SENSE смогут печатать свои модели на персональных трехмерных принтерах семейства CUBE* компании 3D Systems или смогут отправлять модели в облако и распечатывать в компаниях, предоставляющих услуги трехмерной печати. Персональный принтер CUBE поддерживает печать ограниченным набором материалов, тогда как мощные профессиональные и промышленные трехмерные принтеры могут печатать «...металлом, керамикой, акрилом, пластиком и даже съедобным шоколадом и сахарной глазурью» (Пинь Фу).

SENSE Software

Рисунок 2. Сканирование объектов с помощью программы SENSE*

Приложение SENSE поддерживает экспорт моделей в форматы OBJ, DXE, PLY, а также в другие форматы, принятые в САПР-системах. «Пользователи систем автоматизированного проектирования (САПР) предпочитают работать с параметризованными моделями, чтобы при изменении геометрии эти изменения также распространялись на поверхности, текстуры и т. д., — продолжает Пинь Фу. — Программа SENSE совместима с программным пакетом Geomagic Solution компании 3D Systems, который предоставляет самый быстрый способ преобразования отсканированных данных в параметрические модели для систем САПР».

По словам Пинь Фу, технология Intel RealSense способна работать с общей погрешностью в пределах 1 мм: «Этого вполне достаточно для многих персональных продуктов — индивидуально подбираемых оправ очков, обуви или медицинских устройств, таких как шины для срастания сломанных костей. Для промышленного проектирования трехмерные отсканированные модели будут перенесены в среду САПР для повышения детализации и более точной доработки эталонного проекта».

Пинь Фу начала работать в области трехмерного сканирования в 1996 году, когда она стала руководителем и одним из основателей компании Geomagic, ведущей в мире компании по созданию программного обеспечения для трехмерного сканирования. Эта компания в 2013 году была приобретена компанией 3D. Пинь Фу всегда стремилась сделать трехмерное сканирование доступным для широкого круга потребителей и работала над соединением возможностей трехмерного сканирования и трехмерной печати. В корпорации Intel она нашла единомышленников. «Наше сотрудничество с Intel было взаимовыгодным и полезным, — говорит она. — Мы много работаем вместе. Технология Intel RealSense обеспечивает интуитивное взаимодействие с компьютером, а камеры Intel RealSense 3D получают необработанные данные. Наша программа получает это облако точек и преобразует его в полноцветную текстурную модель, пригодную для дальнейшего использования. Мы формируем возможности, позволяющие сделать работу с компьютером без помощи контроллеров в трехмерных приложениях доступной, удобной и интересной».

Пинь Фу подчеркивает важность опыта Intel в области интеграции оборудования с оптимизированным программным обеспечением: «Над Intel RealSense SDK работает великолепная команда. Они отлично знают, как поддерживать сообщество разработчиков». Обе компании помогали друг другу в работе. Инженеры 3D Systems использовали Intel RealSense SDK для создания своих приложений, управления камерой и распознавания лиц. «Нам также очень помогла тесная работа с сотрудниками команды User Experience корпорации Intel при создании интуитивного, удобного в использовании приложения».

Компания 3D Systems также внесла свой вклад в разработку Intel RealSense SDK, предоставив функции обработки отсканированных данных. Эти функции дадут другим разработчикам возможность преобразования облака точек в модели. «При трехмерном сканировании одна из основных проблем заключается в том, что необработанные данные зачастую содержат много помех, — заявляет Пинь Фу. — Мы предусмотрели очень развитые функции очистки, в том числе и возможность заполнения отверстий на основе кривизны поверхностей. За счет этого достигается весьма естественный вид без необходимости заново сканировать предметы». Специалисты 3D Systems также предоставили возможность снижения детализации предметов при сохранении их общей формы. Такую функцию разработчики игр используют для получения объектов с пониженным количеством полигонов для ускоренного рендеринга на лету. Наиболее уникальный алгоритм — процесс сканирования с точным соответствием отображения (WYSIWYG). За счет этого сканирование существенно упрощается для потребителей и для автоматических систем моделирования.

Каковы основные выводы компании 3D Systems, полученные в процессе разработки? «Правильно реализовать трехмерное сканирование — непростая задача, — говорит Пинь Фу. — Чтобы новая технология получила распространение, крайне важно удобство пользователей. Благодаря помощи Intel мы получили огромный объем информации о настройке производительности, тестировании с участием пользователей и получении отзывов на рынке. Работая с корпорацией Intel, мы получили доступ к другим независимым разработчикам программ, производителям компьютеров и розничным компаниям. Эти связи превратились во взаимовыгодные партнерские отношения».

Трехмерный просмотр для улучшения двухмерных изображений

Компания Autodesk, всемирный лидер в области программного обеспечения для трехмерного проектирования, инженерных задач и развлечений, использует нашу технологию для получения трехмерных данных изображений с тем, чтобы пользователи могли придавать объем двухмерным фотографиям. «Технология Intel RealSense идеально подходит для нашего приложения Pixlr*, предназначенного для редактирования изображений, — говорит Гарет Пеннингтон (Gareth Pennington), старший менеджер по программному обеспечению в компании Autodesk. — Нас особенно интересует сегментация фона и возможность добавить еще одно измерение в двухмерные изображения».

При сегментации фонаиспользуются данные глубины для выделения, то есть сегментации, объектов, находящихся на переднем и на заднем планах, чтобы затем можно было извлечь, заменить или дополнить различные аспекты изображения в реальном времени (рис. 3). Алгоритмы сегментации в Intel RealSense SDK ищут данные определенного цвета и глубины, определяют, что следует отобразить и извлечь, затем выдают результаты в формате видео высокой четкости со скоростью 60 кадров в секунду.

Pixlr App

Рисунок 3. Сегментация фона с помощью приложения Pixlr*

«Мы предусматриваем довольно интересные сценарии использования, например мы даем пользователям возможность снимать только свою голову и автоматически удалять фон, чтобы голову можно было преобразовать в графический штамп для переноса на другие изображения, — говорит Пеннингтон. — Также можно создавать индивидуальные смайлики и другие значки для использования в электронных письмах и сообщениях. Например, если вы на корабле, то вы можете себя сфотографировать и применить зеленый фильтр, который будет применяться только к вашему лицу, но не ко всему тому, что находится вокруг вас, чтобы указать, какая это неприятная штука — морская болезнь».

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

Приложение Pixlr в настоящее время доступно и в виде веб-приложения, и в качестве традиционного приложения для Windows*, Mac OS, iOS и Android. Версия с поддержкой технологии Intel RealSense будет приложением для Windows. Рассуждая о перспективах, Пеннингтон заявил: «Интересно размышлять о том, что мы могли бы сделать со всеми прочими возможностями технологии Intel RealSense: отслеживанием движений, распознаванием лица, можно поработать с измерением предметов и с изменением фокуса... Все это очень интересно. В Intel RealSense SDK для нас осталось еще много функций, которые следовало бы изучить. Потенциал Intel RealSense, безусловно, раскроется со временем, когда эта технология станет доступной для широкого круга потребителей. Это будет просто здорово».

Трехмерное изображение на планшетах

С момента своего основания в 2012 годукомпания DotProduct обслуживала профессиональный рынок и первых потребителей услуг трехмерного сканирования: компании нефтегазовой отрасли и энергетики, инженерно-проектные компании, а также организации, занимающиеся криминалистикой и историческими документами. «Эти отрасли используют трехмерные изображения, — поясняет Брайан Ахерн (Brian Ahern), директор компании DotProduct. — Они применяют трехмерные изображения в проектировании и эксплуатации, в обслуживании и модернизации оборудования, во всей своей работе».

Признав, что компактные трехмерные датчики стали доступной альтернативой промышленным сканерам, компания DotProduct разработала решение на базе планшета Android, способное создавать точные трехмерные модели объектов. Эта система поступила в продажу по цене 5000 долларов США. Теперь компания работает с корпорацией Intel над разработкой еще более дешевого планшетного решения на базе Intel RealSense.

«Мы чрезвычайно увлечены технологией Intel RealSense, — говорит Ахерн. — Когда камеры Intel RealSense 3D будут встраиваться в планшеты, доступные в широкой продаже, рынок будет расти в геометрической прогрессии». Брайан считает, что DotProduct становится компанией, ориентированной на программное обеспечение, и будет лицензировать свои технологии производителям устройств, интегрирующих технологию Intel RealSense в свою продукцию.

Как и компании 3D Systems и Autodesk, DotProduct также стремится сделать свои решения более доступными и удобными для потребителей, чтобы привлечь более широкую аудиторию. «В бета-версии 2.0 полностью переделан пользовательский интерфейс. Функции навигации, просмотра и рендеринга полностью интуитивны [рис. 4]».

DotProduct UI Screen
Рисунок 4. Переделанный пользовательский интерфейс DotProduct.

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

Основная технология компании DotProduct основывается на платформе Android, но «…не зависит от нее. Android — это оболочка, а наш код написан на C++. Сейчас мы переносим его на Windows», — говорит Ахерн. После выпуска продукта в 2015 году он будет работать на обеих платформах. Кенн Уокер (Kenn Walker), менеджер по продукту Intel RealSense, добавляет: «Если говорить о приложениях, использующих Intel RealSense, некоторые из них работают на высоком уровне SDK. Приложение DotProduct, напротив, работает ближе к «железу», взаимодействуя с данными в необработанном виде».

Какая вычислительная мощность требуется для обработки всех этих данных? «Чем больше всего (ЦП, ГП, ОЗУ), тем лучше, — говорит Ахерн. — Чем выше мощность, тем лучше результаты».

Сценарии использования самые разнообразные — от игр до продаж, обучения, развлечений и т. д. «В некоторых компаниях, работающих в области дизайна, сотрудникам приходится вручную измерять размеры объектов, комнат и помещений. Это трудоемкий и длительный процесс. Возможность просто навести планшет на какой-либо предмет (рис. 5) или комнату, перенося при этом планшет вокруг, под предметами и над ними, чтобы потом нажать кнопку «Готово» и получить готовую модель, произведет настоящую революцию».

Pipescanning worker

Рисунок 5. Сканирование с помощью планшета

Говоря об основных выводах из процесса разработки, Брайан заявил: «Мы поняли, что даже инженеры порой недооценивают скорость развития потребительских технологий. Мы знали, что рано или поздно появятся мобильные устройства со встроенными трехмерными технологиями, но это произошло быстрее, чем мы предполагали».

Брайан и его команда в DotProduct также поняли, что недостаточно просто предложить покупателям новую технологию: «Нужно либо создать решение, безупречно интегрирующееся в существующие рабочие процессы, либо дать новые интуитивные процессы использования данных для работы и для развлечений. Именно на это мы потратили последнюю пару лет: очень непросто сделать все так, как нужно».

Ресурсы

Изучить технологию Intel RealSense, узнать о бета-версии Intel RealSense SDK для Windows и заказать набор разработчика можно здесь.

Ваш проект готов к демонстрации? Станьте участником программы Intel® Software Innovator.Эта программа поддерживает разработчиков передовых проектов, дает возможность выступить с рассказом о своем проекте и устроить демонстрацию.

Приступите к работе в центре ресурсов для разработчиков.

Прочтите часть 1,часть 2и часть 3этой серии «Преобразование пользовательского интерфейса: проектирование интерфейса будущего».

Intel, эмблема Intel и RealSense являются товарными знаками корпорации Intel в США и в других странах.

* Прочие наименования и товарные знаки могут быть собственностью третьих лиц.

Для технологий Intel может требоваться определенное оборудование, программное обеспечение или службы. Производительность может различаться в зависимости от конфигурации системы. Обратитесь к изготовителю системы или в розничный магазин, где вы ее приобрели.

© Корпорация Intel, 2015. Все права защищены.

Процедурный рендеринг разреженного пространства

$
0
0

Download Source Code ZIPfile

Процедурный рендеринг разреженного пространства (SPVR) — это методика рендеринга пространственных эффектов в реальном времени. Мы очень рады, что в будущей книге «GPU Pro 6» будет глава, посвященная SPVR. В этом документе приводятся некоторые дополнительные сведения

SPVRс высокой эффективностью отрисовывает большой объем, разделяя его на маленькие кусочки и обрабатывая только используемые кусочки. Мы называем эти кусочки «метавокселями». Воксель — это наименьшая часть объема. Метавоксель — это трехмерный массив вокселей. А весь объем в целом — это трехмерный массив метавокселей. В примере есть константы времени компиляции для определения этих чисел. В настоящее время он настроен на объем, равный 10243 вокселям, в виде 323 метавокселей, каждый из которых состоит из 323 вокселей.

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

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

Рисунок 1. Частицы, воксели, метавоксели и различные системы координат

На рис. 1 показаны все составные части: воксели, метавоксели, частица примитива объема, источник света, камера и мир. У каждой составной части есть эталонная точка, которая определяется положением P, направленным вверх вектором U и направленным вправо вектором R. Система трехмерна, но на рис. 1 используется упрощенное двухмерное представление.

  • Воксель — наименьшая часть объема. Для каждого вокселя задается цвет и плотность.
  • Метавоксель — это трехмерный массив вокселей. Каждый метавоксель хранится в виде трехмерной текстуры (например, трехмерной текстуры 323DXGI_FORMAT_R16G16B16A16_FLOAT).
  • Объем — общий объем, состоящий из нескольких метавокселей. На рис. 1 показан упрощенный объем из метавокселей 2х2.
  • Частица — сферический примитив объема с радиальным сдвигом. Обратите внимание, что это трехмерная частица, а не двухмерная плоскость.
  • Камера — та самая камера, которая используется для рендеринга всей остальной сцены из точки наблюдения.

Описание алгоритма

// Рендеринг карты теней для каждой модели сцены, видимой из представления освещения
// Рендеринг предварительного Z-прохода для каждой модели сцены, видимой с точки зрения наблюдателя
// Применение частиц для каждой частицы: для каждого покрываемого частицами метавокселя путем присоединения частиц к списку частиц метавокселя
// Рендеринг метавокселей на цели рендеринга: для каждого непустого метавокселя, заполнение метавокселей частицами и картой теней в качестве входных данных, отслеживание лучей для метавокселей с точки зрения наблюдателя с использованием буфера глубины в качестве входных данных
// Отрисовка сцены в обратный буфер для каждой модели сцены с точки зрения наблюдателя
// Совмещение цели рендеринга с точки зрения наблюдателя с рендерингом полноэкранного спрайта обратного буфера с использованием цели отрисовки как текстуры

Обратите внимание, что в этом примере поддерживается заполнение нескольких метавокселей перед отслеживанием лучей. Заполняется «кэш» метавокселей, затем проводится отслеживание лучей, и процедура повторяется вплоть до обработки всех метавокселей. Также поддерживается заполнение метавокселей только в каждом n-номкадре или только однократное заполнение. Если в реальном приложении нужна статическая или медленно изменяющаяся объемная сцена, то приложение будет работать намного быстрее, если оно не будет обновлять все метавоксели в каждом кадре.

Заполнение объема

В примере метавоксели заполняются покрывающими их частицами. «Покрывающими» означает, что границы частиц пересекаются с границами метавокселя. Пустые метавоксели не обрабатываются. Приложение сохраняет цвет и плотность в каждом вокселе метавокселя (цвет в формате RGB, плотность в виде значения альфа-канала). Эта работа выполняется в пиксельном шейдере. Приложение записывает данные в трехмерную текстуру в виде неупорядоченного представления доступа (UAV) RWTexture3D. Образец приложения отображает двухмерный квадрат, состоящий из двух треугольников, такого размера, чтобы он совпадал с метавокселем (т. е. 32x32 пикселя для метавокселя 32x32x32). Пиксельный шейдер проходит каждый воксель в соответствующем столбце вокселей, вычисляет плотность и цвет каждого вокселя на основе частиц, покрывающих метавоксель.

В примере определяется, находится ли каждый воксель внутри каждой частицы. На двухмерной схеме показана упрощенная частица. (На схеме показана двухмерная окружность с радиальным сдвигом. В трехмерной системе используются сферы с радиальным сдвигом.) На рис. 1 показан радиус окружения частицы rP и ее радиус смещения rPD. Частица покрывает воксель, если расстояние между центром частицы PP и центром вокселя PV меньше расстояния сдвига rPD. Например, воксель в PVIнаходится внутри частицы, а воксель в PVO — снаружи.

Внутри = |PVPP| < rPD

Скалярное произведение вычисляет квадрат длины вектора без затраты лишних ресурсов. Это позволяет избежать ресурсоемкой операции извлечения квадратного корня sqrt(), поскольку можно сравнивать не длины, а квадраты значений длины.

Внутри = (PVPP) ∙ (PVPP) < rPD2

Цвет и плотность зависят от положения вокселя внутри частицы и от расстояния до поверхности частицы rPDвдоль линии, проходящей от центра частицы через центр вокселя.

C = цвет (PVPP, rPD)
D = плотность (PVPP, rPD)

Интересны различные функции плотности. Вот некоторые возможные варианты.

  • Двоичная если воксель находится внутри частицы, то цвет = C и плотность = D (где C и D — константы). В противном случае цвет = черный, плотность = 0.
  • Градиент цвет изменяется от C1 до C2, а плотность изменяется от D1 до D2 по мере изменения расстояния из положения вокселя от центра частицы до поверхности частицы.
  • Подстановка по текстуре — цвет может быть сохранен в одномерной, двухмерной или трехмерной текстуре, он подстанавливается в зависимости от расстояния (X, Y, Z).

В образце реализованы два примера: 1) постоянный цвет, оттенок которого определяется значением смещения, 2) градиент от ярко-желтого до черного на основе радиуса и возраста частицы.

Существует не менее трех интересных способов указания положения в метавокселе.

  1. Нормализованный
    • Число с плавающей запятой
    • Начало координат — в центре метавокселя
    • Диапазон от -1,0 до 1,0
  2. Координаты текстуры
    • Число с плавающей запятой (преобразуется в число с фиксированной запятой алгоритмом получения)
    • Начало координат — в верхнем левом углу двухмерного изображения (верхний левый задний угол трехмерного изображения).
    • Диапазон от 0,0 до 1,0
    • Центр вокселя находится на половине metavoxelDimensions (т. е. 0,0 — угол вокселя, а 0,5 — центр).
  3. Индекс вокселя
    • Целое число
    • Начало координат — в верхнем левом углу двухмерного изображения (верхний левый задний угол трехмерного изображения).
    • Диапазон от 0 до metavoxelDimensions — 1
    • Z — направление света, а X и Y — плоскости, перпендикулярные направлению света.

Положение вокселя в пространстве метавокселя определяется положением метавокселя PM и индексами вокселя (X, Y). Индексы вокселя дискретны, их значение составляет от 0 до N-1 на протяжении метавокселя. На рис. 1 показана упрощенная сетка 2х2 метавокселей размером 8х8 вокселей с PVIв метавокселе (1, 0) в позиции вокселя (2, 6).

Освещение

После вычисления цвета и плотности каждого вокселя в метавокселе вычисляется освещенность вокселей. В образце используется простая модель освещения. Пиксельный шейдер последовательно обходит столбец вокселей, умножая цвет вокселя на текущее значение света. Затем значение света корректируется с учетом плотности вокселя. Существует как минимум два способа корректировки освещения. Вреннинге и Зафар1используют степень e-плотность. Мы используем 1/(1+плотность). В обоих случаях результат изменяется от 1 на нулевом расстоянии до 0 на бесконечности. Результаты выглядят схоже, но деление может быть быстрее, чем exp().

Ln+1 = Ln/(1+плотностьn)

Обратите внимание, что этот цикл распространяет свет по единственному метавокселю. В коде свет распространяется от одного метавокселя к другому с помощью текстуры распространения света. Код записывает последнее значение распространения света в текстуру. Следующий метавоксель считывает свое начальное значение распространения света из этой текстуры. Размер этой двухмерной текстуры задается для всего объема. Это дает два преимущества: можно параллельно обрабатывать несколько метавокселей; итоговое содержимое можно использовать в качестве карты света для отбрасывания теней от объема на остальную сцену.

Тени

В примере используются тени, отбрасываемые сценой на объем, и тени, отбрасываемые объемом на сцену. Сначала отрисовываются непрозрачные объекты сцены на простой карте теней. Объем получает тени путем ссылки на карту теней в начале распространения света. Тени отбрасываются путем проецирования последней текстуры распространения света на сцену. Более подробно о текстуре распространения света мы поговорим чуть позже.

Шейдер проводит выборку карты теней один раз на метавоксель (на столбец вокселей). Шейдер определяет индекс (т. е. строку в столбце), в котором первый воксель попадает в тень. Воксели, находящиеся перед shadowIndex, не в тени. Воксели, находящиеся в позиции shadowIndexили после нее, находятся в тени.


Рисунок 2.Взаимосвязь между значениями Z теней и индексами

Значение shadowIndexсоставляет от 0 до METAVOXEL_WIDTHпо мере изменения значения тени от верхней части метавокселя к его нижней части. Центр локального пространства метавокселя находится в точке с координатами (0, 0, 0), пространство занимает область от -1,0 до 1,0. Поэтому верхний край имеет координаты (0, 0, -1),
а нижний край — (0, 0, 1). Преобразование в пространство света/теней:

Top    = (LightWorldViewProjection._m23 - LightWorldViewProjection._m22)
Bottom = (LightWorldViewProjection._m23 + LightWorldViewProjection._m22)

Что дает следующий код шейдера в FillVolumePixelShader.fx:

float shadowZ      = _Shadow.Sample(ShadowSampler, lightUv.xy).r;
float startShadowZ = LightWorldViewProjection._m23 - LightWorldViewProjection._m22;
float endShadowZ   = LightWorldViewProjection._m23 + LightWorldViewProjection._m22;
uint  shadowIndex  = METAVOXEL_WIDTH*(shadowZ-startShadowZ)/(endShadowZ-startShadowZ);

Обратите внимание, что метавоксели являются кубами, поэтому ширина METAVOXEL_WIDTHтакже является высотой и глубиной.

Текстура распространения света

В дополнение к вычислению цвета и плотности каждого вокселя FillVolumePixelShader.fx записывает итоговое значение распространенного света в текстуру распространения света. В образце кода эта текстура называется $PropagateLighting. Это двухмерная текстура, покрывающая весь объем. Например, образец, настроенный как объем 10243 (323 метавокселя по 323 вокселя в каждом), будет иметь текстуру распространения света 1024x1024 (32*32=1024). Отметим два момента: эта текстура включает место для границы каждого метавокселя толщиной в один воксель; значение, сохраненное в текстуре, является последним значением до тени.

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

float  oneVoxelBorderAdjust = ((float)(METAVOXEL_WIDTH-2)/(float)METAVOXEL_WIDTH);
float2 uvVol       = input.VolumeUv.xy * 0.5f + 0.5f;
float2 uvMetavoxel = uvVol * WIDTH_IN_METAVOXELS;
int2   uvInt       = int2(uvMetavoxel);
float2 uvOffset    = uvMetavoxel - (float2)uvInt - 0.5f;
float2 lightPropagationUv = ((float2)uvInt + 0.5f + uvOffset * oneVoxelBorderAdjust )
                          * (1.0f/(float)WIDTH_IN_METAVOXELS);

Текстура распространения света сохраняет значение света в последнем вокселе, который не находится в тени. Если процесс распространения света встречает поверхность затенения, то распространение света обнуляется (свет не распространяется дальше объекта, отбрасывающего тень). Сохранение последнего значения освещения дает возможность использовать текстуру в качестве карты освещенности. Проецирование этого последнего значения освещения на сцену означает, что поверхность отбрасывания теней получает ожидаемое значение освещения. Поверхности, находящиеся в тени, не используют эту текстуру.

Отслеживание лучей

Рисунок 3.Отслеживание лучей из точки наблюдения

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

blend       = 1/(1+density)
colorresult = colorresult * blend + color * (1-blend)
alpharesult = alpharesult * blend

В образце каждый метавоксель обрабатывается независимо. Отслеживание лучей происходит по очереди для каждого метавокселя. Результаты смешиваются с целью рендеринга с точки зрения наблюдателя. Отслеживание лучей каждого метавокселя осуществляется путем рисования куба (т. е. 12 треугольников) из точки зрения наблюдателя. Пиксельный шейдер отслеживает лучи, проходящие через каждый пиксель, покрываемый кубом. При рендеринге куба используется исключение передней поверхности, поэтому пиксельный шейдер выполняется только один раз для каждого покрываемого пикселя. При рендеринге без исключения каждый луч приходилось бы отслеживать дважды — один раз для передних поверхностей, второй раз для задних. При рендеринге с исключением задней поверхности камера находилась бы внутри куба, пиксели были бы исключены и отслеживание лучей было бы невозможно.

В примере на рис. 3 показано отслеживание двух лучей в четырех метавокселях. Показано, как шаги лучей распределены вдоль каждого луча. Расстояние между шагами одинаковое при проецировании на вектор взгляда. Это означает, что у лучей, направленных в сторону от оси, шаги длиннее. На практике этот подход дал наилучшие результаты (например, по сравнению с равными шагами для всех лучей). Обратите внимание, что точки выборки начинаются на дальней плоскости, а не на задней поверхности метавокселя. Такой подход совпадает с выборкой для монолитного объема (без использования метавокселей). При начале отслеживания лучей на задней поверхности каждого метавокселя образовывались видимые швы на границах метавокселей.

На рис. 3 видно, как выборки оказываются в разных метавокселях. Серые элементы находятся вне метавокселей. Красные, зеленые и синие элементы оказываются в разных метавокселях.

Тестирование глубины

Шейдер отслеживания лучей учитывает буфер глубины, обрезая лучи в соответствии с буфером глубины. Для повышения эффективности отслеживание лучей начинается с первого шага луча, проходящего проверку глубины.


Рисунок 4. Взаимосвязь между глубиной и индексомs

Взаимосвязь между значениями глубины и индексами отслеживания лучей показана на рис. 4. Код прочитывает значение Z из Z-буфера и вычисляет соответствующее значение глубины (т. е. расстояние от наблюдателя). Величина индексов изменяется пропорционально от 0 до totalRaymarchCount в соответствии с изменением глубины от zMin до zMax. Из этого кода получаем (из EyeViewRayMarch.fx):

float depthBuffer  = DepthBuffer.Sample( SAMPLER0, screenPosUV ).r;
float div          = Near/(Near-Far);
float depth        = (Far*div)/(div-depthBuffer);
uint  indexAtDepth = uint(totalRaymarchCount * (depth-zMax)/(zMin-zMax));

Здесь zMin и zMax — значения глубины с точки зрения отслеживания лучей. Значения zMax и zMin соответствуют самой дальней точке от наблюдателя и самой ближней к нему точке.

Сортировка.

При рендеринге метавокселей поддерживаются два порядка сортировки: один для света, другой для наблюдателя. Распространение света начинается в метавокселях, ближайших к источнику света, затем переходит к более дальним метавокселям. Метавоксели полупрозрачны, поэтому для получения правильного результата необходима сортировка с точки зрения наблюдателя. С точки зрения наблюдателя существует два способа сортировки: от заднего плана к переднему с «верхним» альфа-смешением и от переднего плана к заднему с «нижним» альфа-смешением.

Рисунок 5. Порядок сортировки метавокселей

На рис. 5 показано простое расположение трех метавокселей, камеры и источника света. Для распространения света требуется порядок 1, 2, 3; мы должны распространить свет через метавоксель 1, чтобы узнать, сколько света дойдет до метавокселя 2. Затем нужно провести свет через метавоксель 2, чтобы выяснить, сколько света достигнет метавокселя 3.

Также нужно сортировать метавоксели из точки зрения глаза. При рендеринге от переднего плана к заднему мы сначала отрисовали бы метавоксель 2. Синяя и фиолетовая линии показывают, почему расстояние до метавокселей 1 и 3 больше, чем до метавокселя 2. Нам нужно распространить свет через метавоксели 1 и 2 перед рендерингом метавокселя 3. В наихудшем случае требуется распространять свет через весь столбец перед рендерингом любого из его элементов. При рендеринге в порядке от заднего плана к переднему мы сможем отрисовать каждый метавоксель сразу же после распространения в нем света.

В образце сочетается сортировка от переднего плана к заднему и от заднего к переднему, чтобы поддерживать возможность рендеринга метавокселей сразу же после распространения света. Метавоксели над перпендикуляром (зеленая линия) отрисовываются от заднего плана к переднему с «верхним» смешением, а метавоксели под перпендикуляром — от переднего плана к заднему с «нижним» смешением. Такая процедура упорядочения всегда выдает правильные результаты, не требуя огромного объема памяти для размещения всего столбца метавокселей. Обратите внимание, что, если приложение способно выделить достаточно памяти, этот алгоритм всегда может сортировать от переднего плана к заднему с «нижним» смешением.

Альфа-смешение

В образце используется «верхнее» смешение для метавокселей, упорядоченных от заднего плана к переднему (т. е. сначала отрисовывается самый дальний метавоксель, затем следующий по порядку и т. д.). Для метавокселей, упорядоченных от переднего плана к заднему (т. е. сначала отрисовывается ближайший метавоксель, затем следующий и т. д.), используется «нижнее» смешение.

«Верхнее» смешение: Цветназначение = Цветназначение * Альфаисточник + Цветисточник

«Нижнее» смешение: Цветназначение = Цветисточник * Альфаназначение + Цветназначение

При этом альфа-смешение в обоих случаях работает одинаково: альфа-значение назначения увеличивается на альфа-значение пиксельного шейдера.

Альфаназначение = Альфаназначение * Альфаисточник

Ниже приведены состояния рендеринга для «верхнего» и «нижнего» смешения.

Состояния рендеринга «верхнего» смешения (из EyeViewRayMarchOver.rs)

SrcBlend          = D3D11_BLEND_ONE
DestBlend         = D3D11_BLEND_SRC_ALPHA
BlendOp           = D3D11_BLEND_OP_ADD
SrcBlendAlpha     = D3D11_BLEND_ZERO
DestBlendAlpha    = D3D11_BLEND_SRC_ALPHA
BlendOpAlpha      = D3D11_BLEND_OP_ADD

Состояния рендеринга «нижнего» смешения (из EyeViewRayMarchUnder.rs)

SrcBlend          = D3D11_BLEND_DEST_ALPHA
DestBlend         = D3D11_BLEND_ONE
BlendOp           = D3D11_BLEND_OP_ADD
SrcBlendAlpha     = D3D11_BLEND_ZERO
DestBlendAlpha    = D3D11_BLEND_SRC_ALPHA
BlendOpAlpha      = D3D11_BLEND_OP_ADD

Совмещение

Результатом отслеживания лучей из точки наблюдения является текстура с заранее умноженным значением альфа-канала. Мы отображаем полноэкранный спрайт с альфа-смешением для составления изображения с обратным буфером.

Цветназначение = Цветназначение * Альфаисточник + Цветисточник

Состояния рендеринга:

SrcBlend  = D3D11_BLEND_ONE

DestBlend = D3D11_BLEND_SRC_ALPHA

В образце кода цель рендеринга с точки зрения наблюдателя может иметь меньшее разрешение, чем обратный буфер. При уменьшении цели рендеринга значительно повышается производительность, поскольку требуется отслеживать меньше лучей. Тем не менее, если цель рендеринга меньше обратного буфера, на этапе композиции будет выполнено увеличение масштаба, из-за чего вокруг краев силуэта могут образоваться трещины. Это распространенная проблема, решение которой мы оставим на будущее. Решить ее, в частности, можно путем масштабирования на этапе композиции.

Известные проблемы

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

Заключение

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

Разное

Некоторые слайды SPVR из презентации на конференции SIGGRAPH 2014:

https://software.intel.com/sites/default/files/managed/64/3b/VolumeRendering.25.pdf

См. пример в действии на Youtube*:

http://www.youtube.com/watch?v=50GEvbOGUks
http://www.youtube.com/watch?v=cEHY9nVD23o
http://www.youtube.com/watch?v=5yKBukDhH80
http://www.youtube.com/watch?v=SKSPZFM2G60

Дополнительные сведения об оптимизации для платформ Intel:

Whitepaper: Compute Architecture of Intel Processor Graphics Gen 8
IDF Presentation: Compute Architecture of Intel Processor Graphics Gen 8
Whitepaper: Compute Architecture of Intel Processor Graphics Gen 7.5
Intel Processor Graphics Public Developer Guides & Architecture Docs (Multiple Generations)

Благодарности

Благодарю за участие: Марка Фоконно-Дюфрена, Томера Барона, Джона Кеннеди, Джефферсона Монтгомера, Рэндалла Раувендала, Майка Берроуса, Фила Тэйлора, Аарона Кодэй, Егора Юсова, Филипа Стругара, Раджу Бала и Квернита Фремке.

Справочные материалы

1. M. Wrenninge и N. B. Zafar, SIGGRAPH 2010 и 2011 Production Volume Rendering, заметки к курсу: http://magnuswrenninge.com/content/pubs/ProductionVolumeRenderingFundamentals2011.pdf

2. M. Ikits, J. Kniss, A. Lefohn и C. Hansen, Volume Rendering Techniques (технологии объемной отрисовки), GPU Gems, http://http.developer.nvidia.com/GPUGems/gpugems_ch39.html

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

 

Эффективная порядко-независимая прозрачность на Android* с использованием фрагментного шейдера

$
0
0

Download Sample Code ZIPfile

Введение

Этот образец демонстрирует использование расширения GL_INTEL_fragment_shader_ordering, написанного под профиль OpenGL 4.4 и технические требования GLES 3.1. Минимальная требуемая версия OpenGL – 4.2 или ARB_shader_image_load_store. Расширение представляет новую встроенную функцию GLSL,  beginFragmentShaderOrderingINTEL(),которая блокирует выполнение вызова фрагментного шейдера до тех пор, пока вызовы от предыдущих базовых элементов, отображаемые на тех же ху-координатах окна, не будут завершены. В примере эта линия поведения используется для предоставления решений, обеспечивающих порядко-независимую прозрачность в типичной 3D-сцене в реальном времени.

Порядко-независимая прозрачность

Прозрачность – это фундаментальная проблема для рендеринга в реальном времени, ввиду сложности наложения случайного числа прозрачных слоёв в правильном порядке. Этот пример построен на работе, изначально описанной в статьях adaptive-transparencyи multi-layer-alpha-blending (Марк Сальви, Джефферсон Монтгомери, Картик Вайданатан и Аарон Лефон). Эти статьи показывают, как прозрачность может точно соответствовать реальным результатам, полученным от компоновки с использованием А-буфера, но может быть от 5 до 40 раз быстрее, благодаря использованию различных техник необратимого сжатия применительно к прозрачности данных. Данный пример представляет собой алгоритм на базе этих техник сжатия, который подходит для включения в такие приложения, как, например, игры.

Прозрачность бросает вызов

Пример рендеринга тестовой сцены с использованием стандартного альфа-смешивания показан на Рис. 1:


Рис. 1:Пример порядко-независимой прозрачности (OIT)

Геометрия визуализируется в фиксированном порядке: за землей следуют объекты внутри свода, затем свод и, наконец, растения снаружи. Блочные объекты рисуются первыми и обновляют буфер глубины, а затем рисуются прозрачные объекты в том же порядке без обновления буфера глубины. Увеличенное изображение демонстрирует один из визуальных артефактов, получающихся в результате: листва находится внутри свода, но перед несколькими плоскостями стекла. К сожалению, порядок рендеринга диктует правила таким образом, что все плоскости стекла, даже те, что находятся позади листвы, рисуются поверх. Обновление буфера глубины прозрачным объектом создает другой ряд проблем. Традиционно их можно решить разбивкой объекта на несколько небольших частей и их сортировкой front-to-back, исходя из точки расположения камеры. Но даже так идеального результата не достичь, поскольку объекты могут перекрещиваться, а затраты рендеринга, тем временем, возрастают с прибавлением числа отсортированных объектов.

Рис. 2 и рис. 3 показывают увеличенный визуальный артефакт, где на рис. 2 все плоскости стекла нарисованы перед листвой и на рис. 3 корректно отсортированы.


Рис. 2: Не отсортированы


Рис. 3: Отсортированы

Порядко-независимая прозрачность в реальном времени

Было множество попыток применить компоновку произвольно упорядоченных базовых геометрических элементов без необходимости сортировки на CPU или разбивки геометрии на непересекающиеся элементы. Среди таких попыток - depth-peeling, требующий многократного представления геометрии и техник А-буфера, где все фрагменты, связанные с заданным пикселем, хранятся в связном списке, отсортированы и затем перемешаны в корректном порядке. Несмотря на успех А-буфера в офлайн-рендеринге, он мало используется при рендеринге в реальном времени из-за неограниченных требований к памяти и, как правило, низкой производительности.

Новый подход

Вместо А-буфера: хранения всех цветов и данных глубины в попиксельных списках и последующей их сортировки и компоновки, пример использует исследование Марко Сальви и реструктурирует уравнение альфа-смешивания с целью избегания рекурсии и сортировки, создавая «функцию видимости» (Рис. 4):


Рис. 4:Функция видимости

Число шагов в функции видимости соответствует числу узлов, используемых для хранения информации по видимости на попиксельном уровне в процессе рендеринга сцены. По мере добавления пиксели хранятся в структуре узла до его полного заполнения. Затем при попытке включения большего числа пикселей алгоритм подсчитывает, какой из предыдущих узлов может быть присоединен для создания самой маленькой вариации в функции видимости, при этом сохраняя размер набора данных. Финальный этап – вычисление функции видимости vis() и компоновка фрагментов при помощи формулы final_color= .

Образец визуализирует сцену на следующих этапах:

  1. Очистка Shader Storage Buffer Object до стандартных значений по умолчанию.
  2. Визуализация всей блочной геометрии в основной фреймбуфер с обновлением буфера глубины.
  3. Визуализация всей прозрачной геометрии без обновления буфера глубины; финальные фрагментные данные отброшены из фреймбуфера. Фрагментные данные хранятся в наборе узлов внутри Shader Storage Buffer Object.
  4. Резолв данных внутри Shader Storage Buffer Object и подмешивание финального результата в основной фреймбуфер.

Рис 5:

Априори, затраты чтения Shader Storage Buffer Object на стадии резолва могут быть крайне высокими из-за требований пропускной способности. В оптимизации, задействованной в примере, для маскировки участков, где прозрачные пиксели могли бы быть вмешаны во фреймбуфер, используется стенсил буфер. Это меняет рендеринг так, как показано на Рис. 6.

  1. Clear the Stencil buffer.
  2. Clear the Shader Storage Buffer Object to default values on the first pass.
  3. Постановка следующей стенсил операции:
    1. glDisable(GL_STENCIL_TEST);
  4. Визуализация всей блочной геометрии в основной фреймбуфер с обновлением глубины.
  5. Постановка следующих стенсил операций:
    1. glEnable(GL_STENCIL_TEST);
    2. glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    3. glStencilFunc(GL_ALWAYS, 1, 0xFF);
  6. Визуализация всей прозрачной геометрии без обновления буфера глубины; финальные фрагментные данные интегрированы в основной фреймбуфер со значением альфа 0. Стенсил буфер отмечен для каждого фрагмента во фреймбуфере. Фрагментные данные хранятся в наборе узлов внутри Shader Storage Buffer Object. Отбрасывание фрагмента невозможно, так как это мешает обновлению стенсил.
  7. Постановка следующих стенсил операций:
    1. glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    2. glStencilFunc(GL_EQUAL, 1, 0xFF);
  8. Резолв данных внутри Shader Storage Buffer Object только для фрагментов, прошедших стенсил тест и подмешивание финального результата в основной фреймбуфер.
  9. Постановка следующих стенсил операций:
    1. glStencilFunc(GL_ALWAYS, 1, 0xFF);
    2. glDisable(GL_STENCIL_TEST);

Рис. 6: Stencil Render Path

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

01 void PSOIT_InsertFragment_NoSync( float surfaceDepth, vec4 surfaceColor )
02{
03	ATSPNode nodeArray[AOIT_NODE_COUNT];
04
05	// Load AOIT data
06	PSOIT_LoadDataUAV(nodeArray);
07
08	// Update AOIT data
09	PSOIT_InsertFragment(surfaceDepth,
10		1.0f - surfaceColor.w,  // transmittance = 1 - alpha
11		surfaceColor.xyz,
12		nodeArray);
13	// Store AOIT data
14	PSOIT_StoreDataUAV(nodeArray);
15}

Рис. 7: GLSL Shader Storage Buffer Code

Алгоритм, представленный выше, может быть применен на любом устройстве, которое поддерживает Shader Storage Buffer Objects. Однако существует один очень значимый недостаток: возможно наличие множества фрагментов в работе, отображаемых на тех же ху-координатах окна.

Если множественные фрагменты выполняются на тех же xy-координатах окна в одно и то же время, они будут использовать одни и те же начальные данные в PSOIT_LoadDataUAV,но приведут к разным значениям, которые будут испытываться и храниться в inPSOIT_StoreDataUAV – и последнее из них завершит перезапись всех прежних, что были обработаны. Такой эффект – вполне рутинная процедура компрессии, которая может варьироваться от фрейма к фрейму. Его можно заметить в примере при отмене Pixel Sync. Пользователь должен увидеть легкое мерцание в тех местах, где перекрываются прозрачности. Чтобы это было проще это увидеть, применяется функция зума. Чем больше фрагментов графический процессор в состоянии исполнять параллельно, тем больше вероятность увидеть мерцание.

По умолчанию пример избегает эту проблему, применяя новую встроенную GLSL-функцию, beginFragmentShaderOrderingINTEL(),которая может быть использована, когда строка расширения  GL_INTEL_fragment_shader_ordering показывается применительно к оборудованию. Функция ThebeginFragmentShaderOrderingINTEL()блокирует исполнение фрагментного шейдера до момента завершения всех вызовов шейдера от предыдущих базовых элементов, соответствующих тем же xy-координатам окна. Все операции обращения к памяти от предыдущих вызовов фрагментного шейдера, отображаемых на тех же ху-координатах, становятся видимыми для текущего вызова фрагментного шейдера при возврате функции. Это делает возможным слияние предыдущих фрагментов для создания функции видимости в детерминированной модели. Функция thebeginFragmentShaderOrderingINTEL не влияет на применение шейдера для фрагментов с неперекрывающимися ху-координатами.

Пример того, как вызвать beginFragmentShaderOrderingINTE,показан на Рис. 8.

01GLSL code example
02    -----------------
03
04    layout(binding = 0, rgba8) uniform image2D image;
05
06    vec4 main()
07    {
08        ... compute output color
09        if (color.w > 0)        // potential non-uniform control flow
10        {
11            beginFragmentShaderOrderingINTEL();
12            ... read/modify/write image         // ordered access guaranteed
13        }
14        ... no ordering guarantees (as varying branch might not be taken)
15
16        beginFragmentShaderOrderingINTEL();
17
18        ... update image again                  // ordered access guaranteed
19    }

Рис. 8: beginFragmentShaderOrderingINTEL

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

В случае с OIT примером, она просто добавляется, как показано на Рис. 9:

1 void PSOIT_InsertFragment( float surfaceDepth, vec4 surfaceColor )
2 {
3    // from now on serialize all UAV accesses (with respect to other fragments shaded in flight which map to the same pixel)
4 #ifdef do_fso
5    beginFragmentShaderOrderingINTEL();
6 #endif
7    PSOIT_InsertFragment_NoSync( surfaceDepth, surfaceColor );
8 }

Рис. 9: Добавление упорядочения фрагмента в доступ к Shader Storage Buffer

Запрашивается из любого фрагментного шейдера, который потенциально может записывать прозрачные фрагменты, как показано на рис. 10.

 

01 out vec4 fragColor;// -------------------------------------
02 void main( )
03 {
04    vec4 result = vec4(0,0,0,1);
05
06    // Alpha-related computation
07    float alpha = ALPHA().x;
08    result.a =  alpha;
09    vec3 normal = normalize(outNormal);
10
11    // Specular-related computation
12    vec3 eyeDirection  = normalize(outWorldPosition - EyePosition.xyz);
13    vec3 Reflection    = reflect( eyeDirection, normal );
14    float  shadowAmount = 1.0;
15
16    // Ambient-related computation
17    vec3 ambient = AmbientColor.rgb * AMBIENT().rgb;
18    result.xyz +=  ambient;
19    vec3 lightDirection = -LightDirection.xyz;
20
21    // Diffuse-related computation
22    float  nDotL = max( 0.0 ,dot( normal.xyz, lightDirection.xyz ) );
23    vec3 diffuse = LightColor.rgb * nDotL * shadowAmount  * DIFFUSE().rgb;
24    result.xyz += diffuse;
25    float  rDotL = max(0.0,dot( Reflection.xyz, lightDirection.xyz ));
26    vec3 specular = pow(rDotL,  8.0 ) * SPECULAR().rgb * LightColor.rgb;
27    result.xyz += specular;
28    fragColor =  result;
29
30 #ifdef dopoit
31   if(fragColor.a > 0.01)
32   {
33	PSOIT_InsertFragment( outPositionView.z, fragColor );
34	fragColor = vec4(1.0,1.0,0.0,0.0);
35   }
36 #endif
37 }

Рис. 10: Типичный фрагментный шейдер

Только те фрагменты, которые имеют альфа-фактор выше граничного значения, добавляются в Shader Storage Buffer Object, при этом отбраковываются любые фрагменты, не представляющие сцене никаких значимых данных.

Сборка тестового примера

Требования к билду

Установите последние версии Android* SDK и NDK:

Добавьте NDK и SDK в свою ветвь:

export PATH=$ANDROID_NDK/:$ANDROID_SDK/tools/:$PATH

Для сборки:

  1. Проследуйте в папку OIT_2014\OIT_Android*
  2. Только единожды вам может понадобиться инициализировать проект:                                                                                           android update project –path . --target android-19.
  3. Соберите NDK-компонент:                                                                                                                                                                    NDK-BUILD
  4. Соберите APK:
    ant debug
  5. Установите APK:
    adb install -r bin\NativeActivity-debug.apk or ant installd
  6. Выполните его

Выводы

Пример демонстрирует, как исследование адаптивной порядко-независимой прозрачности под руководством Марко Сальви, Джефферсона Монтгомери, Картика Вайданатана и Аарона Лефон, первоначально произведенное на высокопроизводительных дискретных видеокартах с использованием DirectX 11, может быть применено в реальном времени на планшете Android при помощи GLES 3.1 и упорядочения фрагментным шейдером. Алгоритм выполняется внутри постоянного требуемого объема памяти, который может варьироваться, исходя из требований визуальной достоверности. Оптимизации вроде стенсил буфера разрешают применение техники на широком ряде устройств на допустимом уровне производительности, обеспечивая практическое решение одной из самых насущных проблем рендеринга в реальном времени. Принципы, продемонстрированные в образце OIT, могут быть применены к целому спектру других алгоритмов, которые могли бы в нормальном режиме создавать попиксельные связные списки, включая техники объемного затенения и пост-процессинговое сглаживание.

Статьи по теме

https://www.opengl.org/registry/specs/INTEL/fragment_shader_ordering.txt
https://software.intel.com/ru-ru/articles/adaptive-transparency
https://software.intel.com/ru-ru/articles/multi-layer-alpha-blending

Технология Intel® Device Protection и McAfee Mobile Security для Android

$
0
0

Intel® Device Protection Technology

Недавние профильные отчеты говорят о том, что операционная система Android установлена на 59% ноутбуков, планшетов и смартфонов во всем мире. Поскольку рост популярности системы был взрывным и продолжается по сей день, IT-департаменты компаний ищут эффективные пути для управления функциональными возможностями устройств на базе Android и обеспечения их безопасности в рамках корпоративных требований. Недавно компания Intel анонсировала Intel® Device Protection Technology (IDPT), включающую расширенные возможности по безопасности для Android-устройств на базе Intel. В совокупности с мощными базовыми опциями безопасности на существующих SoC-системах Intel, IDPT значительно усиливает защиту устройств. Расширения по безопасности для Android эффективно блокируют и помогают обезопасить устройства от вредоносного программного обеспечения, злонамеренно доставляемого через различные приложения и веб-сайты. Эти устройства должны работать в паре со специальными сервисами безопасности, как, например, McAfee Mobile Security v3.2. Вдобавок, расширения по безопасности оптимизируют стандартное сканирование с целью минимизации влияния на производительность. Это позволяет сервисам безопасности отслеживать новые и измененные файлы и сканировать только нужные из них, тем самым выбирая самую оптимальную модель сканирования, которая занимает секунды вместо минут, благодаря возможности игнорировать неизмененные и ранее отсканированные файлы. Теперь McAfee Mobile Security поддерживает безопасность на уровне ядра путем интеграции с Intel Device Protection Technology. Эта разработка, используемая совместно с McAfee Mobile Security, позволит вам блокировать вредоносное программное обеспечение и защищать устройство, одновременно поддерживая высокую производительность и сохраняя заряд батареи.

McAfee Mobile Security

Ниже перечислены основные проблемы открытых платформ на базе Android:

  • Недостаточная защита от вредоносных приложений и троянов
  • Недостаточная безопасность устройства/ API  управления
  • Незащищенность от руткитов
  • Несанкционированная загрузчики

McAfee Mobile Security помогает решить эти проблемы, являясь лидером по разработке антивирусных продуктов. В этой статье мы расскажем о McAfee Mobile Security для Android.

Загрузка McAfee Mobile Security

Вы можете загрузить McAfee Mobile Security из Google Play.

После загрузки и запуска антивирусного ПО в первый раз приложение потребует от вас пройти процедуру активации через SMS и email.

McAfee Mobile Security оснащен качественным интуитивным интерфейсом. Домашний экран отображает основные антивирусные компоненты: проверку безопасности, безопасность приложений, веб-безопасность и другие. Давайте рассмотрим основные из них.

Базовые компоненты и функции

Сканирование безопасности

Это функционал проверки файлов на вирусы. Проверка карты micro-SD 2 Гб заняла 10 минут, было обнаружено 2 угрозы. Для сравнения, другой антивирус просканировал устройство за 3,5 минуты и ничего не обнаружил.

Конфиденциальность

С помощью этой функции McAfee  сканирует и проверяет ваши приложения на предмет различных типов и уровней доступа к данным и функциям вашего Android-устройства. К примеру, карты Google требуют доступа лишь к местоположению пользователя, в то время как Facebook собирает детальную информацию о пользователе – местоположение, доступ к сети, контакты и другие данные. Если вы не хотите, чтобы приложение имело доступ к вашим данным, вы можете мгновенно удалить его.

Веб-безопасность

Этот мощный инструмент блокирует вредоносные веб-страницы. К сожалению, этот компонент не имеет расширенных настроек. Вы можете лишь актировать и дезактивировать его.

Поиск устройства

Этот компонент позволяет управлять данными с устройства на расстоянии. Вы можете заблокировать устройство и отобразить на экране сообщение с просьбой о возврате. Также возможно отслеживать местоположение телефона. Вы можете удаленно стереть все данные с телефона или сделать копию.

Выводы

Некоторые люди недооценивают риск вредоносных инфекций на смартфонах и планшетах. Другие уверены, что, если они загрузили приложение с Google Play, то им вовсе не стоит беспокоиться о безопасности. Однако угрозы от вредоносного программного обеспечения поступают все чаще и чаще, и лучше обезопаситься сегодня, чем сожалеть завтра. McAfee Mobile Security – самый функциональный выбор для защиты вашего устройства.

Преимущества McAfee Mobile Security:

  • Сканирование приложений с использованием большой базы антивредоносных данных
  • Понятный интерфейс
  • Удаленное управление через Интернет (для защиты от кражи и потери телефона)

Статьи по теме:

  • Об Intel Device Protection Technology можно прочитать здесь.
  • Узнайте больше информации о McAfee Mobile Security на www.mcafee.com.
  • Чтобы загрузить McAfee Mobile Security, откройте Google Play.

Об авторе

Егор Филимонов работает в группе Software & Services корпорации Intel. Он является студентом Факультета математики и механики Государственного Университета им. Лобачевского в Нижнем Новгороде по специальности Прикладная математика и информатика. Его интересы: HPC (High Performance Computing) и мобильные технологии.

Разработка интеллектуального автономного дрона с помощью смартфона Android*

$
0
0

Забавляться с компактными радиоуправляемыми микровертолетами-беспилотниками (так называемыми дронами) очень весело. Но строить такие дроны еще интереснее! Для тех, кто интересуется разработкой собственных «интеллектуальных» беспилотников-дронов, в этой статье приводятся инструкции по созданию интеллектуального автономного дрона с использованием смартфона с Android*, OpenCV*, C++ и Java*. И это только начало. Освоив эти инструкции, вы сможете использовать и другие доступные программы, чтобы расширить возможности вашего дрона. Посетите сайт Intel® Software Academic Program [1] для получения дополнительной информации об учебных материалах Intel® OpenCourseWare для самостоятельно изучения.

Материалы и методы

Автономный и умный?

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

Вы видели рекламу дронов, созданных компаниями Lexus и KMEL Robotics [2], где выступает целый рой маленьких сверхточных дронов? Движениями этих дронов в пространстве можно было управлять со столь высокой точностью благодаря мощным датчикам, размещенным по всему помещению. Поскольку в последнее время дронам уделяется немало внимания в СМИ, вы, возможно, уже знаете, что для их навигации можно использовать GPS. GPS — это очень удобная и простая в использовании система, поскольку она полностью цифровая. Она используется, к примеру, самолетами для навигации во время полетов на большой высоте. Но точность плюс-минус 2,5 м при существующих задержках не позволит автоматическому микровертолету-дрону доставить, к примеру, коробку с пиццей к порогу вашего дома: на 2,5 м ближе — и дрон врежется в ваш дом, на 2,5 м в сторону — и дрон столкнется с каким-либо другим препятствием. Да, эти микровертолеты оснащены независимой навигационной системой, но они не очень «умные».

Чтобы быть действительно «умным», ваш микровертолет должен обладать достаточной вычислительной мощностью, чтобы, к примеру, снимать видео и в реальном времени анализировать такие заснятые объекты, как QR-коды (это просто), фигуры или движения (это уже сложно). Можно также измерять объем помещений и строить модель пространства в реальном времени, как это было сделано в «умном» микровертолете Массачусетского технологического института [3]. Тем не менее для всех этих возможностей требуется довольно мощный процессор, различные датчики (акселерометры и GPS), а также возможность периодической передачи данных по сетям 3G/4G. Кроме того, все это также должно быть легким, удобным при программировании и получать электроэнергию от хорошего аккумулятора. В сухом остатке мы получаем, по сути, очень мощный мобильный телефон, который управляет полетом микровертолета.

Недавно мы разработали устройство дистанционного управления микровертолетом на основе смартфона на Android. В нашем случае это был смартфон ZTE V975 Geek с процессором Intel® Atom Z2580. Использование Android упрощает разработку программного обеспечения и обмен кодом между ПК и смартфоном. Даже собственные библиотеки, такие как Intel® Integrated Performance Primitives (Intel® IPP) [4] или OpenCV [5], можно использовать и на смартфонах с Intel Android, и на ПК. Нет необходимости изобретать велосипед, поскольку смартфон уже оборудован всеми необходимыми компонентами: на нем есть камера, датчик GPS, акселерометр и модуль передачи данных 3G.

Управление моторами

Приняв решение о выборе бортового компьютера, мы были уже готовы к подключению электромоторов. Мы выбрали сервоконтроллер Pololu Maestro*, который стоит около 5 евро, подключается через USB и даже оснащен модулем Bluetooth* с дополнительным интерфейсом Bluetooth с последовательным портом. Эта плата используется для управления стандартными сервомоторами. Если нужно управлять квадрокоптером (четырехмоторным микровертолетом) или другим типом дрона, просто замените блок радиоуправления на смартфон с Android и эту плату Pololu, чтобы превратить микровертолет из радиоуправляемого в автономный и «умный». Этот рецепт исключительно универсален. Правда, ничего сложного?

С помощью нескольких строк кода и стандартного пакета Android USB мы можем управлять сервомоторами и, следовательно, управлять движением нашего летательного аппарата. Еще несколько строк кода — и мы можем получать доступ к GPS, делать фотоснимки и отправлять их по сети 3G. На программном уровне работа с Android позволяет быстро развивать возможности проекта.

Вызовите controlTransferиз UsbDeviceConnection:

import android.hardware.usb.UsbDeviceConnection;
// …
private UsbDeviceConnection connection;
// …
connection.controlTransfer(0x40, command, value, channel, null, 0, 5000);

Эта плата позволяет переместить сервопривод, задав конечное положение, скорость и ускорение. Это все, что необходимо для плавного движения. Аргумент command может быть одним из этих трех значений:

	public static final int USB_SET_POSITION = 0x85;
	public static final int USB_SET_SPEED = 0x87;
	public static final int USB_SET_ACCELERATION = 0x89;

Нужно выбрать соответствующее значение и направить его на нужный сервопривод, выбрав его канал. Полный исходный код и конфигурацию доступа USB в манифесте приложения см. в ZIP-файле [1].

Особенность квадрокоптеров

Пока все в порядке. Все оборудование поддерживает стандарт plug-n-play, код несложен, все делается в Android. Но при разработке встроенных систем существуют определенные особенности, как мы сейчас увидим на примере квадрокоптеров. Существует принципиальная разница между многомоторными дронами и простыми моделями, такими как радиоуправляемые автомобили или самолеты. Если вы управляете радиоуправляемым автомобилям, вам нужен лишь сервопривод электронного управления скоростью (ЭУС) и еще один сервопривод для управления направлением (т. е. для поворота руля). Многомоторному дрону требуется система постоянной балансировки, чтобы удерживать нужное положение. К счастью, квадрокоптеры оснащаются собственной платой стабилизации. Вместо подключения напрямую к плате Pololu и к четырем моторам с ЭУС квадрокоптера (с написанием сложной программы стабилизации на C/C++ или Java на Android), намного проще подключить плату стабилизации к плате Pololu и предоставить управление всеми четырьмя моторами этой плате стабилизации. Управлять всем остальным (высотой, скоростью, наклоном и направлением) можно с помощью простых команд Java: +/- altitude, +/- speed/, +/- inclination, +/- directionи т. п. Мы управляем всеми функциями с помощью смартфона с Android, поскольку у него мощный процессор, но балансировку моторов мы предоставили небольшой отдельной плате стоимостью несколько евро. Вам как разработчику было бы полезно знать об этой плате и о том, почему мы решили ее использовать. Кроме того, плата требуется лишь для начальной калибровки, а после этого про нее можно забыть.

Завершение первого этапа

В конце начального этапа разработки автономного четырехмоторного микровертолета аппаратная «цепочка» выглядит так:

мобильный телефон <> хост-адаптер micro USB-USB <> кабель USB-mini USB <> плата Pololu Maestro <>
 4 кабеля JR <> плата стабилизации <> кабели JR <> ЭУС <> моторы вертолета

Для сравнения у более простых дронов аппаратная «цепочка» устроена так:

мобильный телефон <> хост-адаптер micro USB-USB <> кабель USB-mini USB <> плата Pololu Maestro <>  кабели JR <> ЭУС <> моторы вертолета

В качестве бонуса вы также можете управлять другими сервоприводами, например двухканальной трехмерной камерой, присоединенной к вертолету. Также при необходимости можно управлять закрылками, шасси и т. п. Платы Pololu Maestro могут управлять 6–24 моторами; это гораздо больше, чем требуется для данного проекта, но это дает высокую гибкость.

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

Компьютерное зрение

Мы установили, что нашему дрону требуется мощный бортовой процессор для автономного управления, но пока отсутствует код, способный воспользоваться этой вычислительной мощностью. Итак, давайте сделаем нашего дрона «зрячим».

Зачем?

 

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

В реальных условиях важно, чтобы наш автономный летательный аппарат мог «видеть», например распознавать и отслеживать маркеры или же визуально определять людей. Необходимо получать изображения из Android и анализировать их с помощью OpenCV.

Каким образом?

 

OpenCV— это библиотека функций программирования с открытым исходным кодом для анализа изображений. Она служит основой для многочисленных проектов, посвященных компьютерному зрению и виртуальной реальности. Библиотека OpenCV была изначально разработана корпорацией Intel, а теперь доступна для множества аппаратных платформ и ОС. Можно разрабатывать код на ПК и развертывать его на серверах, смартфонах или интернет-устройствах.

Для тренировки мы сначала попробуем распознать простой знак, такой как круг, и использовать смартфон для управления полетом, чтобы оказаться перед кругом на фиксированном расстоянии. Предположим, что с помощью GPS наш беспилотный вертолет может определить положение взлетной полосы (около 3 м) и прилететь к ней. Он должен быть способен распознать знаки на земле, чтобы занять правильное положение в точности над местом посадки и на фиксированной высоте. После этого микровертолет сможет приземлиться на обозначенном месте с точностью до нескольких сантиметров. Чтобы упростить тест, мы выведем элементы управления полетом на экран, а вы будете имитировать движение дрона, перемещая рукой мобильный телефон.

Навигация с помощью смартфона

Проект Java

OpenCV не входит в состав библиотек, доступных напрямую из Java на платформе Android. Это собственная библиотека, используемая обычно из C++, поэтому потребуется использовать Android NDK. Сегменты кода, отвечающие за получение изображений и за их показ, будут написаны на Java, а обмен данными между Java и C++ будет осуществляться с помощью JNI. Нужно установить Android NDK, Android SDK, создать описанный выше проект «Круги», добавить компонент C/C++, а затем изменить параметры проекта, чтобы использовать библиотеку OpenCV. Параметры см. на следующих снимках экрана Eclipse:


Параметры проекта Java*

 


Параметры проекта C/C++

 


Параметры парсера для проекта C/C++

 


Включает параметры для STL, OpenCV* и NDK

 

В конечном итоге наш проект будет содержать следующее:

Главный файл JavaSrc/MainActivity.java
Файл разметки XMLRes/layout/activity_main.xmlи манифест
Два сборочных файла Jni/Android.mkи Jni/Application.mk
Код cppJni/ComputerVision_jni.cppи заголовок Jni/ComputerVision_jni.h

Архитектура оборудования

В отличие от Java, код на C++ необходимо компилировать для определенной архитектуры процессоров. Это настраивается путем редактирования переменной APP_ABIв файле Application.mk. Для процессора Intel Atom, который установлен в нашем смартфоне, этой переменной нужно присвоить значение x86; остальную работу сделает NDK.

Развертывание

Библиотека OpenCV используется тысячами приложений для Android, и все приложения могут использовать разные версии этой библиотеки. Будучи разработчиком приложения, вы могли бы объединить нужную версию OpenCV в пакет вместе с вашим приложением, но есть и более интересный способ: использовать диспетчер зависимостей под названием OpenCV Manager. Это приложение Android определяет, когда вам требуется OpenCV, какой именно версии, нужна ли помощь с установкой, и загружает OpenCV. Ваше приложение должно будет подключиться к OpenCV Manager, а остальные действия будут выполнены автоматически.

Взаимодействие между C++ и Java, алгоритм

Нужно определять круги в OpenCV, определять их центр и радиус, затем отображать команды оператору смартфона, чтобы добиться идеальной центровки и нужного размера круга. Следующий код Java получает изображение с камеры с помощью API Java для Android. Он осуществляет вызов C++ через JNI и присоединяет указатель к изображению в памяти. Затем код C++ обрабатывает изображение, чтобы распознать круги. Происходит обратный вызов Java для отображения обнаруженных кругов и комментариев.

Дистанционная работа

При тестировании я поместил телефон перед печатным листом бумаги. Для имитации нужного положения микровертолета я выбрал определенное расстояние, чтобы оценить, насколько большим кажется круг через оптику камеры моего телефона. Например: я нарисовал на бумаге круг диаметром 10 см, поместил телефон на расстоянии 20 см от бумаги. Диаметр круга при этом составил 300 пикселей. Вот какого размера он должен быть виден с нужного расстояния. Если круг слишком большой, нужно отодвинуться назад, если слишком маленький — приблизиться. В конечном итоге наш вертолет окажется на нужном расстоянии от круга.

Наш первый тестовый случай очень простой: 1 круг = 1 расстояние. Можно пройти дальше и использовать несколько концентрических кругов. Крупный круг удобно обнаруживается с большого расстояния; средние круги будут использоваться, когда дрон будет уже слишком близко, чтобы «разглядеть» крупный круг, а в конечном итоге дрон должен приземлиться на самый маленький круг. Если круги не обеспечивают достаточную точность, можно использовать и более сложные фигуры, например стрелки.

Поместите круг в центре изображения смартфона, чтобы смоделировать расположение микровертолета прямо над посадочным знаком. Управление такого типа работает достаточно просто. В сочетании с другими данными, такими как цвет, координаты GPS и, возможно, глубина, это несложно реализовать в виде программного кода.

Код Java

…
// capture images from the camera
import org.opencv.Android.CameraBridgeViewBase;
// load OpenCV native dependancy
import org.opencv.Android.OpenCVLoader;
…
public void onResume()
{
super.onResume();
// OpenCV loading with a callback
// non typical code specific to OpenCV
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
}
…
// once the OpenCV manager link established,
// we can load the dynamic library
System.loadLibrary("jni_part");
…

Код С++

…
// typical for JNI : Java class method name
// pointer to RGB image as argument
JNIEXPORT int JNICALL Java_com_example_circles_MainActivity_process
(JNIEnv *jenv, jobject obj, jlong addrGray, jlong addrRgba)
…
// Get the bitmap from pointer
Mat& mRgb = *(Mat*)addrRgba;
// blur, required before detecting circles
medianBlur(mGr,mGr,5);
// OpenCV detection – Hough transformation
HoughCircles(mGr, //grayscale input image
*circles, //output vector
CV_HOUGH_GRADIENT, //detection method to use
4, //inverse ratio of the accumulator resolution to the image
mGr.rows/8, //min distance between centers of detected circles
220, //higher threshold of the two passed intern canny edge detector
200, //accumulator threshold	100
20, //min radius
mGr.cols/8 //max radius
);

Работа и дальнейшие действия

Установите OpenCV Manager из Google Play* [6] и APK-файл вашего приложения из Eclipse* [7]. Запустите приложение и пройдите его настройку; оно обнаружит круги в поле зрения и приведет вас к центру круга с заданным диаметром.

Определение кругов очень просто. На начальном этапе для удобства можно использовать однотонный фон и высококонтрастные изображения. Простые функции компьютерного зрения работают с простыми фигурами точно так же, как младенцы играют с простейшими формами: круги, квадраты, звезды — все геометрические примитивы определяются как векторы. Расширенные функции компьютерного зрения могут обрабатывать не только простые геометрические примитивы, но и любые фотографические изображения. Такие библиотеки используются в приложениях дополненной реальности: они могут обнаруживать присутствие любой фотографии на другой фотографии даже при наличии искажений. Например, если задать фотографию коробки с печеньем, приложение обнаружит положение и трехмерную ориентацию такой коробки на более крупной фотографии. В большинстве случаев приложения для компьютерного зрения работают при перемещении объекта перед неподвижным мобильным телефоном. Объект обнаруживается и может быть дополнен трехмерными объектами, как показано в этом видео: http://www.dailymotion.com/video/
xco8xm_la-realite-augmentee-par-total-imme_tech
[8].

Разумеется, нашему дрону не нужно распознавать упаковки с едой. Но эту же библиотеку можно использовать и иначе: обнаруживать неподвижное фотографическое изображение с помощью движущегося мобильного телефона на борту микровертолета. Пример. Если я предоставлю дрону фотографию места посадки, дрон сможет распознать его, понять, где именно (с высокой точностью) оно находится в пространстве по сравнению с показанным шаблоном, и рассчитать визуальный заход на посадку. Эта же библиотека, другой случай использования.

Для управления дроном просто заменяйте отображаемые указания, отправляя команды power (мощность), roll (крен), pitch (тангаж) и yaw (скольжение) дрону, на котором установлена камера. Команды пилотирования дрона и печатные команды совпадают, поэтому перейти от комнатных тестов к полетам на открытом воздухе будет нетрудно.

На нашем смартфоне при тестировании мы получаем и обрабатываем изображения через каждые 0,08 секунды, то есть 12,5 кадра в секунду. Это означает, что можно без особых усилий оснастить возможностью «компьютерного зрения» дрон, укладываясь при этом в жесткие ограничения по времени разработки/мощности ЦП/потреблению электроэнергии, свойственные небольшим дронам. Все необходимые данные вычисляются независимо.

Можно пройти гораздо дальше. OpenCV — библиотека с открытым исходным кодом, ее можно переносить на самые разные платформы. Кроме того, Intel IPP [5] заменяет некоторые низкоуровневые вызовы OpenCV и ускоряет код путем внедрения процедур, оптимизированных для процессоров Intel. Можно добиться переносимости кода и использовать библиотеку с открытым исходным кодом, получая при этом преимущества производительности Intel IPP.

И наконец, использование смартфона Android с процессором Intel для управления микровертолетом — это оптимальное решение, сочетающее производительность, длительную работу от аккумулятора и простоту разработки. Этот первый проект дает возможность перейти на другую ОС или на более мощную аппаратную платформу, если мощности смартфона недостаточно или если нужно перейти на более крупный вертолет. Кроме того, ознакомьтесь с другими программами [1], где показаны доступные инструкции по разработке в области дронов и роботов.

Об авторах

Авторы:Поль Гермонпрес (Paul Guermonprez), Николя Вайе (Nicolas Vailliet), Седрик Андреолли (Cedric Andreolli)
Ссылка:http://intel-software-academic-program.com/pages/courses#drones
Эл. адрес:paul.guermonprez@intel.com
Команда: Intel Software Academic Program для региона EMEA-Россия, Париж, Франция

Ссылки и Ресурсы

[1] Intel Software Academic Program: http://intel-software-academic-program.com/pages/courses#drones

[2] The Mill: Lexus “Swarm” Behind The Scenes: http://vimeo.com/78549177

[3] Autonomous Robotic Plane Flies Indoors at MIT:  http://www.youtube.com/watch?v=kYs215TgI7c

[4] Intel® Integrated Performance Primitives (Intel® IPP): http://software.intel.com/ru-ru/intel-ipp

[5] OpenCV: http://opencv.org

[6] Google Play: https://play.google.com/store

[7] Eclipse: https://www.eclipse.org

[8] www.dailymotion.com: La réalité augmentée, par Total Immersion. http://www.dailymotion.com/video/xco8xm_la-realite-augmentee-par-total-imme_tech

 

Новая среда разработки Android*-приложений – Android Studio (Beta)

$
0
0

В теории

Эта статья представляет Android* Studio (Beta), новую интегрированную среду разработки, которая, в конце концов, заменит Eclipse ADT Bundle. В качестве примера использования эта статья обрисует линию движения проекта Android, созданного с использованием Eclipse ADT, к использованию Android Studio.

Предупреждение: В момент написания этой статьи Android Studio еще находилась на стадии Beta. Вы можете столкнуться с рядом еще не внедренных опций или ошибками. Если вам дискомфортно работать с Beta-продуктом, вы могли бы продолжить использование привычной среды, к примеру, ADT Eclipse.

Введение

Последние несколько лет Android поощрял разработчиков использовать Eclipse ADT (Android Developer Tools) Bundle в качестве среды для разработки приложений. Ситуация изменилась, когда недавно была анонсирована и стала доступна для загрузки Android Studio (Beta). За последние несколько месяцев мы увидели улучшение новой IDE. Сообщество Android было проинформировано о том, что Android Studio станет официальной Android IDE. Разработчикам, в настоящее время использующим ADT, рекомендовано активно переходить на Android* Studio IDE. В этой статье наглядно показано, что переход является довольно простым.

В отличие от ADT Bundle, базируемой на Eclipse IDE и системе Apache Ant, Android Studio работает на основе IntelliJ* IDEA и системе Gradle. Несмотря на то, что основные компоненты и технологии значительно отличаются, Android предлагает необходимые инструменты и технологические схемы для поддержки перехода от использования ADT к Android Studio.

Статья базируется на JDK-версии 1.8.0_25Android Studio (Beta) 0.9.1 и ADT версии 23.0.2 для системы Windows* 8.1 64-бит.

Установка и настройка

Для установки и запуска Android Studio вам потребуется JDK 6 или выше. Чтобы проверить наличие подходящей версии JDK, откройте окно ввода команды и введите “javac -version”. Вы увидите номер версии javac. Убедитесь, что он выше 1.6, а в ином случае зайдите на http://www.oracle.com/technetwork/java/javase/downloads/index.htmlдля загрузки и установки нужной версии JDK. Вам может потребоваться добавление переменной системной среды “JAVA_HOME” в поле значения наряду с директорией установки JDK.

В загрузке Android Studio нет привязки к Android SDK или инструментам SDK. Вы можете скопировать существующую папку Android «sdk» из IDE, которую вы используете на данный момент. Например, из директории установки ADT в ту же директорию, куда вы собираетесь устанавливать Android Studio - C:\android. Если в вашей системе на данный момент отсутствует SDK, посетите https://developer.android.com/sdk/index.html?hl=iвыберите секцию «Get the SDK for An Existing IDE» для загрузки копии отдельных SDK-инструментов для Windows. Для удобства вы можете задать инсталлятору SDK Tools путь C:\android\sdk folder.

Для загрузки Android Studio Beta посетите официальную страницу загрузки:

https://developer.android.com/sdk/installing/studio.html

Архив представляет собой файл .zip. Просто разархивируйте файл в папку, к примеру, C:\android. Для запуска Android Studio перейдите в C:\android\android-studio\bin и запустите «studio64.exe».

Если все прошло гладко, вы увидите стартовый экран Android Studio, как показано на Рис. 1.

Android Studio start window
Рис. 1 - Стартовый экран Android Studio

Переход с Eclipse ADT на Android Studio

В этой статье сделано два предположения: 1) вы являетесь опытным разработчиком Android-приложений и 2) вы используете ADT на Eclipse, самую популярную среду разработки Android-приложений. С появлением Android Studio вы можете пожелать перенести свои нынешние поддерживаемые или находящиеся в стадии разработки проекты с ADT в Android Studio. В нашем случае мы имеем ресторанное приложение (Рис. 2), которое предлагает много современных опций на базе Android SDK – анимацию, сенсоры, геолокацию и NFC. Приложение было разработано с помощью ADT.

Android restaurant business app
Рис. 2 – Ресторанное бизнес-приложение на Android

Мы покажем пошаговую инструкцию того, как перевести проект в Android Studio таким образом, чтобы продолжить будущую доработку уже на базе новой среды.

Экспорт файлов Gradle в ADT Eclipse

Вы, может быть, знаете, что, используя Android Studio, вы можете импортировать ADT-проект напрямую. Тем не менее, базируясь на наших экспериментах, можно сказать, что наиболее надежный путь – это экспорт файлов билда Gradle из вашего ADT-проекта и затем импорт сгенерированных файлов в Android Studio.

В ADT Eclipse IDE (Рис. 3) кликните правой кнопкой мыши на открытом проекте (в нашем случае это проект «RestaurantApp» в окне Package Explorer) и выберите «Export».

The Eclipse ADT IDE
Рис. 3 - Eclipse ADT IDE

В диалоговом окне «Export» выберите «Android», затем «Generate Gradle build files» (Рис. 4). Диалоговые окна экспорта проведут вас через весь процесс генерации файлов билда Android Studio. На заключительном этапе вам необходимо будет поставить галочку «Force overriding of existing files» и затем нажать «Finish».

ADT&#039;s Export project dialog box
Рис. 4 – В диалогом окне Export выберите опцию по генерации файлов билда Gradle

После завершения процесс экспортирования мы можем увидеть файл build.gradle, сгенерированный в корневой директории проекта «RestaurantApp». Этот файл мы будем использовать для импорта проекта в Android Studio.

Как было упомянуто, в то время как ADT Eclipse использует Apache Ant для управления билдом проекта, Android Studio использует иную систему под названием Gradle. В Gradle билды проектов управляются скриптами вроде файлов build.gradle. Скрипты билда написаны на динамическом языке под названием Groovy. Мы можем заглянуть в файл build.gradle (Пример кода 1). Ключевым моментом является первая строка, которая применяет «android»-плагин к проекту. Плагин добавит некоторое число задач проекту для выполнения требований билда.

apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':google-play-services_lib')
}

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}

Пример кода 1 – Файл build.gradle, сгенерированный для проекта RestaurantApp

После экспортирования файлов билда Gradle мы можем закрыть проект и выйти из ADT Eclipse.

Импорт проектов в Android Studio

Теперь мы запускаем Android Studio и на стартовом экране выбираем «Import non-Android Studio Project» (Рис. 5).

the import project option in Android Studio
Рис. 5 – Опция импорта проекта на стартовом экране Android Studio

На следующем экране мы переходим в папку проекта RestaurantApp и выбираем файл build.gradle, сгенерированный в ADT Eclipse (Рис. 6) и нажимаем ОК.

select the Gradle file to import
Рис. 6 – Выберите файл Gradle для импорта

Готово! Теперь в Android Studio у нас есть проект RestaurantApp (Рис. 7). Мы можем продолжить нашу разработку в рамках новой IDE.

the imported project in Android Studio
Рис. 7 – Импортированный проект в Android Studio

Запуск нового проекта в Android Studio

После знакомства с Android Studio мы можем увидеть, насколько мощным является этот инструмент для разработки приложений, выполняемых на всех видах устройств Android, включая смартфоны, планшеты, Android TV и Android Wear (Рис. 8).

Использование этого инструмента открывает огромные преимущества Android-разработчикам.

new Android form factors
Рис. 8 - Android Studio поддерживает разработку для новых форм-факторов Android

Существующие ограничения

Единственное, о чем стоит напомнить, - Android Studio до сих пор находится в стадии Beta. Некоторые опции все еще находятся на разработке и не включены. К примеру, на момент написания статьи, поддержка NDK была всё еще не интегрирована в инструмент, но по обещаниям Android, это случится совсем скоро.

Другие полезные материалы

Об авторе

Миао Вей – специалист по разработке программного обеспечения в Intel Software и Services Group.

Использование расширенных возможностей компилятора Intel® C++ для приложений Android*

$
0
0

Содержание

Использование выполняемого модуля Intel® Cilk™ Plus в Android для реализации многопоточности приложений

 

Intel® Cilk™ Plus — это расширение C и C++, дающее возможность легко и удобно задействовать многоядерную архитектуру и векторную обработку. Три ключевых слова Intel Cilk Plus предоставляют простую, но удивительно мощную модель для параллельного программирования, а модуль рантайма и библиотеки шаблонов образуют удобную среду для создания параллельных приложений.

При использовании Intel Cilk Plus для реализации многопоточности в приложениях требуется линковка с библиотекой времени выполнения Cilk (libcilkrts.so).

Разработка с помощью компилятора Intel C++ и системы сборки NDK (ndk-build)

Система сборки NDK не линкует библиотеки C++ для модулей, написанных на C, в результате чего компилятор не может выбрать нужную библиотеку Intel Cilk Plus при линковке, что может привести к ошибкам линковки.

1. Добавьте пустой файл C++ в проект, чтобы включить линковку C++ в системе сборки NDK.

2. Укажите совместимую реализацию C++ в файле Application.mk.

  • 'APP_STL:=stlport_shared'или
  • 'APP_STL:=gnustl_static'или
  • 'APP_STL:=gnustl_shared'

3. Измените код Java согласно инструкциям в разделе «Подготовка вызовов JNI» ниже.

Разработка с помощью компилятора Intel C++ без системы сборки NDK (ndk-build)

Если ваша среда разработки содержит код C++, нужно явным образом выполнить линковку с библиотекой GNU_STL или stlport.

Выполните следующие действия.

1. Укажите следующие флаги для компиляции и линковки для соответствующей реализации C++ в NDK.

  • Флаги компиляции:
    -I$ANDROID_GNU_LIBSTDCPP/include -I$ANDROID_GNU_LIBSTDCPP/libs/x86/include
  • Флаги линковки (gnustl_shared):
    -L$ANDROID_GNU_LIBSTDCPP/libs/x86 -lgnustl_shared -lsupc++
  • Флаги линковки (gnustl_static):
    -L$ANDROID_GNU_LIBSTDCPP/libs/x86 -lgnustl_static -lsupc++

где
ANDROID_GNU_LIBSTDCPP=$NDK/sources/cxx-stl/gnu-libstdc++/4.6. 4.6 следует заменить на версию GCC, на которую указывает ANDROID_GNU_X86_TOOLCHAIN. Например, если ANDROID_GNU_X86_TOOLCHAINуказывает на $NDK/toolchains/x86-4.8/prebuilt/linux-x86, то замените 4.6 на 4.8.
При использовании Intel Cilk Plus требуется линковка с библиотекой libcilkrts.so. Эта библиотека находится в папке /compiler/lib/ia32/gnustl.

2. Если используется библиотека C++ stlport_shared (требуется NDK r9 или более поздней версии), добавьте следующие флаги.

  • Флаги компиляции:
    -I$ANDROID_STLPORT_LIBSTDCPP/stlport
  • Флаги линковки:
    -L$ANDROID_STLPORT_LIBSTDCPP/libs/x86 -lstlport_shared

Где
ANDROID_STLPORT_LIBSTDCPP = $NDK/sources/cxx-stl/stlport.

При использовании Intel Cilk Plus соответствующая библиотека находится в папке /compiler/lib/ia32/stlport.

Подготовка вызовов JNI

Подготовка вызовов JNI необходима для использования Intel Cilk Plus для всех версий Android вплоть до Android 4.3 (Jelly Bean MR2). Библиотеку libcilkrts.so нужно загружать из кода Java с помощью следующего вызова API:
System.loadLibrary("cilkrts");

Если приложению требуется динамическая реализация C++, нужно загрузить соответствующую библиотеку в дополнение к libcilkrts.so:

System.loadLibrary("gnustl_shared");
 System.loadLibrary("cilkrts");

или

 System.loadLibrary("stlport_shared");
System.loadLibrary("cilkrts"); 

Использование PGO для повышения производительности приложений в ОС Android*

Профильная оптимизация (Profile-guided Optimization, PGO) повышает производительность приложений путем переупорядочения кода, чтобы исключить неэффективное кеширование, уменьшить объем кода и выявить неверное предсказание при ветвлении. PGO предоставляет компилятору информацию о наиболее часто исполняемых областях приложения. Обладая информацией об этих областях, компилятор может оптимизировать работу приложения..

Для использования PGO в Android (по сравнению с другими ОС) требуются определенные дополнительные действия.

1. Добавьте следующие параметры во флаги C в файле jni/Android.mk:
LOCAL_CFLAGS:= -prof-gen -prof-dir /sdcard.

2. Добавьте разрешение WRITE_EXTERNAL_STORAGE, чтобы разрешить приложению запись выходных данных PGO в папку sdcard. Добавьте следующую строку в файл AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />.

3. Убедитесь, что данные профилирования записываются. Данные профилирования записываются в режиме по умолчанию только при завершении работы приложения. Приложения в Android* обычно не завершают работу. Используйте следующие варианты для принудительного завершения работы приложения или обхода этой проблемы.

А. Вариант 1.Вызов выхода из кода Java.

System.exit(0);

 

Б. Вариант 2.Принудительный вывод дампа данных PGO из нативного кода.

#include <pgouser.h>
	_PGOPTI_Prof_Dump_All();

 

В. Вариант 3.Использование переменных среды для регулярной записи данных производительности на носитель sdcard при запущенном приложении. Чтобы сделать переменные среды доступными для всех приложений, добавьте их в файл init.rc образа Android:

export INTEL_PROF_DUMP_INTERVAL 5000
	export INTEL_PROF_DUMP_CUMULATIVE 1

 

Примечание: Значение INTEL_PROF_DUMP_INTERVAL измеряется в микросекундах, оно не должно превышать INT_MAX.

4. Копирование созданных файлов dyn на хост в папку исходного кода приложения:

adb pull ...

 

5. Изменение флагов C в файле Android.mk, чтобы использовать созданные файлы dyn. Можно использовать параметр -prof-dir, чтобы указать другое расположение файлов.
LOCAL_CFLAGS := -prof-use

См. раздел Профильная оптимизацияв руководстве пользователя и справочном руководстве компилятора Intel® C++ XE 15.0, поставляемых вместе с пакетом, для получения сведений об использовании PGO для оптимизации приложений, созданных с помощью компилятора Intel(R) C++ в ОС Linux*, Windows* и OS X*.

Прочие статьи по теме и ресурсы

 

Intel® System Studio — многоядерное программирование с помощью Intel® Cilk™ Plus
Intel® Cilk™ Plus
Руководство пользователя и справочное руководство компилятора Intel® C++ 15.0
Android* NDK для архитектуры Intel®
Использование Android* x86 NDK с Eclipse* и перенос образца приложения NDK


Дополнительные сведения о средствах Intel для разработчиков Android см. на сайте Intel® Developer Zone for Android.


Создание пакетов APK x86 и ARM* APK с помощью компилятора Intel® и GNU* gcc

$
0
0

Table of Contents

  1. Введение
  2. Подготовка среды сборки
  3. Сборка из командной строки
    1. Настройка приложения
    2. Очистка рабочей области приложения
    3. Сборка двоичных файлов для архитектуры ARM*
    4. Сборка двоичных файлов для архитектуры x86
    5. Подготовка пакета приложения (APK)
  4. Сборка в интегрированной среде разработки Eclipse*
  5. Примечание о невыполнении очистки двоичных файлов в .\libs\[targetabi]
  6. Прочие статьи по теме и ресурсы

Введение

Существуют устройства Android* на процессорах с архитектурами наборов инструкций (ISA) ARM* или x86. Различные архитектуры наборов инструкций не имеют двоичной совместимости, поэтому приложение, содержащее нативный код, должно содержать нативные библиотеки для каждой архитектуры. Одним из механизмов распространения таких приложений являются так называемые «толстые» пакеты приложений Android* («толстые» APK).

В этой статье содержатся пошаговые инструкции по созданию такого «толстого» пакета APK, включающего независимые от архитектуры файлы для виртуальной машины Dalvik* (Dalvik, 2013), а также библиотеки для разных архитектур. В статье описывается сборка нативной библиотеки приложения x86 с помощью Intel® IntegratedNativeDeveloperExperience (INDE).

Для демонстрации используем пример hello-jni из дистрибутива NDK r10 (входящий в состав установки Intel® INDE).

Подготовка среды сборки

Необходимы следующие программные средства. Установите их, следуя приведенной инструкции.

  1. Установите:
  2. Добавьте эту папку в переменную среды PATH:
    • каталог "[jdk7-dir]\jre\bin"для использования виртуальной машины"java" VM. Это требуется для "ant" tool
      Для среды Windows не забудьте указать краткое имя папки "вида PROGRA~2"для " program files (x86)"
  3. Создайте новую переменную среды:
    • "JAVA_HOME=[jdk7-dir]"
  4. Установите:
  5. Добавьте эту папку в переменную среды PATH:
    • каталог "[ant-dir]\bin"для использования средства "ant" tool (расположение of  [ant-dir] по умолчанию: [inde-dir]\IDEintegration)

Сборка из командной строки

В этом разделе содержатся инструкции по созданию пакетов APK для поддержки устройств Android с архитектурой ARM* и x86 в среде сборки с командной строкой.

Откройте окно командной строки или окно терминала в Linux*; перейдите в папку примеров Android NDK "hello-jni"[ndk-dir]\samples\hello-jni; выполните следующие действия.

Примечание: Все средства, перечисленные в разделе выше, должны быть доступны из этого окна.

  1. Настройка приложения

    Выполните следующую команду в папке "hello-jni"для создания файла build.xml который будет впоследствии использован для сборки примера.

        $ android update project --target android-19 --name HelloJni --path . --subprojects

    Примечание.
            --target android-19: соответствует версии (KITKAT)

  2. Очистка рабочей области приложения

    Используйте следующую команду для очистки всей рабочей области, включая библиотеки, для всех архитектур ISA.
        $ ant clean
        $ ndk-build V=1 APP_ABI=all clean

    Примечание:
            . V=1 : печать всех команд по мере их выполнения.
            . APP_ABI=all :принудительная очистка всех промежуточных файлов для всех целевых платформ. Если не указать этот параметр, будет очищен только файл для целевой платформы armeabi

  3. Сборка двоичных файлов для архитектуры ARM*

    Используйте указанную ниже команду для сборки двоичного файла приложения для архитектуры ARM:
        $ ndk-build APP_ABI=armeabi-v7a V=1 NDK_TOOLCHAIN=arm-linux-androideabi-4.8

    Примечание:
            . APP_ABI=armeabi-v7a : настройка компиляции для целевой платформы ARM*.
            . NDK_TOOLCHAIN=arm-linux-androideabi-4.8 : вместо используемого по умолчанию GNU* gcc 4.6, используется gcc 4.8.

    Двоичный файл приложения (libhello-jni.so ) создается по адресу . .\libs\armeabi-v7a\libhello-jni.so

  4. Сборка двоичных файлов для архитектуры x86 с помощью компилятора Intel

    Используйте указанную ниже команду для сборки двоичного файла приложения для архитектуры x86 с помощью компилятора Intel.
        $ ndk-build APP_ABI=x86 V=1 NDK_TOOLCHAIN=x86-icc NDK_APP.local.cleaned_binaries=true

    Примечание:
            . APP_ABI=x86 : настройка компиляции для архитектуры x86.
            . NDK_TOOLCHAIN=x86-icc : замена используемого по умолчанию компилятора gcc 4.6 на компилятор Intel C/C++ для Android.
            . NDK_APP.local.cleaned_binaries=true : отмена удаления библиотеки в каталоге libs/armeabi. См. примечанияниже.

    Двоичный файл приложения (libhello-jni.so ) создается по адресу . .\libs\x86\libhello-jni.so

  5. 5. Подготовка пакета приложения (APK)

    После сборки всех двоичных файлов для каждой целевой платформы Android убедитесь, что папка libs\[targetabi] содержит требуемые библиотеки для каждой целевой архитектуры.

    Чтобы упростить создание пакета и избежать его подписания, используйте следующую команду для создания отладочного пакета.
        $ ant debug

    После этого новый пакет HelloJni-debug.apk появится в папке . .\bin directory. Его можно запустить в имитаторах x86* или ARM*, поддерживающих API уровня 19 или выше, содержащихся в Android SDK.
    Пакет HelloJni-debug.apk содержит библиотеки для двух целевых платформ: ARM EABI v7a и x86.

Сборка в интегрированной среде разработки Eclipse*

  1. Откройте Eclipse и загрузите пример [inde-dir]/IDEintegration/NDK/samples/hello-jni
    • В меню выберите File > New > Project > Android
    • Нажмите кнопку Android Project from Existing Code button
    • В поле Root Directory нажмите кнопкуBrowse... и выберите папку [ndk-dir]/samples
    • Затем щелкните Deselect Allи выберите только нужный проект: hello-jni
    • Снимите флажок  Copy projects into workspace
    • Нажмите кнопку Finish.
  2. Добавьте в проект поддержку нативного кода.
    • Щелкните имя проекта правой кнопкой мыши и выберите Android Tools > Add Native Support...
    • Нажмите кнопку Finish.
    Примечание. Если после этого шага на консоли появляется сообщение об ошибке "Unable to launch cygpath"этот шаг можно пропустить, что не повлияет на проект.

  3. Создайте отдельную конфигурацию сборки для каждой целевой платформы, задайте команду сборки.
    Щелкните проект правой кнопкой мыши и выберите Properties -> C/C++ Build -> "Manage configurations..."
    Щелкните New... чтобы добавить новые конфигурации на основе конфигурации по умолчанию.
    • Имя: x86_icc Описание: для целевой платформы x86 с помощью компилятора Intel icc
    • Имя: arm_gcc Описание: для целевой платформы ARM с помощью компилятора GNU gcc
    В этом же окне свойств проекта установите для параметра Configuration значение x86_icc.
    • Снимите флажок "Use default build command"
    • Добавьте следующий текст в поле Build command field:
      ndk-build APP_ABI=x86 NDK_TOOLCHAIN=x86-icc
    • Щелкните Apply
    В этом же окне свойств проекта установите для параметра Configuration значение "arm_gcc":
    • Снимите флажок "Use default build command"
    • Добавьте следующий текст в поле Build command field:
      ndk-build APP_ABI=armeabi-v7a NDK_TOOLCHAIN=arm-linux-androideabi-4.8
    • Нажмите кнопку Apply затем нажмите кнопку OK
  4. Очистка всей рабочей области приложения
    • Если файл Application.mk существует в папке [eclipse-workspace-dir]\HelloJni\jni убедитесь, что он несодержит следующую строку.
      NDK_APP.local.cleaned_binaries=true
    • Щелкните проект правой кнопкой мыши и выберите Build configurations > Clean all…
  5. Создайте файл Application.mk в папке [eclipse-workspace-dir]\HelloJni\jni если он не существует, и убедитесь, что он содержитследующую строку.
    NDK_APP.local.cleaned_binaries=true
  6. Соберите двоичный файл для целевой архитектуры ARM* с помощью gcc и для целевой архитектуры x86 с помощью компилятора Intel.
    • Щелкните проект правой кнопкой мыши и выберите Build Configurations > Build Selected...
    • Выберите “arm_gcc” and “x86_icc”
    • Нажмите кнопку Ok.
    • Проверьте выходные двоичные файлы по следующим адресам.
      •  [eclipse-workspace-dir]\HelloJni\libs\armeabi-v7a\libhello-jni.so
      • [eclipse-workspace-dir]\HelloJni\libs\x86\libhello-jni.so
  7. Создание неподписанных пакетов приложений
    Щелкните проект правой кнопкой мыши и выберите Android Tools > Export Unsigned Application Package...

Примечание о невыполнении очистки двоичных файлов в .\libs\[targetabi]

Параметр NDK_APP.local.cleaned_binaries=true для отключения удаления собранных ранее библиотек может не работать в будущих версиях NDK. См. [ndk-dir]/build/core/setup-app.mk для получения информации о том, как отключить действия удаления для установленных двоичных файлов.

Прочие статьи по теме и ресурсы 

Дополнительные сведения о средствах Intel для разработчиков Android см. на сайте Intel® Developer Zone for Android.

Android* — высококачественный звук на планшетах Android* с процессорами Intel® Atom™ с помощью API Dolby* Digital

$
0
0

Введение 

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

Устройства на платформе Android* составляют свыше половины рынка планшетов, поэтому операционная система корпорации Google становится предпочитаемой платформой не только для портативных мобильных развлекательных устройств, но и для развлечений в целом. На платформе Android выпускается огромное множество устройств, и далеко не все из них способны предоставить хорошие развлекательные возможности.  

В том, что касается высококачественного звука, следует учитывать три основных фактора.

  1. Производительность ЦП — без мощного процессора звук будет задерживаться или воспроизводиться неравномерно.
  2. Время работы от аккумулятора — обработка звука, как сказано выше, образует достаточную нагрузку на ЦП, поэтому мобильные развлекательные устройства должны долго работать от аккумуляторов.
  3. Качество звука — звук должен быть четким, громким, с ясно различимыми нюансами.

Мы выбрали планшет Samsung Galaxy Tab* 3 10.1 с процессором Intel® Atom™. По скорости работы он не уступает или превосходит все прочие устройства, поэтому производительность здесь точно не проблема. Высокая тактовая частота и использование двухъядерного процессора обеспечивают безупречное воспроизведение звука даже при многозадачной работе.

Кроме того, SoC Intel Atom, используемые в устройствах с Android, оптимизированы с точки зрения потребления электроэнергии, поэтому они очень долго работают от аккумулятора, что особенно характерно для Galaxy Tab 3.

Заключительный фактор — качество звука, здесь за него отвечает встроенное звуковое оборудование Dolby Digital Plus*. Аппаратные ресурсы Dolby предоставляют несколько важных компонентов, среди которых отметим следующие: Volume Maximizer — увеличение громкости звука без искажений; Audio Optimizer — существенное улучшение четкости звука с помощью проприетарных алгоритмов обработки звука Dolby.

Также отметим, что поскольку решение Dolby — аппаратное, оно не вызывает добавочной нагрузки на ЦП. При использовании оно практически не расходует вычислительные ресурсы системы.

Понятие «качество звука» как таковое носит в значительной степени субъективный характер, особенно в том, что касается уже записанного содержимого, но применяемый здесь кодек Dolby Digital Plus содержит целый набор технологий, которые стоит рассмотреть более подробно.

Технология аудиокодека Dolby Digital Plus

Звуковой кодек Dolby Digital Plus включает ряд технологий обработки звука, которые воздействуют на звуковое содержимое, воспроизводящееся на мобильном устройстве. Конечная цель кодека состоит в повышении субъективного качества звука. Следует отметить несколько технологий, связанных с воспроизведением музыки.

Volume Leveler

Volume Leveler непрерывно отслеживает воспроизводимый звук с помощью «психоакустической модели восприятия громкости» (в терминологии Dolby), которая определяет, насколько громким звук будет казаться человеку. Это значение используется для динамической регулировки уровня громкости, чтобы обеспечить одинаковую с точки зрения слушателя субъективную громкость. Одновременно применяется еще одна технология, Auditory Scene Analysis; ее цель — избежать неверной регулировки звука, в результате которой могут быть усилены звуки и моменты мелодии, намеренно сделанные тихими.

Специалисты Dolby заявляют, что Volume Leveler может независимо регулировать оба звуковых канала и даже отдельные частотные диапазоны, чтобы избежать эффекта «накачки» и «вибрации» при обработке звука.

Volume Maximizer

Одно из важных преимуществ кодека Dolby Digital Plus — это модуль Volume Maximizing, обеспечивающий достаточно громкий звук из маленьких динамиков, которыми обычно оснащаются мобильные устройства. После обработки звука в Volume Leveler модуль Maximizer увеличивает амплитуду звука на достаточно значительную величину, вплоть до 12 дБ.

TЧтобы избежать чрезмерного усиления сигнала, которое может привести к обрезанию частотного диапазона, Volume Maximizer использует «упреждающий ограничитель». Ограничитель сочетает усиление сигнала с многодиапазонным сжатием для увеличения громкости звука без искажений.

Audio Optimizer

Частотный диапазон динамиков, которыми оборудуются мобильные устройства, зачастую далек от идеала. Другими словами, для разных частот может достаточно сильно различаться уровень звука. Из-за этого прослушиваемая музыка может звучать ненатурально или приглушенно. Технология Audio Optimizer применяет набор фильтров для обхода возможного несовершенства динамиков. Эти фильтры индивидуально подбираются для каждой модели устройства. Конечная цель — выдать естественный, сбалансированный звук с одинаковым уровнем воспроизведения всех частот, что для большинства устройств на практике означает повышение уровня низких и высоких частот.

Audio Regulator

Заключительный этап обработки музыки, интересующий нас как слушателей – это Audio Regulator. При увеличении громкости выходного звука на мобильных устройствах могут возникнуть искажения. Этот эффект может быть вызван самими усилителями, перегрузкой динамиков, резонансом или «треском» на смартфонах и планшетах. Такое поведение индивидуально для каждого устройства, оно может различаться для разных частот.

Regulator применяет многодиапазонное сжатие с учетом индивидуальных особенностей каждого конкретного устройства. И Audio Regulator, и Audio Optimizer калибруются в соответствии с уникальными особенностями каждого типа устройств.

Кроме того, для сохранения тембра звука при сжатии применяются ограничения.

И наконец, Regulator зависит от громкости. Можно в меньшей степени задействовать управление искажениями или отключать его при невысокой громкости.

Почему звук важен на мобильных устройствах?

Планшеты и смартфоны все чаще становятся предпочитаемыми устройствами для просмотра и потребления развлекательного содержимого. Хорошее качества звука достаточно сильно влияет на общее восприятие развлекательных материалов. Недавно компания Parks Associatesпровела исследование (по заказу Dolby) с целью оценки важности высококачественного звука. Это исследование показало, что в большинстве случаев владельцы смартфонов придают некоторое значение качеству звука при выборе смартфона или планшета.

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

После простой демонстрации технологии обработки звука Dolby Digital и вы с этим, скорее всего, согласитесь.

Использование API Dolby Audio в приложениях Android

Технологии Dolby позволяют очень просто повышать качество звука на устройствах Android, оснащенных аппаратным модулем Dolby Digital Plus. Портал Dolby Developer содержит бесплатный API для поддержки обработки звука Dolby в традиционных приложениях Java*, а также на некоторых сторонних платформах, включая Xamarin, Unity 3D* и Cordova*.

Решение Dolby Digital работает на аппаратном уровне, поэтому оно повышает качество звука вне зависимости от того, каким образом звук загружается и воспроизводится в исходном коде.

Для включения обработки звука Dolby Digital выполните следующие действия.

  1. Загрузите и установите API Dolby Digital в мобильное приложение по адресу https://developer.dolby.com
  2. Получите инстанс объекта DolbyAudioProcessing. Это очень просто: достаточно вызвать GetDolbyAudioProcessing()из API Dolby.
  3. Создайте объект прослушивателя Dolby. Обычно объектом прослушивателя Dolby делается текущая Activity, чтобы упростить реализацию, но это может быть и отдельный класс.

Фрагмент кода Java показан ниже.

import com.dolby.dap.DolbyAudioProcessing;
import com.dolby.dap.OnDolbyAudioProcessingEventListener;
import com.dolby.dap.DolbyAudioProcessing.PROFILE;

public <strong>class</strong> MainActivity
extends Activity implements OnDolbyAudioProcessingEventListener
{
    DolbyAudioProcessing mDolbyAudioProcessing;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        mDolbyAudioProcessing = DolbyAudioProcessing.getDolbyAudioProcessing(this, DolbyAudioProcessing.PROFILE.GAME, this);

        if (mDolbyAudioProcessing == null){
            Toast.makeText(this, "Dolby isn't available on this device", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }
    }
    ...
}

Описание примера

Мне представилась возможность создать приложение для потоковой передачи звука, чтобы помочь независимым музыкантам в привлечении внимания и в демонстрации своей музыки. Важно было иметь устройство, пригодное для демонстрации как музыки, так и приложения. Поэтому по соображениям производительности, длительности работы от аккумулятора и качеству звука для этого проекта был выбран планшет Galaxy Tab 3 10.1 (86-разрядный).

Музыкальное содержимое передается в виде потока из SoundCloud и воспроизводится с помощью объекта MediaPlayer, входящего в состав API Android.

Чтобы можно было использовать код на других платформах (WPF, Магазин Windows* и т. д.), я использовал стороннее средство разработки, Xamarin Android, позволяющее писать собственные приложения для Android на .NET C#. Тем не менее, поскольку Xamarin использует собственные API Java Android, этапы разработки в целом такие же, как при написании приложений Java.

Пример использования API Dolby

Что касается Android Activity, отвечающей за воспроизведение мелодий, я решил сделать ее прослушивателем API Dolby Digital. Это означает, что она отвечает за прослушивание и реагирование на API Dolby Digital с помощью методов, определенных в IOnDolbyAudioProcessingEventListener. Также я реализовал в Activity интерфейс IOnCompletionListenerобъекта MediaPlayer, сделав его единой точкой воспроизведения. Такой подход неплохо работает, но можно выделить эти интерфейсы в отдельные классы, если это требуется архитектурой вашего приложения.

Моя подпись класса выглядит так:

public class Activity1 : Activity, MediaPlayer.IOnCompletionListener, IOnDolbyAudioProcessingEventListener

Я поддерживаю экземпляры обоих объектов MediaPlayerдоступными в качестве переменных на уровне классов. Обратите внимание, что объект DoblyAudioProcessingследует сделать статическим и не следует удерживать более одного экземпляра этого объекта в приложении. Если требуется доступ к объекту DolbyAudioProcessingиз Activity, следует предоставить доступ к нему с помощью одноэлементного класса или какого-либо типа глобальной ссылки.

Для инициализации обработки звука Dolby я создал вспомогательный метод InitAudio(), чтобы безопасно получить ссылку на объект DolbyAudioProcessing. Поскольку по‑прежнему необходима совместимость с другими устройствами, этот метод непригоден для устройств, не оборудованных кодеком Dolby.

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

void InitAudio()
{
     if (mDolbyAudioProcessing != null)
          return;

     mDolbyAudioProcessing = DolbyAudioProcessing.GetDolbyAudioProcessing(this, DolbyAudioProcessing.PROFILE.Music, this);

     if (mDolbyAudioProcessing == null)
     {
          Toast.MakeText(this, "Dolby Audio Processing load failed", ToastLength.Short).Show();
          return;
      }
}

И наконец, я проверяю и сохраняю состояние обработки Dolby, когда действие запускается, и восстанавливаю состояние, когда наше приложение работает в фоновом режиме или закрывается. Оборудование Dolby Digital влияет на весь звук, воспроизводящийся на устройстве, поэтому это очень важный шаг, и он легко осуществляется с помощью методов управления жизненным циклом действия onResume() и onPause().

API SoundCloud

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

Работа с API SoundCloud хорошо документирована, но, поскольку сам этот API достаточно сложен, в нем поначалу может быть непросто разобраться. Сначала следует изучить документацию REST: https://developers.soundcloud.com.

Самый простой способ начать работу — использовать оболочку API Java, доступную на портале GitHub: https://github.com/soundcloud/java-api-wrapper; тем не менее я опишу процесс внедрения SoundCloud вручную.

Нужно создать идентификатор клиента SoundCloud, который является уникальным идентификатором для вашего приложения. Это следует делать при взаимодействии с другими API REST для доступа к общедоступному содержимому.

Воспроизведение содержимого SoundCloud

Рассмотрим процесс доступа к определенному исполнителю в SoundCloud, загрузки информации об альбоме, чтения отдельных мелодий и воспроизведения. Для этого мы будем взаимодействовать со службой RESTful SoundCloud и декодировать возвращаемые данные JSON.

Шаг 1. Создайте идентификатор клиента

Как было сказано выше, этот идентификатор бесплатен, его можно создать здесь: https://soundcloud.com/you/apps

Он будет выглядеть примерно так: “7de8bc189e5ba2ab12fa4223951fabb8”

Шаг 2. Найдите идентификатор исполнителя

Нужно найти идентификатор пользователя исполнителя, чью музыку следует воспроизводить. Это можно сделать непосредственно на веб-сайте SoundCloud или с помощью API SoundCloud. Поскольку мы только изучаем API, я покажу способ быстро найти идентификатор вручную. Откройте страницу любого исполнителя непосредственно на сайте SoundCloud, щелкните Share, а затем Embed. В окне Code & Preview вы увидите тег iFrame. Внутри него вы увидите ссылку, которая будет выглядеть примерно так: https%3A//api.soundcloud.com/users/547647. Число — это нужный нам идентификатор исполнителя.

Шаг 3. Создание запроса для загрузки альбомов

Сейчас мы создадим первый запрос к API SoundCloud. Начнем с адреса API, а затем соберем полный URL-адрес с помощью идентификатора исполнителя с шага 2 и нашего собственного идентификатора клиента с шага 1.

string request = "http://api.soundcloud.com/" + "users/" + artistID + "/playlists.json?client_id=" + clientID; 

Шаг 4. Отправьте запрос

Теперь просто отправьте запрос. Мое приложение написано на C#, поэтому код выглядит так:

public async Task<string> GetUserPlaylists ()
{
    HttpClient client = new HttpClient ();
    var request = "http://api.soundcloud.com/" + "users/" + artistID + "/playlists.json?client_id=" + clientID;

    HttpResponseMessage response = await client.GetAsync (request);

    return await response.Content.ReadAsStringAsync ();
}

Краткое замечание. Этот код может работать на любой современной платформе .NET, которая включает Microsoft HttpClient, в том числе WPF, Магазин Windows или Silverlight*.

Шаг 5. Отмените сериализацию объекта

Здесь можно использовать вашу любимую библиотеку JSON. Когда я пишу код .NET, я использую библиотеку Newtonsoft Json.

_setLists = Newtonsoft.Json.JsonConvert.DeserializeObject<List<AlbumData>>(response);

Переменная response является результатом применения метода GetUserPlaylists() на предыдущем шаге. Мы получим список объектов AlbumData (определенных ниже).

Шаг 6. Создание URL-адреса мелодии

Скорее всего, вы предпочтете представить пользователям набор альбомов, чтобы они выбрали нужный, в ListView; я не буду подробно описывать создание пользовательского интерфейса. 

Ниже приведен код объекта передачи данных AlbumData. Обратите внимание, что внизу он содержит список объектов TrackData, представляющих отдельные мелодии.

К счастью, данные, использованные для заполнения объекта TrackData, содержат URL-адрес для воспроизведения.

Шаг 7. Воспроизведение мелодии

И наконец, воспроизведение звука с удаленного URL-адреса с помощью потоковой передачи по протоколу HTTP на платформе Android выглядит так:

String url = myTrack.StreamURL;
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.SetAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.SetDataSource(url);
mediaPlayer.Prepare();
mediaPlayer.Start();

Где myTrack — конкретный экземпляр TrackData мелодии, которую мне нужно воспроизвести.

Объекты передачи данных SoundCloud

На этом этапе я хочу показать объекты AlbumDataи TrackData. API SoundCloud очень просто использовать, если у вас нет желания писать значительный объем кода для анализа JSON, но мы будем использовать объекты передачи данных (DTO) для хранения проанализированных данных JSON.

Для просмотра альбомов и воспроизведения мелодий нам потребуется два объекта DTO: один будет представлять данные альбома, а второй — отдельные мелодии. Я включил два моих объекта DTO ниже в коде C#. Они приведены полностью, вы можете использовать их в своих проектах.

Если вам требуется работать с API SoundCloud на более глубоком уровне, то может потребоваться создать дополнительные объекты DTO.

AlbumData.cs

using Newtonsoft.Json;
using System.Collections.Generic;

namespace SoundCloud.Json
{
    public class AlbumData
    {
        [JsonProperty("id")]
        public string Id { get; internal set; }

        [JsonProperty("created_at")]
        public string CreatedAt { get; internal set; }

        [JsonProperty("user_id")]
        public string UserId { get; internal set; }

        [JsonProperty("user")]
        public UserData User { get; internal set; }

        [JsonProperty("title")]
        public string Title { get; internal set; }

        [JsonProperty("permalink")]
        public string Permalink { get; internal set; }

        [JsonProperty("permalink_url")]
        public string PermalinkUrl { get; internal set; }

        [JsonProperty("uri")]
        public string Uri { get; internal set; }

        [JsonProperty("sharing")]
        public string Sharing { get; internal set; }

        [JsonProperty("embeddable_by")]
        public string EmbeddableBy { get; internal set; }

        [JsonProperty("purchase_url")]
        public string PurchaseUrl { get; internal set; }

        [JsonProperty("artwork_url")]
        public string ArtworkUrl { get; internal set; }

        [JsonProperty("description")]
        public string Description { get; internal set; }

        [JsonProperty("label")]
        public UserData Label { get; internal set; }

        [JsonProperty("duration")]
        public int Duration { get; internal set; }

        [JsonProperty("genre")]
        public string Genre { get; internal set; }

        [JsonProperty("tag_list")]
        public string TagList { get; internal set; }

        [JsonProperty("label_id")]
        public string LabelId { get; internal set; }

        [JsonProperty("label_name")]
        public string LabelName { get; internal set; }

        [JsonProperty("streamable")]
        public bool Streamable { get; internal set; }

        [JsonProperty("downloadable")]
        public bool Downloadable { get; internal set; }

        [JsonProperty("tracks")]
        public List<TrackData> Tracks { get; internal set; }
    }
}

TrackData.cs

using System;
using Newtonsoft.Json;

namespace SoundCloud.Json
{
    [JsonObject]
    public class TrackData
    {
        [JsonProperty("id")]
        public long Id { get; internal set; }

        [JsonProperty("created_at")]
        public DateTime CreatedAt { get; internal set; }

        [JsonProperty("user_id")]
        public long UserId { get; internal set; }

        [JsonProperty("duration")]
        public long Duration { get; internal set; }

        [JsonProperty("commentable")]
        public bool Commentable { get; internal set; }

        [JsonProperty("state")]
        public string State { get; internal set; }

        [JsonProperty("sharing")]
        public string Sharing { get; internal set; }

        [JsonProperty("tag_list")]
        public string TagList { get; internal set; }

        [JsonProperty("permalink")]
        public string Permalink { get; internal set; }

        [JsonProperty("description")]
        public string Description { get; internal set; }

        [JsonProperty("streamable")]
        public bool Streamable { get; internal set; }

        [JsonProperty("downloadable")]
        public bool Downloadable { get; internal set; }

        [JsonProperty("genre")]
        public string Genre { get; internal set; }

        [JsonProperty("release")]
        public string Release { get; internal set; }

        [JsonProperty("purchase_url")]
        public string PurchaseUrl { get; internal set; }

        [JsonProperty("label_id")]
        public string LabelId { get; internal set; }

        [JsonProperty("label_name")]
        public string LabelName { get; internal set; }

        [JsonProperty("isrc")]
        public string ISRC { get; internal set; }

        [JsonProperty("video_url")]
        public string VideoUrl { get; internal set; }

        [JsonProperty("track_type")]
        public string TrackType { get; internal set; }

        [JsonProperty("key_signature")]
        public string KeySignature { get; internal set; }

        [JsonProperty("bpm")]
        public long? BPM { get; internal set; }

        [JsonProperty("title")]
        public string Title { get; internal set; }

        [JsonProperty("release_year")]
        public string ReleaseYear { get; internal set; }

        [JsonProperty("release_month")]
        public string ReleaseMonth { get; internal set; }

        [JsonProperty("Release_day")]
        public string ReleaseDay { get; internal set; }

        [JsonProperty("original_format")]
        public string OriginalFormat { get; internal set; }

        [JsonProperty("license")]
        public string License { get; internal set; }

        [JsonProperty("uri")]
        public string Uri { get; internal set; }

        [JsonProperty("permalink_url")]
        public string PermalinkUrl { get; internal set; }

        [JsonProperty("artwork_url")]
        public string ArtworkUrl { get; internal set; }

        [JsonProperty("waveform_url")]
        public string WaveformUrl { get; internal set; }

        [JsonProperty("user")]
        public UserItemData User { get; internal set; }

        [JsonProperty("stream_url")]
        public string StreamUrl { get; internal set; }

        [JsonProperty("download_url")]
        public string DownloadUrl { get; internal set; }

        [JsonProperty("playback_count")]
        public long PlaybackCount { get; internal set; }

        [JsonProperty("download_count")]
        public long DownloadCount { get; internal set; }

        [JsonProperty("favoritings_count")]
        public long FavoritingsCount { get; internal set; }

        [JsonProperty("comment_count")]
        public long CommentCount { get; internal set; }

        [JsonProperty("attachments_uri")]
        public string AttachmentsUri { get; internal set; }
    }
}

 

Заключение и выводы

SoundCloud

Приведенная выше информация послужит хорошим фундаментом для начала работы с SoundCloud. Если же требуется более глубокая реализация, например отправка или управление содержимым, потребуется создать дополнительные объекты передачи данных и убедиться, что данные в вашем приложении являются синхронными с SoundCloud. Если вы разрабатываете программы на Java, то имеет смысл заглянуть в Android Sharing Kit: https://github.com/soundcloud/android-intent-sharing/wiki

Dolby Digital и SoundCloud

В службах потоковой передачи звука распространена проблема, связанная с неодинаковым уровнем звука у разных файлов. Это никак не повлияет на предоставление службой содержимого, но очень хорошо, если API Dolby Digital нормализует громкость. Разница в уровнях становится особенно заметна при переключении между мелодиями разных исполнителей.

Android MediaPlayer

Объект MediaPlayer в API Android удобен для воспроизведения локального или потокового звукового содержимого, но его нельзя считать универсальным решением: он работает не всегда. При создании приложений для Android всегда следует проводить тестирование на как можно большем количестве устройств, причем это особенно важно, если речь идет об объекте MediaPlayer. Не следует надеяться на то, что он «просто заработает» на всех устройствах, даже если при тестировании все было идеально. Это особенно касается менее мощных устройств. Попробуйте использовать функции альфа- и бета-тестирования магазина Google Play или используйте службу тестирования, позволяющую запустить ваше приложение на самых разных телефонах и планшетах.

Производительность

Как было сказано выше, будьте осторожнее с MediaPlayer, поскольку на маломощных устройствах он может не работать должным образом. Кроме того, обязательно оптимизируйте другие части вашего приложения, чтобы звук воспроизводился без перерывов. Всегда запускайте код, ожидающий веб-службы, отдельно от пользовательского интерфейса, применяйте такие методики, как повторное использование ячеек и View Holder в списочных элементах управления, чтобы снизить объем используемой памяти и повысить производительность. Полезные советы по оптимизации см. в документации Плавная прокрутка ListView: http://developer.android.com/training/improving-layouts/smooth-scrolling.html

Устройства

Планшет Samsung Galaxy Tab 3 10.1 оказался великолепным демонстрационным устройством, и мне очень понравилось улучшение звука, достигнутое аппаратной обработкой потокового содержимого кодеком Dolby Digital. Этот кодек доступен не на всех устройствах, но все равно имеет смысл интегрировать API Dolby Digital в ваши приложения Android. Реализовать такое решение можно очень быстро, при этом оно существенно улучшает четкость выходного звука.

Дальнейшие действия

Планшет Samsung Galaxy Tab 3 10.1 по-прежнему весьма конкурентоспособен, но рынок мобильных устройств стремительно развивается. Скоро на рынке появятся планшеты с новыми четырехъядерными процессорами Intel Atom. Dell Venue* 8 7000 станет ведущим в своем классе устройством после выпуска в IV квартале 2014 года. Кроме того, оборудование Dolby Digital Plus довольно широко распространено. Компания Lenovo, крупный производитель мобильных устройств, выпускает несколько планшетов, оснащенных кодеком Dolby. Я недавно переключился на Lenovo S8-50f в качестве основного устройства для разработки на платформе Android. Это устройство оборудовано четырехъядерным SoC Intel Atom Z3745 архитектуры x86, 2 ГБ оперативной памяти и, разумеется, кодеком Dolby Digital Plus.

Об авторе

Адриан Стивенс (Adrian Stevens) располагает более чем 14-летним опытом разработки мобильных приложений, он специализируется на межплатформенной разработке на C# и C++. Области работы Адриана включают архитектуру пользовательского интерфейса, обработку звука и сигналов, датчики и математику. Адриан живет в Канаде, в Ванкувере, он увлекается технологиями и предпринимательством и является одним из основателей сообщества межплатформенных разработчиков на C# под названием Meetup.

Адриан начал разрабатывать первые мобильные приложения в 2001 году для устройств Palm Pilot и Pocket PC; он успешно основал и возглавлял небольшую компанию по разработке мобильных решений. Позже Адриан стал преподавателем по разработке программного обеспечения в области мобильных приложений, архитектуры и разработки межплатформенных приложений.

Высокопроизводительное сжатие DEFLATE с оптимизацией для геномных наборов данных

$
0
0

Аннотация

igzip — высокопроизводительная библиотека для выполнения сжатия gzip или DEFLATE. Она была изначально описана в статье Высокопроизводительное сжатие DEFLATE для процессоров с архитектурой Intel. В этой статье описывается связанный выпуск исходного кода, содержащий необязательные (во время сборки) оптимизации для повышения степени сжатия геномных наборов данных в форматах BAM и SAM. igzip работает примерно в 4 раза быстрее, чем Zlib при настройке на максимальную скорость, и с примерно такой же степенью сжатия для геномных данных. Мы считаем, что igzip можно схожим образом оптимизировать для других областей применения, где наборы данных отличаются от обычных текстовых данных.

Обзор

Можно собрать две основные версии igzip: igzip0c и igzip1c. Первая работает быстрее, а вторая — чуть медленнее, но с более высокой степенью сжатия. Обе эти версии значительно быстрее, чем стандартные gzip -1 или Zlib -1, но отличаются чуть меньшей степенью сжатия. В этих реализациях используется набор инструкций SSE 4.2. Они предназначены для процессоров Intel, поддерживающих этот набор инструкций.

В [1] мы описали степень сжатия и производительность igzip при работе над данными общего назначения. После этого мы расширили реализацию для эффективной обработки геномных данных. В вычислительном процессе, используемом при определении геномной последовательности, серьезным ограничением производительности является сжатие данных. Существуют сценарии использования с долгосрочным хранением, когда требуется очень высокая степень сжатия, особенно если учесть значительные размеры наборов геномных данных. Тем не менее на различных этапах определения геномной последовательности существуют операции, в которых требуется очень быстрое сжатие с умеренной степенью сжатия. В этом исследовании мы сосредоточились на двух основных форматах данных, используемых для определения геномной последовательности; это форматы SAM и BAM.

Анализ этих форматов показал, что содержимое данных весьма специфично, встречается только в геномных данных и значительно отличается от обычных данных (например, от наборов данных в коллекции Университета Калгари). Мы выявили следующие основные свойства геномных данных: очень малая длина совпадений при обработке LZ77 (~90 % совпадений длиной менее 8 байт), очень малые смещения (у ~90 % совпадений сдвиг менее 1024 байт) и очень разнообразное распределение литералов (например, в формате SAM значительное количество символов A, T, G, C из обработанных строк последовательностей). Мы изменили таблицы Хаффмана в igzip таким образом, чтобы учесть эти особенности, и добились примерно такой же степени сжатия, как у Zlib-1, но в 4 раза быстрее.

Интерфейс программирования

API

struct LZ_Stream2 {
    UINT8 *next_in;   // Next input byte
    UINT32 avail_in;  // number of bytes available at next_in
    UINT32 total_in;  // total number of bytes read so far

    UINT8 *next_out;  // Next output byte
    UINT32 avail_out; // number of bytes available at next_out
    UINT32 total_out; // total number of bytes written so far
    UINT32 end_of_stream; // non-zero if this is the last input buffer

    LZ_State2 internal_state;
  };

  void init_stream(LZ_Stream2 *stream);
  void fast_lz(LZ_Stream2 *stream);

Основной принцип состоит в том, что next_in указывает на входной буфер, а avail_in указывает длину этого буфера. Аналогичным образом next_out указывает на пустой выходной буфер, avail_out указывает размер этого буфера.

Поля total_in и total_out начинаются с 0 и обновляются функцией fast_lz(). Они соответствуют общему количеству прочтенных или записанных байт на текущий момент на случай, если такая информация нужна вызывающему приложению.

Функция init_stream() статически инициализирует структуру данных потока, и в частности внутреннее состояние.

Вызов fast_lz() возьмет данные из входного буфера (обновив next_in и avail_in) и запишет сжатый поток в выходной буфер (обновив next_out и avail_out). Функция возвращается, когда либо avail_in, либо avail_out выдаст нуль (т. е. когда закончатся входные данные либо когда заполнится выходной буфер).

После передачи последнего входного буфера следует задать флаг end_of_stream. При этом процедура обработает битовый поток до конца входного буфера, если в выходном буфере достаточно места.

Простой пример

LZ_Stream2 stream;
    UINT8 inbuf[LEN_IN], outbuf[LEN_OUT];

    init_stream(&stream);
    stream.end_of_stream = 0;

    do {
        stream.avail_in = (UINT32) fread(inbuf, 1, LEN_IN, in);
        stream.end_of_stream = feof(in);
        stream.next_in = inbuf;

        do {
            stream.avail_out = LEN_OUT;
            stream.next_out = outbuf;

            fast_lz(&stream);

            fwrite(outbuf, 1, LEN_OUT - stream.avail_out, out);
        } while (stream.avail_out == 0);

        assert(stream.avail_in == 0);
    } while (! stream.end_of_stream);

Операция Zlib FLUSH_SYNC в данный момент не поддерживается.

Версии исходного кода

Параметры в файле options.inc определяют, какая версия будет собрана. Это определяет количество символов в синтаксисе YASM. Сценарий Perl преобразует этот файл в options.h для использования в коде C. Редактировать файл options.h вручную не следует. (Если Perl недоступен, можно вручную отредактировать options.h, но затем убедиться, что параметры в файлах options.h и options.inc совпадают.)

Как уже было сказано выше, две основные версии — это 0c и 1c. Версия выбирается путем редактирования файла options.inc, где может быть одна из следующих строк.

   %define MAJOR_VERSION IGZIP0C

или

   %define MAJOR_VERSION IGZIP1C

(В этом выпуске версии IGZIP0 и IGZIP1 не поддерживаются.)

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

  ;%define GENOME_SAM
  ;%define GENOME_BAM

Если обе строки закомментированы (как показано выше), используются таблицы по умолчанию. Не следует раскомментировать обе эти строки одновременно.

По умолчанию igzip создает файл в формате GZIP (RFC 1952). Если строка

  ;%define ONLY_DEFLATE

раскомментирована, то будут сформированы выходные данные формата DEFLATE, т. е. без заголовков GZIP.

Рисунок 1: Поддерживаемые (протестированные) версии в этом выпуске
igzip genomics fig 01

Код можно собрать в Linux или Windows. Существует Makefile для Linux. Код сочетает C и ассемблер. Для сборки ассемблерного кода следует использовать ассемблер YASM. Путь к YASM в Makefile можно изменить в соответствии с местом установки YASM в среде пользователя.

Собрать код можно (под управлением Linux) в виде статической библиотеки, например make lib0c или make lib1c, или в виде общего объекта, например make slib0c или make slib1c.

Результаты

Этот выпуск igzip поддерживает не только две основные версии (igzip0c и igzip1c), но и дополнительную оптимизацию для геномных наборов данных, в частности для файлов BAM и SAM. Эти файлы довольно сильно отличаются от обычных файлов, а распространенность статистических данных по каждому типу этих файлов означает, что можно оптимизировать таблицы Хаффмана для этой статистики и добиться более высокой степени сжатия.

Для иллюстрации три тестовых файла были сжаты при разных конфигурациях. Одним из тестовых файлов был progl из коллекции Университета Калгари (так называемого корпуса Калгари). Он соответствует обычному файлу. Два других файла — произвольные примеры геномных файлов форматов BAM и SAM. В каждом тесте была вычислена степень сжатия как частное от деления размера сжатого файла на размер несжатого файла (чем меньше, тем лучше). Для краткости показана только степень сжатия для «предпочитаемой» версии igzip (т. е. при запуске igzip0c-bam для файла BAM). Как и ожидалось, предпочитаемая версия обеспечивает более высокую степень сжатия, чем другие версии (например, при запуске igzip0c для файла SAM вместо igzip0c-sam). Кроме того, для упрощения мы показываем производительность igzip только для предпочитаемых типов данных. Производительность не слишком различается из‑за разных таблиц Хаффмана в igzip, она больше зависит от входного типа данных.

Примечание.Тесты и оценки производительности проводятся на определенных компьютерных системах и компонентах и соответствуют приблизительной производительности продуктов Intel в этих тестах. Любые отличия в оборудовании системы и в программном обеспечении или конфигурации могут повлиять на фактическую производительность. При выборе приобретаемых продуктов следует обращаться к другой информации и тестам производительности. Дополнительные сведения о тестах производительности и о производительности продуктов Intel см. по адресу http://www.intel.com/performance/resources/benchmark_limitations.htm

Результаты производительности, приведенные в этом разделе, были получены при измерении на процессоре Intel® Core™ i7 4770 (Haswell). Тесты проводились при отключенной технологии Intel® Turbo Boost Technology и представляют производительность без использования технологии гиперпоточности Intel® (Intel® HT) на одном ядре. Мы предлагаем результаты для данных в памяти, исключая файловый ввод-вывод.

Мы скомпилировали реализации Zlib с помощью компилятора GCC с параметрами оптимизации aggressive. В качестве эталона для сравнения мы использовали Zlib версии 1.2.8.

Временные показатели измерялись с помощью функции rdtsc(), которая возвращает счетчик штампа времени процессора (TSC). TSC — это количество тактовых циклов после последнего сброса. TSC_initial — значение TSC, записанное перед вызовом функции. После завершения работы функции rdtsc() вызывается снова, чтобы записать новый счетчик циклов TSC_final. Фактическое количество циклов для вызванной процедуры вычисляется с помощью выражения:

кол-во циклов = (TSC_final-TSC_initial).

Для каждого файла проведено значительное количество таких измерений с последующим усреднением их результатов.

Рисунок 2. Разница в скорости и в степени сжатия igzip0c* по сравнению с gzip/Zlib -1
igzip genomics fig 02

Производительность сжатия (циклов на байт) и степень сжатия
igzip genomics fig 03

В таблице показаны степень сжатия и производительность для «предпочитаемой» версии igzip для соответствующего типа файлов. Видно, что, в частности, для тестовых файлов BAM и SAM, степень сжатия igzip очень близка с zlib -1. Для файлов в формате SAM степень сжатия и скорость оказались такими же, как для некоторых обычных файлов из набора данных Университета Калгари, тогда как для формата BAM и степень сжатия, и скорость ниже, чем для SAM (это касается и igzip, и Zlib). В формате BAM значительная часть данных полей уже упакована в двоичном формате, из-за чего сжатие при помощи алгоритмов LZ77 незначительно. В результатах видно, что по скорости igzip примерно в 4 раза быстрее Zlib (при настройке на максимальную скорость в обоих случаях).

Заключение

igzip — библиотека для высокоскоростного сжатия по алгоритму DEFLATE/gzip. Возможны ее различные конфигурации с разным соотношением степени сжатия и скорости. Кроме того, существуют дополнительные возможности оптимизации для геномных файлов BAM и SAM. При оптимизации степень сжатия близка к gzip -1, но скорость существенно выше. Изучив форматы SAM и BAM, мы считаем, что можно анализировать различные наборы данных из других приложений, которые могут довольно сильно отличаться от стандартных текстовых данных, и разрабатывать индивидуально подобранные реализации igzip со схожими результатами.

Авторы

Джим Гилфорд (Jim Guilford), Винод Гопад (Vinodh Gopal), Шон Галли (Sean Gulley) и Важди Фегали (Wajdi Feghali)

Благодарности

Пауло Нарваэс (Paolo Narvaez), Мишали Наик (Mishali Naik) и Гил Уолрич (Gil Wolrich), спасибо за участие!

Справочные материалы

[1] Высокопроизводительное сжатие Deflate: http://www.intel.com/content/www/ru/ru/
intelligent-systems/wireless-infrastructure/ia-deflate-compression-paper.html
.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

 

 

 

Как Scribblify позволяет создать межплатформенный графический пользовательский интерфейс с Node.js* и встроенной платформой Chromium*

$
0
0

By Edward J. Correia

 

Введение

 

Для разработчика Мэтта Пильца, уроженца Висконсина, тройка явно является счастливым числом. Пильц — основатель компании LinkedPIXEL, , и благодаря своим творческим способностям и упорному труду он одержал победу подряд на трех конкурсах разработчиковпроводимых корпорацией Intel. Недавно его приложение для рисования Scribblifyс 10-точечным сенсорным управлениеми графическим пользовательским интерфейсом на базе Google Chrome* получило главный приз на конкурсе Intel® App Innovation Contest 2013При разработке приложения использовались ресурсы с портала Intel® Developer Zone. Весной 2013 года Пильц выиграл конкурс Intel® Perceptual Computing Challenge, представив приложение Magic Doodle Pad,для рисования с управлением с помощью жестов руки. В 2012 году он выпустил игру Ballastic, оптимизированную для ультрабуков.

Как и в прошлых конкурсных работах, замысел приложения Scribblify (рис. 1) родился задолго до начала конкурса, но приложение Scribblify получило путевку в жизнь именно на мобильных устройствах. Будучи одним из 200 участников конкурса, получивших компьютер-моноблок Lenovo Horizon*от спонсора, корпорации Lenovo, Пильц с радостью принял идею переделать свое приложение для полноразмерного экрана. «Когда я узнал про моноблок Lenovo Horizon с огромным 27-дюймовым сенсорным экраном высокой четкости с разрешением 1920х1080, я понял, как здорово будет создать версию этого приложения для большого полотна, чтобы можно было рисовать прямо на праздничном столе или на других больших поверхностях, — говорит он. — Вот куда меня привела концепция программы». Для этого Пильцу пришлось изменить программу таким образом, чтобы она хорошо работала на экране вшестеро большем, чем раньше, и принимала сенсорный ввод с 10 точек касания вместо одной.

Рисунок 1.Scribblify позволяет пользователям создавать любые наброски и рисунки, от каракулей до настоящего искусства

 

Происхождение Scribblify

Пильц начал заниматься разработкой мобильных приложений в 2010 году, когда он приобрел свое первое мобильное устройство — Apple iPod touch*. Компания LinkedPIXEL выпустила раннюю версию Scribblify в следующем году. «Сначала интерфейс был предназначен для разрешения 480x320. Все было очень маленьким и компактным, чтобы поддерживать крайне ограниченные на тот момент аппаратные ресурсы», — вспоминает он.Приложение Scribblify для iOS* поступило в магазин App Store в январе 2011 года. «Его стали устанавливать, причем с каждым месяцем все больше», — говорит Пильц. Поэтому примерно год назад он выпустил версию для Google Android* .

Пильц описывает Scribblify как программу для непрофессионального рисования и набросков с некоторыми особыми возможностями. «Моя программа отличается от остальных кистями и цветовыми эффектами», — говорит он. Кисти (см. рис. 2), которые он создал сам, включают текстуры, отсутствующие в большинстве подобных приложений для рисования. «Мне нравится думать, что большинство их уникально», — говорит он, но тут же добавляет, что Scribblify не следует считать конкурентом мощных приложений для профессиональной работы над иллюстрациями. «Научиться работать с предназначенным для iPad эквивалентом такого приложения, как Photoshop, очень непросто, — заявляет Пильц. — С другой стороны, есть очень простые приложения для рисования, в которых только одна обычная круглая кисть и совсем немного разных параметров. А на промежуточном уровне, для которого я и задумал Scribblify, не было ничего подобного. Это приложение для пользователей любого возраста, и не нужно обучаться работе с ним: его достаточно просто запустить и можно сразу использовать».

 

Рисунок 2.В приложении Scribblify поддерживается 62 оригинальных кисти

 

Проблемы

 

Первое затруднение возникло, когда пришлось выбрать технологию для создания версии Scribblify для Microsoft Windows*. Сначала Пильц использовал пакет App Game Kit* (AGK) компании TGC, с помощью которого он ранее сделал игру Ballastic. «Мне удалось создать грубый прототип, но его функциональность была крайне ограничена по сравнению с тем, чего я хотел добиться в этом приложении», — говорит Мэтт. Для участия в конкурсе приложения должны быть разработаны для многопользовательского интерфейса Lenovo Aura* и не должны опираться на крупные фрагменты используемой операционной системы. Из правил следовало, что разработчики не должны были использовать никакие встроенные диалоговые окна Windows. «Было бы очень просто использовать в моем приложении стандартные диалоговые окна открытия и выбора файлов или их сохранения при взаимодействии с файловой системой, например, — говорит Пильц. — Но при этом исчезла бы нестандартность, к которой мы стремились на конкурсе Intel: сделать каждое приложение уникальным».

Для решения проблемы Пильц использовал Node.js*, — это серверная платформа JavaScript* на основе событий для создания сетевых служб для V8 — обработчика JavaScript в составе браузера Chrome. По словам Райана Даля, создателя Nodeэта платформа обеспечивает неблокирующий ввод-вывод с помощью цикла событий, а благодаря встроенному пулу событий поддерживает асинхронный файловый ввод-вывод.

«Основное назначение Node.js — разработка веб-приложений и использование их на настольных компьютерах вне зависимости от операционной системы, — говорит Пильц. — Нет необходимости даже в установке Windows. Базой всего приложения является Node.js». С помощью этой платформы и библиотеки под названием Node-Webkit, Пильц реализовал сохранение и загрузку файлов изображений с помощью интерфейса и галереи, которые он создал сам с помощью стандартных веб-технологий. Приложение работает на платформе Chromium* Embedded Framework (CEF), которая предоставляет мощные средства отображения HTML и JavaScript, такие же, как в браузере Chrome.

Как в Scribblify сохраняются и удаляются изображения
При первой загрузке приложения Scribblify общедоступная папка «Мои документы» пользователя открывается через Node.js.


// Initialize Node.js file system
var fs = require('fs');

// Get User's Documents Folder (Win 7+)
var galleryPath = process.env['USERPROFILE'] + "\Documents\Scribblify\";
galleryPath = galleryPath.replace(/\/g, "/"); // Use forward slashes

// See if folder exists, otherwise create it
if(!fs.existsSync(galleryPath))
{
    fs.mkdir(galleryPath);
}



Когда пользователь запрашивает сохранение файла, полотно HTML5 преобразуется в данные изображения.


var saveImg = canvas.toDataURL();

A unique filename is generated based on timestamp, and Node.js saves the image data to the system.
// Write image data buffer to file
var data = saveImg.replace(/^data:image/w+;base64,/, "");
var buf = new Buffer(data, 'base64');
var fName = galleryPath + destFilename;
fs.writeFile(fName, buf, function(err) {
    if(err)
    {
        console.log(err);
    }
});

Если пользователь хочет удалить изображение из галереи, в Node.js это делается очень просто.


fs.unlinkSync(galleryPath + targetImg);



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


var fileList = fs.readdirSync(currentPath);
var result = [];
for (var i in fileList) {
    var currentFileFull = currentPath + '/' + fileList[i];
    var currentFile = fileList[i];
    var fileExt = currentFile.split(".").pop().toUpperCase();
    var stats = fs.statSync(currentFileFull);
    if (stats.isFile() && fileExt == "PNG") {
       result.push(currentFile);
    }
    else if (stats.isDirectory()) {
         // Directory instead...
    }
}

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

Пильцу удалось создать прототип части функций приложения с помощью уже привычных технологий, включая встроенный в HTML5 элемент полотна для пользовательского интерфейса и Node.js для внутренней обработки, но некоторые из новых возможностей приложения оказалось не так просто реализовать. «Я попытался сделать то, что не так часто реализуется в виде веб-приложения: я хотел создать полное творческое приложение для рисования с кистями со сложными текстурами вместо фигур, которые образуются процедурами», — говорит он.

Сначала программа работала хорошо, но потом в ней обнаружилась проблема. «При использовании нескольких точек касания или при слишком быстром рисовании приложения зависало на несколько секунд из-за недостаточной производительности элемента полотна, а затем продолжало работу», — заявляет автор. Поиск решения привел разработчика к Cocos2d-x, это межплатформенная среда с открытым исходным кодом, доступная по лицензии Массачусетского технологического института (МТИ). Недавно в ее ветвь JavaScript была добавлена поддержка WebGL.

С помощью Cocos2d-Javascript удалось намного удобнее перенести код на WebGL, где производительность была намного выше, учитывая хорошую поддержку видеокарты, которой был оборудован моноблок. «Теперь Cocos2d-Javascript отрисовывает изображения на экране с помощью WebGL, кадровая скорость при этом достигает 60 кадров в секунду. Теперь пользоваться программой стало удобно и интересно», — говорит Пильц. В Scribblify используется стандартный HTML для элементов интерфейса и взаимодействия с пользователями. Пильц описывает решение как гибрид стандартного HTML и JavaScript вместе с другими обработчиками, включая Node.js для внутренней обработки и Cocos2d-Javascript для упрощенной отрисовки WebGL.

Для решения общих вопросов Пильц использовал бесплатный сайт Stack Overflow, на котором профессиональные разработчики и программисты-любители обмениваются ответами на вопросы. «Несколько раз бывало, что я изучал определенные задачи или сталкивался с разными затруднениями, — говорит разработчик. — В таких случаях самый быстрый и удобный способ найти решение — это посмотреть, что рекомендуют другие». Для справки по Cocos2d-xи Node.js, Пильц активно использовал API этих продуктов, и, разумеется, он использовал CodeProject* не только для этого проекта, но и для других своих работ. «Я обращаюсь туда всякий раз, когда мне нужна более подробная информация по определенным вопросам программирования, — говорит Пильц. — Там очень полезные форумы обсуждений, связанные с этим конкурсом, и всегда можно очень быстро получить ответ на вопрос».

Пильц также обнаружил ошибку в обработке касаний в Chromium с набором драйверов Lenovo Horizon: после некоторых касаний не срабатывает высвобождение, особенно при быстром использовании. Для решения этой проблемы он создал небольшую «систему сдержек и противовесов», которая выдает предупреждение, если по ошибке записано избыточное количество касаний. Изображение пользователя будет автоматически сохранено в галерее, после чего пользователю будет предложено перезапустить приложение. Затем предоставляются советы по устранению таких проблем в будущем. «Если пользователь коснется экрана, к примеру, всей ладонью, то программа покажет оповещение с предупреждением, что так делать не следует, нужно касаться экрана кончиками пальцев. Помимо этого, программа предложит перезапустить ее, — сказал он. — Я сообщил об этом, отправив формальное сообщение об ошибкеразработчикам Chromium в ходе конкурса.»


var canvas = document.getElementById('canvas');
canvas.addEventListener('touchstart', touchStartFunction, false);
canvas.addEventListener('touchend', touchEndFunction, false);
canvas.addEventListener('touchcancel', touchCancelFunction, false);
canvas.addEventListener('touchmove', touchMoveFunction, false);
canvas.addEventListener('touchleave', touchLeaveFunction, false);

Платформа Chromium* Embedded Framework (на основе которой построен браузер Google Chrome*) уже долгое время поддерживает сенсорное управление, а внедрять ее очень просто. Можно фиксировать различные формы касаний с помощью простых обработчиков событий, таких как touchstart, touchend, touchcancel, touchmoveи touchleave.

 

Из-за ограничений конкурса по времени, а также из-за технических ограничений платформы, с которой работал Пильц, от реализации некоторых функций в Scribblify пришлось отказаться. «Важная функция, которую мне очень хотелось добавить — это полноценная система отмены всех действий и их повтора, но для меня это - «терра инкогнита», мне не удалось разобраться, как реализовать эту функциональность без снижения скорости работы всей системы», — заявляет Пильц. Поэтому на данный момент есть ластик и кнопка для очистки всего полотна. Разработчик также собирается добавить еще несколько режимов рисования и новые кисти.

Отладка

 

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

«Для меня наиболее удобным оказалось то, что средства Chrome для разработчиков включают полнофункциональный отладчик JavaScript. Это дало мне возможность создавать точки остановки и пошагово проходить по коду, отслеживая определенные переменные и свойства, особенно при возникновении проблем», — говорит разработчик. При этом Пильцу удалось проанализировать специфичные элементы модели DOM и обновлять стили на лету, чтобы быстрее достичь нужного результата. Пильц также обнаружил полезные ресурсы для разработчиков, предоставленные корпорацией Lenovo на сайте lenovodev.com, в частности, требования по интеграции для приложений Horizon (требуется регистрация).

Многопользовательский режим

 

Scribblify для моноблока поддерживает 10 одновременных точек касания. Это означает, что одновременно рисовать изображение на полотне могут 10 пользователей. Учитывая временные рамки конкурса, Пильц уделял основное внимание удобству, с которым можно было интегрировать возможности мультисенсорного управления. «Когда я принял окончательное решение разрабатывать веб-приложение с помощью HTML5 и соответствующих технологий, я знал, что сложности обработки мультисенсорного ввода можно обойти, если используемая веб-платформа уже будет поддерживать мультисенсорный ввод», — говорит он.

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

Дополнительные статьи

 

Новые возможности

Чтобы оценить необыкновенность кистей, нужно попробовать Scribblifyв работе или посмотреть один из демонстрационных видеороликов LinkedPIXEL. «Лично мне самым современным аспектом Scribblify представляются именно кисти, — говорит Пильц. — Все эти кисти — мое собственное изобретение, каждая из них обладает множеством разных свойств, которые определяют, как кисть выглядит и как она работает, когда вы рисуете на экране. Они все уникальны».

Пильц также гордится пользовательским интерфейсом, который ему удалось создать практически с нуля всего за 6 недель. «Рисовать всеми десятью пальцами одновременно с помощью 10-точечного мультисенсорного ввода, или когда один пользователь сидит с одной стороны от экрана, а другой — с другой стороны, и они оба одновременно рисуют — по-моему, это совершенно новый подход», — заявляет автор. Пильц признает, что в некоторых возможных случаях он использовал уже готовые решения. «Я использовал кое-какие библиотеки, например, для расширенного выбора цветов, — говорит он. — Некоторые библиотеки с лицензией МТИ ускоряют этот процесс, так что мне не пришлось изобретать велосипед».

В Scribblify также поддерживается новый способ выбора и смешения цветов. «Можно добавить много разных цветовых эффектов, поэтому вы не просто выбираете какой-то базовый цвет, — говорит Пильц. — Можно смешать два цвета вместе или использовать цвета плазмы или даже добавить то, что я называю цветовой переменной, где по мере рисования чередуются темные и светлые оттенки, чтобы картинка получилась более естественной».

Недавно Пильц приступил к работе над переделкой Scribblify в приложении для Windows 8, чтобы можно было распространять его через Магазин Windows, в том числе и с помощью специализированного «отдела» Магазина Windows 8 для Lenovo. Для выполнения требований самым простым способом будущая версия Scribblify будет работать на базе Internet Explorer* 11 вместо Chromium и будет использовать новые способы обработки ввода-вывода файлов, поскольку Node.js не поддерживается. Выпуск версии Scribblify для Магазина Windows ожидается в апреле или мае 2014 года.

О конкурсе

 

В конкурсе Intel App Innovation Contest 2013 разработчикам приложений с порталов Code Project, Habrahabr, ThinkDigitи CSDN, tбыло предложено предоставить идеи приложений для планшетов под управлением Windows и ПК-моноблоков для финансов, здравоохранения, розничной торговли, образования, игр и развлечения. Авторам лучших идей выдавали системы разработки — 200 планшетов и 300 ПК-моноблоков спонсора конкурса, корпорации Lenovo, и предоставляли 6 недель, чтобы воплотить идею в демонстрационную версию приложения. Победившие в конкурсе приложения перечислены здесь,на сайте Intel® Developer Zone.

500 идей было использовано для создания 276 демонстрационных приложений, из которых было отобрано по 5 лучших в 6 категориях. Таким образом, всего в конкурсе 30 приложений-победителей. Приложения оценивались по следующим критериям: насколько хорошо каждое приложение демонстрирует возможности платформы, насколько хорошо оно удовлетворяет потребности данного сегмента рынка, и насколько успешно оно отвечает нуждам предполагаемых конечных пользователей. Разумеется, приложения-победители должны выглядеть достаточно профессионально и использовать хорошую графику, работать быстро и без ошибок и в нужных случаях использовать датчики и сенсорное управление.

Операции масштабирования в Intel Media SDK

$
0
0

В этой статье рассматриваются все операции масштабирования в Intel Media SDK. Масштабирование — одна из самых распространенных операций при обработке видео. Приложение может задать нужную область для каждого видео с помощью конвейера обработки видео (VPP). Используя Intel Media SDK VPP, можно выполнять различные операции масштабирования. Здесь мы описываем две наиболее часто используемые операции и их результаты.

  1. Обрезка
  2. Изменение размера

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

Обнаружение свободной поверхности кадра —используются поверхности из пула поверхностей, заблокированные поверхности нельзя использовать, поэтому выполняется поиск неиспользуемой поверхности.

int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize)
{
    if (pSurfacesPool)
        for (mfxU16 i = 0; i < nPoolSize; i++)
            if (0 == pSurfacesPool[i]->Data.Locked)
                return i;
    return MFX_ERR_NOT_FOUND;
}

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

mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource)
{
    w = pInfo->Width;
	    h = pInfo->Height;
    pitch = pData->Pitch;
	    ptr = pData->Y;
    //read luminance plane
    for (i = 0; i < h; i++) {
        nBytesRead = (mfxU32) fread(ptr + i * pitch, 1, w, fSource);
        if (w != nBytesRead)
            return MFX_ERR_MORE_DATA;
    }
    mfxU8 buf[2048];        // maximum supported chroma width for nv12
    w /= 2;
    h /= 2;
    	ptr = pData->UV;

    // load U
    sts = ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource);
    if (MFX_ERR_NONE != sts)
        return sts;
    // load V
    ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource);
    if (MFX_ERR_NONE != sts)
        return sts;
}

Операция записи на выходную поверхность — после операции RunFrameVPPSync, асинхронно обрабатывающей кадр. Операция синхронизации вызывается для получения всех выходных данных для их обратной записи в необработанный кадр.

mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink)
{
    mfxFrameInfo* pInfo = &pSurface->Info;
    mfxFrameData* pData = &pSurface->Data;
    mfxU32 i, j, h, w;
    mfxStatus sts = MFX_ERR_NONE;

	    for (i = 0; i < pInfo->Height; i++)
		    sts =
    WriteSection(pData->Y, 1, pInfo->Width, pInfo, pData, i, 0,
		    fSink);

			    h = pInfo->Height / 2;
			    w = pInfo->Width;

    for (i = 0; i < h; i++)
        for (j = 0; j < w; j += 2)
            sts =
                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
                             fSink);
    for (i = 0; i < h; i++)
        for (j = 1; j < w; j += 2)
            sts =
                WriteSection(pData->UV, 2, 1, pInfo, pData, i, j,
                             fSink);
    return sts;
}

Мы будем использовать sample_vpp из учебного руководства на странице Media Solution Portal Входной файл foreman.yuv можно получить здесь. Загруженный файл будет в формате Y4M, его нужно будет преобразовать в формат YV12 с помощью ffmpeg.

ffmpeg -i input.y4m output.yuv

Для операций масштабирования используются шесть параметров VPP.

  • CropX, CropY, CropW, CropHопределяют расположение входного и выходного кадров, которое требуется задать явным образом для получения результата.
  • Параметры Widthи Heightследует задать явным образом и для входного, и для выходного кадра. При этом значения высоты и ширины должны быть кратны 16 для кадровых изображений и кратны 32 для полей. 

Обрезка- это одна из самых распространенных операций по обработке видео, она часто используется для определения рабочей области (ROI). С ее помощью также можно изменить соотношение сторон видео. Наиболее распространенные изменения: 16:9->4:3 и 4:3->16:9. При изменении соотношения сторон к изображению добавляются черные полосы либо сверху и снизу, либо справа и слева. Ниже приведена таблица входных параметров для обрезки, изменения соотношения сторон с добавлением черных полос сверху и снизу, справа и слева в sample_vpp.

 CropXCropY CropWCropHШиринаВысота
Input 12812810244641280720
Output_Crop0010244641024464
Output_PillarBoxing128010247201280720
Output_LetterBoxing012812804641280720

Вот какие результаты вы получите при использовании этих параметров. 

Изменение размера- еще одна операция обработки видео, используемая для получения видеоизображения нужного размера. Но в этом случае к изображению не добавляются никакие полосы, просто изменяется его разрешение на выходе. Изменение размера возможно и в двух измерениях, и только в одном (можно изменять только ширину или только высоту видео, что соответствует растяжению по горизонтали и по вертикали). Ниже приведена таблица входных параметров изменения размера и растяжения в sample_vpp. 

 CropXCropY CropWCropHШиринаВысота
Input 00640480640480
Output_Re-size0012807201280720
Output_VerticalStretch00640608640608
Output_HorizontalStretch00720480720480

Вот какие результаты вы получите при использовании этих параметров.


Более подробные сведения о параметрах и функциях вы найдете в руководстве пользователя, которое находится в папке документов установленной копии MSDK или доступноздесь.

Viewing all 357 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>