<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated on Sun, 12 Feb 2012 03:51:48 -0800 -->
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://software.intel.com/ru-ru/articles/graphics/type/technical-article/feed/" rel="self" type="application/rss+xml" />
    <title>Intel Software Network articles фид</title>
    <link>http://software.intel.com/ru-ru/articles/graphics/type/technical-article/</link>
    <description></description>
    <language>ru-ru</language>
    <item>
      <title>Intel® Graphics Performance Analyzers: разработка игр для мира мобильных устройств </title>
      <description><![CDATA[ <p>Увеличьте свою клиентскую базу и адаптируйте свои программы под ноутбуки и нетбуки, которыми пользуется современное быстрорастущее сообщество мобильных геймеров. Используя набор инструментов  Intel® Graphics Performance Analyzers (Intel® GPA), разработчики могут осуществлять анализ и отладку графических приложений  для оптимизации  игр  на базе Microsoft DirectX* API и компьютеров на базе Intel® HD Graphics. Используйте Intel GPA, чтобы расширять список поддерживаемых платформ и разрабатывать инновационные программы, которые станут будущим мира мобильных игр.</p>
<ul>
<li><strong>Поддержка микроархитектуры Intel® Core™ и интегрированной графики Intel® HD Graphics.</strong> Начните использовать инструменты, специально разработанные для анализа и оптимизации игр для новейших платформ, включающих процессоры Intel® Core™ с графикой Intel® HD Graphics.</li>
<li><strong>Детальный анализ в режиме реальном времени.</strong> Находите проблемы, экспериментируйте и оценивайте полученные результаты в реальном времени.</li>
<li><strong>Профилирование платформ.</strong> Оцените производительность игры в разрезе процессора и графического блока, чтобы убедиться, что программа полностью использует доступные мощности системы.</li>
<li><strong>Простой интерфейс.</strong> Получите доступ ко всему набору инструментов с помощью простого настраиваемого интерфейса.</li>
<li><strong>Сетевая удалённая отладка.</strong> Исключите влияние работы Intel GPA на работу вашего графического приложения.</li>
<li><strong>Открытые программируемые библиотеки.</strong> Расширьте  функциональность инструментов согласно вашим конкретным требованиям.</li>
</ul>
<h2 class="sectionHeading">Привлекайте новых клиентов</h2>
<p>Расширьте свою клиентскую базу, обеспечив устойчивую работу своих игр или DirectX приложений на миллионах ПК со встроенной графикой  Intel HD Graphics. Откройте двери навстречу постоянно растущему миру мобильных устройств - оптимизируйте программы для ноутбуков с графикой Intel, включая системы с новыми процессорами Intel Core и  графикой Intel HD Graphics.</p>
<h2 class="sectionHeading">Используйте полный пакет инструментов</h2>
<p>Intel GPA представляет собой полный набор инструментов для детального анализа проблем производительности, начиная от системного уровня и заканчивая уровнями отдельных элементов, такими как вызовы функций отрисовки внутри отдельных фреймов. Инструменты Intel GPA разработаны специально с учётом требований разработчиков, поэтому вы можете сразу эффективно использовать их, не тратя времени на настройку.</p>
<h2 class="sectionHeading">Загрузить полный обзор пакета</h2>
<p>Чтобы ознакомиться с полным текстом краткого обзора Intel® GPA, загрузите следующий документ:<br /><a href="http://software.intel.com/file/29368">Intel® Graphics Performance Analyzers: Game Development for a Mobile World</a> [Eng., PDF 204KB]</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/intel-graphics-performance-analyzers-game-development-for-a-mobile-world/</link>
      <pubDate>Mon, 19 Jul 2010 13:00:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/intel-graphics-performance-analyzers-game-development-for-a-mobile-world/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/intel-graphics-performance-analyzers-game-development-for-a-mobile-world/</guid>
      <category>Сообщество разработчиков графических приложений</category>
      <category>Tools</category>
      <category>Visual Computing</category>
      <category>Сообщество разработчиков программного обеспечения</category>
    </item>
    <item>
      <title>Наглядно о числах с плавающей точкой</title>
      <description><![CDATA[   <p><strong>Мик Уэст (Mick West)</strong></p><p>
    Числа с плавающей точкой проникли почти во все области  программирования компьютерных игр. Они используются для представления всего –  от позиции, скорости и ускорения до хитрых переменных ИИ, координат текстур и  цветов. Однако, несмотря на их повсеместное присутствие, лишь немногие  программисты утруждают себя изучением механизмов, стоящих за числами с  плавающей точкой, их внутренних ограничений и специфичных проблем, которые  могут возникнуть в играх.</p><p>
    В данной статье рассматриваются некоторые проблемы чисел с  плавающей точкой и приводятся соответствующие примеры в надежде на то, что  программисты, если эти проблемы вдруг встанут посреди работы над проектом,  будут к ним готовы.</p>
    <h2>Что  такое число с плавающей точкой?</h2>
    <p>
    Термин «число с плавающей точкой» используется для обозначения  чисел, представленных разными способами. Но в игровом программировании в  основном присутствуют два типа: числа с плавающей точкой одинарной и двойной  точности. </p><p>
    В настоящее время самыми распространёнными являются 32-х  битные числа с плавающей точкой одинарной точности, которые обычно обозначаются  ключевым словом языка С “float”. Из-за подходящих размера и требований к аппаратуре они стали самым  популярным форматом хранения и операций с числами на всех современных игровых  платформах (хотя некоторые платформы в отдельных частях графического процесса  используют 24-х битные числа, что ещё более усложняет проблемы, описанные  ниже).</p><p>
    Число с плавающей точкой состоит из 32-х бит: бит знака, 8 бит  экспонента и 23-х битная мантисса. За дополнительными сведениями можно обращаться  в раздел ссылок.</p><p>
    Чтобы представить себе проблемы чисел с плавающей точкой,  нужно осознать разницу между числами с плавающей точкой и целыми числами.  Посмотрим, как 32-х битное целое число представляет пространство. Начнем с  одномерного пространства: целое число может содержать 2^32 значений, каждое из  которых представляет область на линии между двух точек. Если каждое число  представляет 1 миллиметр, то с помощью целых чисел мы можем выразить любую  дистанцию от 1 миллиметра до 2^32 миллиметров. То есть любую дистанцию до 4295  километров (или 2669 миль) с разрешением 1 миллиметр.</p><p>
    Теперь подумаем, как мы представим с помощью целых чисел двухмерное,  плоское пространство. Взяв разрешение в 1 миллиметр, то мы можем представить  любую позицию в квадрате размером 4295х4295 километров. Если мы взглянем на  этот квадрат вблизи, то увидим решётку, состоящую из целых чисел.</p><p>
    Сделаем ещё один шаг и представим таким же образом трехмерное объёмное  пространство. Теперь каждая индивидуальная позиция выглядит как пространство  внутри куба объемом 1 кубический миллиметр, и все пространство состоит из  решётки кубиков равного размера.</p>
  <p><img src="http://software.intel.com/file/22245" alt="Целые числа как последовательность кубических объёмов" width="350" height="233" /></p>
  <p><em>Рис. 1: Объёмная форма, представленная целыми числами как последовательностью  кубических объёмов.</em></p>
  <p>
    Мы не можем представить ничего, меньшего по размерам, чем один  миллиметр, а объекты, имеющие размер нескольких миллиметров, приобретают  угловатую форму. Эта идея наглядно представлена на рис. 1.</p><p>
    Важно помнить, что все кубики, определяемые целыми числами, имеют  равный размер. В пространстве кубики, расположенные близ центра, являются точно  такими же, как кубики на расстоянии в километр.</p>
    <h2>Числа с плавающей  точкой и целые числа</h2>
    <p>
    Сравним пространство, определённое целыми числами с пространством,  определённым числами с плавающей точкой. Для начала отметим, что и целые, и  числа с плавающей точкой (на практике) хранятся в 32-х битных машинных словах. Очевидно,  что существуют только 2^32 возможных комбинаций битов, следовательно,  теоретически возможное число «плавающих»  чисел  равно числу целых.. [Замечание: на  самом деле возможное количество чисел с плавающей точкой немного меньше,  поскольку некоторые комбинации битов являются «не числами» (“not a  number”, NaN), но ради простоты мы  этот факт будем игнорировать. Плюс к этому, в данной статье мы будем  рассматривать только значения со знаком для упрощения изложения.] </p><p>
    Однако числа с плавающей точкой могут представлять значения в гораздо  более широком диапазоне: от 0 до 2^128.</p><p>
    Принцип, по которому меньшее количество чисел может  представлять большее количество значений, довольно очевиден, особенно если вы изучали  способ представления чисел с плавающей точкой. Однако нам будет полезно ещё раз  проанализировать нюансы.</p><p>
    Ключевая мысль: между каждой степенью двойки находится  одинаковое количество чисел с плавающей точкой. То есть, от 1 до 2 существует 8388608  (или 2^23) возможных плавающих чисел, и от 2 до 4 существует такое же  количество чисел. Точно такое же количество чисел находится между 32768 и  65536, или между 0.03125 и 0.0625.</p><p>
    Можно сказать об этом и другими словами: если мы представляем линейные  координаты с помощью числа с плавающей точкой, то мы имеем большее количество  возможных точек между центром и точкой на расстоянии 1 миллиметр, чем возможных  точек между центром и точкой на другом конце планеты. Это означает, что  точность представления позиции с помощью чисел с плавающей точкой зависит от того,  где вы находитесь и какие единицы используете.</p><p>
    То есть, опять же, если число с плавающей точкой значением 1.0  представляет 1 миллиметр, то, если вы находитесь близ центра (что означает, что  ваша позиция близка к 0,0,0), ваша позиция может быть представлена с точностью  около 0.0000001 мм, а это очень высокая точность.</p><p>
    Однако если вы удаляетесь от центра, то точность начинает  снижаться. На расстоянии 1 км от центра (1000000 мм), точность падает до 0.125 мм,  но это всё ещё хороший показатель. Если же вы удаляетесь на расстояние в 64 км  от центра, то точность падает до 4 мм, что означает, что вы можете представлять  позицию с точностью в 4 мм, то есть получить лишь четверть того разрешения,  которое дают целые числа.</p><p>
    Дальше всё становится еще хуже. Если вы путешествуете до  границы пространства, которое могут представить целые числа, а это 4295 км  (приблизительно дистанция от Лос-Анджелеса до Нью-Йорка или же от Москвы до  Иркутска) или 2^32мм, то поскольку у нас есть только 23 бита мантиссы, точность  падает до 2^9 или 512 мм – примерно пол метра.</p><p>
    Итак, если использовать 32-х битные числа с плавающей точкой  для представления позиции в игре, которая включает в себя всю континентальную  часть США, то на одном из побережий ваше положение может быть представлено с  точностью до полуметра, что, очевидно, неприемлемо.</p>
    <h2>Несколько  вариантов решения</h2><p>
    Использование относительных координат. Центр нашей Вселенной  находится в фиксированной позиции, но все вычисления можно выполнять в  пространстве, сдвинутом относительно центра ближе к месту действия, например в  точку нахождения камеры обзора. Сами позиции можно хранить в виде чисел с  плавающей точкой относительно какого-нибудь локального центра, позиция которого  относительно центра Вселенной определяется неким более точным способом.</p><p>
    Использовать числа с фиксированной точкой. Если важно, чтобы в  игре всё выглядело и действовало одинаково как вблизи центра, так и вдали от  него, то для хранения позиции можно использовать числа с фиксированной точкой. </p><p>
    Это похоже на использование целых чисел, но со значительно  меньшим размером минимального блока, так что, например, 1 может представлять  0,1 мм или сколько вам будет удобно. Можно даже использовать 64-х битные числа  с фиксированной точкой для достижения ещё большей точности.</p><p>
    Еще можно использовать числа двойной точности при определении точек,  находящихся вдали от центра. Либо определять все позиции с двойной точностью и  затем при работе в локальном пространстве конвертировать их в одинарную, или же  определять позицию удалённого места с двойной точностью, а в пределах  локального пространства использовать одинарную точность.</p>
    <h2>Граничные условия</h2><p>
    Мы часто думаем про многоугольники и их границы как о чисто  математических плоскостях и линиях, которые являются полезными при создании  алгоритмов решения некоторых задач. Рассмотрим простую задачу на плоскости: нужно  определить, с какой стороны от линии находится точка.</p><p>
    Этот тест часто используется для определения того, находится  ли точка внутри треугольника, или других сходных задач. Определим задачу математически:  дана линия, заданная двумя точками А и В, и третья точка Р; мы вычисляем  компонент Z  как векторное произведение, AP  и AB, Z, так  что Z=((P-A)x(B-A)).z.</p><p>
    Если Z отрицательно, то Р находится слева, если Z положительно, то она  находится справа от линии. Это отношение является чисто математическим. </p><p>
    Чтобы определить, находится ли точка внутри плоского  треугольника, самым простым методом является пробежать по вершинам треугольника  по часовой стрелке и, используя этот же тест, проверить, что точка находится  справа от каждой из трёх сторон треугольника.</p><p>
    Этот тест можно использовать также для определения пересечения  в пространстве линии и треугольника, когда сначала вершина треугльника  переносится в пространство линии (с помощью преобразования, которые делают  линию параллельной оси z, сводя задачу к варианту на плоскости).</p><p>
    <img width="300" height="269" src="http://software.intel.com/file/22246" alt=""/></p><p>
    <em>Рис. 2: Линия из точки А=(0,0)&nbsp;в точку В=(5000,5000) отделяет все точки Р  данной области на два треугольника в зависимости от знака векторного  произведения АРхАВ.</em></p><p>
    Если у нас есть два треугольника с общей стороной (а это  большинство треугольников в видеоиграх) и мы применяем к ним описанный тест, то  мы можем точно определить, через какой треугольник проходит линия. На рис. 2  показаны два треугольника и результаты теста (Z&lt;0) на линии АВ, которая определяет общую  сторону треугольников. Прекрасное, чистое, математическое разбиение.</p><p>
    Естественно, встаёт очевидная проблема применения этого теста  для точек, лежащих на линии между многоугольниками, где Z=0. В математическом  смысле линия является бесконечно узкой областью между многоугольниками. Но в  практическом мире чисел с плавающей точкой реальность сильно отличается. </p><p>
    <img width="300" height="297" src="http://software.intel.com/file/22247" alt=""/></p><p>
    <em>Рис. 3: В  области х, у от 800.0 до 800.001 присутствует некоторое количество неопределенных  областей между треугольниками.</em></p><p>
    Если приблизиться к линии до уровня блоков, представляемых  числами, то мы увидим, что линия, определяемая как Z=0, состоит из  последовательности областей (см. рис. 3). Более того, если рассматривать вблизи  эту линию, постепенно удаляясь от центра, то размер этих областей будет  увеличиваться (как показано на рис. 4).</p><p>
    <img width="300" height="296" src="http://software.intel.com/file/22248" /></p><p>
    <em>Рис. 4: На той же границе в другой позиции от 4,8000.0 до  4,800.001 неопределенные области имеют гораздо больший размер.</em></p><p>
    В результате ситуация может развиваться двумя путями, в  зависимости от логики программы. Если мы говорим: «Z&gt;0 означает, что точка  находится слева от линии», то все области, находящиеся на лини (Z=0) окажутся маленькими  сквозными дырками, где нет никакого соприкосновения. Быстрым решением здесь  является изменение условия по Z на Z&gt;=0.  Это устраняет проблему дыр, но создаёт новую проблему – области на линии (Z=0) теперь принадлежат  обоим треугольникам.</p><p>
    Проблема может возникнуть в том случае, если процедура определения  соприкосновений возвращает список всех треугольников, по которым она определила  наличие контакта. Логика программы может быть не приспособлена для работы с  контактами в двух разных поверхностях в одном логическом фрейме, что может  приводить к таким проблемам как приклеивание эффектов или несрабатыванию  событий.</p><p>
    Однако чаще всего тест прикосновения линий вернёт ближайшую  точку контакта. Поскольку для обоих многоугольников будет возвращена одна и та  же точка, (что, как мы видели на рисунках, на самом деле является накладкой  областей), то многоугольники будут обнаружены в том порядке, в каком они тестируются.</p><p>
    Исторически складывалось, что многоугольники проверяются  всегда в одном и том же порядке. Однако сейчас, при распространении  многоядерной архитектуры, программисты всё чаще реализуют некоторый вид  параллелизма данных, в котором порядок тестирования отдельных многоугольников  никак не гарантируется и может меняться в зависимости от того, как сторонние  задачи используют ядра процессора и от состояния кэша памяти, которое меняется  от фрейма к фрейму.</p><p>
    В результате тест соприкосновения, выполняемый на одних и тех  же данных, может возвращать любой из двух многоугольников случайным образом.  Скорее всего, один из многоугольников будет возвращаться в 99.99 процентах  случаев, а другой очень редко.</p><p>
    Вы можете даже натолкнуться на неуловимую ошибку (гейзенбаг),  которую очень трудно найти, поскольку она 1) возникает очень редко, 2) условия  ее возникновения невозможно воспроизвести и 3) внесение тестового кода  «исправляет» ошибку.</p><p>
    Существует несколько решений. Во-первых, можно изменить параллельный  алгоритм распределения данных таким образом, чтобы многоугольники с общими  сторонами всегда попадали в один и то же пакет обработки, но это всё равно  оставляет возможность возникновения проблемы двух полигонов с одной и той же  точкой соприкосновения.</p><p>
    Можно попытаться сделать так, чтобы все области, лежащие на  линии Z=0  всегда принадлежали только одному из двух полигонов, путем присваивания признаков  сторонам многоугольников, чтобы одна сторона использовала Z&lt;0, а другая  использовала Z &gt;= 0.</p>
    <h2>Обнаружение блуждающих блоков</h2>
    <p>
    Переменные с плавающей точкой очень удобно использовать для  представления чисел, но нужно иметь ввиду, что они передают математический мир  не так совершенно, как  думаете вы, проектируя  алгоритм. Координаты, представленные числами с плавающей точкой, представляют  собой скорее области пространства, чем точки.</p><p>
    Эти области увеличиваются в размере при удалении от центра  координат и могут создавать заметные артефакты,   такие как дрожание или швы. Это важное соображение, если вы собираетесь  применять движок для отображения миров большого масштаба. </p><p>
    Неточности чисел с плавающей точкой могут проводить к недерминированным  граничным областям разного размера, которым надо уделить отдельное внимание,  чтобы избежать трудноуловимых ошибок.</p>
  <h3>Ссылки</h3>
  <ol>
    <li>Ericson, Christer. “Numerical  Robustness” in Real-Time Collision Detection. San Francisco: Morgan Kaufmann, 2004.</li>
    <li>Freese, Peter. “Solving Accuracy  Problems in Large World Coordinates” in Game Programming Gems 4, Hingham, Mass.: Charles River Media, 2004.</li>
    </ol> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/visualizing-floats/</link>
      <pubDate>Thu, 26 Nov 2009 13:00:00 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/visualizing-floats/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/visualizing-floats/</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Производительность игровой физики на архитектуре Larrabee</title>
      <description><![CDATA[ <p><a href="http://software.intel.com#p1"><strong>Введение</strong><br /></a><a href="http://software.intel.com#p2"><strong>Модели эмуляции игровой физики</strong></a><br /><a href="http://software.intel.com#p3"><strong>Многоядерная архитектура Larrabee</strong></a><br /><a href="http://software.intel.com#p4"><strong>Перенесение моделей игровой физики на платформу Larrabee</strong></a><br /><a href="http://software.intel.com#p5"><strong>Выводы</strong></a><br /><a href="http://software.intel.com#p6"><strong>Ссылки</strong></a></p>
<h2>Аннотация</h2>
<p>Игровая физика лежит в самом сердце любого современного игрового движка и используется для эмуляции естественных движений и взаимодействий объектов, твердых и гибких тел, одежды, воды. Приложения, рассчитывающие физику, очень интенсивно задействуют процессор и память. Стремление к повышенной степени реализма требует более сложных алгоритмов и больших объемов данных. Чтобы удовлетворить растущие требования программ, нужна компьютерная архитектура с высокой скоростью вычислений с плавающей точкой и быстрой шиной памяти. К счастью, современные многоядерные архитектуры общего назначения уже практически превзошли эти требования. Larrabee является одной из таких многоядерных архитектур. Она состоит из массива ядер архитектуры Интел, каждое из которых усилено 16-элементным векторным процессором. В данной статье мы проанализируем несколько игровых приложений и покажем, как расширенный параллелизм потоков и данных в Larrabee сочетается с большим количеством физических алгоритмов, как эти алгоритмы можно распараллелить и перенести на архитектуру  Larrabee и, следовательно, получить хороший прирост производительности.</p>
<a name="p1" id="p1"></a>
<h2>Введение</h2>
<p>Растущий рынок компьютерных игр подогревает стремление разработчиков графики к достижению все большего реализма, правдоподобия и скорости. За последнюю декаду эмуляция игровой физики стала ключевым моментом достижения реализма, которого требуют геймеры.</p>
<p>Высокая степень реализма, однако, требует реалистичных взаимодействий между объектами игры. Например, мяч должен реагировать по-разному на столкновения с бетонной поверхностью и с травой. Физическая симуляция мяча должна учитывать эту разницу в физических свойствах (трение, жесткость и т.д.) этих двух поверхностей и их воздействие на движение мяча. Пушечный снаряд, при попадании в кирпичное здание, должен заставлять отдельные кирпичи падать и, возможно, обрушиться все здание. Тяжелый предмет, брошенный в воду, должен производить брызги и волны, которые должны успокаиваться через некоторое время. Достижение желаемой степени реализма в физических симуляциях требует сложных математических моделей, которые превращаются в жадные до вычислений алгоритмы. По мере роста размеров сцены и увеличения количества объектов, соответственно увеличивается вычислительная сложность и объем структур данных. Эти два фактора делают работу в реальном времени (по меньшей мере 30 FPS, фреймов в секунду) труднодостижимой без использования достаточных аппаратных ресурсов.</p>
<p>Однако, стандартные многоядерные архитектуры быстро приближаются к уровню, который соответствует и даже превосходит этот уровень требований. Larrabee [Seiler et al 2008] является одной из таких высокопоточных многоядерных архитектур. Она состоит из массива процессорных ядер IA Intel, каждое из которых расширено 16-элементным векторным процессором.</p>
<p>В этой статье мы рассмотрим несколько моделей, которые используются для расчета разных типов эмуляции физики в современных играх. Затем кратко коснемся архитектуры Larrabee. В заключение расскажем, как нужно распараллеливать приложения и переносить их на архитектуру Larrabee, чтобы получить должное ускорение. Отдельно остановимся на методах, которые мы использовали для расчета игровой физики, представленной на рис 17 из [Seiler et al 2008]. В общих словах, параллелизм потоков и данных и стандартная процессорная архитектура Larrabee хорошо подходят для множества физических алгоритмов. В данной статье мы показали, как на LRB можно запускать алгоритмы расчета игровой физики. Отдельные реализации игровой физики для РС не вошли в эту статью. Дополнительные детали по производительности и архитектурным особенностям при обработке игровой физики на Larrabee обсуждались в [GamePhysics08].</p>
<a name="p2" id="p2"></a>
<h2>Модели эмуляции игровой физики</h2>
<p>В этом разделе мы рассмотрим высокоуровневую модель развивающейся во времени физической симуляции и несколько основанных на этой модели приложений, рассчитывающих игровую физику. Описание основывается на [Chen07]. На рис. 1 показан типичный процесс физической симуляции. На каждом шаге времени приложение физической симуляции использует на входе состояние сцены (позиция, ориентация, скорость всех объектов), и данные с внешних датчиков (например, показывающих, какие действия выполняет игрок). Приложение рассчитывает физические процессы, которые формируют обновленное состояние (силы, моменты или давление). В зависимости от схемы, эти данные используются для развития сцены во времени (например, с помощью законов движения). Если возникают различные феномены, типа столкновений, то состояние обновляется в зависимости от этих феноменов, и заново рассчитываются силы и повторяются временные фазы, возможно, с меньшим шагом времени.</p>
<p><img height="313" width="321" src="http://software.intel.com/file/18839" alt="Обзор физической эмуляции" /></p>
<p><em>Рис.1. Обзор физической эмуляции.</em></p>
<p>Приведем несколько примеров важных приложений симуляции игровой физики, основанных на процессе, приведенном выше.</p>
<h3 class="sectionHeading">Игровые флюиды с помощью сглаженной гидродинамики частиц</h3>
<p>Сглаженная гидродинамика частиц (СГЧ, Smoothed Particle Hydrodynamics, SPH), как техника интерактивной симуляции флюидов, возникла относительно недавно [Muller2003]. Метод СГЧ рассматривает флюид как набор отдельных частиц и правил их сопротивления изменению плотности: если частицы располагаются слишком близко, силы отталкивания раздвигают их, если они разлетаются слишком далеко, силы притяжения стягивают их обратно. Если пара частиц расположены достаточно далеко друг от друга, между ними не возникает никакой силы. СГЧ дифференцирует уравнения Навье-Стокса (Navier-Stokes) и находит решения для конечного числа частиц в пространстве и времени. В решеточном (grid) методе позиция контрольных точек фиксирована, в случае СГЧ частицы свободно перемещаются в пространстве. Разница фундаментально меняет принцип решения уравнений Навье-Стокса и обычно сильно упрощает его реализацию, делая СГЧ более пригодным для интерактивного окружения.</p>
<p><img height="222" width="374" src="http://software.intel.com/file/18840" alt="Пространственная структура данных для СГЧ" /></p>
<p><em>Рис. 2. Пространственная структура данных для СГЧ.</em></p>
<p>Для отслеживания движений соседних частиц и расстояния их друг от друга, иногда используют структуры данных ускорений. Например, может использоваться равномерная решетка, тогда частицы на каждом шаге симуляции попадают в клетки решетки одинакового размера <em>h</em>. Чтобы найти всех соседей данной частицы, всего лишь нужно проверить все частицы в окружающих клетках.</p>
<h3 class="sectionHeading">Эмуляция ткани</h3>
<p><img height="305" width="342" src="http://software.intel.com/file/18841" alt="Пространственные связи в ткани" /></p>
<p><em>Рис. 3. Пространственные связи в ткани</em></p>
<p>Модели игровой физики рассматривают ткань как набор частиц [Jacobes2001]. Каждая частица подвергается внешним воздействиям, таким как гравитация, ветер, растяжение и другие силы. Как показано на рис. 3(а), для поддержания формы объекта используются пружинные связи, а для предотвращения взаимопроникновения с окружением используются реакции на столкновение. Уравнение движения частицы, образующееся при применении внешних сил, получается с помощью Верлетовского (Verlet) интегрирования. Вышеупомянутые связи создают систему уравнений, соединяющих вместе позиции частиц. Эта система решается на каждом шаге симуляции с помощью релаксации, т.е. усиления связей за определенное число итераций. Это показано на рис. 3(б). Самостолкновения обычно игнорируются.</p>
<h3 class="sectionHeading">Эмуляция твердого тела</h3>
<p>Динамика твердого тела [Eberly2003] эмулирует движение и взаимодействие недеформирующихся объектов при наличии воздействия сил и вращающих моментов. Динамика твердого тела очень часто используется в игровой физике современных игр. Примерами твердых тел могут служить автомобили, куклы, подъемные краны, бочки, ящики и даже целые здания.</p>
<p>При традиционном подходе решается система дифференциальных уравнений, представляющих второй закон Ньютона, F=ma, где m масса объекта, a ускорение, F приложенная сила. Приложенная сила определяет ускорение объекта, так что скорость и позиция получаются с помощью интегрирования этого уравнения. Вычислительные трудности возникают потому, что движение твердого тела нарушается из-за взаимодействия с окружением. Например, рассмотрим разрушаемое окружение, где тысячи твердых объектов взрываются, разрушаются, сталкиваются, что выливается в сотни тысяч взаимодействий. Реалистичная симуляция такой сцены требует обнаружения столкновений (см. следующий раздел), вычисления точек соприкосновения, физически корректное вычисление сил, возникающих во время контакта. Полный процесс, демонстрирующий все шаги, необходимые для эмуляции твердого тела, приведен на рис. 4. Для ускорения определения столкновений используются структуры данных пространственных частиц, такие как гриды или иерархии окружающих объемов. Для определения сил при столкновении, контакт моделируется как линейная комплементарная задача [Baraff97].</p>
<p><img height="237" width="350" src="http://software.intel.com/file/18842" alt="Алгоритм расчета состояния твердого тела" /></p>
<p><em>Рис.4. Алгоритм расчета состояния твердого тела</em></p>
<h3 class="sectionHeading">Обнаружение столкновений</h3>
<p>Обнаружение столкновений является важным моментом  для всех упомянутых приложений и используется для определения, находятся ли два объекта в контакте, или проникают друг в друга, как частица и твердый объект, или взаимодействуют подобно твердому телу и ткани, или просто являются двумя твердыми телами [Ericson04].</p>
<p>Обнаружение столкновений состоит из больших (broad) и малых (narrow) фаз. Большие фазы определяют потенциально сталкивающиеся объекты, отбрасывая не сталкивающиеся пары. Малая фаза берет на входе потенциально сталкивающиеся пары (как выход большой фазы) и проверяет, действительно ли они сталкиваются, а также находит точки соприкосновения. В следующей стадии решатель связей использует эту информацию для расчета сил, необходимых для сопротивления тел взаимопроникновению (рис. 4).</p>
<p>Малая фаза обнаружения столкновений использует структуры данных ускорений, чтобы пространственно разделить эмулируемые объекты, так что затратный тест на столкновение проводится только для объектов, находящихся по соседству друг от друга. Существуют несколько алгоритмов для большой фазы. Самый используемый – sweep and prune (S&amp;P). S&amp;P сортирует начало и конец окружающего объема каждого объекта вдоль всех осей. Когда объекты двигаются, их окружающие объемы могут пересекаться (рис. 5). Если объемы по всем осям двух объектов пересекаются, то велика вероятность, что они столкнулись, и на малой фазе они проверяются алгоритмом обнаружения столкновений. Существует большое количество специализированных и оптимизированных реализаций алгоритма обнаружения столкновений малой фазы, такие как определение столкновения двух сфер или капсул. Однако определение столкновения более сложных выпуклых объектов обычно делается с помощью алгоритма GJK [Gilbert88]. Этот алгоритм итерационно вычисляет расстояние между двумя выпуклыми объектами, пока не найдет минимальное. В случае невыпуклых объектов можно (1) разбить объект на несколько выпуклых и затем применить метод для выпуклых, (2) представить геометрию как триангулярную поверхность и использовать общий алгоритм столкновения триангулярных сеток (mesh), что опять включает использование алгоритма столкновений выпуклых объектов.</p>
<p><img height="170" width="318" src="http://software.intel.com/file/18843" alt="Sweep and Prune" /></p>
<p><em>Рис. 5. Sweep and Prune (S&amp;P)</em></p>
<p><img height="212" width="355" src="http://software.intel.com/file/18844" alt="Схема многоядерной архитектуры Larrabee " /></p>
<p><em>Рис. 6. Схема многоядерной архитектуры Larrabee</em></p>
<a name="p3" id="p3"></a>
<h2>Многоядерная архитектура Larrabee</h2>
<p>Larrabee (см. рис. 6) это многоядерная архитектура Интел, спроектированная в расчете на использование большого количества ядер. На этой архитектуре можно запускать большое число параллельных приложений, таких как 3D рендеринг, игровая физика, обработка медицинских изображений, и другие высокопроизводительные вычисления. Каждое ядро Larrabee поддерживает полный набор инструкций х86. Каждое ядро имеет короткий очередный (in-order) конвейер инструкций, разделяемый между потоками. Аппаратная часть может переключать потоки так, чтобы исполнялись инструкции, готовые к использованию, и останавливает другие потоки, которые находятся в состоянии ожидания своих данных (например, в ситуациях взаимной зависимости данных (back-to-back data dependence), или промаха кеша первого уровня). Как результат, повышенная латентность некоторых потоков прячется за полезной работой других потоков.  Анализ большого количества параллельных приложений говорит, что аппаратная поддержка многопоточности – это хороший компромисс между сложностью аппаратной части и повышением производительности многопоточных приложений.</p>
<p>Хотя архитектура Larrabee имеет очень быструю систему памяти, для снижения суммарных требований сразу многих приложений каждое ядро имеет кэш первого уровня с низкой латентностью. Большой общий полнокогерентный L2 кэш равномерно распределен между ядрами, каждое ядро имеет быстрый доступ к своей части, а для доступа к остальным частям кэша используется системная шина.</p>
<p>Каждое ядро дополнено 16-элементным векторным конвейером (16-wide vector pipeline unit, VPU), который обрабатывает целочисленные и с плавающей точкой единичной точности векторные инструкции. Хорошо известно, что два фундаментальных фактора ограничивают векторную эффективность: (1) контроль потока и (2) непрямой доступ к памяти. Larrabee предоставляет аппаратную поддержку обоих моментов.</p>
<p>Чтобы справиться с контролем потока, каждая инструкция может использовать регистр масок для указания, в какой вектор или адрес памяти будет производиться запись, а какие останутся неизмененными. Существуют команды управления масками, которые устанавливают содержание регистра масок. Чтобы освоить непрямой доступ к памяти, в Larrabee включены инструкции gather/scatter, которые читают и пишут в непрерывные адреса памяти, используя адрес из вектора адресов. 16 элементов могут загружаться или сохраняться в 16 различных адресах памяти. Скорость работы загрузки/сохранения зависит от кэша, который дает доступ к одной линии за такт, что в худшем случае требует 16 доступов к кэшу. Но если данные располагаются на одной линии кэша, что нередко случается во многих графических и других задачах, все эти элементы могут быть загружены за один доступ к L1 кэшу, существенно повышая производительность приложения.</p>
<p><img height="188" width="580" src="http://software.intel.com/file/18845" alt="Характеристики параллелизма" /></p>
<p><em>Рис. 7. Характеристики параллелизма</em></p>
<a name="p4" id="p4"></a>
<h2>Перенесение моделей игровой физики на платформу Larrabee</h2>
<p>Все программы игровой физики выигрывают от высоких вычислительных возможностей архитектуры Larrabee и мощной ISA. В этом разделе мы расскажем, как можно распараллелить приложения, для использования параллелизма Larrabee, как уровня потоков, так и уровня SIMD.</p>
<p>Рис. 7 отображает высокоуровневую характеристику параллелизма уровня потоков и SIMD в разных модулях игровой физики. В конце данного раздела приведена дискуссия о параллелизме и объясняется эта характеристика.</p>
<h3 class="sectionHeading">Очевидный параллелизм</h3>
<p>Для многих игровых движков параллелизм уровня потоков и SIMD является очевидным путем. Например, множественные независимые итерации в цикле легко распределяются на потоки с помощью прагм OpenMP [OpenMP05]. В случае SIMD, вычисления на каждой итерации преобразуются в векторный код с помощью векторизующего компилятора.</p>
<p><img height="104" width="352" src="http://software.intel.com/file/18846" alt="Использование TLP в детекторе столкновений" /></p>
<p><em>Рис. 8. Использование TLP в детекторе столкновений.</em></p>
<p>Алгоритмы обнаружения столкновений являются примерами блоков игровой физики, которые распараллеливаются тривиально. Например, sweep and prune алгоритм большой фазы может обрабатывать объекты абсолютно параллельно, а в алгоритме обнаружения столкновений малой фазы пары объектов абсолютно независимы. Работа этих двух алгоритмов может легко распределяться на потоки с помощью OpenMP (см. рис. 8). Также, как и алгоритм движения частиц, который рассчитывает следующую позицию частицы на основе текущей позиции и данных о приложенных силах – это простой цикл, перебирающий элементы массива и выполняющий над ними элементарные вычисления. Так что все это векторизуется тривиально.</p>
<h3 class="sectionHeading">Синхронизация потоков и программная блокировка</h3>
<p><img height="161" width="346" src="http://software.intel.com/file/18847" alt="Декомпозиция решеток в СГЧ" /></p>
<p><em>Рис. 9. Декомпозиция решеток в СГЧ</em></p>
<p>Некоторые физические алгоритмы при распараллеливании требуют применения синхронизации между несколькими потоками. Обычно для этого используются программные блокировки, гарантирующие взаимное исключение. Например, алгоритм для построения пространственной структуры данных ускоряющихся соседних объектов обращается к частицам СГЧ (см. раздел о игровых флюидах) с целью получения данных обо всех частицах, что требует блокировки взаимного исключения. В нашем случае каждый поток действует на своем локальном наборе частиц. Поток переносит частицы в соответствующие соседние клетки решетки. Поскольку каждая клетка может содержать более одной частицы, несколько частиц добавляются в начало связанного списка. Вставка частиц в одну клетку несколькими потоками требует применения блокировки взаимного исключения, чтобы только один поток мог обновлять список за раз. В таких случаях SIMD параллелизация используется в каждой итерации отдельно, а не совместно, как можно делать, когда все итерации независимы. В другом случае, алгоритм, вычисляющий силы, также является частью приложения игровых флюидов. Здесь каждая частица в клетке решетки обновляет состояние других частиц, которые находятся на определенном расстоянии от нее. Может случиться так, что несколько частиц в той же или другой клетке захотят обновить одну и ту же частицу. В случае, если частицы обрабатываются разными потоками, для корректного выполнения требуется блокировка взаимного исключения, чтобы гарантировать, что только один поток обновляет частицу в данный момент времени. Установка и снятие блокировок на каждую клетку решетки выливается в большие производственные издержки. Чтобы их сократить, мы разбиваем решетку на несколько больших кусков, каждый из которых назначается своему потоку, как изображено на рис. 9. Обновление внутри одного куска решетки гарантированно производится одним потоком и не требует синхронизации. В этом случае только пограничные клетки требуют обработки несколькими потоками и соответствующих блокировок. Размеры кусков грида могут быть настолько большими, что практически сведут к нулю издержки на синхронизацию.</p>
<h3 class="sectionHeading">Аппаратная поддержка SIMD</h3>
<p>Существует подкласс приложений  игровой физики, который в больших объемах использует SIMD параллелизм, но для эффективной работы требует специальной аппаратной поддержки, которая присутствует в архитектуре Larrabee.</p>
<p><img height="536" width="365" src="http://software.intel.com/file/18848" alt="Использование масок в детекторе столкновений малой фазы" /></p>
<p><em>Рис. 10. Использование масок в детекторе столкновений малой фазы.</em></p>
<p>Известно, что основными проблемами эффективности SIMD являются контроль потока и непрямой доступ к памяти. Если в оригинальном скалярном коде есть ветвления, то, чтобы перевести такой код в SIMD необходимо использовать условные операции SIMD. Larrabee предоставляет возможность условного исполнения команд SIMD с помощью векторной битовой маски. Для каждой команды SIMD маска указывает, какие операнды нужно игнорировать.</p>
<p>Маски SIMD приходятся очень кстати во многих алгоритмах обнаружения столкновений малой фазы, таких как столкновения прямоугольников или GJK. Эти алгоритмы обычно содержат много проверок с ранним выходом, которые пытаются определить отсутствие столкновения двух объектов как можно раньше, чтобы избежать последующих интенсивных вычислений. На рис. 10(а) показан пример проверки с ранним выходом (earlyCDtest1 и earlyCDtest2), проверки столкновения между двумя объектами выполняются последовательно. Если оба теста возвращают значение «ложь», то это значит, что объекты столкнулись и запускается программа обнаружения точек контакта getcontactpoints.</p>
<p>Чтобы перевести этот код в Larrabee 16-элементный SIMD, мы выполняем проверку одновременно на 16 парах, используя 16-элементные команды SIMD, как показано на рис. 10(б). Проверки столкновений превращаются в операции, которые устанавливают биты маски, F0 и F1 (рис. 10(в)). Если проверка с ранним выходом выдает результат FALSE, то соответствующий бит маски сбрасывается в 0. Остальная часть кода прочитает нулевое значение маски, что будет означать, что никаких дополнительных проверок этой пары не требуется. Код вычисления точек контакта блокируется маской F1. Если она равна 0, то это значит, что одна из предыдущих проверок совершила ранний выход и, таким образом, результат вычислений не должен менять содержимого структуры данных соответствующей пары. Хотя такой подход означает неэффективное использование команд SIMD в случаях, когда большинство масок равно 0, но он приводит к существенной векторизации кода обнаружения столкновений. В большинстве случаев уровень использования SIMD достаточно высок из-за алгоритма большой фазы, который выкидывает большинство не сталкивающихся объектов – остающиеся объекты с большой вероятностью могут столкнуться и, скорее всего, пройдут ранние тесты. </p>
<p><img height="157" width="585" src="http://software.intel.com/file/18849" alt="Релаксация связей в решателе ткани" /></p>
<p><em>Рис. 11. Релаксация связей в решателе ткани.</em></p>
<p><img height="119" width="358" src="http://software.intel.com/file/18850" alt="Непрямой доступ в алгоритме обнаружения столкновений&lt;" /></p>
<p><em>Рис. 12. Непрямой доступ в алгоритме обнаружения столкновений</em></p>
<p>Традиционно, при программировании аппаратных SIMD векторов, операнды и результаты должны группироваться вместе последовательно в памяти. Для большей эффективности они должны помещаться в выровненные структуры. На рис. 12(а) показан пример массива из 16 структур, по одной на каждую пару объектов, где в каждой структуре имеется три поля. Без аппаратной поддержки чтения векторов, эффективное использование команд SIMD требует перепаковки массива структур в формат структуры массивов. Как показано на рис. 12 (б), поля из разных структур пакуются вместе. Такое перераспределение данных, реализуемое программно, может быть очень затратным.</p>
<p>Larrabee предоставляет аппаратное ускорение подобных операций с помощью поддержки инструкций чтения векторов (см. подраздел Larrabee). Инструкция чтения (gather) собирает соответствующие элементы векторов из разбросанных участков памяти и сохраняет их вместе в один векторный SIMD регистр. В приведенном выше примере команда чтения собирает 16 разбросанных в памяти значений, напр. X0, X1,…, X15.</p>
<p>Видно, что векторная поддержка контроля потока и непрямого доступа к памяти приводит к гораздо более эффективному использованию команд SIMD, чем при программных преобразованиях, и таким образом имеет большую ценность для производительных алгоритмов игровой физики.</p>
<h3 class="sectionHeading">Легко параллелизуемые реализации и алгоритмы</h3>
<p>Большинство алгоритмов игровой физики в большой степени используют SIMD и поточный параллелизм, который легко использовать с помощью аппаратной поддержки SIMD и поточной синхронизации. Однако, существуют несколько алгоритмов, где параллелизм сразу не применишь. Для параллелизации необходимо изменение реализации, или алгоритма, или и того и другого.</p>
<p><img height="564" width="369" src="http://software.intel.com/file/18851" alt="Решатель физики, пригодный для SIMD" /></p>
<p><em>Рис. 13. Как сделать решатель физики пригодным для SIMD</em></p>
<p>Приведем пример алгоритма, который требует изменений игровой ткани. Как было замечено в разделе об эмуляции ткани, алгоритм использует технику итеративной релаксации связей, которая усиливает одну связь за другой, пока вся система не сожмется до состояния, где все связи приходят с состояние равновесия. Усиление связи состоит в изменении позиции каждой частицы решетки, основанной на ее расстоянии от соседей справа, снизу, и по диагонали. Прямое усиление всех связей слева направо, сверху вниз, как на рис. 11(а), приводит к последовательной зависимости между связями и невозможности параллелизации. Вместо этого выполняются несколько проходов по связям. В первый проход приводятся в равновесие вертикальные связи (рис. 11(б)), Видно, что все связи не зависят друг от друга и могут обрабатываться параллельно. Также выполняются проходы по горизонтальным и диагональным связям (рис. 11(в), 11(г)).</p>
<p>Разрушая зависимость между связями, мы можем широко использовать поточный и SIMD параллелизм, но при этом замедляется работа алгоритма, поскольку одна связь теперь воздействует на другие через большее число итераций. Однако с помощью анализа симуляции мы выяснили, что параллельный алгоритм никогда не бывает медленнее, чем последовательный, более чем в два раза. Широкое применение параллелизма компенсирует замедление сходимости.</p>
<p>Другой пример из модели эмуляции твердого тела. Во время выполнения физической симуляции, фаза обнаружения столкновений вычисляет пары сталкивающихся объектов, и они используются как входные данные для фазы разрешения связей. Решатель физики работает с этими парами и вычисляет силы отталкивания, возникающие при контакте, которые препятствуют телам проникнуть друг в друга. На рис. 13 (а) показан случай столкновения четырех тел (три прямоугольника и плоскость основания), где соответствующие пары сталкивающихся объектов приведены на рис. 13 (б). Нужно разрешить результирующие связи C1, C2, C3, и C4 и обновить позиции тел.</p>
<p>Для параллелизации этой фазы нам в идеальном случае надо было бы распределить связи между свободными потоками и разрешать их параллельно. Однако этому часто мешают внутренние зависимости между соседними связями. В нашем примере связи С1 и С2 относятся к телу т2 и не могут разрешаться параллельно. Эти зависимости могут сильно усложнить вычисления, но можно перегруппировать связи по пачкам так, чтобы в каждой пачке не было конфликтующих связей. Т.е. каждая пачка содержит только одну связь для каждого тела.</p>
<p>Алгоритмы перераспределения перебирают связи, составляя упорядоченный список частично наполненных пачек. Каждая связь записывается в первую пачку, не содержащую конфликтующих связей. Как результат, все связи в пачке могут обрабатываться параллельно, а разные пачки должны  обрабатываться последовательно.</p>
<p>Например, мы переупорядочиваем связи на рис 13(б) и получаем две пачки (С1, С3) и (С4, С2), как показано на рис. 13(в). Отметим, что С1 и С3 из первой пачки связаны каждая со своим телом и могут обрабатываться параллельно. То же относится к С4, С2. Как результат, С1 и С3 обрабатываются параллельно и результат прилагается как часть ввода ко второй пачке.</p>
<p>Если внедрять параллелизм вышеприведенным образом, то применение потоков и SIMD является очевидным. Использование поточного параллелизма требует барьерной синхронизации между последовательными пачками параллельно обрабатываемых связей.</p>
<h3 class="sectionHeading">Результаты масштабирования</h3>
<p><img height="262" width="361" src="http://software.intel.com/file/18852" alt="Производительность игровой физики при масштабировании" /></p>
<p><em>Рис. 14. Производительность игровой физики при масштабировании</em></p>
<p>Мы провели детальный анализ масштабирования симуляции в нескольких играх на разных конфигурациях Larrabee [Seiler08]. На рис. 14 показана масштабируемость нескольких популярных тестов игровой физики и алгоритмов твердого тела, флюидов и ткани. Мы получили результат более 50% использования ресурсов на 64 ядрах Larrabee, и в некоторых случаях почти линейное ускорение при параллельной работе. Это означает, что архитектура Larrabee является достаточно масштабируемой для обеспечения растущих потребностей интерактивных алгоритмов твердого тела, флюидов и ткани.</p>
<a name="p5" id="p5"></a>
<h2>Выводы</h2>
<p>В данной статье мы представили несколько ключевых моделей эмуляции физики игры. Для удовлетворения потребностей в вычислительной мощности и памяти этих игровых приложений нам понадобилась компьютерная архитектура, обеспечивающая высокоскоростные вычисления с плавающей точкой и быструю шину памяти.</p>
<p>Мы кратко остановились на многоядерной многопоточной архитектуре Intel Larrabee с 16-элементным векторным процессором. Ее большой  вычислительный потенциал и широкая шина данных вполне удовлетворяют требованиям игровых приложений.</p>
<p>Мы также описали несколько моделей эмуляции игровой физики и показали, как их можно распараллелить, перенести и масштабировать на архитектуру Larrabee. Детали производительности и архитектурные тонкости обсуждаются в статье [GamePhysics08].</p>
<a name="p6" id="p6"></a>
<h2>Ссылки</h2>
<p>[1] [Baraff97] D. Baraff, “Physically Based Modeling: Principals and Practice,” Online Course Notes, SIGGRAPH, 1997. <br />[2] [Eberly03] D. H. Eberly. Game Physics. Morgan Kaufmann/Elsevier, San Francisco, 2003. <br />[3] [Ericson04] Christer Ericson, San Mateo. Real-time Collision Detection (Series in Interactive 3D Technology), Morgan Kaufmann, 2004. <br />[4] [Gilbert88] E. G. Gilbert, D.W. Johnson, and S. S. Keerthi. A fast procedure for computing the distance between complex objects in three-dimensional space. In IEEE Journal of Robotics and Automation, 4(2):193–203, 1988. <br />[5] [Chen07] Yen-Kuang Chen, Jatin Chhugani, Christopher J. Hughes, Corporate Technology Daehyun Kim, Sanjeev Kumar, Victor Lee, Albert Lin, Anthony D. Nguyen, Eftychios Sifakis, Mikhail Smelyanskiy. High-Performance Physical Simulations on Next- Generation Architecture with Many Cores. Intel Technology Journal, 2007. <br />[6] [Jacobsen01] T. Jacobsen, Advanced Character Physics, Game Developers Conference, 2001. <br />[7] [Muller03] M. Muller, D. Charypar, and Markus Gross. Particle-based fluid simulation for interactive applications. In Proceedings of the Eurographics Symposium on Computer Animation, 2003. <br />[8] [OpenMP05] OpenMP Application Program Interface, May 2005, Version 2.5. <br />[9] [Seiler08] Larry Seiler, Doug Carmean, Eric Sprangle, Tom Forsyth, Michael Abrash, Pradeep Dubey, Stephen Junkins, Adam Lake, Jeremy Sugerman, Robert Cavin, Roger Espasa, Ed Grochowski, Toni Juan, Pat Hanrahan. Larrabee: A Many-Core x86 Architecture for Visual Computing. In Proceedings of SIGGRAPH, 2008. <br />[10] [GamePhysics08] Parallelization and Analysis of Game Physics Performance on Larrabee Many-core Architecture. Currently under submission.</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee/</link>
      <pubDate>Thu, 10 Sep 2009 13:00:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee/</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Обзор методов программного моделирования пламени</title>
      <description><![CDATA[ <h2>Введение</h2>
<p>Демонстрационная программа <a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo/">Smoke</a> (Дым) создана  для демонстрации возможностей масштабируемой многопоточной архитектуры игровых  движков.  Приложение Smoke использует новую  концепцию программной генерации огня. Сцена игры представляет собой ферму, на  которой расположены деревья, сельхозтехника, сараи, а также управляемые  искусственным интеллектом животные - лошади, цыплята и ласточки. Пламя,  возникающее от метеоритного дождя, реалистично распространяется по кронам  деревьев, перекидываясь с дерево на дерево и с ветки на ветку. Задача игрока -  быстро потушить огонь.</p>
<p>Рассмотрим механизмы создания  реалистичного пламени, его взаимодействия с объектами игровой сцены и водой.  Вы можете <a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo-download">скачать исходный код </a>Smoke. Инструкции по сборке приложения находятся в подкаталоге smoke\docs архива с исходным кодом.</p>
<h2>Моделирование пламени</h2>
<p>Специалисты компьютерной графики  обратили внимание на тот факт, что рендеринг пламени в 3D как правило  обходится без моделирования физических свойств огня. Природная случайность и  турбулентность пламени часто моделируется с помощью систем частиц на основе  хорошо известных шума Перлина и распределения Гаусса. Это позволяет достигнуть адекватного  эффекта без учета физических свойств пламени, особенно если в сцене присутствует  более одного источника огня.</p>
<p>«Smoke» также  использует традиционную систему частиц, но при этом используется дополнительная  система, в которой огонь рассматривается как источник тепла. Этот тепловой  излучатель учитывает такие аспекты как распространение огня по горючим  материалам, его интенсивность в конкретной точке, взаимодействие источников тепла  с соседними источниками горючего.</p>
<h2>Реализация</h2>
<h2 class="sectionHeading">Объекты в Smoke</h2>
<p>Архитектура Smoke [2] использует различные  компоненты, которые мы будем называть «системы»,  которые выполняют типичные функции игрового  движка, такие как физика, графика, звук, искусственный интеллект и т.д.  Типичный игровой объект в Smoke является абстрактным объектом, привязанным  к нескольким системам. Например, лошадь на «Дымной» ферме привязана к следующим  системам:</p>
<ul>
<li>Графика скелетной анимации и  анимации модели</li>
<li> Геометрия позиционирования и  ориентации в пространстве</li>
<li> Физика обнаружений и контроля  столкновений</li>
<li> Звуковые эффекты</li>
</ul>
<p>Подобная структурная логика применима  ко всем объектам сцены, например, к падающим с неба метеорам, которые также  используют системы графики, физики, звука, плюс систему огня. Система огня отвечает  за физические свойства огня в программе и его графическое представление.</p>
<h2 class="sectionHeading">Система огня</h2>
<p><b>«Умные» частицы</b></p>
<p>Система огня состоит из двух  частей: эмиттер частиц на основе системы частиц, описанной в [1], которая  включает плоские текстуры пламени (частицы огня) и систему источника тепла,  которая моделирует тепловые свойства огня (тепловые частицы).</p>
<table align="center" border="0">
<tbody>
<tr>
<td align="center" width="200">Частицы огня</td>
<td align="center" width="200">Тепловые частицы</td>
</tr>
<tr>
<td ><img title="fire.JPG" src="http://software.intel.com/file/14812" alt="Частицы огня" /></td>
<td ><img title="heat.JPG" src="http://software.intel.com/file/14813" alt="Тепловые частицы" /></td>
</tr>
</tbody>
</table>
<p>Источник топлива, такой как  дерево, как правило, является достаточно сложным объектом, состоящим из  множества ветвей и розеток листьев. Хотя каждый геометрический объект может служить  источником топлива, в том числе метеоры. Таким образом, каждая ветка и розетка дерева  может служить носителем для системы частиц огня. Система использует выровненный  по осям ограничивающий блок (ВООБ, AABB = axis-aligned bounding box) носителя  не только для того, чтобы определять, где должны располагаться видимые частицы  огня, но и для проверки на столкновение частиц в источнике тепла. Как и при  настоящем пожаре, тепло распространяется вверх и в стороны от источника,  перемещаясь к вершине дерева с ветки на ветку, достигает вершины и затем  спускается вниз по кроне, как показано на рис. 1.</p>
<p><img src="http://software.intel.com/file/14814" alt="Система умных частиц – определение источника топлива" width="746" height="523" /></p>
<p><i>Рис. 1. Система умных частиц –  определение источника топлива</i></p>
<p><b>Распространяющийся огонь.</b></p>
<p>Метеоры – единственные объекты в  сцене, которые горят изначально, падая с неба и проходя через деревья или рядом  с ними. Деревья состоят из веток и розеток листьев, каждая из которых  представляет индивидуальный геометрический объект. Метеоры являются носителями  для системы огня, и, пролетая через сцену, некоторые из них проходят рядом с  элементами, также ассоциированными с системой огня. Если такой объект пока не  горит, алгоритм отслеживания столкновений системы огня зажжет его,  распространяя огонь по всему дереву и, возможно, на другие деревья сцены.<br /> Обнаружение столкновений  источников тепла является ресурсоемким вычислительным процессом, который хорошо  вписывается в параллельную архитектуру, ориентированную на задачи и специально разработанную  с учетом многоядерных процессоров. Каждый горящий объект содержит несколько  отдельных языков пламени, которые входят в видимую систему частиц и физическую  частицу источника тепла. В терминах обнаружения столкновений, частица огня представляет  собой луч, который и проверяется на пересечение с соседним ВООБом источника  топлива. Длина этого луча определяет температуру пламени. Объекты вне радиуса  действия этого луча исключаются из расчетов.</p>
<p><img src="http://software.intel.com/file/14815" alt="Система умных частиц – обнаружение столкновений" width="746" height="523" /></p>
<p><i>Рис. 2. Система умных частиц –  обнаружение столкновений</i></p>
<p>На рис. 2 показано, как  столкновение источника тепла с веткой «помечает» ее как горящую. Это активирует  излучатель видимых частиц и тепла этого объекта, позволяя огню  распространяться. Процесс продолжается до тех пор, пока огнем не будут охвачены  все источники топлива в пределах радиуса действия.<br /> Каждый горящий объект проверяется  на соприкосновение с соседними источниками топлива и тепла. Рассмотрим алгоритм  этой проверки в псевдо-коде:</p>
<pre name="code" class="plain:nogutter:nocontrols">For each Fire Object (each tree)<br /><br />For each Fire in  all Fire Objects (each branch)<br /><br />For each Heat  Emitter in each fire<br /><br />Check for  collision against the list of fuel sources<br /><br />If collision,  mark object as burning</pre>
<p>Внутренняя часть кода выполняет  тест на пересечение тепловых лучей источника тепла в дереве А и ветки дерева Б.  Поскольку тепловые частицы принадлежат источникам тепла в разных объектах, эти  горячие частицы переносятся в локальное пространство других геометрических  объектов, как показано на рис. 3.</p>
<p><img src="http://software.intel.com/file/14816" alt="Перенос и тест столкновения" width="746" height="481" /></p>
<p><i>Рис. 3. Перенос и тест столкновения</i></p>
<p><b>Параметры системы огня</b></p>
<p>Система огня использует набор  входных параметров для визуальной и теплоизлучающей систем частиц, которые определяют  специфичное поведение частиц:</p>
<ul>
<li> Тип (сферическое пламя  метеоров, линейное пламя веток, пламя неправильной формы для листьев)</li>
<li> Плотность огня</li>
<li> Размер (плоский)</li>
<li> Импульс</li>
<li> Сдвиг/импульс (изменение позиции  для определения направления пламени)</li>
<li> Время жизни</li>
</ul>
<p><b>Рендеринг огня, дыма и углей</b></p>
<p>Видимая система частиц, используемая  для рендеринга фрагментов огня, использует набор текстур, которые сменяют друг  друга пока частица существует, имитируя переход пламени в дым и искры. Искры вздымаются  над деревьями в виде факелов, реализованных в коде шейдера Ogre3D [3].</p>
<p><img src="http://software.intel.com/file/14817" alt="Огонь, дым и искры над  горящим деревом" width="746" height="560" /></p>
<p><i>Рис 4. Огонь, дым и искры над  горящим деревом</i></p>
<p><b>Вода</b></p>
<p>В приложении Smoke  имеется пожарный шланг, изображенный на рис.  5, который пользователь может «перетаскивать» по сцене, чтобы потушить огонь.</p>
<p>Как было отмечено в предыдущих  параграфах, каждый объект, в нашем случае – объект, привязанный к  геометрическому объекту дерева, проверяется, на столкновение (соприкосновение)  с каким-нибудь из источников тепла, в том числе с соседними негорящими ветвями.  Вода является естественным расширением системы огня, использующим дополнительные  проверки в коде обнаружения столкновений для тушения горящих элементов и  предотвращения распространения огня на соседние объекты.</p>
<p><img src="http://software.intel.com/file/14818" alt="Система огня – Вода" width="746" height="579" /></p>
<p><i>Рис. 5. Система огня – Вода</i></p>
<p>Так же как метеоры используют привязанную  к ним систему огня, настроенную в качестве источника тепла на поджог огня,  невидимые холодные объекты используют систему огня как источник холода, которые  вступают в соприкосновения с другими объектами системы огня. В Smoke используется  плагин ParticleFX из пакета Ogre3D [3] для скриптовой системы частиц. Контроль  столкновений происходит посредством системы огня,  привязанной к невидимым объектам, выпускаемым  с позиции камеры как скорострельные снаряды. Когда водяной объект проходит мимо  или сталкивается с горящим объектом, присоединенная система огня определяет, не  пересекает ли этот горящий объект какой-либо холодный луч, гася огонь.</p>
<p>Дополнительный плюс этого эффекта  в том, что невидимый объект воды также привязан к физической системе Havok [4],  что позволяет воде взаимодействовать с разрушаемыми элементами сцены, например  строениями.</p>
<h2>Заключение</h2>
<p>Демонстрационное приложение Smoke реализует  оригинальный подход к программному моделированию распространяющегося пламени,  включая графические и физические системы частиц, которые могут  взаимодействовать со сценой. Такая концепция прекрасно подходит для  произвольных объектов сцены, особенно в сочетании с параллельной архитектурой  игрового движка, который позволяет распределить трудоемкие расчеты столкновений  объектов между имеющимися в потоками.</p>
<p><b>Исходный код</b></p>
<p><a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo-download">Исходные коды Smoke</a> доступны для загрузки. Инструкции по сборке находятся в zip архиве с исходным кодом в директории Smoke\docs.</p>
<p><b>Планы на будущее</b></p>
<p>Текущая версия системы огня не содержит  несколько эффектов, которые могут быть добавлены в будущем:</p>
<ul>
<li> Разрушение горящих объектов с  течением времени</li>
<li> Повторное возгорание потушенных  объектов</li>
<li> Добавление наложений или  изменение текстур горящих и сгоревших объектов.</li>
</ul>
<h2>Ссылки</h2>
<p>[1] [Luna06]  Frank Luna. Introduction to 3D Game Programming with DirectX 9.0c: A Shader <br /> Approach.  Wordware Publishing Inc. <br /> [2] [Smoke08]  Ryan Shrout. “A Smoke Screen from Intel: Implementing multi-threaded <br /> gaming”. Intel  2008. <br /> [3] [Ogre3D08]  Ogre3D Open Source Object-Oriented Graphics Rendering Engine <br /> <a href="http://www.ogre3d.org/">http://www.ogre3d.org</a>. <br /> [4] [Havok08]  Havok Physics <a href="http://www.havok.com/">http://www.havok.com</a>.</p>
<h2>Об авторах</h2>
Хью Смит (Hugh Smith) старший  программист в группе Software Services Group, работает с независимыми производителями  игровых программ по внедрению оптимизации для графических и многоядерных систем  Интел в ведущие игровые продукты. Его электронный адрес<br /> hugh.a.smith в домене intel.com.
<p> </p>
<p>Джефф Фримен (Jeff Freeman)  программист в группе Software Solutions Group, где он работает с графическими  решениями Интел в отделе Visual Computing Software Division. Имеет степень  бакалавра компьютерных наук от Rensselaer Polytechnic Institute. Его  электронный адрес <br /> jeffrey.m.freeman в домене intel.com.</p>
<h2>Дополнительные изображения</h2>
<p><img src="http://software.intel.com/file/14819" width="746" height="560" /></p>
<p><img src="http://software.intel.com/file/14820" width="746" height="560" /></p>
<p><img src="http://software.intel.com/file/14821" width="746" height="560" /></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire/</link>
      <pubDate>Sun, 02 Aug 2009 13:00:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire/</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Зачем может понадобиться расширенный набор растровых операций  и как выбрать нужную</title>
      <description><![CDATA[ <p><strong>Автор:</strong> Михаил Трофимов (mt2)</p>
<p>Наверное все, кто когда-либо решал задачи программирования графики, знакомы с функцией API MS Windows BitBlt, которая позволяет эффективно скопировать битовый образ из одной области оперативной памяти (растра, bitmap) в другую. Обращение к этой функции выглядит следующим образом (здесь и далее мы используем Delphi-7; любителям других языков не составит труда сделать соответствующий перевод):</p>
<pre name="code" class="delphi:nogutter:"><br />function  BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; <br />                     SrcDC: HDC; XSrc, YSrc: Integer; <br />                     Rop: DWORD): BOOL;  stdcall; // unit Windows<br /></pre>
<p><br />где SrcDC, DestDC –области памяти: исходный растр и растр назначения, т.е. «откуда» и «куда», <br /> соответственно;</p>
<p>X, Y, Width, Height,  XSrc, YSrc – начало координат и размеры прямоугольной области для  <br /> «куда» и начало координат для «откуда»;</p>
<p>Rop – код растровой операции.</p>
<p>Об этом последнем параметре и пойдет речь. Но прежде чем рассказать о практической задаче на углубленное (или, если хотите, «продвинутое») использование этих операций, напомню, что в математике и в Computer Sci. графом называется конструкция, состоящая из непустого множества вершин и множества ребер, причем каждому ребру соответствует пара вершин, которая это ребро соединяет. В компьютере графы проще всего представляются с помощью матрицы смежности - двумерного массива булевского типа, где элемент (i,j) имеет значение true, если существует ребро, соединяющее вершины i,j, и false в противном случае. (Здесь речь идет о так называемых неориентированных графах. Подробнее о графах см. [1-3] .) Другим часто применяемым представлением графа является список смежности – список всех ребер, т.е. список соответствующих пар вершин. Однако для человеческого восприятия граф лучше нарисовать - это, в частности, показал недавно проводившийся конкурс Intel Threading Challenge – при решении задач на использование алгоритмов теории графов у участников сразу возник спрос на инструменты для их (графов) визуализации и редактирования. Для более основательных задач такие инструменты являются незаменимыми. На рисунке представлено фото экрана с одним из подобных инструментов – MT2GraphEdit-2004 (подробнее о нем см. [4]):</p>
<p><img src="http://software.intel.com/file/17436" alt="Инструмент визуализации графов MT2GraphEdit-2004" width="467" height="288" /></p>
<p>Вершины графа раскрашены в результате работы некоего алгоритма – пользователь MT2GraphEdit-2004 может писать фильтры (plugins) и таким образом испытывать свои алгоритмы, что называется, не «отходя от кассы» - нарисовал граф и запустил из меню свой фильтр. Но вот, готовя статью об одном таком алгоритме в научный журнал, я был вынужден обрабатывать это фото в Adobe PhotoShop - в журнале ведь иллюстрации черно-белые! Я изменил изображение графа следующим образом:</p>
<p><img src="http://software.intel.com/file/17437" alt="Измененное изображение графа" width="300" height="168" /><br />Т.е. вместо кружков, изображающих вершины, нарисовал графические примитивы: квадратики, ромбики, … , туз пик, наконец, чтобы каждая пиктограмма соответствовала определенному цвету. Сейчас, разрабатывая новый редактор графов MT2GE, я решил добавить эту опцию в программу: чтобы можно было как раскрашивать вершины графа, так и назначать им некий графический примитив – пиктограмму 16х16 из более чем сотни пиктограмм, находящихся в стандартном наборе редактора. Таким образом, передо мной возникла задача: в точке с координатами вершины программа должна рисовать соответствующую ей пиктограмму, закрашивая ее определенным по ходу работы программы цветом. И должна это делать достаточно быстро, чтобы всякие перерисовки при удалении и возвращении вершин, команды undo и redo не тормозили пользователя. Очевидное решение: копировать с помощью вышеупомянутой функции BitBlt соответствующий графический примитив в точку с координатами вершины, выбрав растровую операцию Rop такой, чтобы вершина закрашивалась цветом, установленным для кисти (brush) данного холста (canvas).</p>
<p><img src="http://software.intel.com/file/17438" alt="Вершины графа закрашены цветом" width="292" height="167" /><br />В любом элементарном учебнике по программированию графики для MS Windows есть список пятнадцати основных растровых операций с именами от cmBlackness до cmWhiteness – «собака зарыта» в слове «основных»: поиск в MSDN Lib приводит на страницу «Ternary Raster Operations» [5], где в таблице приведен их полный набор – 257 операций. Пытаясь решить свою задачу с помощью только основных операций, я получил следующий код (см. папку test1 из приложенного архива):</p>
<pre name="code" class="delphi">  ImageListBm.Draw(bm.Canvas,0,0,shape);<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0,srcand);<br />  BitBlt (bm.canvas.Handle,0,0,15,15, bm.Canvas.Handle,0,0,notsrccopy);<br />  bm.canvas.Brush.Color := color;<br />  BitBlt (bm.canvas.Handle,0,0,15,15, bm.Canvas.Handle,0,0,mergecopy);<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0,srcpaint);<br /></pre>
<p><img src="http://software.intel.com/file/17439" alt="Ребра графа" width="103" height="97" /></p>
<p>Забегая вперед, укажу альтернативное решение:</p>
<pre name="code" class="delphi">procedure TForm1.drawShape(x,y, shape, color : integer);<br />const<br />  ROP_PSDPxax = $00B8074A;<br />var<br />   bm : TBitmap;<br /><br />begin<br />  bm := TBitmap.Create;<br />  bm.Width := 16;<br />  bm.Height := 16;<br />  ImageListBm.Draw(bm.Canvas,0,0,0);<br />  canvas.Brush.Color := color;<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0, ROP_PSDPxax);<br />  bm.Free;<br />end;<br /><br /></pre>
<p>Здесь мы говорим о троичных растровых операциях (Ternary Raster Operations) – есть еще и двоичные (binary Raster Operations), но они для BitBlt не используются. Троичными эти операции называются потому, что оперируют с тремя операндами: с исходным растром (S), с кистью (P)  и с растром назначения (D). В набор операторов входят булевы функции: «И» (a), «НЕ» (n), «ИЛИ» (o), «исключающее ИЛИ» (x). Такой набор имеет свойство функциональной полноты, даже с некоторым избытком – меньший набор из этих функций также будет функционально полон. Это значит, что любая булева функция может быть представлена комбинацией функций набора. Далее, в растровых операциях булевы операции над пикселами растров представлены в так называемой польской записи, удобной для исполнения на стековой машине [6,7].  Например, растровая операция PSo есть операция «ИЛИ» над каждым пикселом кисти и исходного растра, вычисленное значение заменяет соответствующий пиксел в растре назначения. Каждая растровая операция представляется в виде 32-х битового целого числа, в котором старшее слово – индекс булевой операции (Operation index), а младшее – код операции. Индекс булевой операции – это расширенное (добавлением нулей до шестнадцати бит) восьмибитовое значение, представляющее собой комбинацию битов результата для таблицы истинности, соответствующей булевой функции для трех вышеназванных операндов  S, D и P. Например, для операции PSo этот индекс будет равен 00FC. Ниже будет описан инструмент, вычисляющий эту таблицу, и приведено фото панели этого инструмента с такой таблицей. Очевидно, что все возможные значения индексов лежат в диапазоне от 00 до FF, т.е. реализуются все возможные 256 операций плюс еще одна дополнительная NOMIRRORBITMAP с индексом за пределами этого диапазона.</p>
<p>Как выбрать нужную операцию из 257? Для этого я написал уже упомянутый инструмент ROP. Вот как он выглядит (с учетом добавленной в «фотошопе» разметки):</p>
<p><img src="http://software.intel.com/file/17440" alt="Инструмент ROP" width="467" height="371" /></p>
<p>С помощью кнопок “Load” (позиции 1,2 на рисунке) загружаем изображения для аргументов функции BitBlt: Dest  для DestDC и Source для SrcDC. Указываем позицию X, Y на изображении Dest (3), «нажав» в соответствующее место мышью. Задаем цвет кисти (4) и, выбрав приглянувшуюся растровую операцию (5) из списка результатов действия растровых операций на выбранные изображения, смотрим на результат (6). При этом в таблице истинности (7) табулируется выбранная логическая функция, ее представление в польской нотации отображается в поле (8), а в инфиксной форме – в поле (9), соответствующий шаблон для вызова BitBlt с этой операцией - в поле (10). Код функции и растровая операция отображаются в полях (11),(12) соответственно. Поле (13) показывает стандартное имя растровой операции, если такое имя существует. Для занесения информации из этих полей в буфер обмена достаточно нажать с помощью мыши на нужное поле. Можно сохранить выбранный результат с помощью кнопки “Save”, а также основную информацию о результате кнопками “Graphics Log”, “Text Log”. Можно решать и другую задачу: задать таблично желаемые значения функции, выделяя соответствующее поле таблицы (7) и вводя нужное значение 1 или 0 кнопками (14). Можно также провести поиск функции по значениям: “Op.index” (например - 1F), “r Polish” (например - PDSoan) или по имени (например - NOTSRCCOPY). Если поиск прошел удачно, индикатор слева от поля Find окрашивается в зеленый цвет, в противном случае – в красный. Кнопки “About” и “Exit” комментариев не требуют :)</p>
<p>С помощью этого инструмента я отобрал три решения своей задачи (см. папку test2 из приложенного архива):</p>
<p><img src="http://software.intel.com/file/17441" alt="3 решения задачи" width="207" height="53" /></p>
<p>То есть при обозначении вершины графа графическим примитивом «бублик» можно доводить линии, изображающие ребра этого графа, только до квадрата, описывающего этот примитив, а также продолжать или не продолжать ребра в «дырке бублика». В последнем случае без маски не обойтись. В программе я реализовал все три варианта, предоставив пользователю возможность выбирать нужный стиль в меню установок. С точки зрения теории графов все три стиля вполне приемлемы. Программа test2 измеряет время, затраченное на отрисовку этих решений, а также, для сравнения, время, затраченное на отрисовку кружка и буквы близких размеров стандартными методами. Результаты сопоставимы, буква рисуется медленнее. Таким образом, решение оказалось подходящим.</p>
<p>Графы один из важнейших объектов программирования – вспомним хотя бы, что списки и деревья – тоже графы. Поэтому необходимость изображения графов возникает достаточно часто в самых различных задачах. Схема метро, схема шоссейных и железных дорог, электросхема – все это графы. Кроме того, вывод разноцветных графических примитивов может понадобиться и во многих других задачах, например, для обозначений различных игровых единиц (units) на  игровой карте. Поэтому надеюсь, что данный инструмент окажется полезен многим программистам. Если читатели выскажут такое желание, то сюда же можно будет выложить и исходный код этого инструмента. Для этого мне нужно будет дописать в него дополнительные комментарии, чтобы легче было ориентироваться.</p>
<p>В заключение хочу поблагодарить всех, кто откликнулся на мой вопрос с горячим желанием помочь на сайте <a href="http://www.delphikingdom.com/">http://www.delphikingdom.com/</a></p>
<h3><a href="http://software.intel.com/file/17472/">Zip-архив  с файлами</a>:</h3>
<p>Паки test1, test2 – исходные коды и исполняемые файлы примеров.<br />Папка ROP – исполняемый файл инструмента ROP.</p>
<h3>Список литературы и Интернет-источников.</h3>
<ol type="1">
<li>Ф.Харари, Теория графов, М.:УРСС, 2003.</li>
<li>А.А.Зыков, Основы теории графов, М.:Вузовская книга, 2004.</li>
<li>В.Липский, Комбинаторика для программистов, М.:Мир, 1988.</li>
<li>М.И. Трофимов, Инструментальная программа редактирования молекулярных графов MT2 Graph Edit 2004 версия 1.8.1,3-й  Международный симпозиум "Компьютерное обеспечение химических исследований CACR-2006", IVTN-2006, Ярославль, 2006, с. 45. http://www.ivtn.ru/2006/biomedchem/enter/paper.php?p=441</li>
<li><a href="http://msdn.microsoft.com/en-us/library/dd145130(VS.85).aspx">http://msdn.microsoft.com/en-us/library/dd145130(VS.85).aspx</a></li>
<li>А. В. Ахо, Р. Сети, Д. Д. Ульман. <em>Компиляторы: принципы, технологии и инструменты.</em> М.: «Вильямс», 2003. С. 51.</li>
<li><a href="http://ru.wikipedia.org/?oldid=14808020">http://ru.wikipedia.org/?oldid=14808020</a></li>
</ol> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/extended-raster-operations-set/</link>
      <pubDate>Sun, 26 Apr 2009 13:00:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/extended-raster-operations-set/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/extended-raster-operations-set/</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Метод точного рендеринга частиц объема с помощью пиксельного шейдера</title>
      <description><![CDATA[ <p>Многие игры, даже работающие на современном «продвинутом»  оборудовании, рендерят частицы с помощью смотрящих на камеру прямоугольников (quads). В большинстве случаев  эти частицы представляют собой массивы других, более мелких частиц. Объем этих  мелких частиц эмулируется с помощью расчета того, сколько они привносят в  картину, используя простую функцию блендинга. Функция блендинга определяет,  насколько эмулированный объем частиц затеняет сцену за ним.</p>
<p>Такой имитации объема использовался в играх много лет, но в  данной статье мы рассмотрим другой метод, который использует шейдер для более  точной физической передачи частиц объема. Этот метод дает более точную  зрительную передачу эмулированных объемов и потенциально снижает необходимое  количество частиц, что в свою очередь повышает производительность рендеринга.</p>
<p>Для начала нужно заметить, что рассматриваемый метод  ограничивается частицами, которые представляют собой некоторое количество других  субчастиц, и что дальнейший анализ предполагает их равномерное распределение.  Существуют методы, которые позволяют пользователю определять функции для более  сложных объектов, но в рамках данной статьи мы их рассматривать не будем.  Многие игры имитируют такие эффекты как пыль, туман, газ, пламя, и так далее,  годами используя один и тот же метод. В частности, они определяют, насколько  частица заслоняет сцену позади нее, используя альфа-канал.</p>
<p>Альфа-канал служит для определения степени прозрачности, при  этом используется следующий алгоритм: результирующий цвет пиксела (Cr) интерполируется  некоторой функцией (А) между цветом окружения (Ci) и цветом частицы (Cp). В большинстве  случаев, которые я наблюдал, альфа канал определяет значение А, а сама функция  выглядит так:</p>
<p><strong>Cr = A*Cp + (1-A)*Ci; </strong></p>
<p><em>Основная функция интерполяции.</em></p>
<p>Что же не так с этой функцией? В ней используются две операции  сложения и две умножения, в большинстве случаев она рассчитывается аппаратно.  Она легка и проста в использовании.</p>
<p>Смотрящие на камеры полупрозрачные многоугольники, которые  рендерятся с использованием этой функции, эмулируют макроскопические объемы  микроскопических частиц. Если все сделано правильно, -  частицы должны быть отсортированы от заднего  плана к переднему, квады, на которые они рендерятся, не должны соприкасаться с  другими квадами сцены, и так далее, - при соблюдении ряда условий  эффект будет достаточен для эмуляции больших объемов  микроскопических частиц.</p>
<p>Правильность отрисовки зависит от команды художников, многие  движки сортируют частицы по мере рендеринга, так что здесь все в порядке. А что  произойдет, если частицы наложатся на другие объекты? Следствием того, что все  частицы рендерятся как смотрящие на камеру многоугольники, является тот факт,  что частицы практически не сталкиваются друг с другом. Чего нельзя сказать о  столкновении частиц с другими геометрическими объектами сцены.</p>
<p>В некоторых случаях частицы обрабатываются без оглядки на  буфер глубины, и это означает, что ничто не будет загораживать сами частицы. В  других случаях можно проверить столкновение каждой частицы с объектами  остального мира и сделать так, чтобы их не было. В целом же, в большинстве игр  артефакты, связанные с соприкосновением  частиц  и их окружения, считались приемлемыми.</p>
<p><img src="http://software.intel.com/file/15532" alt="Пример из Chrome Dragon Engine, который использует  режим модулированного блендинга для отображения частиц дыма" width="580" height="433" /></p>
<p><em>Рис. 1. Пример из Chrome Dragon Engine, который использует  режим модулированного блендинга для отображения частиц дыма.</em></p>
<p>К сожалению, из-за артефактов, которые возникают при таком  методе рендеринга частиц, художникам приходится прибегать к ухищрениям:</p>
<ol type="1">
<li>Обычно, на первом проходе расчета эффектов       объема художник создает частицы такого размера и плотности, которые ему       кажутся оптимальными. Когда же эффект добавляется в игру, сразу становится       понятно, что частицы получились слишком большими. При рендеринге художнику       приходится менять их внешний вид и подгонять таким образом, чтобы избежать       возможных столкновений с объектами окружения.</li>
<li>В случаях, когда нужны частицы,       расположенные близко к геометрическим объектам, художнику приходится не       только искусственно сжимать частицы, чтобы избежать существенных       артефактов, но и увеличивать количество частиц, чтобы заполнить образовавшееся       место. Как только количество частиц возрастает, нужно сразу менять значения       альфы в функции, чтобы компенсировать возросшее возможное  наложение частиц друг на друга.</li>
</ol>
<p>Это снижает планируемое разрешение альфа канала (и, в принципе, может вызывать артефакты  в картинке), делает сам эффект более зернистым и плотным, а хуже всего то, что  заставляет художника (а иногда и программиста) тратить время на исправление основной  интерполирующей функции.</p>
<p>Благодаря тому, что современного оборудования с избытком хватает  на базовые функции интерполяции, в большинстве игр артефакты столкновений  полупрозрачных частиц с окружением воспринимаются как приемлемые.</p>
<p>В комплектах разработчиков (SDK), таких как OpenGL или DirectX, определены методы рендеринга, которые  просто вызывали соответствующую функцию блендинга одной строчкой. К сожалению,  художники работали не покладая рук, пытаясь привнести базовые партикулярные  эффекты в игры и привыкли рассчитывать на эту строчку кода.</p>
<p>В последние годы произошел значительный прорыв в возможностях аппаратного  рендеринга: были изобретены шейдеры. Даже на дешевой графической плате  разработчик может определить практически любую функцию (обычно ограниченную  количеством свободных регистров и возможностями языка шейдера).</p>
<p>С помощью пиксельного шейдера, технологий рендеринга текстур, плюс  немного математики, мы можем точнее эмулировать объемы, которые раньше  изображали частицы. Проблема современных методов рендеринга частиц объема  в том, что они, как и почти вся геометрия  игры, плоские. Они представляют собой повернутые к камере плоскости,  обрабатываемые с предположением, что их толщина никогда не будет видна.</p>
<p>Таким образом, реальная глубина проявляется тогда, когда  эмулированная глубина (а точнее – ее отсутствие) оказывается рядом с действительно  объемными объектами. Проблема возникает из-за того, что мы отображаем глубину  на эти повернутые к камере многоугольники. Мы берем видимое представление объема  в пространстве, проецируем его на плоскость, затем рендерим плоскость обратно в  объемное пространство.</p>
<p>Предположим, что мы хотим решить эту проблему, не прибегая к существенному  изменению сложившегося порядка действий, которые художник предпринимает в  первый заход. Что нам нужно, чтобы лучше представить объем? Допущения и математика.  В данной статье мы рассмотрим следующие допущения:</p>
<ol type="1">
<li>Содержание каждой частицы имеет       равномерную плотность. То есть, если бы мы взяли пробу из настоящего       объема, из которого была взята текстура частицы, то её плотность была бы       равна плотности любой другой пробы из того же объема.</li>
<li>Существуют две границы с реальным       миром, неявно определенные для каждого пиксела в текстуре источника. Эти       границы – ближняя и дальняя границы объема, который представляется пикселом.</li>
<li>Существует плоскость, которая       определяет зеркальное изображение границы объема для каждого пиксела (это       допущение будет опущено в последующем примере).</li>
<li>Пользователь имеет доступ к значениям       глубины, заданным для сцены, перекрытой частицей в пиксельном шейдере.</li>
</ol>
<p>Мы также примем, что обрабатываемые пиксели многоугольника  представляют собой объемы, видимые с точки расположения камеры.</p>
<p>Идея в том, чтобы взять нарисованный полигон и определить  вокруг него псевдо объем, заданный границами многоугольника, продолженными в ту  сторону, куда смотрит камера.</p>
<p>В следующем примере для создания объема многоугольник  продолжен как в направлении камеры, так и от камеры на некоторое расстояние D.</p>
<p>Начальный многоугольник определяет зеркальную плоскость P(mi), альфа канал каждого  пиксела определяет, насколько граница  B(sp) субчастицы отклоняется  от P(mi). На практике объем был  бы определен как многоугольник, продолженный в противоположную от камеры  сторону, только для того, чтобы вполне воспользоваться аппаратным клиппингом.</p>
<p>Пикселы, перекрытые другими объектами, отбрасываются и не  участвуют в расчетах ближней части объема.</p>
<p><img src="http://software.intel.com/file/15533" alt="" width="580" height="250" /></p>
<p><em>Рис. 2.</em></p>
<p>Теперь для каждого пиксела в частице у нас имеется некоторое  пространство, вдоль всех лучей, проходящих через пиксель, которые и определяют  информацию о столкновении, необходимую, чтобы убрать элиасинг, вызванный плоскостью  частицы. Есть по меньшей мере два пути рассматривать информацию от  альфа-компонента текстуры:</p>
<ol type="1">
<li>Как среднюю плотность микроскопических       частиц в диапазоне от переднего до заднего края объема. Я буду называть       этот метод «методом средней плотности».</li>
<li>Как относительную плотность в       микроскопическом объеме вдоль луча, представленного пикселом. Я назову       этот метод «методом объемной плотности».</li>
</ol>
<p>Для работы шейдера нам потребуется знать глубину окружения в  районе данного пикселя. Эти данные могут передаваться как текстурная информация  от предыдущей стадии рендеринга текстуры. Назовем ее EnvironmentDepth.</p>
<p>Нам потребуется пиксельная позиция начального полигона,  который определяет нашу плоскость отражения. Она может быть получена от  вершинного шейдера. Назовем ее ParticleDepth.</p>
<p>Нам также потребуется функция маппинга от значения альфа к  реальной глубине, чтобы определить глубину девиации, назовем ее DeviationExtent. Скорее  всего, глубина девиации будет постоянной во всем многоугольнике и, возможно, во  всей частице.</p>
<p>Мы возьмем без изменений существующую текстуру частиц, с  цветом и значением альфа, как они были определены в начале.</p>
<p>Определим глобальную функцию прозрачности, которая будет  преобразовывать максимальную плотность частицы и актуальный пропуск цвета через  объем, которую назовем VolumeAlpha. Эта функция определяет  максимальную прозрачность/непрозрачность, какую позволяет объем.</p>
<p>Как следствие, мы сможем увеличить разрешение при расчете  прозрачности, нормализуя альфа канал текстуры частицы, и глобально модулировать  его со значение VolumeAlpha.</p>
<p>Это также позволит нам глобально менять прозрачность всех  частиц.</p>
<p>Теперь альфа канал определяет отношение девиации от плоскости  отражения к границам. Координаты положения частицы в реальном мире относительно  камеры определяются как ParticleDepth  -/+ DeviationExtent. Настоящая граница объема частицы определяется как ParticleDepth -/+ TextureAlpha * DeviationExtent.</p>
<p>Теперь мы можем определить более точное представление  скрывающих свойств частиц, с объектами позади, внутри и спереди нее.</p>
<p>Рассчитаем значения альфа, основываясь на предыдущих  выкладках.</p>
<p>FarParticleDepth = ParticleDepth +  TextureAlpha * DeviationExtent * 0.5;</p>
<p>NearParticleDepth = ParticleDepth - TextureAlpha * DeviationExtent * 0.5;</p>
<p><strong>Расчет средней плотности:</strong></p>
<p>// Get the Environment Depth in terms  of the volume, values we are interested</p>
<p>// in are in the range 0 to DeviationExtent.</p>
<p>Alpha = (EnvironmentDepth – ParticleDepth)/(DeviationExtent);</p>
<p>// Clamp the value to 0..1</p>
<p>Alpha = VolumeAlpha * Clamp( Alpha, 0.0, 1.0 );</p>
<p>// Get resultant pixel</p>
<p>OutputColour = Alpha * ParticleColour + (1.0 – Alpha) * SourceColour;</p>
<p><strong>Расчет объемной плотности:</strong></p>
<p>// Get the Environment Depth in terms  of the volume, values we are interested</p>
<p>// in are in the range 0 to DeviationExtent.</p>
<p>Range = (EnvironmentDepth – ParticleDepth)/(DeviationExtent);</p>
<p>// Scale this range based on the alpha value defined for the pixel</p>
<p>Range = Range *  (1.0/ParticleAlpha);</p>
<p>// Normalize the value to -1..1</p>
<p>Alpha = Clamp( Range, -1.0, 1.0 ) * 0.5 + 0.5;</p>
<p>Alpha = Alpha * VolumeAlpha;</p>
<p>// Get resultant pixel</p>
<p>OutputColour = Alpha * ParticleColour + (1.0 – Alpha) * SourceColour;</p>
<p>Эти алгоритмы используют простой метод интерполяции, который  много лет имеет аппаратную реализацию для случаев отсутствия столкновений. Если  же объемы частиц сталкиваются с окружающими объектами, алгоритм линейно увеличивает  вклад частицы в изменение фона на основе количества объема, закрытого фоном.</p>
<p><img src="http://software.intel.com/file/15534" alt="Экран из движка Chrome Dragon, полученный методом  средней плотности" width="580" height="431" /></p>
<p><em>Рис. 3. Экран из движка Chrome Dragon, полученный методом  средней плотности. (Та  же сцена, что и на рис. 1)</em></p>
<p><img src="http://software.intel.com/file/15535" alt="Экран из движка Chrome Dragon, полученный методом  средней плотности" width="580" height="431" /></p>
<p><em>Рис. 4. Экран из движка Chrome Dragon, полученный методом  объемной плотности. (Та  же сцена, что и  на рис. 1)</em></p>
<p>Применяя данный метод рендеринга частиц, следует иметь ввиду,  что рендерится представление объема и что глубина этого объема, скорее всего,  относится к другому измерению частицы. Возможно, было бы лучше определить  какую-нибудь функцию, переводящую размер частицы в глубину.</p>
<p>Про метод объемной плотности можно добавить, что объемы  используют альфа канал, чтобы определить границы объема для каждого пиксела. К  сожалению, в основном в частицах для изображения объема используется градиент  от центра текстуры, который грубо определяет объем в форме клина.</p>
<p>Как видно на рис.1, многие частицы имеют немного дефектный  вид. Чтобы исправить его, в картинке, возможно, придется определить альфа  компонент текстуры настоящими значениями объема.</p>
<p>Этот подход может быть распространен на:</p>
<ol type="1">
<li>Кодирование девиации от плоскости       отражения в один из каналов текстуры. Это позволит автору определять       альтернативную медиану глубины, назначая точку отражения как девиацию от       начальной плоскости частицы.</li>
<li>Кодирование нормальной объемной       информации в три канала текстуры и передача цвета объема как равномерного       для всей частицы. Это позволяет обрабатывать в шейдере информацию о       подсветке в реальном времени.</li>
</ol>
<p>Современные методы рендеринга объемных частиц полны  недостатков и скоро могут выйти из употребления. Но ситуацию можно исправить с  помощью реализованных в современной аппаратуре шейдеров. Плюс ко всему,  предложенные изменения существующих методов рендеринга требуют лишь незначительных  изменений в работе художников, добавляют незначительное количество регистров в  шейдер, малое число шейдерных инструкций и не требуют значительных изменений для  существующего механизма рендеринга в игре.</p>
<p>Самое важное, что частицы будут лучше отвечать замыслам  художников,  и, что возможно уменьшение количества  частиц без снижения качества изображения.</p>
<p> </p>
<h2>Библиография</h2>
<p>Spherical Billboards for Rendering Volumetric Data - ShaderX 5 - Thomas  Umenhoffer, Laslo Szirmay-Kalos and Gabor Szijarto</p>
<p>Volumetric Post-Processing - Game Programming Gems 5 - Dominic Filion,  Artificial Mind &amp; Movement, and Sylvain Boissé, Motorola</p>
<p>OpenGL Shading Language (Orange Book) - Randi J. Rost</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader/</link>
      <pubDate>Tue, 31 Mar 2009 14:00:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader/</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Проектируем архитектуру параллельного игрового движка</title>
      <description><![CDATA[ <a href="http://software.intel.com/file/8109">Разработка параллельной среды игрового движка (PDF)</a><a id="1" name="1"></a>
<h2>1. Введение</h2>
<p>С приходом на рынок многоядерных процессоров необходимость разработки игровых движков с поддержкой параллельных вычислений становится все более очевидной. Все еще возможно передавать основную нагрузку на графический процессор и использовать однопоточный движок, однако прирост производительности при использовании всех доступных в системе процессоров – как CPU, так и GPU – сулит куда более богатые возможности. Например, при использовании игрой нескольких CPU можно увеличить количество физических объектов (твердых тел), что придаст игре реалистичности, или разработать более «умный» искусственный интеллект, действия которого будут максимально приближены к человеческим.</p>
<a id="1.1" name="1.1"></a>
<h3>1.1. Обзор</h3>
<p>Говоря о дизайне параллельного игрового движка, мы подразумеваем, что параллельный, или многопоточный движок способен адекватно масштабироваться с учетом количества доступных на конкретной платформе процессоров. Масштабирование осуществляется за счет выполнения различных функциональных блоков в параллельном режиме, задействуя все доступные процессоры. На самом деле, это легче сказать, чем сделать: игровой движок включает множество частей, которые активно взаимодействуют друг с другом, в результате чего могут возникать различные ошибки многопоточности. При разработке движка такие взаимодействия необходимо принимать во внимание, предусматривая оптимальные механизмы синхронизации данных, предотвращающие блокировку при синхронизации. В движке также должно быть предусмотрено выполнение синхронизации данных в параллельном режиме, чтобы свести число последовательных операций к минимуму.</p>
<a id="1.2" name="1.2"></a>
<h3>1.2. Допущения</h3>
<p>В статье предполагается, что читатель имеет некоторые практические знания в области разработки современных компьютерных игр, а также опыт распараллеливания игровых движков или прикладных приложений.</p>
<a id="2" name="2"></a>
<h2>2. Режим параллельного выполнения</h2>
<p>Режим параллельного выполнения является краеугольным камнем эффективной многопоточной игровой среды. Чтобы добиться по-настоящему параллельной работы игрового движка, с минимальными затратами на синхронизацию, необходимо сделать так, чтобы каждая система работала в своем собственном режиме выполнения, как можно меньше взаимодействуя с другими системами движка. Конечно, при этом не обойтись без совместного доступа к данным. Однако, вместо того, чтобы каждая система обращалась к общим данным, например, за координатами положения или ориентации объекта, каждой системе следует предоставить свою копию данных. Это устранит взаимную зависимость разных частей движка от данных. Уведомления об изменениях, внесенных какой-либо частью в общие данные, передаются менеджеру состояний (State Manager), который помещает все изменения в очередь – это называется режимом обмена сообщениями (messaging). После того, как разные системы завершили свой очередной цикл выполнения, они обрабатывают сообщения от менеджера состояний, в соответствие с которыми обновляют свои внутренние структуры данных. Использование подобного механизма позволяет значительно сократить накладные затраты на синхронизацию, обеспечивая независимую работу систем.</p>
<a id="2.1" name="2.1"></a>
<h3>2.1. Режимы выполнения</h3>
<p>Менеджер состояний исполнения эффективен при синхронизации операций по определенному тактовому импульсу. Это позволяет всем системам синхронизироваться между собой своевременно. При этом частота синхронизации не обязательно должна соответствовать частоте кадров. Длительность тактов также не обязательно привязывать к какой-либо конкретной частоте, - она может быть выровнена по кадрам таким образом, что один такт соответствует времени, потраченному на завершения одного кадра (вне зависимости от его длительности). Иными словами, конкретная реализация менеджера состояний определяет частоту или длительность тактов.</p>
<p>На Рисунке 1 показано, как разные системы работают в «свободном режиме» пошагового выполнения (free step mode), при этом необязательно, чтобы все они завершали выполнение операции за один и тот же такт. Также возможен и жесткий режим пошагового выполнения (lock step mode, см. Рисунок 2), когда выполнение всех систем завершаются за один такт.</p>
<a id="fig1" name="fig1"></a><img src="http://software.intel.com/file/10886" border="0" alt="Состояние выполнения в свободном пошаговом режиме" width="625" height="353" />
<p>Рисунок 1: Состояние выполнения в свободном пошаговом режиме</p>
<a id="2.1.1" name="2.1.1"></a>
<h3>2.1.1. Свободный пошаговый режим</h3>
<p>Этот режим выполнения позволяет всем подсистемам непрерывно работать в течение времени, требуемого им для завершения очередной порции вычислений. Название «свободный» не следует понимать буквально - подсистемы синхронизируются не в произвольный момент времени, они лишь, «свободны» в выборе необходимого числа тактов.</p>
<p>Как правило, в этом режиме недостаточно послать менеджеру состояний простое уведомление об изменении состояния, - вместе с уведомлением об изменении состояния потребуется также передать данные. Это вызвано тем, что система, которая изменила общие данные, может находиться в состоянии выполнения, в то время как другая система, ожидающая эти данные, уже готова выполнить обновление. В этом случае требуется больше памяти т.к. нужно создавать больше копий данных. Поэтому «свободный» режим нельзя считать универсальным решением на все случаи жизни.</p>
<a id="2.1.2" name="2.1.2"></a>
<h3>2.1.2. Жесткий пошаговый режим</h3>
<p>Этот режим подразумевает, что выполнение задач всех систем завершается за один такт. Такой механизм проще в реализации и не требует передачи данных с уведомлением, поскольку система, которая зависит от изменений, сделанных другой системой, может просто запросить нужную переменную у другой системы (разумеется, в конце цикла выполнения).</p>
<p>При жестком режиме также можно реализовать псевдо-свободный пошаговый режим операций, путем чередования вычислений между различными шагами. В частности, это может потребоваться для расчетов ИИ, где за первый такт вычисляется начальная «общая цель», а затем производится расчет некоторой более детальной цели, вытекающей из начальной.</p>
<a id="fig2" name="fig2"></a><img src="http://software.intel.com/file/10887" border="0" alt="Состояние выполнения в жестком пошаговом режиме" width="625" height="353" />
<p>Рисунок 2: Состояние выполнения в жестком пошаговом режиме</p>
<a id="2.2" name="2.2"></a>
<h3>2.2. Синхронизация данных</h3>
<p>Вероятна ситуация, когда несколько подсистем изменяют одни и те же общие данные. Чтобы разрешить проблему конкурентных изменений обмен сообщениями должен предусматривать некий механизм, позволяющий определять приоритет изменений. Существуют два подхода:</p>
<ul type="disc">
<li>Время – правильное значение хранится в подсистеме, сделавшей последнее изменение. </li>
<li>Приоритет – правильное значение принадлежит системе, имеющей наибольший приоритет. Этот механизм может сочетаться с временным механизмом (для обработки изменений, внесенных подсистемами с одинаковым приоритетом). </li>
</ul>
<p>Данные, признанные устаревшими с точки зрения обоих механизмов, могут быть просто перезаписаны или исключены из очереди уведомлений.</p>
<p>В случае, если данные являются общими, использование различными системами относительных значений может быть затруднительно, так как при синхронизации возникает зависимость от хронологического порядка их поступления. Поэтому везде, где это требуется, следует использовать абсолютные значения. Тогда при обновлении своих локальных данных все подсистемы могут просто заменить старые значения новыми. Оптимальным решением может стать также сочетание абсолютных данных с относительными, в зависимости от конкретной ситуации. Например, общие данные, такие как координаты положения и ориентации, должны иметь абсолютные значения, так как конечные матрицы преобразования зависят от хронологии поступления данных. А, к примеру, подсистема генерации частиц, (являющаяся единственным владельцем информации о частицах) может посылать обновления относительных значений.</p>
<a id="3" name="3"></a>
<h2>3. Движок</h2>
<p>При проектировании движка основное внимание следует уделять его гибкости, обеспечивающей легкое расширение функциональности. Такой подход позволит относительно легко модифицировать движок для работы на платформах, имеющих те или иные ограничения, например, ограничения по памяти. В целом движок состоит из двух частей - оболочки и набора «менеджеров». Оболочка (раздел 3.1) содержит части игры, которые тиражируются в процессе выполнения, т.е. существуют в нескольких экземплярах. В нее также входят элементы, участвующие в выполнении основного цикла игры. Менеджеры (раздел 3.2) представляют собой одноэлементные (singleton) объекты, с которыми взаимодействует логическая часть игры.</p>
<p>На приводимой ниже схеме представлены части игрового движка:</p>
<a id="fig3" name="fig3"></a>
<p><img src="http://software.intel.com/file/10888" border="0" alt="Высокоуровневая архитектура движка" width="627" height="351" /></p>
<p>Рисунок 3: Высокоуровневая архитектура движка</p>
<p>Заметим, что функциональные блоки, относящиеся непосредственно к игре, рассматриваются как отдельный от движка элемент. Это и обеспечивают необходимую гибкость, обеспечиваемую тем, что сам движок играет роль «клея», соединяющего функциональные части. Модульность также позволяет загружать или выгружать системы по мере необходимости.</p>
<p>Интерфейсы представляют собой средство связи между движком и системами. Со стороны системы, интерфейс необходим для того, чтобы предоставить движку доступ к функционалу системы, а со стороны движка – для того, чтобы системы могли взаимодействовать с менеджерами.</p>
<p>Общее представление о такой блочной организации можно получить из Приложения А, «Пример схемы движка». Как указывалось в разделе 2 «Режим параллельного выполнения», системы, по своей сути, являются дискретными элементами. Благодаря этому они могут работать параллельно без вмешательства в работу других систем. В то же время, это порождает определенные проблемы в тех случаях, когда системам необходимо обмениваться информацией, ведь данные необязательно находятся в стабильном состоянии. Обмен информацией между системами может потребоваться по следующим двум причинам:</p>
<ul type="disc">
<li>Чтобы сообщить другой системе об изменении, внесенном в общие данные (например, координаты положения или ориентации объектов), </li>
<li>Чтобы запросить некоторые функции, недоступные в рамках конкретной системы (например, система расчета ИИ обращается к системе расчета геометрии/физики для проверки пересечения лучей). </li>
</ul>
<p>Первая проблема коммуникации между системами решается путем реализации менеджера состояний, как было описано в предыдущем разделе. Более подробно работа менеджера состояний рассматривается в разделе 3.2.2 «Менеджер состояний».</p>
<p>Для решения второй проблемы в системе предусматривается механизм для предоставления служб, которые могут потребоваться другой системе. Более подробное описание этого механизма содержится в разделе 3.2.3 «Менеджер служб».</p>
<a id="3.1" name="3.1"></a>
<h3>3.1. Оболочка</h3>
<p>Оболочка (внутренняя интегрированная среда) служит для объединения всех элементов движка. В оболочке происходит инициализация движка, за исключением менеджеров, экземпляры которых создаются глобально. В ней также хранится информация о сцене. Для обеспечения большей гибкости сцена реализуется в виде так называемой универсальной сцены, которая содержит универсальные объекты, представляющие собой контейнеры для соединения воедино различных функциональных частей сцены. Более подробное описание среды приводится в разделе 3.1.2.</p>
<p>Цикл игры также выполняется в оболочке и имеет следующий порядок:</p>
<a id="fig4" name="fig4"></a>
<p><img src="http://software.intel.com/file/10889" border="0" alt="Основной цикл игры" width="625" height="294" /></p>
<a id="3.1.1" name="3.1.1"></a>
<p>Рисунок 4: Основной цикл игры</p>
<p>На первом этапе цикла игры происходит обработка всех ожидающих сообщений окон операционной системы, так как движок, как правило, выполняется в оконной среде. Без этого движок не реагировал бы на вызовы операционной системы. На следующем этапе планировщик назначает задачи систем с помощью менеджера задач. Более подробно данный этап рассматривается в разделе 3.1.1 ниже. На последующем этапе все изменения, обработанные менеджером состояний (подробное описание в разделе 3.2.2), передаются требуемым элементам движка. На заключительном этапе интегрированная среда проверяет статус выполнения, определяя, следует ли завершить работу движка либо продолжить выполнение каких-либо операций, например, для перехода к следующей сцене. Статус выполнения движка хранится в менеджере окружения, описание которого приводится в разделе 3.2.4.</p>
<a id="3.1.2" name="3.1.2"></a>
<h3>3.1.1. Планировщик</h3>
<p>Планировщик генерирует опорный тактовый сигнал выполнения с заданной частоты. Тактовый сигнал также может поступать в «свободном» режиме, например, для режима бенчмарка. В таком режиме следующая операция начинается сразу после выполнения предыдущей, без ожидания истечения времени такта.</p>
<p>Планировщик передает системы на выполнение через менеджер задач за один такт генератора. В свободном пошаговом режиме (раздел 2.1.1) планировщик опрашивает системы, определяя, сколько тактовых шагов им понадобится, чтобы завершить выполнение. На основании опроса, планировщик определяет, какие системы готовы к выполнению, а какие завершат работу в конкретный шаг тактового генератора. Количество шагов может быть изменено планировщиком в том случае, если какой-либо системе требуется больше времени на выполнение. В жестком пошаговом режиме (раздел 2.1.2) все системы начинают и заканчивают исполнение в один тактовый шаг, соответственно, планировщик ожидает, когда завершится выполнение всех систем.</p>
<a id="fig5" name="fig5"></a>
<h3>3.1.2. Универсальная сцена и объекты</h3>
<p>Универсальная сцена и объекты выполняют функцию контейнеров функциональных блоков, реализованных в рамках определенных систем. Сами по себе, универсальная сцена и объекты не имеют никаких функций, кроме способности взаимодействовать с движком. Тем не менее, они должны быть достаточно гибкими, чтобы поддержать все доступные в той или иной системе функции. Таким образом, универсальная сцена и универсальные объекты не привязаны к конкретной системе, и обеспечивают свободное взаимодействие систем. Преимущество такого подхода заключается в независимости систем друг от друга, а следовательно - возможности их параллельной работы.</p>
<p>На приведенной ниже схеме показаны контейнеры универсальной сцены и универсального объекта:</p>
<p><img src="http://software.intel.com/file/10890" border="0" alt="Универсальная сцена и универсальный  объект" width="626" height="294" /></p>
<a id="3.2" name="3.2"></a>
<p>Рисунок 5: Универсальная сцена и универсальный объект</p>
<p>Принцип работы надстройки можно проиллюстрировать на следующем примере: универсальная сцена включает параметры графики, физики и других систем. Графическая часть сцены в таком случае отвечает за инициализацию дисплея и другие графические процедуры, физическая часть - за взаимодействие твердых тел, силу тяжести и т.п. Сцена содержит объекты, поэтому в универсальной сцене будет присутствовать несколько универсальных объектов. Универсальные объекты также могут быть включать параметрами графики, физики и т.п. Таким образом, графическая часть объекта будет отвечать за прорисовку объекта на экране, физическая - за взаимодействие твердого тела объекта с другими твердыми телами.</p>
<p>Более подробная схема взаимодействия движка с системами приводится в Приложении B - «Схема связи движка и системы».</p>
<p>Следует заметить, что универсальная сцена и универсальный объект отвечают за регистрацию всех своих «надстроек» в менеджере состояний, с тем, чтобы все надстройки получали уведомления об изменениях, внесенных другими надстройками (т.е. другими системами). В качестве примера можно привести графическую часть, которая регистрируется в менеджере для получения данных об изменениях, вносимых физической частью координаты положения и ориентации.</p>
<p>Дополнительная информация о компонентах системы приводится в Разделе 5.2 «Компоненты системы».</p>
<h3>3.2. Менеджеры</h3>
<p>Менеджеры обеспечивают поддержку глобальных функций в рамках движка и реализуются в виде singleton-объектов, иными словами, менеджер каждого типа доступен только в одном экземпляре. Это обусловлено тем, что дублирование ресурсов менеджеров неизбежно приведет к избыточности и отрицательно скажется на производительности. Менеджеры также предоставляют общую функциональность, которая востребована всеми системами.</p>
<a id="3.2.1" name="3.2.1"></a>
<h3>3.2.1. Менеджер задач</h3>
<p>Менеджер задач отвечает за упорядочение системных задач в рамках пула потоков. В пуле потоков создается по одному потоку на процессор, чтобы обеспечить оптимальное n-кратное масштабирование и предотвратить назначение излишних потоков, исключая неоправданные издержки переключения задач в операционной системе.</p>
<p>Менеджер задач получает от планировщика список задач для выполнения, а также информацию о том, завершения каких задач необходимо дождаться. Планировщик, в свою очередь, получает список задач от разных систем. На каждую систему выделяется только одна главная задача - данный метод называется «функциональная декомпозиция». Однако, в рамках каждой главной задачи допускается порождать необходимое количество подзадач для обработки данных (что определяется спецификой системы), таким образом внутри системы вполне может быть реализована «декомпозиция по данным».</p>
<p>На приведенной ниже схеме приводится пример того, как задачи могут быть распределены менеджером задач между потоками для выполнения на четырехъядерной системе:</p>
<a id="fig6" name="fig6"></a>
<p><img src="http://software.intel.com/file/10891" border="0" alt="Пример пула потоков в менеджере  задач" width="625" height="264" /></p>
<a id="3.2.2" name="3.2.2"></a>
<p>Рисунок 6: Пример пула потоков в менеджере задач</p>
<p>Помимо обработки запросов планировщика, менеджер задач может опрашивать системы последовательно в каждом из потоков, в результате чего системы получают доступ к локальной памяти потоков.</p>
<p>Некоторые детали реализации менеджера задач можно найти в Приложении D – «Советы по реализации задач».</p>
<h3>3.2.2. Менеджер состояний</h3>
<p>Управление состояниями – это часть механизма обмена сообщениями, которые позволяет отслеживать внесенные системами изменения и распространять уведомления о них среди других задействованных систем. В целях сокращения числа уведомлений, системы должны быть зарегистрированы в менеджере состояний для отслеживания нужных им изменений. Данный механизм основывается на так называемой «модели наблюдателя» (observer design pattern), которая более детально рассматривается в Приложении C – «Модель наблюдателя». Вкратце, модель наблюдателя предполагает использование объекта-наблюдателя, который следит за изменениями в субъекте, при этом роль посредника между ними выполняет менеджер изменений.</p>
<p>Данный механизм работает следующим образом:</p>
<p>1) Наблюдатель регистрирует субъект, за изменениями в котором он планирует вести наблюдение, в менеджере изменений (или менеджере состояний);</p>
<p>2) когда субъект изменяет какое-либо из своих свойств, он направляет уведомление об изменении в менеджер изменений;</p>
<p>3) менеджер изменений выдает уведомление об изменении в субъекте наблюдателю по сигналу оболочки</p>
<p>4) наблюдатель запрашивает у субъекта фактически измененные данные.</p>
<p>Свободный пошаговый режим выполнения (Раздел 2.1.1) вносит в этот механизм некоторые сложности. Во-первых, вместе с уведомлением об изменении потребуется передать и данные, так как система, которая внесла изменение в общие данные, может все еще выполняться и поэтому у нее нельзя запросить итоговое значение. Во-вторых, если система еще не готова к тому, чтобы получить изменения в конце тактового шага, менеджеру состояний потребуется удерживать измененные данные до тех пор, пока все зарегистрированные для их получения системы не придут в состояние готовности.</p>
<p>В оболочке реализуется два менеджера состояний, один из которых оперирует изменениями на уровне сцены, а другой - изменениями на уровне объекта. Это обусловлено тем, что сцена и объекты, в большинстве случаев, используют различные сообщения, относящиеся к их работе, поэтому разделение менеджеров снимает необходимость обработки лишних сообщений. В то же время, любые изменения объекта, имеющие отношение к сцене, будут зарегистрированы в сцене, и таким образом она будет получать соответствующие уведомления об изменениях.</p>
<p>Чтобы устранить накладные расходы на синхронизацию, менеджер состояний создает очередь изменений для каждого потока, создаваемого менеджером задач. Поэтому при доступе к очереди никакой синхронизации не требуется. По завершении выполнения очереди могут быть объединены с помощью методов, рассмотренных в Разделе 2.2.</p>
<a id="fig7" name="fig7"></a>
<p><img src="http://software.intel.com/file/10892" border="0" alt="Уведомление о внутренних изменениях UObject" width="368" height="162" /></p>
<p>Рисунок 7: Уведомление о внутренних изменениях UObject</p>
<p>Хотя вам может показаться, что уведомления об изменениях придется распространять в последовательном режиме, существует возможность их распараллеливания. Когда системы выполняют свои задачи, они выполняют операции над всеми своими объектами. Например, физическая система управляет перемещением объектов, проверяя их на предмет столкновения и задавая новые параметры ускорения и т.п., по мере того, как физические объекты взаимодействуют друг с другом. Во время уведомления об изменении объект системы больше не взаимодействует с другими объектами в рамках своей системы, а взаимодействует с другими настройками универсального объекта, с которым он ассоциируется. Это значит, что универсальные объекты теперь независимы друг от друга, и каждый универсальный объект может обновляться в параллельном режиме. Следует заменить, что возможны некоторые нетипичные ситуации, которые следует учитывать в процессе синхронизации. Тем не менее, у вас все же появляется шанс добиться частично параллельной работы того, что на первый взгляд было возможно только в последовательном режиме.</p>
<a id="3.2.3" name="3.2.3"></a>
<h3>3.2.3. Менеджер сервисов</h3>
<p>Менеджер сервисов предоставляет некоторым системам доступ к определенным функциям, которые не реализованы внутри самих систем. Необходимо заметить, что менеджер сервисов реализует это опосредованно, через соответствующие интерфейсы. Таким образом, каждая система, содержащая функциональность предоставленного интерфейса, регистрируется в менеджере сервисов.</p>
<p>В менеджере сервисов доступен лишь небольшой набор сервисов, поскольку структура движка направлена на то, чтобы поддерживать как можно более дискретную работу систем. Кроме того, системы не могут предоставлять любой сервис по своему усмотрению, необходимо строгое использование менеджера сервисов.</p>
<a id="fig8" name="fig8"></a>
<p><img src="http://software.intel.com/file/10893" border="0" alt="Пример работы менеджера сервисов" width="405" height="135" /></p>
<p>Рисунок 8: Пример работы менеджера сервисов</p>
<p>Другой задачей менеджера сервисов является предоставление разным системам доступа к свойствам друг друга. Свойства – это специфичные для каждой системы значения, которые не передаются при обмене сообщениями. Например, такими свойствами является разрешение экрана в графической системе, или значение силы тяжести в физической системе. Менеджер сервисов предоставляет разным системам доступ к этим свойствам, в то же время, не позволяя непосредственно управлять ими. Он также следит за тем, чтобы все изменения свойств помещались в очередь и публиковались только в случае последовательного выполнения. Следует учитывать, что доступ к свойствам другой системы требуется достаточно редко и является исключительным случаем. Это может понадобиться, например, при открытии окна консоли, для того, чтобы включить/выключить режим каркасной сетки в графической системе, или для системы интерфейса пользователя, чтобы изменить требуемое разрешение экрана. Фактически, данная возможность используется для установки параметров, которые не изменяются от кадра к кадру.</p>
<a id="3.2.4" name="3.2.4"></a>
<h3>3.2.4. Менеджер среды</h3>
<p>Менеджер среды (окружения) обеспечивает функциональность среды выполнения движка. К числу предоставляемых менеджером среды функциональных групп относятся:</p>
<ul type="disc">
<li>Переменные – имена переменных и данные, совместно используемые в масштабах всего движка. Переменные обычно задаются при загрузке сцены или определенных настроек пользователя и запрашиваются движком или различными системами. </li>
<li>Выполнение – данные о статусе выполнения, например, о завершении сцены или завершении программы. Эти параметры могут быть заданы и запрошены как движком, так и системами. </li>
</ul>
<a id="3.2.5" name="3.2.5"></a>
<h3>3.2.5. Менеджер платформы</h3>
<p>Менеджер платформы обрабатывает все абстракции вызовов операционной системы, а также обеспечивает некоторую дополнительную функциональность. Преимуществом такого подхода является возможность поместить несколько типичных действий в рамки одного вызова, снимая необходимость отдельных имплементаций во всех вызывающих системах.</p>
<p>В качестве примера можно привести загрузку динамической библиотеки какой-либо системы. Помимо загрузки системы, менеджер также получает данные о точке входа функции и затем вызывает функцию инициализации библиотеки. В нем также предусмотрен дескриптор (handle) библиотеки. После завершения движка библиотека выгружается.</p>
<p>Менеджер платформы также отвечает за предоставление информации о процессоре, например, о поддерживаемых SIMD-инструкциях и подобных параметрах..</p>
<a id="4" name="4"></a>
<h2>4. Интерфейсы</h2>
<p>Интерфейсы являются средством взаимодействия оболочки, менеджеров и систем. Оболочка и менеджеры располагаются в самом движке, поэтому оболочка имеет прямой доступ к менеджерам. Системы же находятся за рамками движка и отличаются по функциональности. Таким образом, возникает необходимость общего способа работы с ними. С другой стороны, системы не могут напрямую работать с менеджерами, им необходим некий способ обращения к менеджерам, хотя и необязательно к полной их функциональности (поскольку некоторые элементы менеджеров доступны только для оболочки).</p>
<p>Интерфейсы предлагают функциональность, которая необходима для унификации обращений. Таким образом, оболочка «знает» детали каждой системы и может общаться с ней посредством определенного набора вызовов.</p>
<a id="4.1" name="4.1"></a>
<h3>4.1. Интерфейсы субъекта и наблюдателя</h3>
<p>Интерфейсы субъекта и наблюдателя используются для регистрации наблюдателя в субъекте и передачи уведомлений об изменениях от субъекта к наблюдателю. Также необходим «субъект по умолчанию», поскольку функциональность по управлению регистрацией/и исключением наблюдателя является общей для всех субъектов.</p>
<a id="4.2" name="4.2"></a>
<h3>4.2. Интерфейсы менеджеров</h3>
<p>Доступ к менеджерам, хоть они и являются одноэлементными объектами, напрямую имеет только оболочка. Системы имеют опосредованный доступ к менеджерам, так как иначе каждый менеджер должен был бы иметь специальный интерфейс. Такой интерфейс необходимо было бы передавать в каждую систему при ее инициализации, а это неэффективно.</p>
<p>Отметим, что интерфейс каждого менеджера специфичен для конкретного менеджера, а, следовательно, не является универсальным.</p>
<a id="4.3" name="4.3"></a>
<h3>4.3. Системные интерфейсы</h3>
<p>Системам необходимы интерфейсы, чтобы оболочка получила доступ к их компонентам. Без интерфейса оболочке пришлось бы поддерживать определенную реализацию каждой новой системы, которая добавляется в движок.</p>
<p>В системе содержатся четыре компонента, поэтому системе необходимо реализовать четыре интерфейса: сама система, сцена, объект и задача. Данные компоненты рассматриваются в разделе 5 «Системы». Интерфейсы – это средства доступа к таким компонентам. Системный интерфейс предлагает способы создания или уничтожения сцен. Интерфейсы сцен обеспечивают способы создания и уничтожения объектов, а также способ получения «главной задачи». Интерфейс задач используется менеджером задач при постановке задач в пул потоков.</p>
<p>Интерфейсы сцен и объектов также являются производными интерфейсов субъектов и наблюдателя, поскольку они являются частями системы, которые должны взаимодействовать друг с другом и с универсальной сценой и объектом, к которым они прикреплены.</p>
<a id="4.4" name="4.4"></a>
<h3>4.4. Интерфейсы изменений</h3>
<p>Также существуют некоторые особые интерфейсы, используемые для передачи данных между системами. Любые системы, производящие определенные изменения, также должны реализовать данный интерфейс. Примером интерфейса такого типа является геометрия. Интерфейс геометрии получает данные по положению, ориентации и масштабу по каждому элементу. Любые системы, вносящие изменения в геометрию, должны реализовать данный интерфейс, чтобы разные системы могли обращаться к изменениям геометрии, при этом им не будет нужно знать о других системах.</p>
<a id="5" name="5"></a>
<h2>5. Системы</h2>
<p>Системы – это то, что обеспечивает игровую функциональность движка. Чтобы избавить движок от необходимости знать все типы систем, они должны реализовать интерфейсы, описанные в пункте 4.3 «Системные интерфейсы». Это существенно облегчает процесс добавления новой системы в движок.</p>
<a id="5.1" name="5.1"></a>
<h3>5.1. Типы</h3>
<p>Движок должен иметь несколько предварительно заданных типов систем, которые подходят для стандартных компонентов игры. Например, - геометрия, графика, физика (столкновение твердых тел), аудио, ввод, ИИ и анимация.</p>
<p>Для систем, реализующих функциональность за рамками общих функциональных блоков игры, рекомендуется создавать специализированный тип. Отметим, что любые системы, которые изменяют конкретные данные специализированных типов, должны знать об интерфейсе специализированного типа, поскольку движок не предоставляет такую информацию.</p>
<a id="5.2" name="5.2"></a>
<h3>5.2. Компоненты системы</h3>
<p>Система содержит несколько компонентов, которые необходимо реализовать. Такими компонентами являются: система, сцена, объект и задача. Все компоненты используются для взаимодействия с различными частями движка.</p>
<p>На следующей схеме показана связь между компонентами:</p>
<a id="fig9" name="fig9"></a>
<p><img src="http://software.intel.com/file/10894" border="0" alt="Связь между компонентами системы" width="625" height="219" /></p>
<p>Схема 9: Компоненты системы</p>
<p>Более подробная схема связи систем с движком содержится в Приложении А «Схема связи движка и систем».</p>
<a id="5.2.1" name="5.2.1"></a>
<h3>5.2.1. Система</h3>
<p>Компоненты «система» отвечает за инициализацию системных ресурсов, которые будут оставаться более или менее постоянными в течение периода работы движка. Примером этого является графическая система, анализирующая все адреса ресурсов для определения места их нахождения для ускорения загрузки после использования ресурса. Разрешение экрана также может задаваться графической системой.</p>
<p>Система также является главной точкой ввода данных для оболочки и предоставляет информацию о себе (например, сведения о своем типе), а также обеспечивает способы создания и уничтожения сцен.</p>
<a id="5.2.2" name="5.2.2"></a>
<h3>5.2.2. Сцена</h3>
<p>Компонент «сцена», иногда называемый «системной сценой», отвечает за управление ресурсами, относящимися к текущей сцене. Универсальная сцена использует системные сцены для расширения своей функциональности, наследуя свойства, предлагаемые данной системной сценой. Примером данного компонента является физическая сцена, создающая новый мир и задающая гравитацию для мира при инициализации сцены.</p>
<p>Сцена также предлагает способы создания и уничтожения объектов. Она также управляет компонентом задач, который используется для работы на сцене, и предлагает способ его получения.</p>
<a id="5.2.3" name="5.2.3"></a>
<h3>5.2.3. Объект</h3>
<p>Компонент «объект», также называемый «системным объектом», представляет собой объект в сцене и обычно связан с тем, что пользователь видит на экране. Универсальный объект использует системные объекты для расширения своей функциональности, таким образом, свойства объектов системы доступны в универсальном объекте.</p>
<p>Примером: допустим, есть универсальный объект, унаследовавший свойства геометрии, графики и физики для создания на экране деревянного бруса. Геометрия отвечает за информацию о положении, ориентации и масштабе, система графики выводит его на экран с помощью заданной сетки, а физическая система применяет к нему алгоритм столкновения твердых тел, чтобы он взаимодействовал с другими твердыми брусьями и системой гравитации.</p>
<p>В определенных ситуациях системный объект может быть связан с изменениями другого универсального объекта или одного из его расширений. В этом случае можно создать ссылку с тем, чтобы системный объект мог наблюдать за другим объектом.</p>
<a id="5.2.4" name="5.2.4"></a>
<h3>5.2.4. Задача</h3>
<p>Компонент задач, именуемый системной задачей, отвечает за действия в сцене. Когда задача получает команду обновиться от менеджера задач, она выполняет функции системы в отношении объектов на данной сцене.</p>
<p>Задача также может разделить исполнение на подзадачи и спланировать подзадачи в менеджере задач для дальнейшего распараллеливания. Это позволяет движку легче масштабироваться под конфигурацию с несколькими процессорами. Данная техника называется декомпозицией данных.</p>
<p>Какие-либо изменения объектов записываются менеджером состояний в период обновления задачи сцены. Подробная информация о менеджере задач содержится в пункте 3.2.2.</p>
<a id="6" name="6"></a>
<h2>6. Связываем все вместе</h2>
<p>Даже относительно поверхностное изложение концепции параллельного игрового непросто воспринять за один раз, тем более, что различные его части очень тесно взаимодействуют друг c другом. Давайте зайдем с другой стороны, и рассмотри работу движка шаг за шагом.</p>
<a id="6.1" name="6.1"></a>
<h3>6.1. Инициализация</h3>
<p>Работа движка начинается с инициализации менеджеров и оболочки.</p>
<ul type="disc">
<li>Оболочка обращается к загрузчику сцен для загрузки сцены. </li>
<li>Загрузчик определяет, какие системы используются в сцене, затем обращается к менеджеру платформы для загрузки каждого из модулей. </li>
<li>Менеджер платформы загружает соответствующие модули и передает их менеджеру интерфейсов. Системный модуль возвращает загрузчику указатели на системы, которые содержат системный интерфейс. </li>
<li>Системный модуль также регистрирует в менеджере сервисов любые сервисы, которые он предлагает. </li>
</ul>
<a id="fig10" name="fig10"></a>
<p><img src="http://software.intel.com/file/10895" border="0" alt="Инициализация движка и оболочки" width="370" height="228" /></p>
<p>Схема 10: Инициализация движка и оболочки</p>
<a id="6.2" name="6.2"></a>
<h3>6.2. Этап загрузки сцены</h3>
<p>Управление возвращается загрузчику, который загружает сцену.</p>
<ul type="disc">
<li>Загрузчик создает универсальную сцену и обращается к каждому системному интерфейсу за системными сценами, расширяющими функциональность универсальной сцены. </li>
<li>Универсальная сцена проверяет каждую системную сцену на изменения общих данных и возможные запросы общих данных. </li>
<li>Затем универсальная сцена регистрирует в менеджере состояний соответствующие системные сцены, чтобы они получали уведомление об изменениях. </li>
<li>Загрузчик создает универсальный объект для каждого объекта в сцене и определяет, какая система будет расширять универсальный объект. Универсальный объект использует ту же модель регистрации системных объектов в менеджере, что и универсальная сцена. </li>
<li>Загрузчик создает системные объекты через интерфейсы системной сцены, которые он получил раньше, и «надстраивает» универсальные объекты системными объектами. </li>
<li>Затем планировщик запрашивает интерфейсы системных сцен в отношении их главных задач, поскольку он отвечает за их перенаправление менеджеру задач. </li>
</ul>
<a id="fig11" name="fig11"></a>
<p><img src="http://software.intel.com/file/10896" border="0" alt="Инициализация универсальной сцены и объекта" width="416" height="242" /></p>
<p>Схема 11: Инициализация универсальной сцены и объекта</p>
<a id="6.3" name="6.3"></a>
<h3>6.3. Цикл игры</h3>
<ul type="disc">
<li>Менеджер платформ вызывается для обработки всех оконных сообщений и (или) других системных вызовов, необходимых для работы на текущей платформе. </li>
<li>Затем исполнение передается планировщику, который ждет окончания такта для продолжения работы. </li>
<li>Планировщик в свободном шаговом режиме проверяет, какие из системных задач были исполнены в предшествующем такте. Все выполненные задачи передаются менеджеру задач. </li>
<li>Затем планировщик определяет, какие задачи будут завершены в текущем такте, и ждет их завершения. </li>
<li>При жестком шаговом режиме планировщик выдает менеджеру все задачи и ждет их выполнения в каждом такте. </li>
</ul>
<a id="6.3.1" name="6.3.1"></a>
<h3>6.3.1. Исполнение задач</h3>
<p>Исполнение менеджером задач.</p>
<ul type="disc">
<li>Менеджер задач выстраивает очередь из направленных ему задач и начинает обрабатывать каждую задачу, по мере появления свободных потоков. (Выполнение задач специфично для каждой системы. Системы могут работать, используя только одну или несколько задач. Во втором случае используется менеджер задач, создавая, таким образом, возможность параллельного исполнения.) </li>
<li>Задачи выполняются как на всей сцене, так и на определенных объектах, изменяя внутренние структуры данных. </li>
<li>Любые данные, которые считаются общими, например, положение и ориентация должны передаваться в другие системы. Системная задача осуществляет это посредством системной сценой или системного объекта (в зависимости от того, что менялось), информируя своего наблюдателя об изменении. В данном случае наблюдатель, по сути, является менеджером изменений. </li>
<li>Менеджер изменений ставит в очередь информацию об изменении. При этом те типы изменений, в которых наблюдатель не заинтересован, просто игнорируются. </li>
<li>Если задаче требуется какие-либо сервисы, она обращается к менеджеру сервисов. Менеджер задач также может использоваться для изменения свойств другой системы, не использующей механизм сообщений (например, система ввода пользователя меняет разрешение экрана графической системы). </li>
<li>Задачи также могут обращаться к менеджеру среды для получения переменных среды, изменения состояния исполнения (например, приостановка исполнения, переход к следующей сцене и т.д.). </li>
</ul>
<a id="fig12" name="fig12"></a>
<p><img src="http://software.intel.com/file/10897" border="0" alt="Менеджер задач и задачи" width="252" height="387" /></p>
<p>Схема 12: Менеджер задач и задачи</p>
<a id="6.3.2" name="6.3.2"></a>
<h3>6.3.2. Распределение</h3>
<p>После того, как все задачи текущего такта завершили выполнение, основной цикл вызывает менеджера состояний для распределения изменений среди всех объектов и систем.</p>
<ul type="disc">
<li>Менеджер состояний обращается к каждому из своих менеджеров изменений для распространения накопленных изменений. Это осуществляется посредством проверки каждого субъекта и поиска наблюдателей, следящих за такими субъектами. </li>
<li>Затем менеджер изменений обращается к наблюдателю, информируя его об изменении (наблюдателю также передается указатель на интерфейс субъекта). При свободном шаговом режиме наблюдатель получает измененные данные из контролера изменений, однако, при использовании фиксированного шагового режима наблюдатель обращается за данными непосредственно к субъектам. </li>
<li>Наблюдатели, заинтересованные в изменениях, осуществляемых системным объектом, обычно представляют другие системные объекты, которые все прикреплены к одному и тому же универсальному объекту. Это позволяет разбивать процесс распространения изменений на задачи для параллельного исполнения. Для ограничения синхронизации в задаче группируются связанные расширения любых универсальных объектов. </li>
</ul>
<a id="6.3.3" name="6.3.3"></a>
<h3>6.3.3. Динамическая проверка и выход</h3>
<p>Итоговый шаг основного цикла представляет собой проверку состояния рабочего цикла. Существует несколько состояний рабочего цикла: исполнение, пауза, следующая сцена и пр. Если состояние рабочего цикла установлено на исполнение, будет выполнена очередная итерация цикла игры. Если рабочий цикл установлен на выход, происходит выход из игры:, освобождаются ресурсы и приложение закрывается. Могут быть реализованы другие состояния рабочего цикла такие, как пауза, переход на следующую сцену и пр.</p>
<a id="7" name="7"></a>
<h3>7. Заключительные соображения</h3>
<p>Ключевым моментом всего вышесказанного является раздел 2 – «Состояние параллельного исполнения». Проектирование систем для функциональной декомпозиции в сочетании с декомпозицией данных позволит добиться значительного распараллеливания, а также обеспечит масштабируемость и поддержку будущих процессоров с еще большим количеством ядер. Не забывайте использовать менеджеры состояний вместе с механизмом сообщений для синхронизации всех данных с минимальными издержками.</p>
<p>«Модель наблюдателя» является, по сути, расширенным механизмом сообщений, необходимо потратить некоторое время на исследования, чтобы создать эффективную реализацию под конкретный движок. Наблюдатель должен обеспечивать эффективное взаимодействие различных систем для синхронизации общих данных.</p>
<p>Управление задачами играет важную роль в регулировании нагрузки. Следуя советам в Приложении D, вы сможете создать эффективный менеджер задач для своего движка.</p>
<p>Как вы видите, разработка движка с высокой степенью параллелизации является решаемой задачей, если использовать четко определенный механизм сообщений и структуру. Соответствующее встраивание параллелизма в ваш движок игры обеспечит существенное увеличение производительности на современных и будущих процессорах.</p>
<a id="8" name="8"></a>
<h2>8. Информация об авторе</h2>
<p>Джеф Эндрюз – Application Engineer Intel, занимающийся оптимизацией программного кода игрового ПО. Он также изучает различные технологии повышения производительности игр. Джф являлся ведущим архитектором демонстрационной оболочки Smoke компании Intel.</p>
<a id="A" name="A"></a>
<h2>Приложение A. Схема примерного движка</h2>
<p>Главный цикл игры начинает обработку (см. Схему 4, «Главный цикл игры»).</p>
<p><img src="http://software.intel.com/file/10898" border="0" alt="Схема связи движка и системы" width="625" height="594" /></p>
<a id="B" name="B"></a>
<h2>Приложение B. Схема связи движка и системы</h2>
<p><img src="http://software.intel.com/file/10899" border="0" alt="Схема связи движка и системы" width="631" height="796" /></p>
<a id="C" name="C"></a>
<h2>Приложение C. Модель наблюдателя</h2>
<p>Модель наблюдателя описана в книге “Design Patterns: Elements of Reusable Object-Oriented Software”, Эриха Гамма (Erich Gamma) и др., первоначально изданной Addison-Wesley в 1995 г.</p>
<p>Основной идеей данной модели является алгоритм, в котором, любые элементы, заинтересованные в изменениях данных или состояний других элементов, не обременяются задачей периодического опроса. Модель определяет субъект и наблюдателя, которые используются для уведомления об изменениях. Процесс работает так: наблюдатель наблюдает за субъектом на предмет каких-либо изменений. Менеджер изменений выступает в роли модератора между двумя данными компонентами. Данная связь отображена на следующей схеме:</p>
<a id="fig13" name="fig13"></a>
<p><img src="http://software.intel.com/file/10900" border="0" alt="Конструктивный шаблон наблюдателя" width="628" height="212" /></p>
<p>Схема 13: Конструктивный шаблон наблюдателя</p>
<p>Ниже приводится поток операций:</p>
<ol type="1">
<li>Наблюдатель регистрируется в субъекте, за изменениями которого он планирует наблюдать, посредством менеджера изменений.</li>
<li>Менеджер изменений в реальности является наблюдателем. Вместо регистрации наблюдателя в субъекте, он сам регистрируется в субъекте и ведет собственный перечень, где указывается, какой наблюдатель зарегистрирован в каком субъекте.</li>
<li>Субъект вносит наблюдателя (на самом деле менеджер изменений) в свой список наблюдателей, которые заинтересованы в его состоянии; иногда дополнительно применяется тип изменений, который определяет, в каких именно изменениях заинтересован наблюдатель, что позволяет оптимизировать процесс распространения уведомления об изменении.</li>
<li>Когда субъект осуществляет изменение своих данных или состояния, он уведомляет наблюдателя посредством механизма обратного вызова и передает информацию об измененных типах.</li>
<li>Менеджер изменений выстраивает в очередь уведомления об изменениях и ждет сигнала для их распределения по объектам и системам.</li>
<li>Во время распределения менеджер изменений обращается к реальным наблюдателям.</li>
<li>Наблюдатели запрашивают субъект в отношении измененных данных или состояния (или получают данные из сообщений).</li>
<li>Когда наблюдатель более не заинтересован в субъекте, он снимает свою регистрацию из субъекта посредством контроллера изменений.</li>
</ol><a id="D" name="D"></a>
<h2>Приложение D. Советы по реализации задач</h2>
<p>Хотя распределение задач может быть реализовано различными путями, лучше всего поддерживать количество рабочих потоков равным количеству доступных логических процессоров платформы. Избегайте привязки задач к определенному потоку, поскольку задачи из различных систем не будут завершаться одновременно, что может привести к дисбалансу нагрузки между рабочими потоками, по сути, сокращая степень параллелизма. Также стоит изучить библиотеки управления задачами, например, Intel® Threading Building Blocks, что может упростить разработку.</p>
<p>В менеджере задач возможны варианты оптимизации, которые могут использоваться для обеспечения беспроблемного выполнения центральным процессором различных задач. Вот эти варианты:</p>
<ul type="disc">
<li>Обратный порядок – если последовательность подаваемых первичных задач относительно статична, задачи могут подаваться в обратном порядке от кадра к кадру. Данные по последней задаче для исполнения в предшествующем кадре, скорее всего, сохранятся в кэше, поэтому подача задач в обратном порядке для следующего кадра будет почти гарантировать то, что кэш центрального процессора не придется вновь наполнять верными данными.</li>
<li>Совместное использование кэша – у некоторых многоядерных процессоров общая кэш-память разделена на секции с тем, чтобы два процессора могли пользоваться одной кэш-памятью, а два других – отдельной кэш-памятью. Подача подзадач из одной системы на процессоры, вместе использующих кэш, повысит вероятность того, что данные уже будут находиться в общей кэш-памяти.</li>
</ul>
<a id="list" name="list"></a>
<h2>Список схем</h2>
<p><a href="http://software.intel.com#fig1">Схема 1</a>: Состояние исполнения, используя свободный шаговый режим 5<br /><a href="http://software.intel.com#fig2">Схема 2</a>: Состояние исполнения, используя жесткий пошаговый режим 6<br /><a href="http://software.intel.com#fig3">Схема 3</a>: Высокоуровневая архитектура движка 8<br /><a href="http://software.intel.com#fig4">Схема 4</a>: Главный цикл игры 9<br /><a href="http://software.intel.com#fig5">Схема 5</a>: Расширение универсальной сцены и объекта 10<br /><a href="http://software.intel.com#fig6">Схема 6</a>: Пример пула потоков менеджера задач 11<br /><a href="http://software.intel.com#fig7">Схема 7</a>: Внутреннее уведомление об изменении универсального объекта 12<br /><a href="http://software.intel.com#fig8">Схема 8</a>: Пример менеджера сервисов 13<br /><a href="http://software.intel.com#fig9">Схема 9</a>: Компоненты системы 17<br /><a href="http://software.intel.com#fig10">Схема 10</a>: Инициализация менеджера движка и системы 19<br /><a href="http://software.intel.com#fig11">Схема 11</a>: Инициализация универсальной сцены и объекта 19<br /><a href="http://software.intel.com#fig12">Схема 12</a>: Менеджер задач и задачи 20<br /><a href="http://software.intel.com#fig13">Схема 13</a>: Конструктивный шаблон наблюдателя 25</p>
<a id="bibliography" name="bibliography"></a>
<h2>Литература</h2>
<p>Gamma, E., Helm, R., Johnson, R., Vlissides, J., (1995-2000). Design Patterns: Elements of Reusable Object-Oriented Software. USA: Addison-Wesley.</p>
<p>Домашняя страница <a href="http://www.threadingbuildingblocks.org">Intel® Threading Building Blocks (TBB)</a>.</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine/</link>
      <pubDate>Wed, 18 Feb 2009 13:00:00 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine/</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Просто об импостерах</title>
      <description><![CDATA[ <h2>Введение</h2>
<p>Рендеринг сложных динамических сцен в реальном времени – довольно сложная задача. Разработчики, как и любители компьютерных игр, предпочитают иметь дело с максимально реалистичной виртуальной средой, ради которой не приходилось бы жертвовать качеством геймплея или скоростью. Примером такой среды, часто используемой в современных играх и рассмотренной в нашей статье, являются открытые природные ландшафты. Природный ландшафт подразумевает рендеринг большого количества геометрических объектов, что сильно сказывается на производительности. Рельеф, вода, облака и растительность – лишь основные составляющие этой сложнейшей задачи. Однако, благодаря изобретательности и творческому подходу при использовании  3D API, например, OpenGL, Direct3D* или любого другого API, разработчик может «выжать» из современного оборудования просто поразительное быстродействие.</p>
<p>Наш пример посвящен рендерингу моделей деревьев и основан на применении Direct3D*, но предлагаемые идеи могут применяться к любой другой трехмерной сцене, содержащей множество объектов сходной геометрии и построенной на основе любого 3D API. Деревья являются любопытным примером, поскольку обладают всеми обязательными атрибутами действительно сложной задачи для рендеринга. Они имеют сложную геометрию, в изобилии присутствуют в природном ландшафте и подвергаются воздействию природных факторов (таких как притяжение, ветер и т.д.). При этом для них может требоваться весьма детальная прорисовка текстур. Поскольку деревья существуют в природе, люди знают, как они выглядят, как ведут себя и как взаимодействуют с окружающей средой. Соответственно, у людей имеются определенные представления о том, как должны выглядеть деревья в игре. Если поставлена задача создания максимально реалистичной среды, разработчикам следует учитывать эти представления при создании виртуальных пространств.</p>
<h2>Целесообразность рендеринга полной геометрии</h2>
<p>В реальном мире произрастает множество видов деревьев, и моделирование их всех было бы чрезвычайно трудной задачей, которая потребовала бы огромных затрат времени. Однако, большинство деревьев в одном географическом районе относительно похожи, поэтому детальных моделей всего лишь четырех деревьев, которые затем можно поворачивать и масштабировать, будет вполне достаточно, чтобы смоделировать действительно реалистичный лес. Тем более, что для этого не нужно искать талантливого художника или быть им. Каждое дерево в приводимом нами примере динамически генерируется с помощью программных алгоритмов и содержит более 10 000 полигонов. Количество деревьев на нужном участке земли, а также тип, масштаб, угол поворота и положение каждого дерева определяются с помощью функции шума (noise function). Порог, определяющий плотность деревьев в лесу, задается изменяемой константой, и в первой сцене нашего примера ее значение подобрано таким образом, чтобы создать в общей сложности до 400 деревьев.</p>
<p>Предположим, что все деревья в первой сцене определены и характеристики каждого дерева (тип дерева, масштаб, угол поворота и положение) заданы. Возникает вопрос, каким образом их следует рендерить. Ответ на него отнюдь не очевиден и, в сущности, меняется в зависимости от желаемого результата. Мы рассмотрим возможные подходы к решению данной проблемы, взвешивая все «за» и «против», а также расскажем подробнее о некоторых важных особенностях программной реализации. Желаемым результатом в нашем случае является максимально быстрый рендеринг реалистичных моделей деревьев.</p>
<p>Первый способ значительно медленнее остальных, и производительность в данном случае недостаточна для моделирования игровой среды в реальном времени. Его принцип прост: рендеринг полной геометрии всего, что есть в сцене. Четыреста деревьев, по десять с чем-то тысяч полигонов на каждое дерево, не говоря уже о земле, небе, воде – это немалый объем геометрии, более 4 миллионов треугольников на кадр! Конечно, объем вычислений, который должен быть выполнен на программном уровне, весьма незначителен. Но наш движок не так эффективен, как лучшие из существующих сегодня коммерческих игровых движков, и мы смогли получить всего 1 или 2 кадра в секунду, что абсолютно неприемлемо. При таком результате следует вплотную заняться оптимизацией, и, как мы увидим далее, вполне возможно добиться существенных улучшений не снижая количества полигонов в дереве или плотности деревьев в лесу.</p>
<p>Первая очевидная возможность оптимизации – применить один из методов отсечения невидимых объектов сцены (visibility culling). В нашем примере мир делится с помощью 2-мерной сетки, при этом каждая ячейка (quadrant) сетки содержит отдельный участок рельефа, отдельную плоскость на заданном уровне для моделирования воды, и связанный список деревьев. Все те ячейки, которые не попадают в пространство обзора камеры, просто исключаются из рендеринга. Конечно, это несколько упрощенный подход к отсечению невидимых объектов, и он создает дополнительную нагрузку на программную часть, однако он помогает добиться желаемого результата. Далее по тексту мы будем подразумевать, что режим отсечения невидимых объектов включен. Это небольшое, казалось бы, изменение позволяет отрисовывать лишь 40% ячеек сетки 10 х 10, что дает максимальную частоту кадров 3 fps. Более тонкая сортировка (например, деление сцены на большее количество мелких ячеек) позволит сократить процент отрисовываемых ячеек примерно до 25%. Тем не менее, рендеринг полной геометрии видимой сцены все еще является чрезвычайно ресурсоемкой задачей, и вопрос о том, что же все-таки нужно оставить в кадре, пока не решен.</p>
<h2>О пользе импостеров</h2>
<p>Как выясняется, вовсе необязательно рендерить полную геометрию дерева, которое находится так далеко от камеры, что занимает на экране лишь один пиксель. Пользователь в любом случае едва ли сможет его разглядеть. Более того, нет необходимости в рендеринге каждого дерева, которое не находится настолько близко к воображаемой камере, чтобы пользователь мог разглядеть разницу между трехмерным деревом и похожей на дерево текстурой, или импостером (impostor). Импостер, в данном контексте, представляет собой билборд (billboard, двухмерный прямоугольник), лицевая сторона которого всегда повернута к камере, с текстурой, имитирующей геометрический объект, который он заменяет, как показано на рис. 1 и 2.</p>
<p><img src="http://software.intel.com/file/9227" alt="" width="300" height="276" /></p>
<p><em>Рис. 1: Дерево и импостер в режиме отображения объемных объектов (solid view) (альфа-канал импостера позволяет пропускать темные участки при рендеринге).</em></p>
<p><img src="http://software.intel.com/file/9228" alt="" width="300" height="276" /></p>
<p><em>Рис. 2: То же дерево и импостер в режиме отображения сетки (wireframe view)</em></p>
<p>Использование импостеров радикально сокращает количество полигонов, но влечет за собой ряд новых вопросов:</p>
<ul>
<li>Как с помощью биллбордов представлять отдельные деревья под разными углами зрения?</li>
<li>Когда следует рендерить импостер, а когда – реальное дерево?</li>
<li>Как генерировать импостеры?</li>
</ul>
<br />
<p>Теперь начинается самое интересное с точки зрения разработчика. Представьте, что вы обходите по кругу дерево в реальном мире. Ветки дерева неподвижны по отношению к стволу. Иными словами, они не вращаются на стволе, чтобы постоянно быть у вас перед глазами. Теперь представьте, что камера в игре движется вокруг дерева – или любого похожего объекта. Если дерево будет выглядеть одинаково с любой точки обзора, цель симулирования реальности достигнута не будет. Чтобы избежать этого, следует отрисовывать полную геометрию любого дерева, находящегося в пределах определенного расстояния от камеры, а дальние деревья можно отображать в виде импостеров. Но и в этом случае остается одна проблема.</p>
<p>Как мы уже упоминали, каждое дерево в сцене обладает уникальными характеристиками, присвоенными ему при генерировании. Если для всех импостеров применять одинаковую текстуру, то все деревья, изображенные импостерами, будут выглядеть абсолютно одинаково, и в итоге ваш лес будет выглядеть совсем не натурально. Кроме того, если дистанция от камеры до дерева сократится до величины, при которой геометрия дерева должна быть отрисована полностью, обязательно проявится весьма заметный эффект внезапного появления. Однако еще не все потеряно, так как в нашем арсенале есть мощный инструмент, который поможет поддержать иллюзию: метод «рендеринг в текстуру» (render-to-texture).</p>
<h2>Умелое использование метода render-to-texture</h2>
<p>Рендеринг деревьев только с одной точки обзора (вида) нецелесообразен по причинам, упоминавшимся выше; следовательно, необходимо решить, сколько видов для каждого дерева нужно рендерить в текстуру, следует ли использовать одну текстуру для каждого вида или одну текстуру для всех выбранных видов. Секрет выбора количества видов - в тщательном подборе расстояния замены, т.е. расстояния от камеры, на котором вместо импостера рендерится уже полная геометрия дерева. Чтобы сократить объем занимаемой памяти и при этом сохранить иллюзию реальности, в нашем примере используется расстояние замены, при котором отсутствует заметный эффект внезапного появления. Мы используем всего восемь видов: север, северо-восток, восток, и так далее. Обычно этих восьми видов вполне достаточно, но вы можете экспериментировать с большим или меньшим количеством, в зависимости от потребностей вашего приложения. Конечно, при этом важно учитывать, что все зависит от масштабов виртуального мира, где должны расти деревья. Но после ряда экспериментов относительно нетрудно найти подходящую величину.</p>
<p>Рассмотрим вторую проблему: использовать по одной текстуре для каждого вида или одну текстуру, изображающую все восемь видов модели дерева. Подкачка текстур (texture swapping) в современных API может оказаться весьма ресурсоемкой, поэтому рендериг каждого вида дерева в отдельную текстуру может привести к существенным затратам ресурсов. Рендеринг всех восьми видов дерева в одну текстуру значительно сокращает объемы подкачки текстур. Следующий шаг, рендеринг всех восьми видов всех четырех деревьев в одну текстуру, вообще устраняет необходимость в подкачке текстур в интервалах обработки импостеров. В целях сохранения реалистичности при одновременном снижении нагрузки на ресурсы системы и повышении производительности в нашем примере используется именно последний метод.</p>
<p>Хотя данное решение и весьма эффективно, рендеринг всех возможных видов модели в одну текстуру по методу render-to-texture имеет свои недостатки. Первый недостаток связан с рендерингом в текстуру с альфа-каналом и присущ всем методам рендеринга в текстуру (альфа-канал необходим для того, чтобы сделать возможным альфа-тест на фоне импостеров за проход рендера). В приводимом в качестве примера коде создается область памяти для вывода изображения (render target, область рендеринга) с альфа-каналом, который, однако, поддерживается не всеми аппаратными графическими средствами. Мы протестировали наш пример на нескольких графических картах и получили хорошие результаты (с использованием последних доступных версий драйверов), но вовсе не исключаем, что на некоторых конфигурациях наш пример не будет запускаться правильно.</p>
<p>Если необходимо обеспечить совместимость с графическими картами, которые не поддерживают объекты типа «render target» с альфа-каналом, существует способ обойти эту проблему. Вместо того, чтобы создавать область рендеринга с альфа-каналом, создайте базовую (блокируемую) область рендеринга. Также создайте текстуру в системной памяти с тем же размером, что и область рендеринга, текстуру с альфа-каналом в системной памяти, и текстуру с альфа-каналом в видеопамяти. Этот метод проиллюстрирован на приводимой ниже схеме, и мы разберем его более подробно:</p>
<p><img src="http://software.intel.com/file/9229" alt="" width="466" height="96" /></p>
<p><em>Рис. 3: Создание импостера с альфа-каналом для графических карт, прямо не поддерживающих рендеринг в текстуры с альфа-каналом.</em></p>
<p>Сначала создайте объект в области рендеринга. Заблокируйте область рендеринга, скопируйте данные в текстуру в системной памяти, имеющую тот же размер, и разблокируйте область рендеринга. На этом этапе область рендеринга можно удалить, она больше не понадобится. Скопируйте данные из текстуры в системной памяти в текстуру с альфа-каналом в системной памяти, по необходимости устанавливая при этом значения альфа-канала (непрозрачные пиксели там, где отрисован объект, прозрачные в остальных областях). Наконец, заблокируйте текстуру с альфа-каналом в видеопамяти, скопируйте данные из системной текстуры с альфа-каналом и разблокируйте видео-текстуру с альфа-каналом. В результате должен получиться точный импостер объекта с установленными значениями прозрачности для альфа-теста при рендеринге импостера. Поскольку эти операции выполняются только во время запуска, потери производительности не существенны.</p>
<p>Второй недостаток метода рендеринга всех возможных видов в одну текстуру связан с возможной альтернативой импостерам – точечными спрайтами (point sprites). Если все восемь видов всех четырех деревьев отрисованы в одну текстуру, это означает, что для каждого импостера должен применяться какой-либо метод трансформации текстуры (см. рис. 4). В DirectX* 8.0 точечные спрайты не поддерживают трансформацию текстуры, поэтому, разрешив точечные спрайты, придется рендерить каждый вид каждого дерева в отдельную текстуру. Мы отвергли этот вариант по причинам, описанным выше, поэтому мы вынуждены отказаться от использования точечных спрайтов, хотя они и имеют преимущество в виде необходимости хранения только z-координаты (z-position).</p>
<p><img src="http://software.intel.com/file/9230" alt="" width="362" height="211" /></p>
<p><em>Рис. 4: Трансформации текстуры импостера (выбор координат текстуры)</em></p>
<p>При этом усложняется реализация текстур с MIP-картами (MIP-mapped textures), поскольку необходимо создавать буферы вокруг вида каждого дерева, чтобы избежать размытости на границах текстур.</p>
<p>После определения схемы текстурирования следует переходить к следующему важному аспекту, который необходимо учитывать при рендеринге сотен (возможно, тысяч) мелких объектов в Direct3D*: правильное использование буферов вершин. Поскольку все импостеры, по сути, представляют собой квадранты (quads) с координатами конкретной текстуры, рассчитываемыми на основе угла поворота каждого дерева, можно использовать</p>
<ul>
<li>единый буфер вершин на 32 вершины для всех импостеров или</li>
<li>буфер вершин на 4 вершины для каждого импостера </li>
</ul>
<br />
<p>В каждом из этих случаев придется «на лету» выбирать нужные координаты текстуры для каждого импостера, однако это справедливо для любой ситуации, когда одна текстура изображает несколько видов. Снижение производительности происходит из-за сотен вызовов функции DrawIndexedPrimitive(), причем за каждый вызов получается рендерить только 4 вершины.</p>
<p>Большей эффективности можно добиться за счет выполнения трансформаций для всех импостеров на программном уровне с последующим помещением всех трансформированных вершин в единый большой буфер вершин. В примере использован буфер вершин, способный вместить 1000 импостеров деревьев (4000 вершин), хотя потенциально возможна поддержка до 16 000 импостеров деревьев (64 000 вершин). В примере реализована поддержка только 1000 импостеров деревьев на буфер, поскольку прирост производительности при увеличении вместимости буфера свыше 4000 вершин ничтожно мал. Хотя может показаться, что это чересчур сложное решение для того, чтобы использовать лишь одну текстуру, советуем вам попробовать выполнять расчеты трансформаций импостеров (масштабирование, поворот, позиционирование, расчет координат текстуры) на программном уровне и использовать единый большой буфер вершин. Конечный результат будет весьма хорош как визуально, так и с точки зрения производительности. Производительность, измеряемая по частоте кадров, возрастает с жалких 3 fps до целых 90 fps, то есть почти на 1000%!</p>
<p><img src="http://software.intel.com/file/9231" alt="" width="233" height="159" /></p>
<p><em>Сцена, отрисованная без импостеров</em></p>
<p><img src="http://software.intel.com/file/9232" alt="" width="233" height="160" /></p>
<p><em>Аналогичная сцена, отрисованная с импостерами</em></p>
<h2>Выводы</h2>
<p>Как свидетельствуют факты, быстрый рендеринг простых импостеров представляет собой замечательный инструмент в арсенале разработчика. Сочетание таких методов, как «render-to-texture», с алгоритмическим созданием контента (procedural content) снижает потребность в дополнительных графических ресурсах и сокращает время разработки контента. Тщательное продумывание процессов отсечения невидимых объектов, текстурирования и использования API поможет увеличить общую скорость рендеринга в вашем графическом конвейере и в итоге повысит общее качество визуализации. Надеемся, что представленные здесь идеи пригодятся вам, когда вы в следующий раз столкнетесь со сложной проблемой виртуального представления реального мира.</p>
<p><strong><a href="http://software.intel.com/en-us/articles/code-samples-license-2?target=http%3A%2F%2Fwww.intel.com%2Fcd%2Fids%2Fdeveloper%2Fasmo-na%2Feng%2F17950.htm">Загрузить исходный код</a></strong></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/impostors-made-easy/</link>
      <pubDate>Wed, 04 Feb 2009 13:00:00 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/impostors-made-easy/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/impostors-made-easy/</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Оптимизация компьютерных игр для ультрамобильных ПК</title>
      <description><![CDATA[ <!--l version="1.0" encoding="utf-8" standalone="no-->
<div class="Section1">
<p><em><strong>Рост популярности ультрамобильных ПК способствует расширению рынка компьютерных игр на базе Microsoft Windows* XP. Но для этого разработчики игр должны внести некоторые изменения. В большинстве случаев одна и та же версия игры подойдет как для UMPC, так и обычного ПК.</strong></em></p>
<p><em><strong></strong><br /> </em><em>Мэтт Гиллеспи (Matt Gillespie), Майкл Финкель (Michael Finkel) и Виктория Бейли (Victoria Bailey)</em></p>
<p> </p>
<div class="sectionHeading">
<p>Введение</p>
</div>
<p> </p>
<p>Платформа UMPC (Ultra-Mobile PC) приобретает все большую популярность в среде разработчиков игр. Отсутствие полноценного порта ОС компенсируется использованием ОС Microsoft Windows* XP Tablet PC Edition, однако форм-фактор UMPC все же накладывает определенные ограничения в области компьютерных игр. К примеру, разрешение сенсорных экранов ультрамобильных ПК 800x480 или 1024x600 пикселей слишком мало, а форматное соотношение может показаться пользователям необычным. Кроме того, разработчикам предстоит найти достойную замену обычной клавиатуре и мыши, да и отсутствие привода CD-ROM причиняет определенные неудобства. <br /></p>
<p>В основе представленных в настоящем документе методов оптимизации компьютерных игр для платформы UMPC лежит анализ множества существующих на рынке игрушек. При выполнении игр на базе ультрамобильного ПК определялись сильные и слабые стороны платформы, а также характерные особенности UMPC. Наряду с рекомендациями по изменению конструкции ультрамобильных ПК для обеспечения более высокого качества игр в данном документе также описаны стандартные проблемы, возникающие при использовании UMPC, и оптимальные методы их решения.</p>
<p> </p>
<div class="sectionHeading">
<p>Размер экрана</p>
</div>
<p> </p>
<p>Небольшой размер экрана ультрамобильных ПК создает определенные сложности для восприятия графических элементов. Разработчикам не рекомендуется использовать как слишком мелкую графику, так и чрезмерно крупные элементы. В первую очередь пользователи испытывают сложности при чтении текста и распознавании значков; некоторые кнопки и элементы нажимаются с трудом, а окна определенных игр не помещаются на экране ПК.</p>
<p> </p>
<div class="sectionHeading">
<p>Размер текста и значков</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> При переносе интерфейсов игр на платформу UMPC уменьшение размеров текста и значков может затруднить их восприятие. Необходимо постараться избавиться от этой распространенной проблемы. Зачем нужны элементы, которых не видно? Текст может быть отлично виден на экране в 15 дюймов, но практически неразличим при переносе на экран размером 5 на 7 дюймов (»12x17 см). Наряду с размером шрифта необходимо также настроить размер окна чата и других текстовых окон. Не стоит для этого уменьшать шрифт, поскольку тогда восприятие текста будет затруднено.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> В идеале разработчики игр для платформы UMPC должны сокращать количества текста, а размер шрифта должен соответствовать небольшому экрану ультрамобильных ПК. Необходимо избегать небольших элементов и делать объект отличимыми друг от друга. Если текст скрывает другие элементы игры, разработчики должны предусмотреть возможность индивидуальной настройки шрифта с тем, чтобы пользователь сам определил оптимальный размер.</p>
<p> </p>
<div class="sectionHeading">
<p>Функционирование кнопок и других элементов</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> Наряду с переносом текста не менее важной проблемой является перенос кнопок и других активных игровых элементов на платформу ультрамобильных ПК. В отличие от остального интерфейса размер кнопок в UMPC должен увеличиться: точно попасть на кнопку пером или пальцем намного сложнее, чем указателем мыши, используемым в стандартных ПК. Как видно из рисунка 1, эта проблема наиболее актуальна при размещении нескольких кнопок или элементов рядом: шансов попасть на другой элемент намного больше. Приложив определенные усилия, пользователь, конечно, сможет выбрать нужную ему кнопку, однако данная проблема является существенным недостатком этого типа систем.</p>
<p><br /> <br /> <img src="http://software.intel.com/file/9128" alt="" width="369" height="176" /></p>
<p><strong>Рис. 1.</strong> На мониторе ПК размером 20 дюймов (слева) пользователь может с легкостью выбрать кость домино, используя курсор. Однако при переносе изображения на экран ультрамобильного ПК размером 5 дюймов (справа) сложности возникают не только с выбором нужного элемента, но и с определением количества точек на каждой кости.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> Так же, как и в случае с текстом и значками разработчики игр должны использовать кнопки и элементы большого размера и четкой формы. Кроме того, пространство между этими элементами должно быть достаточным, чтобы пользователь мог с легкостью выбрать нужную кнопку. В тех случаях, когда рядом с кнопкой или другим элементом находится текстовая надпись, она должна войти в активную область элемента, чтобы пользователю было проще попасть.</p>
<p> </p>
<p><strong>Размер игровой области</strong></p>
<p> </p>
<p><strong>Проблема:</strong> Если в играх для UMPC используются окна фиксированного размера, которые не изменяются в соответствии с размером экрана ультрамобильного ПК, игровая область может отображаться не полностью, а некоторые элементы окна и вовсе могут отсутствовать, как показано на Рис. 2. Дополнительная сложность связана с широтой экрана UMPC, который поддерживает разрешения 800x480 и 1024x600: при этом размер окна игры должен подгоняться под стандартное соотношение 4:3, как это принято в большинстве компьютерных игр.</p>
<p><br /> <br /> <img src="http://software.intel.com/file/9129" alt="" width="369" height="89" /></p>
<p><strong>Рис. 2.</strong> На обычном ПК (слева) пользователь видит всю игровую область, включая информационные компоненты интерфейса. Если окно игры обрезается в соответствии с размером экрана ультрамобильного ПК меньшего размера и с другим форматным соотношением (в центре), часть игровой области будет скрыта. На рисунке эта область (в центре и по краям экрана) закрыта полупрозрачной заливкой. Если же окно игры трансформируется в зависимости от размера UMPC (справа), все элементы игры остаются видимыми и присутствует допустимое оптическое искажение.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> В качестве основного способа решения проблемы можно предложить разработку игр с учетом разрешений 800x480 и 1024x600. В этом случае все игровые элементы будут присутствовать на экране. Также размер игрушек можно подгонять в соответствии с широким экраном ультрамобильных ПК. С помощью некоторых простых изменений даже сокращенные версии игр станут для пользователей более удобными. К примеру, в некоторых случаях достаточно добавить полосы прокрутки и функцию изменения размера окна (вручную или автоматически), чтобы вся область экрана стала доступной. Это позволяет сделать игры, в первую очередь на базе браузеров, намного привлекательнее для пользователей.</p>
<p> </p>
<div class="sectionHeading">
<p>Сенсорный экран</p>
</div>
<p> </p>
<p>Использование сенсорного экрана вместо мыши делает задачу переноса игр на ультрамобильный ПК еще сложнее. В большинстве случаев сенсорный экран выполняет те же функции, что и мышь с той разницей, что мышь регистрирует линейное перемещение курсора пользователем, а экран реагирует на нажатия, каждый раз определяя другое местоположение при нажатии пользователем на панель. Определенные проблемы вызывает невозможность перемещения курсора без нажатия и отношения между функциями левой и правой кнопки мыши.</p>
<p> </p>
<div class="sectionHeading">
<p>Точное распознавание нажатий на сенсорный экран</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> Игры для ультрамобильных ПК должны правильно распознавать движения курсора в виде ряда точек (соответствующих нажатиям пользователя на сенсорный экран) при отсутствии линейного перемещения курсора (обеспечивается при использовании мыши). Эта проблема встречается достаточно часто; к примеру, она возникает в играх, где перемещается ракурс пользователя, и курсор всегда находится в центре экрана (чаще всего это используется в играх-стрелялках от первого лица). В таких случаях при прикосновении игрока к экрану курсор будет хаотично двигаться по всему окну, а не перемещаться в ту область, до которой дотронулся пользователь.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> Если игра отслеживает движение курсора от точки А к точке В, она должна также правильно связывать нажатие кнопки в точке А и последующее нажатие в точке B без перемещения курсора между этими точками. Еще один распространенный способ решения этой проблемы — установка внешней мыши в ультрамобильный ПК, хотя данный метод считается пользователями нежелательным.</p>
<p> </p>
<p><strong>Точное отображение на сенсорном экране</strong></p>
<p> </p>
<p>Если игра ведется в полноэкранном режиме, но игровая область не совпадает с областью экрана (не заполняется весь экран, либо выходит за его рамки), информация с сенсорного экрана может интерпретироваться неправильно. <br /></p>
<p><strong>Проблема (разрешение игры меньше, чем размер физического экрана)</strong>: Если в полноэкранном режиме разрешение игры меньше, чем размер физического экрана, игровая область может выравниваться по центру, а по краям оставаться пустое пространство (окно 640x480 выравнивается на экране размером 800x480 или окно с разрешением 800x600 переносится на экран размером 1024x600, а по краям остаются черные полосы). Несоответствие размеров окна и экрана может привести к неправильному отображению, поскольку поверхность сенсорного экрана переносится на меньшую игровую область. Эта ошибка, как показано на <strong>Рис. 3</strong>, может привести к неверному восприятию действий пользователя интерфейсом: активная область кнопки может не совпадать с визуальным образом кнопки.</p>
<p> </p>
<p> </p>
<table border="0" cellspacing="0" cellpadding="0" width="560">
<tbody>
<tr>
<td width="225">
<p><img src="http://software.intel.com/file/9130" alt="" width="225" height="167" /></p>
</td>
<td width="9">
<p> </p>
</td>
<td width="326">
<p><strong>Рис. 3.</strong> Если окно игры выровнено по центру, а по краям остались черные полосы, игровая логика, реагирующая на нажатия на сенсорный экран, может не справиться с переносом всей области физического экрана в меньшее по размеру окно игры. В этом случае игра будет переносить место действительного нажатия на экран (на рисунке показано желтой стрелкой) в другую точку (показано красным взрывом).</p>
</td>
</tr>
</tbody>
</table>
<p><br /></p>
<p><strong>Способ решения проблемы: </strong>Даже в случае выравнивания игры по центру и наличия черных полос по сторонам окна действия пользователя могут верно отображаться на экране, если логика отображения рассматривает черные полосы, как часть экрана (несмотря на то, что они не используются в игре). Эта оптимизация позволит точно отображать место нажатия. <br /></p>
<p><strong>Проблема (разрешение игры больше, чем размер физического экрана):</strong> В тех случаях, когда вертикальное пространство окна игры больше физического размера экрана, действия на сенсорном экране могут неправильно отображаться по вертикали, а не по горизонтали (как показано на Рис. 4). Обычно это приводит к тому, что сенсорный экран переносится на все окно игры, а не только на видимую область. И опять же место нажатия пользователем на экран не соответствует точке его отображения в окне игры.</p>
<p> </p>
<table border="0" cellspacing="0" cellpadding="0" width="560">
<tbody>
<tr>
<td width="225">
<p><img src="http://software.intel.com/file/9131" alt="" width="225" height="167" /></p>
</td>
<td width="9">
<p> </p>
</td>
<td width="326">
<p><strong>Рис. 4.</strong> Если часть окна игры (показано полупрозрачной заливкой) не присутствует на физическом экране, игра может переносить место действительного нажатия на экран (на рисунке показано желтой стрелкой) в другую точку (показано красным взрывом) в связи с несовпадением размеров окна игры и физического экрана.</p>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p><br /> <strong>Способ решения проблемы:</strong> При разработке необходимо учесть, что операционная система должна точно отображать сенсорный экран на видимую область (включая участки, не используемые в игре), не включая невидимые участки окна. Также можно предложить разработчикам включить в игры настраиваемую пользователями функцию поддержки разрешения экрана 800x480 или 1024x600. В некоторых случаях игра может сама автоматически растягивать окно до полного размера экрана, если допускаются искажения размеров игровых элементов.</p>
<p> </p>
<div class="sectionHeading">
<p>Замена эффекта наведения курсора</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> Во многих играх используется особый эффект: при наведении пользователем курсора на объект или место в игре (не нажимая на него) появляется анимированная информация или всплывающая подсказка. Эта функция часто используется для поддержки новичков, однако в сенсорных экранах перемещение курсора без нажатия на него невозможно.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> Поскольку эффект наведения курсора не совместим с современными версиями аппаратного обеспечения платформы UMPC, разработчики должны изыскивать альтернативные способы вызова анимации или всплывающей подсказки. К примеру, такая информация может появляться только на определенном этапе игры. Другой способ решения проблемы – разработка интерфейса с функцией временного преобразования нажатия в движение мыши. Например, при удержании определенной кнопки нажатия на сенсорный экран будут интерпретироваться, как перемещение курсора.</p>
<p> </p>
<div class="sectionHeading">
<p>Перенос функций правой кнопки мыши</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> Чтобы воспроизвести нажатие правой кнопки мыши в стандартных сенсорных экранах ультрамобильных ПК, необходимо удерживать нажатие дольше, чем при вызове функций левой кнопки мыши. Однако при этом возникает большая вероятность путаницы между кнопками. Более того, невозможно одновременно нажать левую и правую кнопки.</p>
<p><br /> <br /> <strong>Способ решения проблемы:</strong> Должны быть предоставлены другие варианты вызова функций правой кнопки мыши, как, например, двойной щелчок или размещение активных кнопок на экране. Кроме того, можно использовать внешнюю мышь или другое указывающее устройство, хотя игра может стать от этого менее удобной.</p>
<p> </p>
<div class="sectionHeading">
<p>Форм-фактор</p>
</div>
<p> </p>
<p>Ряд проблем при разработке игр для платформы UMPC связан с различиями аппаратных средств ультрамобильного и обычного ПК. Например, в отличие от настольного ПК в форм-факторе UMPC могут присутствовать сенсорный экран, джойстик, программируемые пользователем кнопки и специальные кнопки, как, например, кнопка меню, однако отсутствуют клавиатура и привод CD-ROM. Конечно, пользователь может дополнительно установить клавиатуру, привод CD-ROM и другие периферийные устройства, но это намного снизит портативность устройства. Кроме того, различные модели UMPC различаются по набору элементов, и ограничения, связанные с форм-фактором, также отличаются в зависимости от конкретного ПК. В связи с этим разработчикам игр приходится обычно ориентироваться на наименьший общий знаменатель аппаратных функций с точки зрения требований ядра.</p>
<p> </p>
<div class="sectionHeading">
<p>Привод CD-ROM</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> В настоящее время большая часть игр распространяется на CD-дисках. Они используются не только для установки игр на ПК, но часто и для подтверждения права владения игрой в качестве защиты от воровства, либо для динамичной загрузки содержимого диска, например, видеопоследовательности. Поскольку в обычных ультрамобильных ПК такой привод отсутствует, возникает необходимость в использовании внешних приводов, и компьютер становится менее портативным. К тому же у некоторых пользователей такой тип привода может отсутствовать. Эта проблема не относится к играм, размещенным в Интернете, или играм на базе браузера.</p>
<p><br /> <strong>Способ решения проблемы:</strong> Прекрасной альтернативной игр на CD-дисках для ультрамобильных ПК является распространение игр через Интернет. Этот способ используется уже практически повсеместно и дальнейшее развитие платформы UMPC только повысит его популярность. Разработчики также должны рассмотреть возможность использования сертификатов или других программных средств вместо физических CD-дисков в качестве подтверждения права владения играми. Если в процессе игры необходима загрузка видео или других элементов с диска, разработчики могут поместить это содержимое на жесткий диск ультрамобильного ПК.</p>
<p> </p>
<div class="sectionHeading">
<p>Ограничение количества команд</p>
</div>
<p> </p>
<p><strong>Проблема: </strong>По сравнению с обычным ПК со стандартными клавиатурой и мышью форм-фактор UMPC поддерживает меньшее количество команд. Даже в играх, управляемых джойстиком, может требоваться использование нескольких кнопок, которые присутствуют на обычной ручке управления, но отсутствуют в ультрамобильных ПК. Кроме того, у пользователей UMPC могут возникнуть сложности с играми, где ключевым компонентом являются сочетания клавиш на клавиатуре. Ограничения, накладываемые в этой области форм-фактором, не распространяются на игры, управляемые мышью.</p>
<p><br /> <strong>Способ решения проблемы:</strong> Разработчики могут устранить такие ограничения ультрамобильных ПК, сократив количество команд, необходимых для управления игрой. Это также касается быстрых ссылок на опции меню. В качестве более гибкого решения можно предложить использование кнопок на экране. Если сделать кнопки контекстно зависимыми, т.е. их появление будет связано с определенной ситуацией, это будет общим решением проблемы ограничения количества команд.</p>
<p> </p>
<div class="sectionHeading">
<p>Требования к наличию клавиатуры</p>
</div>
<p> </p>
<p><strong>Проблема:</strong> Во многих играх клавиатура используется не только для выполнения команд, но также и для присвоения имени героям, создания профилей, сохранения игр или поддержки чата в интерактивных играх. Клавиатура также может потребоваться для введения имени профиля в начале игры, однако в течение игры клавиатура не нужна. Кроме того, в некоторых случаях игрокам предлагается указать имя сохраненной игры с помощью клавиатуры. Чаще всего экранная клавиатура не отображается поверх игрового интерфейса, т.е. этот способ решения проблемы неприемлем.</p>
<p><br /> <strong>Способ решения проблемы:</strong> Разработчики могут создавать игры, поддерживающие экранную клавиатуру (например, она не должна по умолчанию появляться в полноэкранном режиме), или встраивать такую виртуальную клавиатуру в интерфейс игр, чтобы она появлялась в случае необходимости. Простой способ минимизации данной проблемы – использование значений по умолчанию для текстовых строк, включая имена профилей, сохраненных игр и т.д. В этом случае пользователи могут выбирать нужное значение, нажимая на сенсорный экран. В качестве дополнительного значения текстовых строк можно использовать кнопки интерфейса, которые наугад выбирают новое значение из списка имен героев, созданного разработчиком. Снимок экрана, на котором пользователь вышел из игры, с указанием даты и времени можно использовать в качестве названия сохраненной игры. Поскольку функции чата не являются ключевыми для большинства игр, в ультрамобильных ПК их можно отключить, не ухудшая при этом качества игры.</p>
<p> </p>
<div class="sectionHeading">
<p>Заключение</p>
</div>
<p> </p>
<p>С помощью различных способов оптимизации создатели игр и разработчики архитектуры платформы UMPC могут решить наиболее распространенные проблемы процесса разработки этой продукции. В качестве базового руководства можно использовать оптимальные методы, описанные в данном документе. Поскольку в ультрамобильных ПК на базе Windows используется полная версия операционной системы, то намного проще обеспечить поддержку для этих систем, чем создавать полный порт к отдельной операционной системе. Таким образом, постепенная работа над описанными проблемами позволит разработчикам игр идти в ногу с растущим рынком ультрамобильных систем и создавать конкурентное преимущество для своей продукции.</p>
<p> </p>
<strong>
<div class="sectionHeading">
<p><strong>Дополнительные ресурсы</strong></p>
</div>
<p> </p>
<p>С помощью следующих ресурсов создатели игр и разработчики архитектуры смогут оптимально объединить требования платформы UMPC со своей продукцией.</p>
<p> </p>
<p><a href="http://softwarecommunity-rus.intel.com/isn/Home/Mobility.aspx">Intel® Software Network Mobile Developer Community</a> (Сообщество разработчиков Intel® Software Network) содержит основную информацию для разработчиков в сфере мобильных устройств. В этом ресурсе представлена техническая документация, наборы для разработчиков, форумы, базы знаний и блоги. <a href="http://www.intel.com/software/mobile">http://www.intel.ru/software/mobile</a></p>
<p> </p>
<p>На Web-сайте платформы Intel UMPC представлена основная информация о платформе и описаны возможности, которые она открывает для разработчиков и пользователей. <a href="http://www.intel.com/design/mobile/platform/umpc.htm" target="_blank">http://www.intel.com/design/mobile/platform/umpc.htm</a></p>
<p> </p>
<p>В сообществе UMPC содержится информация об устройствах, приложениях и моделях использования, а также форумы для пользователей и разработчиков. <a href="http://www.umpc.com/" target="_blank">http://www.umpc.com/</a></p>
<p> </p>
<p>На ресурсе <a href="http://www.umpcbuzz.com/" target="_blank">UMPC Buzz</a> содержатся ссылки на новостные темы, блоги, форумы и программные файлы для платформы UMPC. <a href="http://www.umpcbuzz.com/" target="_blank">http://www.umpcbuzz.com/</a></p>
<p><br /></p>
</strong></div> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/best-practices-in-game-design-for-the-ultra-mobile-pc/</link>
      <pubDate>Wed, 04 Feb 2009 13:00:00 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/best-practices-in-game-design-for-the-ultra-mobile-pc/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/best-practices-in-game-design-for-the-ultra-mobile-pc/</guid>
      <category>Сообщество разработчиков мобильного ПО</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Краткий справочник по интегрированным графическим ускорителям Intel® серии GMA *4500</title>
      <description><![CDATA[ <p><em>Данная статья содержит краткий обзор возможностей и технические характеристики интегрированных графических ускорителей Intel серии GMA *4500.</em></p>
<h2>Условные обозначения чипсетов</h2>
<p>Наборы системной логики Intel классифицируются с точки зрения платформы и рыночного сегмента, на который они ориентированы. В настоящий момент в нашем ассортименте представлены чипсеты для настольных ПК, ноутбуков, серверов и рабочих станций, для встроенных систем и устройств потребительской электроники. Данная статья рассматривает чипсеты для настольных ПК и ноутбуков и включает описание различий между интегрированными графическими ускорителями Intel®, входящих в состав рассматриваемых чипсетов.</p>
<p>Стандартные чипсеты для настольных систем выпускаются как с интегрированным графическим ускорителем (GMA, Graphics Media Accelerator), так и без него. Чипсеты без GMA имеют в названии префикс или суффикс «P», а чипсеты с GMA – соответственно «G» или «Q». Чипсеты серии «G» в первую очередь предназначены для потребительских настольных систем, в то время как серия «Q» ориентирована на системы для малого, среднего и крупного бизнеса. Например, Intel® G965 Express представляет собой продукт для потребительских настольных ПК, а Intel® Q965 Express – это решение для малого/среднего/крупного бизнеса. Чипсеты для ноутбуков, как правило, маркируются префиксом или суффиксом «М». В частности, аналогичная модель для ноутбука называется Intel® GM965 Express.</p>
<p>Вы можете ознакомиться с полным ассортиментом чипсетов Intel® и их техническими характеристиками, перейдя по приводимой ниже ссылке.</p>
<p><a href="http://www.intel.com/design/chipsets/express_flyer.htm">http://www.intel.com/design/chipsets/express_flyer.htm</a></p>
<h2>Графические ускорители Intel® серий GMA 4500, X4500 и X4500HD</h2>
<p>В приведенной ниже таблице показаны основные характеристики чипсетов серии Intel® 4 Series. В сочетании с процессорами Intel® Core2™ Duo, чипсеты серии Intel® 4 Series обеспечивают высокую производительность и низкое время отклика. В Таблице 1 приводится подробное описание графических функций, которые поддерживаются чипсетами с графическими ядрами GMA 4500, X4500 и X4500HD.</p>
<table class="tableformat1" border="0" cellspacing="0" cellpadding="5" width="624">
<tbody>
<tr>
<td width="139">
<p>Чип</p>
</td>
<td width="122">
<p>G45</p>
</td>
<td width="117">
<p>G43</p>
</td>
<td width="117">
<p>G41</p>
</td>
<td width="128">
<p>Q45/Q43</p>
</td>
</tr>
<tr>
<td width="139">
<p>Графическое ядро</p>
</td>
<td width="122">
<p>GMA X4500HD</p>
</td>
<td width="117">
<p>GMA X4500</p>
</td>
<td width="117">
<p>GMA X4500</p>
</td>
<td width="128">
<p>GMA 4500</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования MPEG2</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования VC1</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования AVC</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Функции защиты HD-содержимого PAVP/HDCP</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Интерфейсы дисплея</p>
</td>
<td width="122">
<p>DisplayPort, HDMI, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="117">
<p>DisplayPort, HDMI, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="117">
<p>DisplayPort, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="128">
<p>DisplayPort, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
</tr>
<tr>
<td width="139">
<p>Разрешение HD</p>
</td>
<td width="122">
<p>1080p/i, 720p</p>
</td>
<td width="117">
<p>1080p/i, 720p</p>
</td>
<td width="117">
<p>1080p/i, 720p</p>
</td>
<td width="128">
<p>1080p/i, 720p</p>
</td>
</tr>
<tr>
<td width="139">
<p>Поддержка DirectX*</p>
</td>
<td width="122">
<p>DX 10</p>
</td>
<td width="117">
<p>DX 10</p>
</td>
<td width="117">
<p>DX 10</p>
</td>
<td width="128">
<p>DX 10</p>
</td>
</tr>
<tr>
<td width="139">
<p>Рейтинг совместимости Windows Vista*</p>
</td>
<td width="122">
<p>Premium</p>
</td>
<td width="117">
<p>Premium</p>
</td>
<td width="117">
<p>Premium</p>
</td>
<td width="128">
<p>Premium</p>
</td>
</tr>
<tr>
<td width="139">
<p>Поддержка OpenGL*</p>
</td>
<td width="122">
<p>2.0*</p>
</td>
<td width="117">
<p>2.0*</p>
</td>
<td width="117">
<p>2.0*</p>
</td>
<td width="128">
<p>2.0*</p>
</td>
</tr>
<tr>
<td width="139">
<p>Технология Intel® Clear Video</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
<tr>
<td width="139">
<p>Постпроцессинг HD-содержимого</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
</tbody>
</table>
<p>*Поддержка OGL 2.0 будет добавлена после обновления драйвера. Изначально поддерживается OGL 1.5.</p>
<p>Таблица 1: <strong>Функции графических ускорителей чипсетов Intel® 4 Series</strong></p>
<h2>Технология Intel® Clear Video</h2>
<p>Пользователи современных домашних кинотеатров систем ожидают от своего ПК отличного качества воспроизведения видео и высокой четкости изображения. Графические решения Intel с технологией Intel® Clear Video Technology имеют улучшенныесредства обработки видео и обладают богатым потенциалом для цифровых развлечений. Графические решения Intel также поддерживают новейшие форматы высокого разрешения, в том числе HD DVD и Blu-ray. В Таблице 2 указаны функции работы с видео, которые поддерживаются новейшими моделями интегрированных графических ускорителей Intel.</p>
<table class="tableformat1" border="0" cellspacing="0" cellpadding="5" width="624">
<tbody>
<tr>
<td width="94">
<p>Категория</p>
</td>
<td colspan="2" width="157">
<p>Функция</p>
</td>
<td width="60">
<p>G965</p>
</td>
<td width="53">
<p>G33<br /> G31</p>
</td>
<td width="53">
<p>G35</p>
</td>
<td width="69">
<p>G41</p>
</td>
<td width="69">
<p>G43</p>
</td>
<td width="69">
<p>G45</p>
</td>
</tr>
<tr>
<td rowspan="9" width="94">
<p> </p>
<p>Декодирование цифрового содержимого HD</p>
</td>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения VC1</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование VC1</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной VC1</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения MPEG2</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование c кодированием расстояния (DC) MPEG2</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной MPEG2</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td rowspan="10" width="94">
<p>Улучшение качества видео/пост-процессинг</p>
</td>
<td colspan="2" width="157">
<p>Поддержка Advanced DI (HD)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Поддержка Advanced DI (SD)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Определение модуляции/режима Film Mode для HD</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Определение модуляции/режима Film Mode для SD</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Фильтры Detail и Denoise</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Нелинейное анаморфное масштабирование</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>4x4 масштабирование с высоким качеством</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>6x6 масштабирование по полифазной матрице</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Управление цветом ProcAmp Color</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Управление цветом ProcAmp для HD</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="3" width="96">
<p>Защита цифрового содержимого</p>
</td>
<td width="156">
<p>COPP/OPM</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Защита от захвата экрана</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Protected Audio/Video Path (PAVP)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="2" width="96">
<p>Поддержка дисплея</p>
</td>
<td width="156">
<p>Поддержка разрешения Full HD 1080p</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Intel® TV Wizard</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="6" width="96">
<p>Интерфейсы дисплея</p>
</td>
<td width="156">
<p>HDMI (встроенный)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>HDMI (через SDVO)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>DisplayPort</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>S-video (через SDVO)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>DVI / SDVO / VGA</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Независимые выходы на два дисплея (Dual Independent Display)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
</tbody>
</table>
<p>Таблица 2: <strong>Сравнение чипсетов с технологией Intel® Clear Video</strong></p>
<p>Перечисленные ниже ресурсы Intel помогут вам получить как общую, так и более подробную информацию о графических ускорителях и чипсетах Intel.</p>
<p>Описание возможностей графических ускорителей Intel: <a href="http://download.intel.com/products/graphics/intel_graphics_guide.pdf">http://download.intel.com/products/graphics/intel_graphics_guide.pdf</a></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics/</link>
      <pubDate>Wed, 04 Feb 2009 13:00:00 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics/#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics/</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
  </channel></rss>
