СПОСОБ СОЗДАНИЯ СТЕРЕОСКОПИЧЕСКОГО ИНТЕРФЕЙСА ПОЛЬЗОВАТЕЛЯ КОМПЬЮТЕРА
METHOD OF CREATING STEREOSCOPIC COMPUTER USER INTERFACE

Изобретение относится к способам создания графического интерфейса пользователя компьютера, точнее к способам создания стереоскопического интерфейса пользователя компьютера, содержащего двухпортовый видеоконтроллер и устройство для показа стереоизображения на базе двух жидкокристаллических дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно. Изобретение может быть использовано для разработки специализированных систем обработки стереоизображений, предназначенных для работы операторов в стереоочках, например для фотограмметрических работ.
В последние годы в связи с появлением ЖК-дисплеев разработан ряд систем создания стереоизображений путем формирования двух изображений на двух отдельных ЖК-дисплеях и проецирования их на отдельную обозреваемую поверхность. Такие системы имеют преимущества перед стереосистемами на базе ЭЛТ-дисплеев, состоящие в меньших габаритах, в более экономном электропотреблении и в более высокой экологичности, связанной с меньшей утомляемостью глаз пользователя при использовании ЖК-дисплеев по сравнению с ЭЛТ-дисплеями.
С другой стороны, появились двухпортовые видеоконтроллеры, к двум выходам которых могут быть подключены указанные ЖК-дисплеи. Особенностью современных видеоконтроллеров является аппаратная реализация стандартов DirectX и OpenGL. При этом средства драйвера видеоконтроллера позволяют выбирать один из нескольких режимов работы видеоконтроллера. Одним из режимов является режим расширения рабочего стола, в котором окно рабочего стола может отображаться на двух дисплеях таким образом, что левая половина рабочего стола отображается на одном дисплее, а правая - на другом дисплее.
Полноценная работа пользователя с компьютером, к которому подключено указанное устройство создания стереоизображения, предполагает наличие стереоскопического графического интерфейса пользователя, в котором пользователю хорошо видны все элементы графического интерфейса (окна, кнопки, курсор мыши и т.п.) в рамках видимого им стереоизображения, которое может включать в себя как собственно стереоскопическое изображение, создаваемое приложением, так и плоские изображения, в том числе как элементы графического интерфейса данного приложения, так и изображения окон других приложений. Для выполнения этого условия средства графического интерфейса должны согласованно отображаться на обоих дисплеях, обеспечивая единое стереоскопическое изображение всего рабочего стола компьютера.
В патенте США 6344860 предложен способ создания стереоскопического изображения интерфейса пользователя, который очевидным образом может быть реализован на двух ЖК-дисплеях с использованием вышеуказанного режима расширения рабочего стола. Для этого достаточно отобразить главный и ведомый объекты интерфейса соответственно на экраны первого и второго дисплеев и тем самым создать требуемый стереоскопический графический интерфейс.
Способ состоит в том, что:
показывают на экране дисплея главный (master) объект интерфейса;
показывают на экране дисплея ведомый (slave) объект интерфейса, являющийся дубликатом главного объекта интерфейса и находящийся на фиксированном смещении от главного объекта интерфейса;
показывают главный курсор в одной части экрана дисплея;
показывают ведомый курсор в другой части экрана дисплея;
перемещают ведомый курсор в фиксированном соотношении относительно главного курсора на основании перемещения указывающего устройства, где перемещение ведомого курсора включает в себя перемещение ведомого курсора с корректировкой ведомого объекта интерфейса, чтобы отследить любые измерения, производимые в главном объекте интерфейса в ответ на по крайней мере одно из событий: MOUSE_MOVE, MOUSE_UP, MOUSE_DOWN, MOUSE_ENTER, MOUSE_EXIT;
определяют, меняется ли объект интерфейса ввиду перемещения главного курсора;
копируют новый фон в память, стирают ведомый курсор, стирают любые накладывающиеся части ведомого курсора исходя из нового фона и показывают новый ведомый курсор на новом фоне, если определено, что объект интерфейса меняется ввиду перемещения главного курсора;
стирают ведомый курсор, применяют изменения к объекту интерфейса и показывают новый ведомый курсор, если определено, что объект интерфейса не меняется ввиду перемещения главного курсора.
Недостатком этого способа является необходимость поддержания двух объектов интерфейса (главного и ведомого) и тем самым специальной разработки средств управления ресурсами, связанными с интерфейсом. Помимо курсора мыши, рассмотренного в патенте США 6344860, сюда могут относиться окна других приложений, всплывающие подсказки и т.д. Появление новых типов ресурсов вызывает необходимость разработки специальных средств управления такими ресурсами, совместимыми с данным интерфейсом.
В [http://www.racurs.ru/?page=102] приводится описание модуля PHOTOMOD Stereo Draw, предназначенного для создания и редактирования трехмерных векторных объектов в стереорежиме, который обеспечивает стереоскопический интерфейс пользователя. В соответствии с [http://www.racurs.ru/?page=405] для работы в оконных стереорежимах требуются профессиональные видеокарты (NVIDIA Quadro FX) с поддержкой стереорасширений OpenGL. Кроме того, в литературе отсутствует какая-либо информация о способе создания этого стереоскопического интерфейса пользователя.
Помимо способов создания стереоскопического интерфейса пользователя в целом имеется ряд технических решений, посвященных стереоскопическому показу отдельных элементов интерфейса пользователя. Так, в патенте США 6225979 предлагается способ стереоскопического показа курсора, в заявке US 2002/0047835 предлагается способ стереоскопического показа иконок.
В патенте РФ 2380763 предлагается способ создания стереоскопического интерфейса пользователя с использованием графического интерфейса прикладных программ DirectDraw, режима видеоконтроллера, в котором производится клонирование изображения на оба выхода видеоконтроллера, и оверлеев. Недостатком способа, описанного в патенте РФ 2380763, является невозможность использования классов, функций, методов и процедур DirectDraw в сочетании с современным оборудованием, использующим графические API DirectX версии 10 и выше, как указано в [http://msdn.microsoft.com/en-us/library/windows/desktop/gg426115%28v=vs.85%29.aspx], что также затрудняет получение прямого доступа к видеопамяти, используемое в способе, описанном в патенте РФ 2380763. Применение описанного в патенте РФ 2380763 метода с использованием объекта отсечения невозможно при использовании графического API Direct3D версий 10 и выше, как указано в [http://msdn.microsoft.com/en-us/library/windows/desktop/bb322323%28v=vs.85%29.aspx]. Наряду с этим, в патенте РФ 2380763 описывается использование интерфейса DirectDraw для настольных (Desktop) систем одновременно со ссылкой на функции мобильной платформы DirectDraw, которые отличны от функций DirectDraw для настольных (Desktop) систем.
С учетом сказанного, актуальной является разработка способа создания стереоскопического графического интерфейса пользователя компьютера с двухпортовым видеоконтроллером широкой номенклатуры и устройством для показа стереоизображения на базе двух ЖК-дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно, который был бы совместим с современным оборудованием, использующим графические API DirectX версии 10 и выше.
Это достигается за счет того, что устанавливают режим работы видеоконтроллера, в котором производится отображение изображения на оба выхода таким образом, что суммарное разрешение выходного сигнала превышает по горизонтали или вертикали в два раза разрешение монитора для отображения горизонтальной или вертикальной стереопары соответственно. Создают программный интерфейс прикладных программ, позволяющий создавать элементы графического пользовательского интерфейса в трехмерной сцене и устанавливают уровень кооперации указанного программного интерфейса в соответствии с типом приложения (полноэкранное, оконное или комбинированное), использующего выдачу на экран стереоизображений. В указанном интерфейсе создают трехмерную сцену средствами трехмерного графического движка в памяти компьютера. В процессе работы определяют, когда необходимо изменить детализацию элементов трехмерной сцены. Формируют первичное изображение в графическом буфере для первого глаза. Одновременно формируют разностное изображение в графическом буфере для второго глаза. Формируют сигнал на выходе видеоконтроллера, с учетом выбранного метода стереоскопического отображения. При этом непрерывно подают указанные сигналы для первого и второго глаза с первого и второго выходов видеоконтроллера на экраны указанных дисплеев.
Такой способ обеспечивает достижение основного технического результата, состоящего в обеспечении стереоскопического графического интерфейса пользователя компьютера с использованием современных существующих средств трехмерной графики. Кроме того, исключается необходимость разработки специальных средств управления ресурсами пользовательского интерфейса, связанных с наличием двух объектов, обеспечивающих изображения интерфейса для левого и правого глаза пользователя.
При наличии нескольких окон стереоскопического приложения возможно создание стереоскопического графического интерфейса пользователя в каждом таком окне при наличии аппаратной поддержки такой функции со стороны видеоконтроллера и монитора или совокупности мониторов [http://3dvision-blog.com/6109-when-and-how-you-can-use-the-3d-vision-windowed-3d-mode/].
Создание трехмерной сцены может включать в себя создание элементов графического пользовательского интерфейса, в том числе сложной формы, используя полигональные сетки (меши) либо маски прозрачности, текстовые элементы графического пользовательского интерфейса, используя технологию RTT (Render-To-Texture). При этом достигается дополнительный технический результат, состоящий в возможности создания элементов графического интерфейса произвольной сложной формы, а также в ускорении визуализации текстовых элементов интерфейса, возможности их отрисовки на поверхности любого элемента интерфейса и экономии видеопамяти.
Создание графического пользовательского интерфейса может включать в себя определение порядка следования элементов графического пользовательского интерфейса путем явного указания порядка следования таковых либо приоритета следования категорий элементов интерфейса. Определение порядка следования элементов может быть представлено в виде XML файла или какого-либо другого файла структурированных данных. При этом достигается дополнительный технический результат, состоящий в экономии вычислительных ресурсов и повышении удобства для пользователя при работе с таким интерфейсом.
Изменение трехмерной сцены в процессе работы программы может включать в себя изменение детализации элементов трехмерной сцены в зависимости от порядка следования таковых либо в зависимости от производительности аппаратной части и текущей нагрузки на таковую со стороны самого приложения, либо сторонних приложений в текущий момент времени, для поддержания величины задержки обработки одного кадра в графическом буфере в диапазоне, сравнимом с интервалом времени смены кадров на мониторах. Для изменения детализации элементов интерфейса может использоваться метод LOD (Level Of Details - уровень детализации), при котором помимо основной трехмерной модели элемента интерфейса создается аппроксимированные копии такой модели. Аппроксимированные копии могут создаваться в режиме реального времени либо заранее. В зависимости от текущей нагрузки на видеоконтроллер для визуализации выбирается либо оригинальная модель, либо та или иная аппроксимированная копия. При этом достигается дополнительный технический результат, состоящий в существенном ускорении процесса визуализации трехмерной сцены без потери информативности элементов графического интерфейса.
Изменение трехмерной сцены может включать в себя метод, при котором при необходимости вывода стереоскопических изображений или стереоскопического видеопотока в указанном окне приложения совершают ряд дополнительных операций, в т.ч. создают элемент-приемник, корректируют размеры такого элемента, измеряют стереоскопический параллакс элемента-приемника, измеряют стереоскопический параллакс стереоскопического изображения, отображаемого на таком элементе, проводят необходимые корректировки положения и размеров элемента-приемника. При этом достигается дополнительный технический результат, состоящий в возможности комфортного отображения заранее созданных сторонними средствами стереоскопических изображений в рамках стереоскопического графического интерфейса без нарушения непрерывности стереоскопического параллакса по глубине трехмерной сцены.
Отображение стереоизображения либо стереоскопического видеопотока на поверхности элемента-приемника может содержать принудительную подмену прямоугольных областей графического буфера, соответствующих левому и правому каналам проекции поверхности элемента-приемника на зрительную плоскость, на содержимое левого и правого каналов стереоизображения либо стереоскопического видеопотока путем вызова ряда необходимых функций, методов, процедур программного интерфейса драйвера видеоконтроллера либо передачи необходимых параметров программному интерфейсу драйвера видеоконтроллера при наличии аппаратной и программной поддержки подобных возможностей со стороны видеоконтроллера. При этом достигается дополнительный технический результат, состоящий в экономии вычислительных ресурсов, поскольку в этом случае не требуется определение стереоскопического параллакса стереоизображения и перестроение трехмерной сцены.
Визуализация трехмерной сцены может содержать возможность переключения левого и правого каналов путем вызова ряда необходимых функций, методов, процедур программного интерфейса драйвера видеоконтроллера либо передачи необходимых параметров программному интерфейсу драйвера видеоконтроллера при наличии аппаратной и программной поддержки подобных возможностей со стороны видеоконтроллера. При этом достигается дополнительный технический результат, состоящий в повышении гибкости применения стереоскопического интерфейса и более широком спектре используемого оборудования для отображения интерфейса.
В процессе работы системы расхождение итогового (наблюдаемого пользователем на дисплее) стереоскопического изображения (стереоскопический параллакс) может является изменяемым. Изменение стереоскопического параллакса может происходить путем изменения настроек драйвера видеоконтроллера либо иным способом. При этом достигается дополнительный технический результат, состоящий в повышении комфорта стереоскопического отображения интерфейса для пользователя.
При визуализации трехмерной сцены возможен поворот либо вращение элементов графического пользовательского интерфейса любым возможным способом. При этом достигается дополнительный технический результат, состоящий в расширении функционала графического интерфейса и повышении удобства его использования пользователем.
При отображении стереоскопического интерфейса может применяться преобразование цифрового сигнала изображения интерфейса, получаемого на выходе либо выходах видеоконтроллера, из цифрового в аналоговый. При этом достигается дополнительный технический результат, состоящий в расширении состава используемого оборудования для отображения интерфейса.
При создании трехмерной сцены может создаваться две и более точек наблюдения (камер) в трехмерной сцене. При этом достигается дополнительный технический результат, состоящий в повышении информативности графического интерфейса с помощью использования дополнительных вьюпортов (областей визуализации), содержащих разный набор элементов интерфейса, а также возможности создания стереокамер в трехмерной сцене, что приведет к экономии вычислительных ресурсов, затрачиваемых на операции пересчета стереоскопического параллакса.
Создание трехмерной сцены может производиться с помощью какого-либо графического движка, фреймворка либо платформы, в т.ч. такого, который использует Direct3D или OpenGL. При этом достигается дополнительный технический результат, состоящий в повышении скорости развертывания системы интерфейса, а также возможности более гибкого внедрения стереоскопического интерфейса в различные программные комплексы, использующие трехмерные графические движки.
Изобретение поясняется графическими материалами, где:
Фиг.1. Схемы подключения стереомониторов lcReflex-1703 и lcReflex-2002.
Фиг.2. Архитектура интерфейса прикладных программ.
Фиг.3. Структура графа трехмерной сцены
Фиг.4. Схема процесса определения области перекрытия окон.
Реализация изобретения
1. Общее описание
Устройство для обеспечения стереоскопического графического интерфейса пользователя компьютера включает в себя компьютер с двухпортовым видеоконтроллером и устройством для показа стереоизображения на базе двух жидкокристаллических дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно. В качестве видеоконтроллера могут использоваться, например, видеокарты Nvidia GTX580 и Nvidia GTX 680, а в качестве устройства создания стереоизображения на базе двух ЖК-дисплеев - например, стереомонитор lcReflex-1703 или lcReflex-2002. Их существенное для нас отличие состоит в том, что lcReflex-1703 имеет два VGA-входа, тогда как lcReflex-2002 имеет один VGA-вход и один DVI-D-вход [http://www.stereo-pixel.ru/lcreflex2002.htm]. Зарубежным прототипом этих изделий является стереомонитор StereoMirror [http://www.planar.com/products/desktop-touch-screen-monitors/stereoscopic-3d/].
На фиг.1 приведены схемы подключения стереомониторов lcReflex-1703 и lcReflex-2002 соответственно к выходам двухпортового видеоконтроллера. Преобразование цифрового DVI-сигнала в аналоговый VGA-сигнал осуществляют с помощью DVI-адаптера [http://www.svideo.com/dvi.html].
На фиг.2 приведена схема, взятая из [http://msdn.microsoft.com/ru-RU/library/windows/desktop/bb219679%28v=vs.85%29.aspx] (обозначенные на схеме элементы присутствуют и в Direct3D версий 10 и 11) и иллюстрирующая архитектуру интерфейса прикладных программ, в которой реализуется изобретение. Эта схема иллюстрирует связи между прикладными программами, интерфейсом дисплеев, уровнем аппаратных абстракций (hardware abstraction layer - HAL) и видеоконтроллером с аппаратурой дисплеев. Приложения осуществляют управление аппаратурой дисплеев через аппаратно-зависимый интерфейс дисплеев, который выполняет проверку параметров, управление видеопамятью и учетные операции. HAL может быть составной частью аппаратуры дисплеев или, напротив, может быть реализован в программном обеспечении компьютера. В последнем случае HAL обычно реализован как DLL. HAL создается и реализуется производителем видеокарт или микросхем видеоконтроллеров. Дополнительно интерфейс дисплеев может включать в себя уровень эмуляции аппаратуры (hardware emulation layer - HEL), чтобы эмулировать аппаратные свойства дисплеев, если они не реализованы в аппаратуре.
В качестве интерфейса прикладных программ (API) используют средства, позволяющие производить визуализацию трехмерной графики. Примерами систем, которые обеспечивают такой интерфейс, являются DirectX [http://msdn.microsoft.com/ru-RU/librarv/windows/desktop/bbl72268%28v=vs.85%29.aspx], OpenGL и т.д. Ниже рассматривается реализация предлагаемого способа на базе системы DirectX, причем реально используется только часть системы DirectX, обеспечивающая вывод изображений и трехмерной графики, и известная под названием Direct3D. В случае OpenGL реализация способа производится аналогично с изменениями, очевидными для специалиста в области программирования.
Прежде всего, устанавливают режим работы видеоконтроллера, в котором производится отображение изображения на оба выхода таким образом, что суммарное разрешение выходного сигнала превышает по горизонтали или вертикали в два раза разрешение монитора для отображения горизонтальной или вертикальной стереопары соответственно. Установка режима работы видеоконтроллера описывается ниже в п.2.
Далее создают программный интерфейс прикладных программ, позволяющий создавать элементы графического пользовательского интерфейса в трехмерной сцене, и устанавливают уровень кооперации указанного программного интерфейса в соответствии с типом приложения (полноэкранное, оконное или комбинированное), использующего выдачу на экран стереоизображений. В случае комбинированного приложения, которое может динамически переключаться пользователем в полноэкранный или оконный режим, производят отслеживание текущего режима работы приложения и соответственно изменяют уровень кооперации. Способы создания программного интерфейса и установки необходимого уровня кооперации рассматриваются ниже в п.3.
В указанном интерфейсе создают трехмерную сцену средствами трехмерного графического движка. Графический движок представляет собой объектно-ориентированный фреймворк, который включает все части процесса рендеринга в объектной модели, тем самым предоставляя абстрактный программный уровень. Основной задачей графического движка является построение и визуализация трехмерной сцены, представленной в программе в виде классов и объектов. Общая структура представления трехмерной сцены в графическом движке изображена на фиг.3.
В качестве графического движка можно использовать любой объектно-ориентированный трехмерный графический движок, в том числе разработанный исключительно для создания графического пользовательского интерфейса на основе трехмерной сцены, поддерживающий следующие функции: полная поддержка графических API OpenGL и Direct3D, совместимость с операционными системами Windows, Linux, Mac OS X и iOS, поддержка большинства графических файловых форматов, возможность программирования графического процессора, поддержка шейдерных языков высокого уровня. Примером удовлетворяющего требованиям графического движка является OGRE (Object-Oriented Graphics Rendering Engine) [http://www.ogre3d.org/about/features]. Классы и функции графического движка приводятся на примере таковых в графическом движке OGRE.
Объекты класса Entity содержат один или более объектов класса SubEntity, которые являются непосредственно визуализируемыми трехмерными объектами. Сами узлы сцены (объекты класса Scene Node) могут существовать без каких-либо прикрепленных к ним визуализируемых объектов, выполняя в данном случае служебную функцию маркера координат. Объект класса MovableObject прикрепляется к узлу сцены, таким образом движимые трехмерные объекты могут быть перемещены не только относительно начала координат трехмерной сцены, но и относительно локальной системы координат родительского объекта класса Node, что позволяет создавать составные элементы графического интерфейса, состоящие их нескольких трехмерных объектов, и оперировать ими как единым объектом. Таким образом, в системе определяется лишь одна матрица трансформации. Подобный метод наследования и управления объектами применяется в комплексе для всех элементов графического интерфейса. Объект класса Renderable является указателем на то, что все объекты связанного класса Subentity являются видимыми, т.е. их необходимо визуализировать.
Определяют состав элементов графического интерфейса, которые необходимо визуализировать в данный момент времени (на текущем кадре). Состав элементов интерфейса определяется прикладной программой и передается графической системе в виде структурированных данных, например, на языке XML, после чего инициализируют графический движок, строят общий граф трехмерной сцены, создают соответствующие объекты определенных классов.
Загружают в видеопамять ресурсы, необходимые для корректного отображения графического интерфейса, в том числе текстуры и шейдеры, инициализируют материалы. Создают объект менеджера сцены и разбивают пространство трехмерной сцены одним из существующих алгоритмов, например, BSP или окто-деревом. Затем создают объект класса камера. Определяют графическую подсистему рендеринга. Для загрузки и кэширования необходимых ресурсов задействуют объекты класса Resource. Объекты данного класса отвечают за загрузку, обработку, хранение, удаление из памяти таких ресурсов, как изображения, текстуры, трехмерные объекты, материалы, шрифты, векторные данные, пиксельные шейдеры. Для обеспечения кроссплатформенности интерфейса реализуют дочерние классы, отвечающие за загрузку изображений и текстур с учетом используемого графического API, поскольку формат представления таких данных различен в разных API.
Загрузку и инициализацию шейдеров осуществляют с помощью специального дочернего класса GPUProgram. Для обеспечения поддержки большинства шейдеров данный класс включает в себя дочерние классы для высокоуровневых шейдеров, таких как HSL, - класс HighLevelGPUProgram, и низкоуровневых (геометрических и вершинных) -классы D3D9GPUProgram, D3DllGPUProgram, GLGPUProgram, обеспечивающих инициализацию загружаемых шейдеров и предотвращение попыток выполнения участков кода шейдера, не поддерживаемых используемьм графическим API.
Создают главный цикл рендеринга, определяют необходимые параметры визуализации, в т.ч. параметры камеры, определяют режим приложения (полноэкранное, оконное, смешанное).
Определяют порядок следования элементов графического интерфейса с учетом установленного базового стереоскопического параллакса. Плоскость трехмерной сцены, параллельная полю зрения и, как следствие, плоскости экрана со стереоскопическим параллаксом, равным 0, соответствует ближайшему к наблюдателю массиву точек трехмерной сцены. Для пользователя все объекты, расположенные на этой плоскости, выглядят расположенными на поверхности экрана при стереоскопическом режиме отображения. Все объекты трехмерной сцены, расстояние от объекта камеры до которых превышает расстояние от объекта камеры до указанной плоскости, выглядят для пользователя расположенными от него дальше плоскости экрана в стереоскопическом режиме отображения.
Позиционируют элементы графического интерфейса в пространстве трехмерной сцены, учитывая заданную максимальную глубину сцены (максимально допустимый стереоскопический параллакс, вычисленный или заданный заранее). Данную операцию производят итерационно и повторяют на каждом кадре. В зависимости от суммарного количества элементов графического интерфейса выбирают минимальный шаг, т.е. минимальное расстояние по продольной оси наблюдения (продольной оси объекта камеры в системе координат объекта класса Node, к которому прикреплен объект камеры) между смежными (соседними) элементами графического интерфейса, что позволяет осуществлять комфортное стереоскопическое отображение интерфейса для пользователя при любом количестве элементов графического интерфейса. На каждой итерации (на каждом кадре визуализации) для всех объектов трехмерной сцены попарно проверяют данное минимальное расстояние. В случае, если минимальное расстояние оказывается меньше рассчитанного минимального шага, производят корректировку положения в пространстве трехмерной сцены всех объектов, что в некоторых случаях требует перестроения графа сцены. При этом заново запускают функцию разбиения пространства.
Выполняют подсчет количества перекрывающих друг друга элементов графического интерфейса. Перекрывающие друг друга элементы объединяют в множества. Из всех таких множеств выбирают такое множество, которое содержит максимальное количество элементов. В случае, если количество элементов выбранного множества оказывается равным или большим максимального количества элементов, производят изменение минимального шага и полное перестроение графа трехмерной сцены, что требует выполнения функции разбиения пространства. Максимальное количество элементов вычисляют по формуле
С=[(Pmax/Smin) - М]+D,
где Pmax - максимальный стереоскопический параллакс, Smin - минимальный шаг на текущем кадре визуализации, М - суммарное количество отображаемых на текущем кадре визуализации элементов графического интерфейса, D - т.н. буферное количество возможных элементов помимо существующих, которое задается заранее. Параметр D введен для ускорения работы программы, поскольку в таком случае перестроение трехмерной сцены производят не при каждом изменении количества элементов, а лишь в том случае, если величина такого изменения превышает D. Параметр D устанавливают на этапе инициализации графической подсистемы и не изменяют в процессе выполнения программы.
Определяют положение системного курсора операционной системы, производят сокрытие (исключение из потока визуализации) маркера системного курсора путем вызова функции ShowCursor (BOOL bShow) и установкой параметра bShow в значение FALSE. Создают специальный элемент графического интерфейса в виде объекта в пространстве трехмерной сцены, расположенном на видимой поверхности пересекаемого элемента графического интерфейса. Для определения пересечения курсора и элементов интерфейса выполняют построение трехмерного вектора, соединяющего точку в плоскости экрана (плоскость минимального параллакса), соответствующую позиции системного курсора и соответствующей точки на плоскости наблюдения. Определяют ближайший к наблюдателю элемент графического интерфейса, поверхность которого пересекает полученный вектор, после чего элемент графического интерфейса, соответствующий курсору, перемещают в определенную таким образом точку. В случае, если пересечения не обнаружено, элемент-курсор помещают в точку, соответствующую пересечению полученного вектора с плоскостью, расположенной от плоскости наблюдения на расстоянии, равном (С·Smin)/2.
Определяют необходимость изменения детализации элементов графического пользовательского интерфейса в зависимости от порядка следования таковых либо в зависимости от производительности аппаратной части и текущей нагрузки на таковую со стороны самого приложения либо сторонних приложений на текущей итерации визуализации, для поддержания величины задержки обработки одного кадра в графическом буфере в диапазоне, сравнимом с интервалом времени смены кадров на мониторах. Для этого задействуют функции API операционной системы. Величину текущей задержки обработки кадра определяют по меткам процессорного времени (функция microtime()).
Определение того, когда необходимо производить вывод измененных изображений в соответствующее окно приложения, может производиться способом, состоящим в обеспечении синхронного изменения изображения с достаточно высокой частотой, обеспечивающей комфортное восприятие изображения пользователем. Приемлемой является частота 60 Гц, совпадающая с частотой обновления кадров ЖК-мониторами. В этом случае применяется программируемый таймер, использующий функцию MicroTime(). Обработчик событий таймера запускает средства формирования обновленных изображений. Достоинством такого способа является его простота. Дополнительно можно использовать то, что, в соответствии с системными соглашениями Windows, при изменении положения или размера окна создается системное сообщение, которое может быть получено приложением [http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx]. Для этого приложение может использовать одну из нескольких функций, самой распространенной из которых является WndProcQ. При отсутствии сообщения принимается решение, что вывод измененных изображений, изменения которых связаны исключительно с изменением конфигурации окон, не требуется.
При необходимости осуществляют комбинирование различного стереоскопического контента на поверхности элементов графического интерфейса. Подробнее этот вопрос рассмотрен в п.4.
Выполняют непосредственно визуализацию трехмерной сцены и передают полученное изображение либо пару изображений (в зависимости от выбранной технологии стереоскопического отображения) в графический буфер видеопроцессора. Для этого задействуют функции класса HardwareBuffer графического движка. Подробнее данный процесс рассмотрен в п.5.
Определяют часть окна программы, перекрываемую окнами других приложений. Для этого определяют координаты левого верхнего угла и размеры окна стереоскопического приложения с помощью соответствующих функций WinAPI Windows.Forms.LocationQ и Windows.Forms.Size(). Для каждого стороннего окна определяют прямоугольную область пересечения с рабочей областью приложения, представленную в программе объектом типа Rectangle [http://msdn.microsoft.com/ru-ru/library/system. drawing.rectangle.aspx]. После этого объединяют все прямоугольники, соответствующие перекрывающим областям окон сторонних приложений, в результате чего получают координатное описание фигуры перекрытия, соответствующей перекрываемой области окна стереоскопического приложения. В трехмерной сцене создают спрайт, соответствующий указанной фигуре перекрытия. Для конвертации экранных координат в координаты трехмерной сцены используют функцию ConvertPixelsToClipSpace(). После этого из-за изменения состава графа сцены совершают переразбиение пространства трехмерной сцены таким образом, что полигоны, находящиеся по отношению к камере за поверхностью спрайта, исключаются из визуализации, что приводит к существенному ускорению процесса рендеринга при оконном режиме работы стереоскопического приложения. Созданный спрайт закрашивают текстурой, которую создают из изображения, сформированного для первого глаза. Подробнее это описано в п.6.
Корректировка изображения может приводить к так называемому расхождению (tearing) при смене кадров на экранах мониторов [http://www.anandtech.com/show/2803/5]. Суть этого явления состоит в том, что при выдаче очередного кадра на экран монитора начало кадра может соответствовать старому изображению, а конец кадра - новому изображению. В этом случае на экране монитора появляется горизонтальная полоса, разделяющая два плохо стыкующихся между собой изображения. Для устранения этого эффекта при формировании изображений для первого и второго глаза и при корректировке визуальных атрибутов изображения дополнительно может использоваться синхронизация выполнения этих операций со сменой кадров на мониторах. Более подробно этот вопрос рассматривается в п.7.
В соответствии с частотой смены кадров мониторов формируют сигнал изображения интерфейса для первого глаза на первом выходе видеоконтроллера и одновременно формируют сигнал изображения для второго глаза на втором выходе видеоконтроллера. Клонирование изображения для второго глаза осуществляется видеоконтроллером за счет выполненной настройки видеоконтроллера. При этом клонированное изображение накладывается на изображение, сформированное для второго глаза, с помощью спрайта, что дает окончательное изображение для второго глаза. При этом на первом и на втором выходах видеоконтроллера получаются соответственно цифровой сигнал изображения для первого и для второго глаза, имеющий формат DVI. В зависимости от используемого стереомонитора эти сигналы либо непосредственно подают на входы ЖК-мониторов, либо дополнительно перед подачей на монитор производят преобразование цифрового сигнала в аналоговый с помощью конвертера DVI в VGA.
В процессе работы компьютера непрерывно подают изображения для первого и второго глаза с первого и второго выходов видеоконтроллера на экраны указанных дисплеев. Пользователь рассматривает изображение на экране стереомонитора через стереоочки.
Докажем, что при выполнении описанного способа достигается основной технический результат, состоящий в обеспечении стереоскопического графического интерфейса пользователя.
Рассмотрим сначала статический случай, когда не производится никакого перемещения или изменения размеров окон. В соответствии с установленным режимом работы видеоконтроллера производится расширение изображения с основной поверхности на оба выхода видеоконтроллера, сигналы с которых подаются на первый и второй монитор соответственно. Следовательно, во всех местах стереоизображения, которые не накрыты спрайтом, пользователь будет видеть обоими глазами одно и то же изображение. Поскольку форма и положение спрайта в экранных координатах соответствует областям клиентской части стереоокна, закрытым другими окнами, то в таких областях вместо содержимого стереоскопического окна будет видно содержимое изображения для первого глаза. Таким образом, все окна, закрывающие какую-либо часть стереоокна или расположенные вне стереоокна, будут видны двум глазам пользователя одинаково. Тем самым пользователь в стереоочках будет хорошо видеть все другие окна как плоские изображения, расположенные в одной плоскости. С другой стороны, в тех местах стереоизображения, для которых задана прозрачность спрайта, поскольку спрайт используется только для второго выхода видеоконтроллера, изображение для первого глаза будет совпадать с изображением в окне, а изображение для второго глаза будет совпадать с изображением на спрайте. Следовательно, в области клиентской части окна со стереоизображением изображение для первого и второго глаза совпадают с ранее сформированными изображениями для первого и второго глаза, т.е. пользователь будет видеть стереоизображение.
Рассмотрим теперь, что будет происходить при изменении изображения в стереоокне в случае, когда размеры и положение стереоокна и других окон не меняются. Изменения изображения в стереоокне происходят в соответствии с логикой работы приложения, создающего стереоизображение. В соответствии с системными соглашениями Windows, при изменении положения или размера окна создается системное сообщение, которое может быть получено приложением [http://msdn.microsoft.com/en-us/library/ms644990%28VS.85%29.aspx]. Для этого приложение может использовать одну из нескольких функций, самой распространенной из которых является WndProcQ. В этом случае выполнение приложением вышеописанного этапа определения необходимости производить вывод изображений в соответствующее окно указанного приложения и на спрайт приводит к принятию решения о том, что необходимо производить вывод изображений. После этого приложение производит вывод измененных изображений. Для измененных изображений имеет место все, что было описано в предыдущем абзаце, т.е. в этом случае пользователь будет видеть правильное стереоскопическое изображение интерфейса с измененным стереоизображением в клиентской части окна приложения. Если по логике работы приложения происходит непрерывное изменение стереоизображения, например в случае проигрывания на компьютере стереофильма, качество изображения будет существенно зависеть от синхронности обновления изображения для первого и второго глаза.
Поскольку обновление кадров на обоих мониторах происходит с частотой обновления кадров монитора, которая составляет порядка десятков герц, достаточно, чтобы цикл обновления изображения на первом и втором выходах укладывался в интервал времени порядка 10 мс, что вполне реально для современных компьютеров и видеоконтроллеров.
Наконец, рассмотрим поведение стереоизображения при изменении положения или размеров стереоокна или других окон. При изменении положения или размеров стереоокна или других окон выполнение приложением вышеописанного этапа определения необходимости производить вывод изображений в соответствующее окно указанного приложения и на оверлей приводит к обнаружению факта возникновения события изменения формы или положения какого-либо окна, в т.ч. окна стереоскопического приложения. В этом случае производится корректировка изображения на втором выходе с учетом нового расположения окон, и после выполнения всех действий, связанных с формированием изображений, пользователь будет видеть правильное стереоизображение, как и в вышерассмотренном статическом случае. С учетом того, что обнаружение факта возникновения событий изменения формы и положения области клиентской части окна, в которое производится вывод стереоизображения, не закрытой другими окнами, происходит с задержкой, сравнимой с интервалом времени смены кадров на мониторах, время установления правильного изображения будет сравнимо с интервалом времени смены кадров на мониторах. Таким образом, в самом худшем случае возможно некоторое мелькание или кратковременное неправильное изображение в тех частях экрана, в которых изменилось видимое окно, после чего установится правильное стереоизображение. Если указанная задержка составляет только долю интервала времени смены кадров на мониторах, то время установления правильного изображения окажется меньше времени смены кадров на мониторах, и указанного кратковременного появления неправильного изображения не будет вообще.
2. Установка режима работы видеоконтроллера
В соответствии с действующей концепцией Windows (начиная с Windows 2000) драйверов видеокарт установка тех аспектов режима работы видеоконтроллера, которые связаны с управлением конфигурацией видеомониторов, возложена на мини-порт-драйвер видеокарт. При этом установка режимов горизонтального кадрирования (panning), включающая в себя, в частности, неиспользование режима расширения рабочего стола на два монитора, в мини-порт-драйвере должна производиться только по запросам через панель управления [http://msdn.microsoft.com/en-us/library/ff570516.aspx]. По этой причине установка режима работы видеокарты производится пользователем в окне настроек монитора.
Для установки режима работы видеокарты Nvidia GTX580 или Nvidia GTX 680 в контекстном меню рабочего стола выбирают пункт «Свойства» и в появившемся окне «Свойства: Экран» выбирают вкладку «Параметры». На этой вкладке щелчком мышью в кнопку «Дополнительно» открывают окно «Свойства: Модуль подключения монитора…», в котором выбирают вкладку «Мониторы», на которой выбирают необходимый режим работы видеоконтроллера.
Наряду с использованием мыши настройку режима работы видеокарты в окне «Свойства: Модуль подключения монитора» можно производить с помощью клавиатуры, используя клавишу Tab для перехода между кнопками окна и клавишу Enter вместо щелчка мышью.
3. Создание программного интерфейса и установка уровня кооперации
Способы создания программного интерфейса и установки уровня кооперации зависят от типа приложения, использующего вывод стереоизображений (полноэкранное, оконное или комбинированное). Эти способы рассматриваются в пп 3.1, 3.2 и 3.3 соответственно.
3.1. Полноэкранные приложения
Приложения с полноэкранным эксклюзивным режимом создают путем инициализации Direct3D определением устройства D3D pDirect3D=Direct3DCreate9(D3D_SDK_VERSION), указанием режима D3DDISPLAYMODE Display, вызовом функции pDirect3D ->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Display) и определением параметров D3DPRESENT_PARAMETERS Direct3DParametr: Direct3DParametr.FullScreen_RefreshRateInHz=Display.RefreshRate;
Direct3DParametr.Windowed=FALSE.
Эти параметры удерживают приложение на переднем конце z-порядка окон и запрещают GDI рисовать поверх окна приложения.
При создании окна операционная система Windows возвращает приложению указатель созданного окна, при обработке которого производят создание программного интерфейса и установку уровня кооперации. Создание программного интерфейса включает в себя:
- получение списка всех драйверов Direct3D;
- выбор драйвера Direct3D;
- инициализацию Direct3D с использованием выбранного драйвера и установку уровня кооперации Direct3DParametr.Windowed;
- получение списка поддерживаемых видеорежимов;
- выбор исходного видеорежима;
- активизацию выбранного видеорежима.
Эти действия выполняют известными способами, описанными, например, в [http://www.codesampler.com/d3dbook/chapter_04/chapter_04.htm].
3.2. Оконные приложении
Как и в случае полноэкранного режима, при создании главного окна приложения операционная система Windows возвращает приложению указатель созданного окна, при обработке которого производят создание программного интерфейса и установку уровня кооперации. В отличие от полноэкранного приложения, создание программного интерфейса для оконного приложения включает в себя:
- инициализацию Direct3D с использованием уже задействованного в системе драйвера и установку уровня кооперации DirectSDParametr. Windowed=TRUE;
- получение информации о текущем видеорежиме.
Эти действия выполняют известными способами, описанными, например, в [http://www.morrowland.com/apron/tutorials/d3d/d3d_window.php]. При этом в функции инициализации Direct3D в качестве глобального идентификатора драйвера указывают 0, что означает, что используется видеокарта, задействованная в данный момент в системе.
3.3. Комбинированные приложения
В соответствии с [http://www.rastertek.com/dxlltut03.html] комбинированное приложение позволяет переключаться между оконным и полноэкранным режимами по ходу работы приложения, которое можно запустить в оконном режиме. Если же приложение работает слишком медленно, то пользователь имеет возможность переключиться в полноэкранный режим. Приложение запускается в полноэкранном режиме, но в любой момент работы программы можно переключиться в альтернативный режим, нажав комбинацию клавиш<Alt>+<Enter>, о чем пользователя обычно информирует подсказка, располагающаяся в левом верхнем углу экрана.
Для комбинированного приложения при переключении режимов повторяют весь способ инициализации заново для нового режима, предварительно выполнив уничтожение объекта Direct3D и окна, существовавших до переключения режима. Для этого освобождают все ресурсы, созданные при работе до переключения режима, с помощью функций pDirect3DDevice -> ReleaseQ и pDirect3D -> ReleaseQ из соответствующих классов, после чего создают все необходимые ресурсы в новом режиме и устанавливают уровень кооперации, соответствующий новому режиму.
4. Совмещение различного стереоскопического графического контента при необходимости вывода стереоскопических изображений или стереоскопического видеопотока в рамках стереоскопического графического пользовательского интерфейса выполняют следующие операции.
Определяют или создают элемент-приемник в трехмерной сцене, представляющий собой прямоугольный элемент графического пользовательского интерфейса, представленный в виде набора полигонов, на поверхности которого будут отображать стереоизображение либо стереоскопический видеопоток. Определение такого элемента осуществляют либо на основании действий пользователя, либо автоматически при наличии среди элементов интерфейса свободного (незанятого в текущий момент элемента-приемника). При отсутствии такового элемент-приемник создают средствами графического движка автоматически путем определения объекта класса Node, к которому прикрепляют объекты классов Entity [http://www.ogre3d.org/docs/api/html/classOgre_l_lEntity.html] и ManualObject [http://www.ogre3d.org/tikiwiki/ManualObject].
При необходимости размеры выбранного элемента-приемника изменяют таким образом, чтобы соотношение сторон прямоугольной плоской поверхности указанного элемента-приемника соответствовало соотношению сторон стереоизображения или соотношению сторон кадра видеопотока. Изменение размеров элемента-приемника производят путем исполнения вершинных или геометрических шейдеров, либо напрямую указывают новые координаты для каждой из вершин трехмерного меша, представленного в программе объектом класса ManualObject.
Производят вычисление стереоскопического параллакса элемента-приемника по формуле:
Ре=(Pmax·Se)/Smin,
где Pmax - максимальный стереоскопический параллакс, Se - глубина элемента-приемника, Smin - минимальный шаг на текущем кадре визуализации.
Затем вычисляют минимальный стереоскопический параллакс стереоизображения либо стереоскопического видеопотока. Для этого определяют характерные пары точек изображения, вычисляют вектор расхождения для каждой пары характерных точек в двумерном пространстве изображения. Далее определяют пару характерных точек с минимальной длиной вектора. Длина вектора определенной пары точек определяется как минимальный стереоскопический параллакс изображения.
Проверяют условие превышения стереоскопическим параллаксом элемента-приемника минимального стереоскопического параллакса стереоизображения либо стереоскопического видеопотока. В случае подтверждения условия элемент-приемник перемещают в пространстве трехмерной сцены по направлению к точке наблюдения по продольной оси наблюдения на расстояние, равное минимальному шагу Smin, тем самым уменьшая стереоскопический параллакс элемента-приемника. Данную операцию повторяют до тех пор, пока стереоскопический параллакс элемента-приемника не окажется меньшим или равным минимальному стереоскопическому параллаксу стереоизображения или стереоскопического видеопотока.
В случае, если стереоизображение или стереоскопический видеопоток являются комбинированными, т.е. состоящими из двух и более однотипных графических ресурсов, для каждого из которых определена маска прозрачности (альфа-канал), производят следующие действия.
Вычисляют минимальный стереоскопический параллакс каждого из стереоизображений либо стереоскопических видеопотоков, образующих комбинированное стереоизображение либо комбинированный стереоскопический видеопоток вышеуказанным методом. Таким образом, для каждого элемента комбинированного стереоскопического графического ресурса повторяют этап 2 в части вычисления минимального стереоскопического параллакса.
Создают дополнительные поверхности элемента-приемника, каждая из которых расположена соответственно минимальному стереоскопическому параллаксу стереоизображения или стереоскопического видеопотока и представляет собой объект класса SubEntity, связанный с объектом класса Entity, соответствующим элементу-приемнику, аналогично созданию самого элемента-приемника. Глубину каждой из поверхностей определяют по формуле:
Zs=[\(Pr-Ре)|/Smin]+Ze,
где Pr - минимальный стереоскопический параллакс стереоизображения или стереоскопического видеопотока, Ре - стереоскопический параллакс элемента-приемника, Smin - минимальный шаг, Ze - глубина элемента-приемника.
Проверяют условие параллельности векторов нормалей поверхностей элемента-приемника и продольной оси наблюдения. В случае непараллельности таковых положение и размер дополнительных поверхностей элемента-приемника корректируют при помощи афинных преобразований либо путем задания кватернионов преобразования таким образом, чтобы нормали указанных поверхностей и продольной оси наблюдения были параллельны. Осуществление преобразований производят путем вызова функций D3DXMatrixPerspectiveFovLH и pDirect3DDevice->SetTransform(D3DTS_PROJECTION, &MatrixProjection).
Производят загрузку необходимых графических ресурсов для отображения элемента-приемника, после чего средствами графического движка осуществляют визуализацию трехмерной сцены, содержащей элемент-приемник.
5. Визуализация трехмерной сцены
Визуализация трехмерной сцены выполняется средствами графического движка. В случае использования API Direct3D визуализация в общем случае может выполняться с помощью программного кода, аналогичного следующему.
VOID RenderingDirect3D()
{
if(pDirect3DDe vice=NULL) // если интерфейс создан, то можно приступать к рендерингу
return;
// чистим задний буфер
pDirect3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(39, 64, 139), 1.0f, 0); //(23, 95, 54)
pDirect3DDevice->BeginScene();
// указываем источник для визуализации
pDirect3DDevice->SetStreamSource(0, pBufferVershin, 0, sizeof(CUSTOMVERTEX));
// указываем тип вершин
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, CIRCLE_RES*2);
// Отрисовка элементов
pDirect3DDevice->SetStreamSource(0, pBufferObjects, 0, sizeof(CUSTOMVERTEX));
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, 3);
pDirect3DDevice->EndScene();
pDirect3DDevice->Present(NULL, NULL, NULL, NULL); // Вывод заднего буфера }.
В случае отображения горизонтальной стереопары определяют два вьюпорта, для первого и правого глаза соответственно, и располагают их в позициях [0] и [0,5] относительно полного разрешения экрана по горизонтали.
Вьюпортом называется проекция вида из камеры на поверхность рендера (в данном случае, на экран) - камера визуализирует сцену из вьюпорта и размещает результаты в некое подмножество целей прорисовки ("rendering target"), которое может занимать всю поверхность рендера или только часть этой поверхности. Каждый вьюпорт имеет одну камеру в качестве источника и одну цель в качестве точки назначения. Одна камера имеет только 1 вьюпорт, но может иметь несколько целей. Вьюпорт также имеет порядок наложения Z-order (порядок расположения объектов по оси Z по отношению к наблюдателю), то есть, если имеется более одного вьюпорта на единственную цель прорисовки, и эти вьюпорты частично перекрываются, один из них должен перекрывать другой по некоторым предопределенным правилам [http://www.ogre3d.org/docs/api/html/classOgre_l_lViewport.html].
В графическом движке Z-order для объектов класса Viewport определяют по следующим правилам: чем меньше параметр Z-order, тем дальше объект от наблюдателя. [http://www.ogre3d.org/docs/api/html/classOgre_l_lViewport.html].
Инициализацию создания вьюпортов производят с помощью вызова функции AddVieport в рамках графического движка:
//Создание вьюпортов:
Viewport* vp=mWindow->addViewport(mCamera,0,0,0,.5,1);
Viewport* vp2=mWindow->addViewport(mCamera2,1,.5,0,.5,1),
которая устанавливает виртуальные камеры в сцене в нужные позиции и производит рендеринг из этих камер.
Первый параметр функции определяет используемую камеру, второй параметр - порядок наложения (Z-order) вьюпорта (чем выше, тем ближе к наблюдателю), причем этот параметр не может быть одним и тем же для двух (и более) вьюпортов, даже если они не перекрываются. Следующие 2 параметра - это положения левого и верхнего краев вьюпорта, которые выражаются числом из диапазона от 0 до 1. Последние 2 параметра - ширина и высота вьюпорта в процентном выражении относительно размеров экрана (они также выражены в диапазоне от 0 до 1).
В случае вертикальной стереопары определяют два вьюпорта аналогично случаю горизонтальной стереопары и располагают их в позициях [0] и [0,5] относительно полного разрешения экрана по вертикали.
В случае анаморфной горизонтальной стереопары стереопару сжимают по горизонтали вдвое при помощи пиксельного шейдера.
В случае анаморфной вертикальной стереопары стереопару сжимают по вертикали вдвое при помощи пиксельного шейдера.
Чересстрочную стереопару получают из горизонтальной стереопары посредством применения шейдера, который на нечетные строки ставит нечетные строки одного вьюпорта, а на четные - нечетные строки второго вьюпорта. Пример такого шейдера:
float4x4 WorldViewProj: WorldViewProjection;
float4 mainVS
(
float4 pos: POSITION,
float2 uv: TEXCOORDO,
out float2 oUv: TEXCOORDO
)
: POSITION
{
oUv=uv;
return mul(pos, WorldViewProj);
}
float4 mainPS
(
float2 uv: TEXCOORDO,
uniform sampler2D evenSample: register(s0),
uniform sampler2D oddSample: register(s1),
uniform float4 texSize
)
: COLOR
{
float4 even=tex2D(evenSample, uv);
float4 odd=tex2D(oddSample, uv);
return (fmod(uv.y * texSize.y, 2)=0) ? even: odd;
}
6. Создание спрайта для кооперации окна приложения с окнами сторонних приложений
Для быстрого создания и визуализации спрайта (плоский объект с текстурой), применяют геометрический и пиксельный шейдеры.
Создают геометрический шейдер на языке HLSL (High Level Shader Language).
Пример геометрического шейдера:
[maxvertexcount(6)]
void GS(point GS_INPUT point[1], inout TriangleStream<PS_INPUT>triStream)
{
PS_INPUT vl,v2,v3,v4,v5,v6;
//Для каждой вершины спрайта:
v.p=float4(sprite[0].topLeft[0],sprite[0].topLeftill-sprite [0].dimensions[1],0,1);
v.t=float2(0,1);
triStream.Append(v);
}
После создания геометрического шейдера задают функцию конвертирования экранных координат в координаты трехмерной сцены.
Пример такой функции:
inline float convertPixelsToClipSpace(const int pixelDimension, const int pixels)
{
return (float)pixels/pixelDimension*2 -1;
}
inline float convertPixelsToClipSpaceDistance(const int pixelDimension, const int pixels)
{
return (float)pixels/pixelDimension*2;
}
После этого создается пиксельный шейдер:
struct PS_INPUT
{
float4 p: SV_POSITION;
float2 t: TEXCOORD;
float opacity: OPACITY;
}
Рассчитывают размер и положение спрайта путем указания вершин спрайта. Для прямоугольного спрайта данная операция может выглядеть следующим образом:
verts[0].topLeft[0]=convertPixelsToClipSpace(800,200);
verts[0].topLeft[1]=-convertPixelsToClipSpace(600,0);
verts[0].dimensions[0]
convertPixelsToClipSpaceDistance(800,400);
verts[0].dimensions[1]
convertPixelsToClipSpaceDistance(600,42);
verts[0].opacity=1.
После данных операций создается вершинный буфер:
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem=& verts;
D3D10_BUFFER_DESC bd;
bd.Usage=D3D10_USAGE_DEFAULT;
bd.ByteWidth=sizeof(SpriteVertex) * (numSprites);
bd.BindFlags=D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags=0;
bd.MiscFlags=0;
if (FAILED(pD3DDevice->CreateBuffer(&bd, ScinitData, &pVertexBuffer))) return fatalError("Could not create vertex buffer!").
Шейдеры включают в технику рендера методом, поддерживаемым используемым API. Например, так:
technique10 RENDER
{
pass P0
{
SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(CompileShader(gs_4_0, GS()));
SetPixelShader(CompileShader(ps_4_0, PS()));0.0f, 0.0f, 0.0f, 0.0f), 0×FFFFFFFF);
}
}.
В случае запуска стереоскопического приложения в оконном режиме встает необходимость обеспечения кооперации с окнами сторонних приложений в случае перекрытия окнами сторонних приложений рабочей области стереоскопического приложения. Наряду с этим существенным ускорением процесса визуализации трехмерной сцены является обеспечение вывода в поток рендеринга только тех областей трехмерной сцены, которые не перекрываются окнами сторонних приложений. Данные задачи реализуют с помощью следующей последовательности операций.
Итеративно (на каждом кадре визуализации) проверяют условие работы стереоскопического приложения в оконном режиме с помощью отслеживания событий инициализации Direct3D и считывания булевого параметра FULL_SCREEN. Все последующие операции выполняют лишь в том случае, если параметр FULL SCREEN является ложью (false).
Определяют координаты левого верхнего угла и размеры окна стереоскопического приложения с помощью соответствующих функций WinAPI Windows.Forms.Location() и Windows.Forms.Size(). В результате создают объект типа Rectangle.
Производят циклический перебор всех открытых окон операционной системы, имеющих видимую клиентскую часть и имеющих более высокий Z-уровень по сравнению с окном стереоскопического приложения. Для каждого такого окна определяют прямоугольную область пересечения с рабочей областью стереоскопического приложения, представленную в программе объектом типа Rectangle [http://msdn.microsoft.com/ru-ru/library/system.drawing.rectangle.aspx].
Производят объединение всех прямоугольников, соответствующих перекрывающим областям окон сторонних приложений, в результате чего получают координатное описание фигуры, соответствующей перекрываемой области окна стереоскопического приложения. Схема данного процесса представлена на фиг.4.
В трехмерной сцене создают спрайт, соответствующий фигуре перекрытия. Для конвертации экранных координат в координаты трехмерной сцены используется функция ConvertPixelsToClipSpace, аналогичная описанной в п.6. После этого из-за изменения состава графа сцены производят переразбиение пространства трехмерной сцены таким образом, что полигоны, находящиеся по отношению к камере за поверхностью спрайта, исключаются из визуализации, что приводит к существенному ускорению процесса рендеринга при оконном режиме работы стереоскопического приложения.
Производят итеративное (на каждом кадре визуализации) отслеживание событий перемещения окон сторонних приложений, окна стереоскопического приложения, изменение состава видимых окон, их Z-индекса, а также их размеров. В случае успеха такой проверки выполняют изменение формы и положения спрайта описанным способом.
7. Синхронизация корректировки изображений со сменой кадров
Вертикальная синхронизация (VSync: Vertical Synchronization) - это опциональный параметр поведения драйвера видеокарты. Включенная вертикальная синхронизация означает, что после отрисовки очередного кадра, во время переключения буферов (функция SwapBuffers() в OpenGL и функция IDirect3DSwapChain() в Direct3D) драйвер будет ждать начала очередного обратного хода луча монитора и только потом переключит экранные буферы.
Для синхронизации корректировки изображений со сменой кадров необходимо, чтобы вертикальная синхронизация была включена. Это можно сделать по меньшей мере двумя способами.
Включить или выключить vsync обычно можно вручную в настройках драйвера видеокарты. Для этого открывают окно настройки экрана Display Properties (правой кнопкой мыши кликают на рабочем столе и выбирают пункт выпадающего меню Свойства (Properties)), выбирают вкладку Настройки (Settings), нажимают кнопку Дополнительно (Advanced), указывают настройки для ожидания вертикальной синхронизации (Wait for Vertical Sync) путем включения или отключения флага [http://www.ehow.com/how_7872535_open-device-driver-vertical-synchronize.html].
Чтобы программно включить или выключить VSync в OpenGL, выполняют следующий программный код (или аналогичный) [http://www.gamedev.ru/tip/?id=3719]:
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int intervals);
void set_vsync(bool enabled) // true -- VSync включен, false -- выключен
{
PFNWGLSWAPINTERVALEXTPROC wglSwapInterval=NULL;
wglSwapInterval=(PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapInterval) wglSwapInterval(enabled ? 1: 0);
}
Чтобы программно включить или выключить VSync в Direct3D, перед инициализацией D3DDevice присваивают полям структуры D3DPRESENT_PARAMETERS следующие значения, чтобы включить синхронизацию
[http://www.gamedev.ru/terms/vsync]:
g_d3d9Parameters.SwapEffect=D3DSWAPEFFECT_COPY;
g_d3d9Parameters.Presentation!nterval=D3DPRESENT_INTERVAL_ONE;
Отметим, что при использовании сглаживания вместо D3DSWAPEFFECT_COPY устанавливают D3DSWAPEFFECT_DISCARD.