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

Изобретение относится к способам создания графического интерфейса пользователя компьютера, точнее, к способам создания стереоскопического интерфейса пользователя компьютера, содержащего двухпортовый видеоконтроллер и устройство для показа стереоизображения на базе двух жидкокристаллических дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно. Изобретение может быть использовано для разработки специализированных систем обработки стереоизображений, предназначенных для работы операторов в стереочках, например, для фотограмметрических работ.
В последние годы в связи с появлением ЖК-дисплеев разработан ряд систем создания стереоизображений путем формирования двух изображений на двух отдельных ЖК-дисплеях и проецирования их на отдельную обозреваемую поверхность. Такие системы имеют преимущества перед стереосистемами на базе ЭЛТ-дисплеев, состоящие в меньших габаритах, в более экономном электропотреблении и в более высокой экологичности, связанной с меньшей утомляемостью глаз пользователя при использовании ЖК-дисплеев по сравнению с ЭЛТ-дисплеями.
С другой стороны, появились двухпортовые видеоконтроллеры, к двум выходам которых могут быть подключены указанные ЖК-дисплеи. Особенностью современных видеоконтроллеров является аппаратная реализация стандартов DirectX и OpenGL. При этом средства драйвера видеоконтроллера позволяют выбирать один из нескольких режимов работы видеоконтроллера. Одним из режимов является режим выдачи одного и того же изображения на оба дисплея (режим клонирования) с использованием оверлея, причем в зависимости от настроек драйвера видеоконтроллера оверлей может отображаться как на оба дисплея, так и только на один из дисплеев. Другим режимом является режим расширения рабочего стола, в котором окно рабочего стола может отображаться на двух дисплеях таким образом, что левая половина рабочего стола отображается на одном дисплее, а правая - на другом дисплее.
Полноценная работа пользователя с компьютером, к которому подключено указанное устройство создания стереоизображения, предполагает наличие стереоскопического графического интерфейса пользователя, в котором пользователю хорошо видны все элементы графического интерфейса (окна, кнопки, курсор мыши и т.п.) в рамках видимого им стереоизображения, которое может включать в себя как собственно стереоскопическое изображение, создаваемое приложением, так и плоские изображения, в том числе как элементы графического интерфейса данного приложения, так и изображения окон других приложений. Для выполнения этого условия средства графического интерфейса должны согласованно отображаться на обоих дисплеях, обеспечивая единое стереоскопическое изображение всего рабочего стола компьютера.
В патенте США 6344860 предложен способ создания стереоскопического изображения интерфейса пользователя, который очевидным образом может быть реализован на двух ЖК-дисплеях с использованием вышеуказанного режима расширения рабочего стола. Для этого достаточно отобразить главный и ведомый объекты интерфейса соответственно на экраны первого и второго дисплеев и тем самым создать требуемый стереоскопический графический интерфейс. Способ состоит в том, что:
показывают на экране дисплея главный (master) объект интерфейса;
показывают на экране дисплея ведомый (slave) объект интерфейса, являющийся дубликатом главного объекта интерфейса и находящийся на фиксированном смещении от главного объекта интерфейса;
показывают главный курсор в одной части экрана дисплея;
показывают ведомый курсор в другой части экрана дисплея;
перемещают ведомый курсор в фиксированном соотношении относительно главного курсора на основании перемещения указывающего устройства, где перемещение ведомого курсора включает в себя перемещение ведомого курсора с корректировкой ведомого объекта интерфейса, чтобы отследить любые измерения, производимые в главном объекте интерфейса в ответ на по крайней мере одно из событий: MOUSE_MOVE, MOUSE_UP, MOUSE_DOWN, MOUSE_ENTER, MOUSE_EXIT;
определяют, меняется ли объект интерфейса ввиду перемещения главного курсора;
копируют новый фон в память, стирают ведомый курсор, стирают любые накладывающиеся части ведомого курсора исходя из нового фона и показывают новый ведомый курсор на новом фоне, если определено, что объект интерфейса меняется ввиду перемещения главного курсора;
стирают ведомый курсор, применяют изменения к объекту интерфейса и показывают новый ведомый курсор, если определено, что объект интерфейса не меняется ввиду перемещения главного курсора.
Недостатком этого способа является необходимость поддержания двух объектов интерфейса (главного и ведомого) и тем самым специальной разработки средств управления ресурсами, связанными с интерфейсом. Помимо курсора мыши, рассмотренного в патенте США 6344860, сюда могут относиться окна других приложений, всплывающие подсказки и т.д. Появление новых типов ресурсов вызывает необходимость разработки специальных средств управления такими ресурсами, совместимыми с данным интерфейсом.
[http://www.racurs.ru/?page=102]
[http://www.racurs.ru/?page=405]
В  приводится описание модуля PHOTOMOD Stereo Draw, предназначенного для создания и редактирования трехмерных векторных объектов в стереорежиме, который обеспечивает стереоскопический интерфейс пользователя. В соответствии с , для работы в оконных стереорежимах требуются профессиональные видеокарты (NVIDIA Quadro FX) с поддержкой стереорасширений OpenGL. Кроме того, в литературе отсутствует какая-либо информация о способе создания этого стереоскопического интерфейса пользователя.
Помимо способов создания стереоскопического интерфейса пользователя в целом имеется ряд технических решений, посвященных стереоскопическому показу отдельных элементов интерфейса пользователя. Так, в патенте США 6225979 предлагается способ стереоскопического показа курсора, в заявке US 2002/0047835 предлагается способ стереоскопического показа иконок.
С учетом сказанного, актуальной является разработка способа создания стереоскопического графического интерфейса пользователя компьютера с двухпортовым видеоконтроллером широкой номенклатуры и устройством для показа стереоизображения на базе двух ЖК-дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно, который не требовал бы разработки специальных средств управления ресурсами пользовательского интерфейса, связанных с необходимостью поддерживать два изображения для каждого элемента интерфейса пользователя.
Это достигается за счет того, что устанавливают режим работы видеоконтроллера, в котором производится клонирование изображения на оба выхода с использованием оверлея только для указанного второго выхода видеоконтроллера. Создают программный интерфейс прикладных программ, позволяющий напрямую обращаться к видеопамяти, с аппаратной поддержкой оверлейных поверхностей и устанавливают уровень кооперации указанного программного интерфейса в соответствии с типом приложения (полноэкранное, оконное или комбинированное), использующего выдачу на экран стереоизображений. Создают первичную поверхность и оверлейную поверхность. В процессе работы определяют, когда необходимо производить вывод измененных изображений в соответствующее окно указанного приложения и на оверлейную поверхность, путем обработки сообщений операционной системы, включающих в себя сообщения WM_PAINT окну указанного приложения и по меньшей мере часть других сообщений окну указанного приложения и окнам других приложений, позволяющую указанному приложению обнаружить факт возникновения событий изменения формы и положения области клиентской части окна, в которое производится вывод стереоизображения, не закрытой другими окнами, с задержкой. сравнимой с интервалом времени смены кадров на мониторах. При необходимости вывода измененных изображений в указанном окне приложения:
- определяют область первичной поверхности, соответствующую клиентской части указанного соответствующего окна, не закрытой в данный момент другими окнами;
- выбирают прямоугольник источника на оверлейной поверхности и прямоугольник приемника на первичной поверхности таким образом, чтобы указанные прямоугольники имели одинаковые размеры, определяющие размеры оверлея, причем указанный прямоугольник приемника содержал указанную область первичной поверхности;
- определяют отображение указанного прямоугольника приемника на указанный прямоугольник источника и определяют область прямоугольника источника, являющуюся образом указанной области первичной поверхности при указанном отображении;
- устанавливают цветовой ключ источника для оверлейной поверхности;
- формируют изображение для первого глаза в указанной области первичной поверхности;
- формируют изображение для второго глаза в указанном прямоугольнике источника таким образом, чтобы в указанной области прямоугольника источника изображение совпадало с требуемым изображением в стереоокне для второго глаза, а в оставшейся части указанного прямоугольника источника цвета всех пикселей принадлежали диапазону прозрачности указанного цветового ключа;
- корректируют визуальные атрибуты оверлея в соответствии с положением указанных прямоугольников источника и приемника.
В соответствии с частотой смены кадров мониторов формируют сигнал изображения интерфейса для первого глаза на первом выходе видеоконтроллера и одновременно формируют сигнал изображения для второго глаза на втором выходе видеоконтроллера путем сканирования первичной поверхности, подачи сигнала сканирования на два выхода видеоконтроллера и наложения сигнала сканирования оверлейной поверхности на сигнал, формируемый на указанном втором выходе, с учетом указанных положений указанного прямоугольника на оверлейной поверхности и на первичной поверхности и указанного цветового ключа. При этом непрерывно подают указанные сигналы для первого и второго глаза с первого и второго выходов видеоконтроллера на экраны указанных дисплеев.
Такой способ обеспечивает достижение основного технического результата, состоящего в обеспечении стереоскопического графического интерфейса пользователя компьютера с использованием только одного объекта интерфейса. Как следствие, исключается необходимость разработки специальных средств управления ресурсами пользовательского интерфейса, связанных с наличием двух объектов, обеспечивающих изображения интерфейса для левого и правого глаза пользователя.
Дополнительно после создания первичной поверхности могут создавать объект отсечения и присоединять его к окну, в которое предполагается осуществлять вывод стереоскопических изображений. В этом случае определение области клиентской части указанного окна, не закрытой в данный момент другими окнами, производят с помощью объекта отсечения. Это обеспечивает более простое определение указанной области клиентской части окна, не требующее перебора всех других окон.
Необходимость вывода измененных изображений в соответствующее окно приложения могут определять, например, по таймеру или путем обработки сообщений Windows о перемещении окна и об изменении видимой области окна. Первый вариант обеспечивает реализацию синхронного процесса обновления изображений, а второй вариант обеспечивает реализацию асинхронного процесса обновления изображений.
Возможен вариант способа, в котором для определения области клиентской части указанного окна, не закрытой в данный момент другими окнами, устанавливают значение указанной области равным всей клиентской части указанного окна в экранных координатах, определяют все окна, имеющие более высокий Z-уровень по сравнению с указанным окном, для каждого такого очередного окна определяют, является ли это окно видимым, и если это так, то вычитают область, закрываемую этим окном, из текущего значения области. Это обеспечивает реализацию способа без использования объекта отсечения, что ускоряет выполнения операций блиттинга на оверлейную поверхность.
Первичная поверхность и оверлейная поверхность могут быть созданы переключаемыми, что обеспечивает реализацию покадрового переключения изображений и улучшает качество динамических изображений.
Изобретение поясняется графическими материалами, где:
Фиг.1. Схемы подключения стереомониторов lcReflex-1702 и lcReflex-2002.
Фиг.2. Архитектура интерфейса прикладных программ.
Фиг.3. Отображение изображения с оверлея.
Фиг.4. Выбор размеров и положений оверлея и пересчет областей.
Фиг 5. Общая схема архитектуры PanelLink.
Осуществление изобретения
1. Общее описание
[http://www.racurs.ru/?page=405]
[http://www.
planar.com/advantages/innovation/docs/SPIE_Elec_lmaging05_Final.pdf].
ТМ
Устройство для обеспечения стереоскопического графического интерфейса пользователя компьютера включает в себя компьютер с двухпортовым видеоконтроллером и устройством для показа стереоизображения на базе двух жидкокристаллических дисплеев, подключенных к первому и второму выходам указанного видеоконтроллера и создающих изображения для первого и для второго глаза пользователя соответственно. В качестве видеоконтроллера могут использоваться, например, видеокарты Radeon 9200 или Radeon 9600, а в качестве устройства создания стереоизображения на базе двух ЖК-дисплеев - например, стереомонитор lcReflex-1702 или lcReflex-2002. Их существенное для нас отличие состоит в том, что lcReflex-1702 имеет два VGA-входа, тогда как lcReflex-2002 имеет один VGA-вход и один DVI-D-вход . Зарубежным прототипом этих изделий является стереомонитор StereoMirror
[http://www.svideo.com/dvi.html]
На фиг.1 приведены схемы подключения стереомониторов lcReflex-1702 и lcReflex-2002 соответственно к выходам двухпортового видеоконтроллера. Преобразование цифрового DVI-сигнала в аналоговый VGA-сигнал осуществляют с помощью DVI-адаптера .
[http://www.bringyou.to/games/ddraw.PDF, p.7]
На фиг.2 приведена схема, взятая из  и иллюстрирующая архитектуру интерфейса прикладных программ, в которой реализуется изобретение. Эта схема иллюстрирует связи между прикладными программами, интерфейсом дисплеев, уровнем аппаратных абстракций (hardware abstraction layer - HAL) и видеоконтроллером с аппаратурой дисплеев. Приложения осуществляют управление аппаратурой дисплеев через аппаратно-зависимый интерфейс дисплеев, который выполняет проверку параметров, управление видеопамятью и учетные операции. HAL может быть составной частью аппаратуры дисплеев или, напротив, может быть реализован в программном обеспечении компьютера. В последнем случае HAL обычно реализован как DLL. HAL создается и реализуется производителем видеокарт или микросхем видеоконтроллеров. Дополнительно интерфейс дисплеев может включать в себя уровень эмуляции аппаратуры (hardware emulation layer - HEL), чтобы эмулировать аппаратные свойства дисплеев, если они не реализованы в аппаратуре.
[http://www.bringyou.to/games/ddraw.PDF, р.1]
В качестве интерфейса прикладных программ (API) используют средства, позволяющие напрямую обращаться к видеопамяти с возможностью аппаратного блиттинга и аппаратной поддержкой оверлейных поверхностей. Примерами систем, которые обеспечивают такой интерфейс, являются DirectX , OpenGL и т.д. Ниже рассматривается реализация предлагаемого способа на базе системы DirectX, причем реально используется только часть системы DirectX, обеспечивающая вывод плоских изображений и известная под названием DirectDraw. В случае OpenGL реализация способа производится аналогично с изменениями, очевидными для специалиста в области программирования.
Прежде всего, устанавливают режим работы видеоконтроллера, в котором производится клонирование изображения на оба выхода с использованием оверлея только для указанного второго выхода видеоконтроллера. Установка режима работы видеоконтроллера описывается ниже в п.2.
Далее создают программный интерфейс прикладных программ, позволяющий напрямую обращаться к видеопамяти, с аппаратной поддержкой оверлейных поверхностей и устанавливают уровень кооперации указанного программного интерфейса в соответствии с типом приложения (полноэкранное, оконное или комбинированное), использующего выдачу на экран стереоизображений. В случае комбинированного приложения, которое может динамически переключаться пользователем в полноэкранный или оконный режим, производят отслеживание текущего режима работы приложения и соответственно изменяют уровень кооперации. Способы создания программного интерфейса и установки необходимого уровня кооперации рассматриваются ниже в п.3.
[http://www.bringyou.to/garnes/ddraw.PDF. p.15]
[http://www.bringyou.to/games/ddraw.PDF. р.33-34]
В указанном интерфейсе создают первичную поверхность и оверлейную поверхность. Поверхность  представляет собой линейный массив в памяти, выделенной для изображений. Обычно поверхность располагается в памяти видеоконтроллера, хотя поверхности могут находиться и в системной памяти. Поверхность может обеспечивать контекст устройства (device context), что дает возможность применять функции GDI. Первичная поверхность - это поверхность, видимая в данный момент на мониторе. Оверлейные поверхности, иногда называемые оверлеями, - это поверхности с особыми аппаратно поддерживаемыми свойствами . Оверлейная поверхность является аналогом прозрачного куска пластика, на котором можно рисовать и который можно поместить перед монитором. Когда оверлей находится перед монитором, можно видеть как оверлей, так и содержимое первичной поверхности, не закрытой оверлеем, но если удалить оверлей, содержимое первичной поверхности не изменится. При показе оверлейной поверхности драйверу сообщают. где и как должна быть видима оверлейная поверхность. Когда видеоконтроллер выдает линии сканирования на монитор, он проверяет положение каждого пикселя первичной поверхности относительно оверлея, чтобы узнать, должен ли вместо пикселя первичной поверхности быть виден пиксель оверлея. Если это так, видеоконтроллер подставляет данные из оверлея для соответствующего пикселя, как показано на фиг.3. Как и с другими типами поверхностей, путем включения соответствующих флагов можно создавать либо отдельный оверлей, либо цепочку переключения (flipping chain) из многих оверлейных поверхностей. В предлагаемом способе оверлейная поверхность используется для создания стереоскопического изображения путем нанесения на оверлейную поверхность по меньшей мере тех частей изображения для второго глаза, которые отличаются от соответствующих частей изображения для первою глаза. Способы создания поверхностей рассматриваются ниже в п.4.
В процессе работы определяют, когда необходимо производить вывод изображений в соответствующее окно указанного приложения и на оверлейную поверхность, путем обработки сообщений операционной системы, включающих в себя сообщения WM_PAINT окну указанного приложения и по меньшей мере часть других сообщений окну указанного приложения и окнам других приложений, позволяющую указанному приложению обнаружить факт возникновения событий изменения формы и положения области клиентской части окна, в которое производится вывод стереоизображения, не закрытой другими окнами, с задержкой, сравнимой с интервалом времени смены кадров на мониторах. В отличие от используемого в стандартных оконных приложениях способа определения необходимости вывода измененных изображений, при котором необходимость вывода измененных изображений определяется получением окном сообщения WM_PAINT, при создании стереоскопического изображения интерфейса вывод измененных изображений производят чаще, учитывая дополнительно события, связанные с закрытием части окна другими окнами. В случае наступления таких событий производят изменение содержимого оверлейной поверхности, добиваясь того, чтобы непрозрачная часть оверлейной поверхности соответствовала области клиентской части окна со стереоизображением, которая не закрыта другими окнами. Способы определения, когда необходимо производить вывод измененных изображений в соответствующее окно указанного приложения, рассматриваются ниже в п.5.
При необходимости вывода изображений в указанном приложении выполняют последовательность действий, связанных с формированием и выводом требуемых изображений. Эти действия включают в себя следующие семь действий.
Прежде всего, определяют область первичной поверхности, соответствующую клиентской части соответствующего окна, не закрытой в данный момент другими окнами. Эти другие окна включают в себя окна других приложений, а также другие окна того же приложения, например стандартные окна, органы управления типа кнопок, всплывающие подсказки и т.д. Именно в эту незакрытую область клиентской части окна и в соответствующую часть оверлея осуществляют вывод стереоизображения. Определение области клиентской части окна, не закрытой в данный момент другими окнами, может производиться по крайней мере тремя разными способами, описание которых приводится ниже в п.6.
Далее выбирают прямоугольник источника на оверлейной поверхности и прямоугольник приемника на первичной поверхности таким образом, чтобы указанные прямоугольники имели одинаковые размеры, определяющие размеры оверлея, причем указанный прямоугольник приемника содержал указанную область первичной поверхности. Определяют отображение указанного прямоугольника приемника на указанный прямоугольник источника и определяют область прямоугольника источника, являющуюся образом указанной области первичной поверхности при указанном отображении. Способы выполнения этих двух действий описываются ниже в п.7.
Формируют изображение для первого глаза в указанной области первичной поверхности. Для формирования изображения на первичной поверхности используют переключение страниц в случае переключаемой первичной поверхности или блиттинг из буфера первичной поверхности на первичную поверхность в случае, если первичная поверхность не является переключаемой. Это описывается в п.8.
Формируют изображение для второго глаза в указанном прямоугольнике источника таким образом, чтобы в указанной области прямоугольника источника изображение совпадало с требуемым изображением в стереоокне для второго глаза, а в оставшейся части указанного прямоугольника источника цвета всех пикселей принадлежали некоторому диапазону прозрачных цветов. Это описывается в п.9.
[http://www.bringyou.to/games/ddraw.PDF, р.36]
Для оверлейной поверхности устанавливают цветовой ключ источника, задающий указанный диапазон прозрачных цветов. В соответствии с  цветовой ключ используется при вызове метода IDirectDrawSurface::UpdateOver]ay для управления тем, какая часть оверлейной поверхности будет видна над первичной поверхностью, а какая часть оверлейной поверхности будет прозрачной. Цветовые ключи оверлея могут быть связаны как с источником, так и с приемником, что устанавливается методом IDirectDrawSurface::SetColorKey. В предлагаемом способе используют цветовой ключ источника, для чего выставляют флаг DDCKEY_SRCOVERLAY в первом параметре dwFlags этого метода. Метод IDirectDrawSurface::UpdateOverlay использует цветовой ключ источника, чтобы определить, какие пиксели на оверлейной поверхности следует рассматривать как прозрачные, дающие возможность видеть через них первичную поверхность. Формирование цветового ключа может производиться разными способами, которые рассматриваются в п.8.
[http://alexborman.narod.ru/Doc/ P2.htm]
Корректируют визуальные атрибуты оверлея  в соответствии с положением указанных прямоугольников источника и приемника. Для этого используют функцию IDirectDrawSurface::UpdateOverlay, позволяющую скорректировать положение оверлея относительно границ экрана, размеры и положение прямоугольника на оверлейной поверхности, который используется в качестве оверлея.
[http://www.codenet.ru/progr/directx/read6.php]
Корректировка изображения как на основной, так и на оверлейной поверхности может приводить к так называемому расхождению (tearing) при смене кадров на экранах мониторов . Суть этого явления состоит в том, что при выдаче очередного кадра на экран монитора начало кадра может соответствовать старому изображению, а конец кадра - новому изображению. В этом случае на экране монитора появляется горизонтальная полоса, разделяющая два плохо стыкующихся между собой изображения. Для устранения этого эффекта при формировании изображений для первого и второго глаза и при корректировке визуальных атрибутов оверлея дополнительно может использоваться синхронизация выполнения этих операций со сменой кадров на мониторах. Более подробно этот вопрос рассматривается в п.11.
В соответствии с частотой смены кадров мониторов формируют сигнал изображения интерфейса для первого глаза на первом выходе видеоконтроллера и одновременно формируют сигнал изображения для второго глаза на втором выходе видеоконтроллера путем сканирования первичной поверхности, подачи сигнала сканирования на два выхода видеоконтроллера и наложения сигнала сканирования оверлейной поверхности на сигнал, формируемый на указанном втором выходе, с учетом указанных положений указанного прямоугольника на оверлейной поверхности и на первичной поверхности. Клонирование изображения для первого глаза осуществляется видеоконтроллером за счет выполненной настройки видеоконтроллера. При этом на клонированное изображение накладывается изображение оверлея, что дает окончательное изображение для второго глаза. При этом на первом и на втором выходах видеоконтроллера получаются соответственно цифровой сигнал изображения для первого глаза, имеющий формат DVI, и аналоговый сигнал изображения для второго глаза, имеющий формат VGA. В зависимости от используемого стереомонитора эти сигналы либо непосредственно подают на входы ЖК-мониторов, либо дополнительно перед подачей на монитор производят преобразование цифрового сигнала в аналоговый с помощью конвертера DVI в VGA.
В процессе работы компьютера непрерывно подают изображения для первого и второго глаза с первого и второго выходов видеоконтроллера на экраны указанных дисплеев. Пользователь рассматривает изображение на экране стереомонитора через стереоочки.
Докажем, что при выполнении описанного способа достигается основной технический результат, состоящий в обеспечении стереоскопического графического интерфейса пользователя.
Рассмотрим сначала статический случай, когда не производится никакого перемещения или изменения размеров окон. В соответствии с установленным режимом работы видеоконтроллера производится клонирование изображения с основной поверхности на оба выхода видеоконтроллера, сигналы с которых подаются на первый и второй монитор соответственно. Следовательно, во всех местах стереоизображения, которые не накрыты оверлеем или соответствуют тем пикселям оверлея, которые имеют цвета, принадлежащие диапазону прозрачных цветов цветового ключа, пользователь будет видеть обоими глазами одно и то же изображение. Поскольку такие цвета присвоены всем пикселям, принадлежащим областям клиентской части стереоокна, закрытым другими окнами, то в таких областях вместо оверлея будет видно содержимое первичной поверхности. Таким образом, все окна, закрывающие какую-либо часть стереоокна или расположенные вне стереоокна, будут видны двум глазам пользователя одинаково. Тем самым пользователь в стереоочках будет хорошо видеть все другие окна как плоские изображения, расположенные в одной плоскости. С другой стороны, в тех местах стереоизображения, для которых цветовой ключ задает непрозрачность оверлея, поскольку оверлей используется только для второго выхода видеоконтроллера, изображение для первого глаза будет совпадать с изображением в окне, а изображение для второго глаза будет совпадать с изображением на оверлее. Следовательно, в области клиентской части окна со стереоизображением изображение для первого и второго глаза совпадают с ранее сформированными изображениями для первого и второго глаза, т.е. пользователь будет видеть стереоизображение.
Рассмотрим теперь, что будет происходить при изменении изображения в стереоокне в случае, когда размеры и положение стереоокна и других окон не меняются. Изменения изображения в стереоокне происходят в соответствии с логикой работы приложения, создающего стереоизображение. В соответствии с системными соглашениями Windows, при необходимости изменить изображение в окне, приложение должно само инициировать сообщение WM_PAINT, в ходе обработки которого будет скорректировано изображение. Для этого приложение может использовать одну из нескольких функций, самой распространенной из которых является InvalidateRect(). Практически вызов этой функции сразу приводит к посылке в окно сообщения WM_PAINT [Финогенов К.Г. WIN32. Основы программирования. М. Диалог-МИФИ. 2006, с.220]. В этом случае выполнение приложением вышеописанного этапа определения необходимости производить вывод изображений в соответствующее окно указанного приложения и на оверлей приводит к принятию решения о том, что необходимо производить вывод изображений, поскольку приложение получило сообщение WM_PAINT. После этого приложение производит вывод измененных изображений. Для измененных изображений имеет место все, что было описано в предыдущем абзаце, т.е. в этом случае пользователь будет видеть правильное стереоскопическое изображение интерфейса с измененным стереоизображением в клиентской части окна приложения. Если по логике работы приложения происходит непрерывное изменение стереоизображения, например в случае проигрывания на компьютере стереофильма, качество изображения будет существенно зависеть от синхронности обновления изображения на первичной поверхности и на оверлее.
Поскольку обновление кадров на обоих мониторах происходит с частотой обновления кадров монитора, которая составляет порядка десятков герц, достаточно, чтобы цикл обновления изображения на основной поверхности и на оверлее укладывался в интервал времени порядка 10 мс, что вполне реально для современных компьютеров и видеоконтроллеров.
Наконец, рассмотрим поведение стереоизображения при изменении положения или размеров стереоокна или других окон. При изменении положения или размеров стереоокна или других окон выполнение приложением вышеописанного этапа определения необходимости производить вывод изображений в соответствующее окно указанного приложения и на оверлей приводит к обнаружению факта возникновения события изменения формы или положения области клиентской части окна, в которое производится вывод стереоизображения, не закрытой другими окнами. В этом случае производится корректировка изображения на оверлейной поверхности с учетом нового расположения окон, и после выполнения всех действий, связанных с формированием изображений, пользователь будет видеть правильное стереоизображение, как и в вышерассмотренном статическом случае. С учетом того, что обнаружение факта возникновения событий изменения формы и положения области клиентской части окна, в которое производится вывод стереоизображения, не закрытой другими окнами, происходит с задержкой, сравнимой с интервалом времени смены кадров на мониторах, время установления правильного изображения будет сравнимо с интервалом времени смены кадров на мониторах. Таким образом, в самом худшем случае возможно некоторое мелькание или кратковременное неправильное изображение в тех частях экрана, в которых изменилось видимое окно, после чего установится правильное стереоизображение. Если указанная задержка составляет только долю интервала времени смены кадров на мониторах, то время установления правильного изображения окажется меньше времени смены кадров на мониторах, и указанного кратковременного появления неправильного изображения не будет вообще.
2. Установка режима работы видеоконтроллера
В соответствии с действующей концепцией Windows (начиная с Windows 2000) драйверов видеокарт установка тех аспектов режима работы видеоконтроллера, которые связаны с управлением конфигурацией видеомониторов, возложена на минипорт-драйвер видеокарт. При этом установка режимов горизонтального кадрирования (panning), включающая в себя, в частности, неиспользование режима расширения рабочего стола на два монитора, в минипорт-драйвере должна
[http://msdn.microsoft.com/en-us/library/ms800853.aspx]
производиться только по запросам через панель управления . По этой причине установка режима работы видеокарты производится пользователем в окне настроек монитора.
[http://download.hightech.com.hk/manual/2k4Aug/English/Rade9600.pdf,
[http://download.hightech.com.hk/manual/2k4Aug/English/Rade9600.pdf,
Для установки режима работы видеокарты Radeon 9600 или Radeon 9700 в контекстном меню рабочего стола выбирают пункт «Свойства», и в появившемся окне «Свойства: Экран» выбирают вкладку «Параметры». На этой вкладке щелчком мышью в кнопку «Дополнительно» открывают окно «Свойства: Модуль подключения монитора...», в котором выбирают вкладку «Мониторы». На этой вкладке имеются средства для установки с  p.9], а для установки режима показа оверлея только на первичном дисплее в соответствии с  p.16 - 17] на вкладке "Overlay" щелчком мышью по кнопке «Clone mode options» открывают окно «Clone mode settings», в котором взводят флаг «Standard», означающий, что контент оверлея будет показываться только на первичном дисплее.
Наряду с использованием мыши настройку режима работы видеокарты в окне «Свойства: Модуль подключения монитора…» можно производить с помощью клавиатуры, используя клавишу Tab для перехода между кнопками окна и клавишу Enter вместо щелчка мышью.
3. Создание программного интерфейса и установка уровня кооперации
Способы создания программного интерфейса и установки уровня кооперации зависят от типа приложения, использующего вывод стереоизображений (полноэкранное, оконное или комбинированное). Эти способы рассматриваются в пп 3.1, 3.2 и 3.3 соответственно.
3.1. Полноэкранные приложения
[http://msdn.microsoft.com/en-us/library/aa919097.aspx]
Приложения с полноэкранным эксклюзивным режимом создают вызовом функции CreateWindowEx() с расширенным стилем окна WS_EX_TOPMOST и стилем окна WS_VISIBLE. Эти стили удерживают приложение на переднем конце z-порядка окон и запрещают GDI рисовать на первичной поверхности. В соответствии с , приложения с полноэкранным эксклюзивным режимом нельзя создавать со стилем WS_EX_TOOLWINDOW без риска непредсказуемого поведения. Стиль WS_EX_TOOLWINDOW предотвращает то, чтобы окно становилось окном самого верхнего уровня, что требуется для приложения DirectDraw с полноэкранным эксклюзивным режимом.
При создании окна операционная система Windows посылает созданному приложению сообщение WM_CREATE, при обработке которого производят создание программного интерфейса и установку уровня кооперации. Создание программного интерфейса включает в себя:
- получение списка всех драйверов DirectDraw;
- выбор драйвера DirectDraw;
- инициализацию DirectDraw с использованием выбранного драйвера и установку уровня кооперации DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
- получение списка поддерживаемых видеорежимов;
- выбор исходного видеорежима;
- активизацию выбранного видеорежима.
[http://mishinoleg.narod.ru/hitech/progr/directx/03.html]
Эти действия выполняют известными способами, описанными, например, в .
[http:.//www.firststeps.ru/mfc/directx/r.php?5]
Отметим, что при использовании DirectDraw версии 7.1 и выше вместо функции DirectDrawCreate следует использовать функцию DirectDrawCreateEx , чтобы можно было использовать новые возможности DirectX.
3.2. Оконные приложении
http://msdn.microsoft.com/en-us/library/aa919097.aspx]
В соответствии с [, если приложение использует DirectDraw в оконном режиме, можно создавать окна с любым стилем окна. Как и в случае полноэкранного режима, при создании главного окна приложения операционная система Windows посылает созданному приложению сообщение WM_CREATE, при обработке которого производят создание программного интерфейса и установку уровня кооперации. В отличие от полноэкранного приложения, создание программного интерфейса для оконного приложения включает в себя:
- инициализацию DirectDraw с использованием уже задействованного в системе драйвера и установку уровня кооперации DDSCL_NORMAL;
- получение информации о текущем видеорежиме.
[http://www.piter.com/lib/9785314001l3/gwin.phtml?fil=wgp03]
Эти действия выполняют известными способами, описанными, например, в . При этом в функции DirectDrawCreate в качестве глобального идентификатора драйвера указывают 0, что означает, что используется видеокарта, задействованная в данный момент в системе.
3.3. Комбинированные приложения
[http://ollegrasoft.narod.ru/Delphi_DirectX/Chapter3/l.htm#15
В соответствии с , раздел «Комбинированные приложения»], комбинированное приложение позволяет переключаться между оконным и полноэкранным режимами по ходу работы приложения, которое можно запустить в оконном режиме. Если же приложение работает слишком медленно, то пользователь имеет возможность переключиться в полноэкранный режим. Приложение запускается в полноэкранном режиме, но в любой момент работы программы можно переключиться в альтернативный режим, нажав комбинацию клавиш <Alt> + <Enter>, о чем пользователя обычно информирует подсказка, располагающаяся в левом верхнем углу экрана.
Для комбинированного приложения при переключении режимов повторяют весь способ инициализации заново для нового режима, предварительно выполнив уничтожение объекта DirectDraw и окна, существовавших до переключения режима. Для этого освобождают все ресурсы, созданные при работе до переключения режима, с помощью функций Release из соответствующих классов, после чего создают все необходимые ресурсы в новом режиме и устанавливают уровень кооперации, соответствующий новому режиму.
4. Создание первичной поверхности и оверлейной поверхности
Способы создания первичной поверхности и оверлейной поверхности зависят от типа приложения, использующего вывод стереоизображений (полноэкранное, оконное или комбинированное). Эти способы рассматриваются в пп 4.1, 4.2 и 4.3 соответственно.
4.1. Полноэкранные приложения
[http://www.piter.com/lib/978531400113/gwin.phtml?fil=\wgp01]
В соответствии с  полноэкранное приложение DirectDraw получает исключительные права на работу с видеоустройствами. Полноэкранное приложение может свободно выбрать любой из режимов, поддерживаемых видеокартой, и управлять содержимым всей палитры. Кроме того, полноэкранные приложения могут выполнять переключение страниц. Благодаря этим преимуществам полноэкранные приложения превосходят оконные по скорости и гибкости.
В случае полноэкранного приложения обычно создают переключаемую первичную поверхность и оверлейную поверхность с одним или несколькими вторичными буферами, размеры которых в точности соответствуют экрану мониторов, а оставшуюся видеопамять используют для создания внеэкранных поверхностей. Это обеспечивает максимальное быстродействие при выдаче изображений на мониторы.
[http://www.bringyou.to/games/ddraw.PDF
Формат пикселей и размеры первичной поверхности должны соответствовать текущему видеорежиму. Поэтому при создании первичной поверхности нет необходимости задавать ее формат пикселей и размеры , p.18]. Чтобы создать первичную поверхность, значение поля dwCaps структуры DDSURFACEDESC2 устанавливают равным DDSCAPS_PRIMARYSURFACE и вызывают метод CreateSurface интерфейса IDirectDrawSurface.
Для создания первичной поверхности из нескольких поверхностей добавляют к первичной поверхности один или несколько задних буферов. Для этого перед вызовом метода CreateSurface в поле dwFlags структуры DDSURFACEDESC2 устанавливают флаг DDSD_BACKBUFFERCOUNT, в поле ddsCaps.dwCaps этой структуры устанавливают флаг DDSCAPS_COMPLEX (а для обеспечения переключения страниц добавляют еще флаг DDSCAPS_FLIP), а в поле dwBackBufferCount этой структуры указывают число задних буферов [http://www.bringyou.to/games/ddraw.PDF. p.19]. Для выполнения излагаемого способа достаточно наличие одного заднего буфера. Большее число задних буферов может быть полезно в том случае, если приложение может предсказать динамику по крайней мере части изображения, например, в случае выполняемой в реальном времени анимации, и заранее выполнить заполнение по крайней мере части каждого из нескольких будущих кадров. В принципе, это достаточно редкая ситуация.
[http://www.bringyou.to/games/ddraw.PDF
[http://msdn.microsoft.com/en-us/library/ms796542.aspx]
[http://warayg.narod.ru/context/prog/Articlcs/ l.htm]
Оверлейную поверхность создают точно так же, как и первичную поверхность, с той лишь разницей, что в соответствующей структуре DDSCAPS2 взводят флаг DDSCAPS_OVERLAY , p.36]. Следует заметить, что оверлейная поверхность может поддерживать разные форматы пикселей, и среди них выбирают тот, который поддерживается видеоадаптером. установленным в компьютере. Более того, в соответствии с  оверлейная поверхность может иметь глубину пикселей, отличную от глубины пикселей первичной поверхности. Информацию о не RGB форматах, поддерживаемых драйвером, получают с помощью метода IDirectDraw4::GetFourCCCodes. При попытке создания оверлейной поверхности полезно попытаться создать поверхность с наиболее предпочтительным форматом пикселей, переходя к другому формату в случае, если данный формат пикселей не поддерживается драйвером. Как указано в , функция GetFourCCCodes выдает поддерживаемые коды не-RGB форматов (FourCC), но они включают не только YUV, но и форматы сжатых текстур и пр. Копаться в данном списке и гадать относительно каждого формата, YUV это или не YUV, не представляется рациональным. Разные коды не-RGB форматов форматы практически одинаковы и отличаются только порядком записи компонент. Тем не менее, например, видеокарта Trident 3D не признает один из этих форматов и работает только с другим, поэтому даже такой ограниченный перебор оказывается полезным. GeForce поддерживает два формата YUV и еще некоторые.
Относительно задних буферов оверлейной поверхности имеют место те же соображения, что и для задних буферов первичной поверхности.
4.2. Оконные приложения
http://www.piter.com/lib/978531400113/gwin.phtml?fil=wgp01
В соответствии с [, раздел «Оконные приложения»], поскольку оконное приложение DirectDraw отображается на рабочем столе вместе с окнами остальных приложений, оно вынуждено использовать видеорежим (разрешение экрана и глубину пикселей), установленный в Windows в настоящий момент. Оконные приложения имеют доступ к первичной поверхности, однако не могут выполнять «настоящее» переключение страниц. Кроме того, первичная поверхность не соответствует клиентской области окна, а изображает весь рабочий стол. Это означает, что программа приложения должна следить за расположением окна и его размерами, чтобы графика выводилась в нужном месте.
В случае оконного приложения переключение страниц запрещено, изображения приходится копировать на первичную поверхность из внеэкранных буферов. Внеэкранный буфер для клиентской области окна создают в видеопамяти. В этом случае содержимое окна можно построить на внеэкранной поверхности, а затем быстро скопировать на первичную поверхность с применением аппаратного ускорения. При невозможности создать внеэкранный буфер в видеопамяти его создают в основной памяти, что приводит к замедлению копирования внеэкранного буфера на первичную поверхность.
Чтобы создать первичную поверхность, значение поля dwCaps структуры DDSURFACEDESC2 устанавливают равным DDSCAPS_PR1MARYSURFACE
и вызывают метод CreateSurface интерфейса IDirectDrawSurface. Создание внеэкранного буфера может производиться как непосредственно после создания первичной поверхности, так и при необходимости создания измененного изображения в стереоокне в случае, если размера ранее созданного внеэкранного буфера не достаточно и необходимо увеличить его размер. В первом случае размер внеэкранного буфера выбирают равным размеру первичной поверхности, а во втором случае - соответствующим текущему размеру клиентской части окна, не закрытой другими окнами, чтобы прямоугольник внеэкранного буфера мог накрыть текущую клиентскую часть окна, не закрытую другими окнами. Чтобы создать внеэкранный буфер первичной поверхности, значения полей dwWidth и dwHeight структуры DDSURFACEDESC2 устанавливают равными ширине и высоте внеэкраного буфера, значение поля dwCaps структуры DDSURFACEDESC2 устанавливают равным DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY и вызывают метод CreateSurface интерфейса IDirectDrawSurface4.
Чтобы создать оверлейную поверхность, значение поля dwCaps структуры DDSURFACEDESC2 устанавливают равным DDSCAPS_OVERLAY и вызывают метод CreateSurface интерфейса IDirectDrawSurlace. Создание буфера оверлейной поверхности может производиться как непосредственно после создания оверлейной поверхности, так и при необходимости создания измененного изображения в стереоокне. В первом случае размер буфера выбирают равным размеру оверлейной поверхности, а во втором случае - соответствующим текущему размеру клиентской части окна, не закрытой другими окнами, чтобы прямоугольник буфера оверлейной поверхности мог накрыть текущую клиентскую часть окна, не закрытую другими окнами. Чтобы создать буфер оверлейной поверхности, значения полей dwWidth и dwHeight структуры DDSURFACEDESC2 устанавливают равными ширине и высоте буфера оверлейной поверхности, значение поля dwCaps структуры DDSURFACEDESC2 устанавливают равным DDSCAPS_OFFSCREENPLAIN | DDSCAPS VIDEOMEMORY и вызывают метод CreateSurface интерфейса IDirectDrawSurface. Относительно формата цвета пикселей имеют место те же соображения, что и в случае полноэкранного приложения.
[http://alexborman.narod.ru/Doc/P2.htm
Можно, однако, создать переключаемую основную поверхность и в оконном режиме. Для этого используют следующий прием , раздел «Переключающиеся поверхности и количество фреймов GDI»]. Еще до создания первичной поверхности GDI уже использует видеопамять контроллера для отображения. При создании первичной поверхности с двумя задними буферами с помощью метода CreateSurface последний в качестве адреса первичной поверхности выдает адрес памяти той поверхности, которая уже используется интерфейсом GDI. Далее копируют содержимое первичной поверхности в первый задний буфер и выполняют переключение поверхностей, так что первичная поверхность станет вторым задним буфером. После этого GDI не имеет никакой информации относительно DirectDraw и продолжает действовать на этой поверхности, даже если переключить эту поверхность, и она станет невидимым вторым задним буфером. В этом случае при создании изображения для первого глаза копируют содержимое этого второго заднего буфера в первый задний буфер pMiddle и формируют в нем изображение части стереокна, не закрытой другими окнами (см. п.9), что дает полностью сформированное изображение для первого глаза. После этого выполняют функцию pPrimary->Flip (pMiddle), что приводит к превращению первого заднего буфера в первичную поверхность и тем самым к показу сформированного изображения. Это обеспечивает достижение дополнительного технического результата, состоящего в отсутствии моргания изображения, которое имеет место при отсутствии переключения из-за последовательной рисовки фрагментов изображения непосредственно на первичной поверхности.
4.3. Комбинированные приложения
Как было указано в п.3.3, для комбинированного приложениия при переключении режимов повторяют весь способ инициализации заново для нового режима, предварительно выполнив уничтожение объекта DirectDraw и окна, существовавших до переключения режима. При этом при переходе в полноэкранный режим создание необходимых поверхностей производят в соответствии с п.4.1, а при переходе в оконный режим - в соответствии с п.4.2. Соответственно при выходе из каждого режима производят уничтожение всех созданных для работы в этом режиме поверхностей.
5. Определение того, когда необходимо производить вывод измененных изображений
Определение того, когда необходимо производить вывод измененных изображений в соответствующее окно приложения и на оверлейную поверхность, может производиться по меньшей мере двумя разными способами. Первый способ состоит в обеспечении синхронного изменения изображений с достаточно высокой частотой, обеспечивающей комфортное восприятие изображения пользователем. Приемлемой является частота 60 Гц, совпадающая с частотой обновления кадров ЖК-мониторами. В этом случае используют программируемый таймер, посылающий сообщения WM_TIMER. Обработчик таких сообщений запускает средства формирования обновленных изображений. Достоинством такого способа является его простота.
Второй способ определения необходимости вывода измененных изображений в соответствующее окно приложения состоит в использовании обработки сообщений Windows о перемещении окна и об изменении видимой области окна. При использовании версии DirectX не ниже 8.1 для отслеживания изменения видимой части окна используют метод OnClipChange интерфейса IOverlayNotify [Help no Visual Studio, раздел IOverlay::Advise]. В этом случае с помощью метода IOverlay: Advise задают использование функции обратного вызова при возникновении события ADVISE_CLIPPING, означающего изменения области отсечения (синхронизированной с окном), а в качестве функции обратного вызова используют функцию, осуществляющую формирование и вывод изображений для первого и второго глаза в области клиентской части окна, не закрытой другими окнами.
6. Определение области клиентской части указанного окна, не закрытой в данный момент другими окнами
Определение области клиентской части указанного окна, не закрытой в данный момент другими окнами, может быть осуществлено несколькими способами. Простейший способ состоит в использовании объекта отсечения. Более сложный способ состоит в непосредственном учете всех имеющихся окон без использования объекта отсечения. Его преимущество состоит в том, что при отсутствии объекта отсечения сохраняется возможность быстрого блиттинга.
При использовании объекта отсечения он должен быть присоединен к окну (см. п.4.2). В этом случае используют метод DirectDrawClipper::GetClipList [http://www.piter.com/lib/978531400113/gwin.phtml?fil=wgp01, раздел «Интерфейс DirectDrawClipper»], который выдает список отсечения, представляющий собой совокупность непересекающихся прямоугольников, покрывающих в совокупности не закрытую другими окнами клиентскую часть указанного окна.
При определении незакрытой другими окнами клиентской части указанного окна без использования объекта отсечения предварительно устанавливают значение области равным всей клиентской части указанного окна в экранных координатах. Далее для этого окна определяют все окна, имеющие более высокий Z-уровень по сравнению с указанным окном, с помощью функции GetWindow или EnumChildWindows. Как указано в справке по системе Visual C++ [http://msdn.microsoft.com/downloads/Visual Studio 2005], второй вариант является более надежным. Для каждого такого очередного окна с помощью функции IsWindowVisible определяют, является ли окно видимым, и если это так, то определяют, какую область клиентской части данного окна закрывает очередное окно. Для этого определяют регион очередного окна с помощью функции GetWindowRgn (в экранных координатах) и вычитают этот регион из текущего значения области с помощью функции CombineRgn [http://msdn.microsoft.com/en-us/librarv/ms536688(VS.85).aspx]. После перебора всех окон, имеющих более высокий Z-уровень по сравнению с указанным окном, получается значение региона Rgn, соответствующего не закрытой другими окнами клиентской части указанного окна, в экранных координатах.
7. Выбор прямоугольников источника и приемника оверлея и пересчет областей
Выбор прямоугольников источника и приемника оверлея поясним с использованием фиг.4. В верхней части изображена первичная поверхность, на которой расположена клиентская часть окна, в которое производят вывод стереоизображений. Эта клиентская часть окна представляет собой прямоугольник ABCD. На эту клиентскую часть окна частично накладываются три других окна, в результате чего область первичной поверхности, соответствующая клиентской части указанного окна, не закрытой в данный момент другими окнами, не совпадает со всем прямоугольником ABCD. На фиг.4 эта область заштрихована. В качестве размеров оверлея выбирают ширину и высоту прямоугольника, который может накрыть указанную область первичной поверхности. Границы такого прямоугольника изображены в верхней части фиг.4 пунктирной линией. Выбор размеров и положений оверлея определяется конфигурацией указанной области первичной поверхности и аппаратными ограничениями на положение и размеры прямоугольников источника и приемника.
maх
min
max
min
min
max
min
max
min
max
min
max
Конфигурация указанной области первичной поверхности определяет минимальные размеры прямоугольника оверлея. Минимальный прямоугольник, накрывающий указанную область первичной поверхности, имеет размеры (Δx, Δy), где Δx=x-x+1, Δy=y-y+1, x и x - минимальное и максимальное значения координаты x точек указанной области в координатах первичной поверхности, y и y - минимальное и максимальное значения координаты у точек указанной области в координатах первичной поверхности. Вычисление экстремальных значений x, x, y и y зависит от способа получения указанной области первичной поверхности, описанного в п.6 (с использованием или без использования объекта отсечения).
Если область первичной поверхности получена с помощью объекта отсечения, то исходными данными для определения указанных экстремальных значений является список отсечения, получаемый с помощью метода IDirectDrawClipper::GetClipList [http://doc.51windows.net/Directx9_SDK/?url=/Directx9_SDK/htm/idirectdrawclippergetcliplist.htm]. Первый параметр этого метода является указателем на список отсечения, являющийся структурой типа RGNDATA. Поле rdh этой структуры является структурой RGNDATAHEADER, поле rcBound которой является структурой типа RECT,
min
max
min
max
задающей минимальный прямоугольник, охватывающий регион. Это дает значения x, x, y и y.
[http://msdn.microsoft.com/en-us/library/ms536688(VS.85).aspx]
[http://msdn.microsoft.com/en-us/library/ms536649.aspx]
min
max
min
max
Если область первичной поверхности получена без использования объекта отсечения, то, как указано в последнем абзаце п.6, она получается в результате последнего выполнения функции CombineRgn, первый параметр которой является указателем на вычисленный регион , являющийся структурой типа RGN. С помощью функции GetRegionData  получают соответствующую структуру типа RGNDATA, что, как и в предыдущем абзаце, позволяет получить значения x, x, y и y.
[http://msdn.microsoft.com/en-us/library/aa918460.aspx]
В соответствии с различными аппаратными ограничениями, драйверы некоторых устройств налагают ограничения на положение и размеры прямоугольников источника и приемника, используемых для показа оверлейных поверхностей . Для получения этих ограничений используют метод IDirectDraw::GetCaps, а затем проверяют значения связанных с оверлеем флагов поля dwCaps структуры DDCAPS. Следующая таблица показывает поля и флаги, относящиеся к ограничениям на выравнивание границ и размеров. Нулевые значения полей означают отсутствие соответствующих ограничений.
Категория
Флаг
Поле
Boundary (position) restrictions
DDCAPS_ALIGNBOUNDARYSRC
dwAlignBoundarySrc
DDCAPS_ALIGNBOUNDARYDEST
dwAlignBoundaryDest
Size restrictions
DDCAPS_ALIGNSIZESRC
dwAlignSizeSrc
DDCAPS_ALIGNSIZEDEST
dwAlignSizeDest
Имеется два типа ограничений: ограничения на границы и ограничения на размеры. Оба типа ограничений выражаются в терминах пикселей (не байтов) и могут применяться к прямоугольникам источника и приемника. Кроме того, эти ограничения могут меняться в зависимости от форматов пикселей оверлея и первичной поверхности.
Ограничения на границы влияют на то, где можно помещать прямоугольник источника или приемника. Значения полей dwAlignBoundarySrc и dwAlignBoundaryDest говорят, как выравнивать левый верхний угол соответствующего прямоугольника. Координата x левого верхнего угла прямоугольника (поле left структуры RECT) должна быть кратна выданному значению.
Ограничения на размеры влияют на правильные значения ширины прямоугольников источника или приемника. Значения полей dwAlignSizeSrc и dwAlignSizeDest говорят о том, как выравнивать ширину в пикселях соответствующего прямоугольника. Прямоугольники должны иметь ширину в пикселях, кратную выданному значению.
[http://ati.amd.com/developer/sdk/RadeonSDK/Html/Info/2DAndVideo.html]
Для видеокарт семейства Radeon указанные ограничения отсутствуют , т.е значения всех четырех вышеуказанных полей равны нулю.
0
min
0
min
min
0
min
0
Прежде всего, заменяют нулевые значения указанных в таблице полей значением, равным 1. В качестве значения координаты x левого верхнего угла прямоугольника приемника берут максимальное значение, кратное dwAlignBoundaryDest и не превосходящее x Аналогично, в качестве значения координаты y левого верхнего угла прямоугольника приемника берут максимальное значение, кратное dwAlignBoundaryDest и не превосходящее y. Для определения ширины ΔX и высоты ΔY прямоугольника источника и приемника (в пикселях) вычисляют наименьшее общее кратное N чисел dwAlignSizeSrc и dwAlignSizeDest. В качестве значения ΔX берут наименьшее целое число, кратное N, которое не меньше Δx+x-x. В качестве значения ΔY берут наименьшее целое число, кратное N, которое не меньше Δy+y-y. Очевидно, что так выбранный прямоугольник приемника является минимальным прямоугольником, который накрывает указанную область первичной поверхности и удовлетворяет аппаратным требованиям на прямоугольник назначения оверлея.
1
1
В качестве прямоугольника источника выбирают прямоугольник на оверлейной поверхности, который имеет те же размеры, что и выбранный прямоугольник приемника, а координаты левого верхнего угла кратны значению dwAlignBoundarySrc. Простейший способ такого выбора состоит в том, что координаты (х, у) левого верхнего угла выбирают равными (0, 0), т.е. размещают прямоугольник источника в левом верхнем углу оверлейной поверхности. С другой стороны, возможны и другие варианты выбора прямоугольника источника, например когда левый верхний угол оверлейной поверхности занят под какие-либо другие цели. Например, удобно иметь всегда два прямоугольника источника: тот, который уже был использован для вывода оверлея на экран монитора, и новый прямоугольник источника, который используется для формирования нового контента оверлея.
0
0
1
1
1
0
1
0
После этого определяют отображение указанного прямоугольника приемника на указанный прямоугольник источника. Это отображение φ в координатах первичной поверхности (Х, Y) и координатах оверлейной поверхности (Х, Y) имеет вид X=Х+а,Y=Y+b,
1
0
1
0
где а=x-x, b=y-у. Наконец, определяют область прямоугольника источника,
[http://msdn.microsoft.com/en-us/library/ms536621(VS.85).aspx]
являющуюся образом указанной области первичной поверхности при указанном отображении φ. Она получается сдвигом объекта типа RGNDATA, задающего указанную область первичной поверхности (см. выше), на вектор (а, b). Такой сдвиг выполняют с помощью функции OffsetRgn .
8. Формирование изображений для первого глаза
8.1. Изображение для первого глаза формируют на основной поверхности таким образом, чтобы в области клиентской части окна, в которой производят вывод стереоизображения, не закрытой другими окнами, изображение совпадало с требуемым изображением в стереоокне для первого глаза, а в оставшейся части первичной поверхности определялось изображениями других окон и неклиенской части указанного стереоокна. Возможно несколько способов формирования такого изображения, причем выбор способа, используемого в конкретной ситуации, зависит от наличия уже сформированного изображения для первого глаза (без учета конфигурации окон), наличия заднего буфера основной поверхности, характера изменения изображения во времени, а также специфики приложения, использующего вывод стереоизображений. Ниже в пп.8.2 и 8.3 приводятся примеры способов, которые могут быть использованы для формирования изображений для первого глаза.
8.2. Формирование изображения для первого глаза при наличии заранее приготовленного изображения
Простейший способ формирования изображения для первого глаза состоит в использовании заранее приготовленного изображения. В этом случае копируют существующее изображение на часть надлежащей поверхности, соответствующую клиентской части стереоокна, не закрытой другими окнами, с использованием объекта отсечения. В зависимости от конфигурации буферов первичной поверхности в качестве надлежащей поверхности может выступать первичная поверхность, задний буфер первичной поверхности или внеэкранная поверхность (их использование в зависимости от типа приложения см. в п.4).
8.3. Формирование изображения для первого глаза средствами GDI
[http://www.netcode.ru/cpp/?artID=329]
Для использования средств GDI обеспечивают получение доступа к надлежащей поверхности, для чего используют метод GetDC интерфейса DirectDrawSurface для надлежащей поверхности. Параметром метод GetDC является указатель на DC (контекст устройства. Device Context) , через который можно осуществлять вывод на поверхность стандартными функциями Win32. Метод ReleaseDC() должен быть вызван сразу же после завершения работы с DC. Как и в случае с Lock() и Unlock(), функцию ReleaseDC() необходимо вызывать после GetDC() как можно быстрее. Это связано с тем, что внутри функции GetDC() вызывается Lock(), а внутри ReleaseDC() - Unlock(). B зависимости от конфигурации буферов в качестве надлежащей поверхности может выступать первичная поверхность, задний буфер первичной поверхности или внеэкранная поверхность (их использование в зависимости от типа приложения см. в п.4).
9. Формирование изображений для второго глаза
9.1. Изображение для второго глаза формируют в указанном прямоугольнике источника на оверлейной поверхности таким образом, чтобы в указанной области прямоугольника источника изображение совпадало с требуемым изображением в стереоокне для второго глаза, а в оставшейся части прямоугольника источника цвета всех пикселей принадлежали некоторому диапазону прозрачных цветов. Возможно несколько способов формирования такого изображения, причем выбор способа. используемого в конкретной ситуации, зависит от наличия уже сформированного изображения для второго глаза (без учета конфигурации окон), наличия заднего буфера оверлейной поверхности, необходимости изменения изображения, типа такого изображения, а также специфики приложения, использующего вывод стереоизображений. Ниже в пп.9.2 и 9.3 приводятся примеры способов, которые могут быть использованы для формирования изображений для второго глаза.
9.2. Формирование изображения для второго глаза при наличии заранее приготовленного изображения
Простейший способ формирования изображения для второго глаза в указанном прямоугольнике источника состоит в использовании заранее приготовленного изображения. В этом случае формирование требуемого изображения состоит в том, чтобы скопировать существующее изображение в указанный прямоугольник источника и заполнить пиксели, лежащие вне указанной области прямоугольника, прозрачными цветами в соответствии с выбранным цветовым ключом. Способы выбора цветового ключа рассматриваются ниже в п.10.
Возможно два варианта формирования изображения в указанном прямоугольнике источника, отличающиеся порядком выполнения копирования существующего изображения и заполнения пикселей, лежащих вне указанной области прямоугольника, прозрачными цветами.
Первый способ состоит в том, что сначала заполняют весь прямоугольник источника одним цветом, входящим в диапазон прозрачности цветового ключа. С учетом того, что физически прямоугольник источника находится на оверлейной поверхности, заполнение прямоугольника одним цветом производят с помощью аппаратных средств видеокарты, используя для этих целей метод IDirectDrawSurface::Blt. При этом задают в качестве первого параметра указатель на прямоугольник источника, NULL в качестве второго и третьего параметров, DDBLT_COLORFILL в качестве флага и в качестве последнего параметра задают указатель на структуру типа DDBLTFX, в поле dwFillColor которой указывают требуемый цвет. Далее создают объект отсечения, соответствующий указанной области внутри прямоугольника источника, и прикрепляют его к оверлейной поверхности. Если исходное изображение не находится на поверхности DirectDraw, в системной памяти создают поверхность DirectDraw, соответствующую исходному изображению, и копируют в нее изображение с помощью функции BitBlt. После этого с помощью метода IDirectDrawSurface::Blt производят копирование полученного изображения из созданной поверхности на часть указанного прямоугольника источника, определяемую указанным объектом отсечения. Это позволяет избежать использования функции BitBlt для копирования в видеопамять, что является очень медленной операцией. Если же исходное изображение находится на поверхности DirectDraw, то непосредственно с помощью метода IDirectDrawSurface::Blt копируют исходное изображения на часть указанного прямоугольника источника, определяемую указанным объектом отсечения.
Второй способ состоит в том, что сначала копируют исходное изображение на прямоугольник источника, а затем область вне указанной области внутри прямоугольника источника заполняют указанным одним цветом. Как и в предыдущем случае, если исходное изображение не находится на поверхности DirectDraw, в системной памяти создают поверхность DirectDraw, соответствующую исходному изображению, и копируют в нее изображение с помощью функции BitBlt. После этого с помощью метода IDirectDrawSurface::Blt производят копирование полученного изображения из созданной поверхности на часть указанного прямоугольника источника. Далее создают объект отсечения, соответствующий дополнению указанной области прямоугольника источника до всего прямоугольника источника, и прикрепляют его к указанной оверлейной поверхности. Наконец, производят заполнение указанного дополнения указанным одним цветом с помощью метода IDirectDrawSurface::Blt. При этом, как и в предыдущем способе, задают в качестве первого параметра указатель на прямоугольник источника, NULL в качестве второго и третьего параметров, DDBLT_COLORFILL в качестве флага и в качестве последнего параметра задают указатель на структуру типа DDBLTFX, в поле dwFillColor которой указывают требуемый цвет. Наличие объекта отсечения приведет к тому, что указанным цветом будет заполнено только дополнение указанной области до всего прямоугольника источника.
1
1
1
Как правило, цветовой ключ выбирают таким образом, чтобы цвета пикселей исходного изображения не принадлежали диапазону цветового ключа. Для этого в качестве диапазона цветового ключа берут диапазон состояний только из одного значения цвета. Может, однако, оказаться так, что некоторые пиксели исходного изображения в указанной области имеют цвет, принадлежащий диапазону прозрачности цветового ключа. В этом случае, если не принять никаких дополнительных мер, на окончательно сформированном изображении на экране монитора такие пиксели на оверлее будут прозрачными, т.е. вместо изображения оверлея в соответствующих местах будет показываться фоновое изображение, т.е. изображение, на которое будет накладываться оверлей. Чтобы избежать этой неприятности, производят корректировку исходного изображения, заменяя цвета всех пикселей, достаточно близкие к указанному одному значению цвета, значением заменяющего цвета, который вычисляют заранее для выбранного цветового ключа. В качестве заменяющего цвета берут любой ближайший к ключевому цвету. Проще всего это осуществить в случае, когда глубина цвета исходных изображений и глубина цвета оверлейной поверхности совпадают. В этом случае, как будет показано п.10, можно заранее так подобрать цветовой ключ, что корректировать надо будет самое большее один цвет (r, g, b) пикселей исходного изображения. В общем случае, когда глубина цвета оверлейной поверхности меньше глубины цвета исходных изображений или когда цветовой ключ выбирают из каких-либо других соображений, определяют все цвета исходного изображения, которые преобразуются в ключевой цвет, и заменяют их цветом (r,g,b), отличным от всех таких цветов.
1
1
1
Если исходное изображение находится в системной памяти, то такую замену осуществляют путем перебора всех пикселей изображения и замены всех таких значений (r, g, b) на значение (r,g,b). Если исходное изображение находится в
видеопамяти, то такую замену целесообразно осуществлять, используя графический конвейер видеоконтроллера. Для этого DirectDraw предоставляет класс Shader и язык высокого уровня HLSL разработки шейдеров.
9.3. Формирование изображения для второго глаза средствами GDI
Использование средств GDI оправдано в случаях, когда имеет смысл сразу выводить на оверлей некоторые изменения изображения, не заботясь при этом об отсутствии моргания. Такая ситуация имеет место, например, когда взаимные положения и размеры окон не меняются, и при этом, например, пользователь выполняет редактирование векторного стереоизображения с помощью мыши. Эта технологическая операция часто встречается, например, при выполнении цифрования стереопар, построенных на базе аэро- или космических снимков, с целью получения трехмерной векторной карты [Алчинов А.И., Кекелизде В.Б. Технология построения рельефа местности на ЦФС «Талка» // Геопрофи, 2005, №3, с.22-24]. В этом случае наличие моргания даже полезно и обозначает тот участок изображения, который в данный момент редактируется пользователем.
[http://directxx.narod.ru/directdraw.html].
[http://msdn.microsoft.com/en-us/library/ms533l80(VS.85).aspx1.
Для получения доступа к оверлейной поверхности используют метод GetDC интерфейса DirectDrawSurface для оверлейной поверхности  Метод GetDC() возвращает DC (контекст устройства. Device Context), через который можно осуществлять вывод на поверхность стандартными функциями Win32. Метод ReleaseDC() должен быть вызван сразу же после завершения работы с DC. Как и в случае с Lock() и Unlock(), функцию ReleaseDC() необходимо вызывать после GetDC() как можно быстрее. Это связано с тем, что внутри функции GetDC() вызывается Lock(), а внутри ReleaseDC() - Unlock(). Для обеспечения адресации к нужному прямоугольнику оверлейной поверхности (см. п.7) используют функцию SetViewportOrgEx.
10. Формирование цветового ключа
[http://vbstreets.ru/Projects/Graphics/66357.aspx]
[http://msdn.microsoft.com/en-us/library/ms535429(VS.85).aspx]
Понятие цветового ключа возникло в интерфейсе DirectDraw , однако впоследствии с появлением интерфейса GDI+ механизм цветовых ключей был также реализован в GDI+ . Это разные механизмы, и не следует их путать.
[http://www.gamasutra.com/features/ 20010629/geczy_01.htm]
Работу с цветовыми ключами в DirectDraw осуществляются через интерфейс IDirectDrawSurface [http://vbdx.chat.ru/dxcorner/directdravv/ckeysur.html]. Для задания цветового ключа используют метод SetColorKey класса IDirectDrawSurface. Чтобы установить цветовой ключ источника, используют флаг DDCKEY_SRCOVERLAY в первом параметре dwFlags этого метода. Следует отметить, что начиная с версии DirectX 8 цветовые ключи не поддерживаются .
[http://msdn.microsoft.com/en-us/library/ms796511.aspx]
Как указано в , если драйвер DirectDraw имеет биты возможностей (caps) для блиттинга, но не для прозрачного блиттинга, то для блиттинга вызывается драйвер DirectDraw, а для прозрачного блиттинга вызывается HEL. В случае прозрачного блиттинга HEL передается указатель на видеопамять, и он сравнивает каждый байт из заднего буфера поверхности с цветовым ключом. Если байт не соответствует цветовому ключу, HEL копирует его в поверхность приемника, используя центральный процессор. Эта эмуляция также происходит для других операций, не поддерживаемых аппаратурой, или если видеопамять расположена вне видеокарты.
Цветовой ключ формируют таким образом, чтобы значение верхней границы диапазона цветового ключа совпадало со значением нижней границы диапазона цветового ключа. Тем самым набор цветов, принадлежащих диапазону цветов цветового ключа, состоит только из одного цвета, называемого ключевым цветом. Выбор ключевого цвета зависит от глубины цвета пикселей основной поверхности.
Если имеет место палитровый режим отображения, то в качестве ключевого цвета выбирают любой цвет в формате пикселей оверлейной поверхности, который не входит в используемую палитру основной поверхности. Это гарантирует то, что ни один пиксель изображения на оверлейной поверхности не имеет цвета, входящего в диапазон цветового ключа, что существенно при дальнейшем формировании областей прозрачности на оверлейной поверхности.
[http://progma.narod.ru/directdraw.html
[http://jack.kiev.ua/linuxjournal/LJ/0081/4401.html]
[http://mini-stalker.googlecode.com/svn-history/r29/trunk/Mini_STALKER/animation.h]
[http://www.gamasutra.com/features/20010629/geczy_02.htm]
Если режим отображения является беспалитровым, то в качестве ключевого цвета выбирают фиксированный цвет, который реже всего встречается на реальных изображениях. Приемлемыми являются, например, черный цвет ], синий цвет , красно-синий цвет , фуксин .
Отдельные пиксели реального изображения могут иметь цвет, который выбран в качестве указанного цвета цветового ключа. В этом случае производят корректировку изображения, заменяя значения цвета всех таких пикселей соседним значением цвета (см.п.10).
Если указанное в п.9.2 заранее приготовленное изображение имеет глубину цвета, совпадающую с глубиной цвета оверлейной поверхности, то значение ключевого цвета можно выбрать так, чтобы при конвертировании формата цвета пикселей заранее приготовленного изображения самое большее один цвет пикселей любого такого заранее приготовленного изображения при конвертировании принимал значение ключевого цвета. В самом деле, рассмотрим отображение φ цветового пространства заранее приготовленного изображения в цветовое пространство оверлейной поверхности. Поскольку эти два цветовых пространства имеют одинаковую глубину цвета, то мощности двух цветовых пространств совпадают. Следовательно, либо отображение φ биективно, либо не является сюрьективным. В первом случае при любом выборе значения ключевого цвета при конвертировании формата цвета пикселей заранее приготовленного изображения самое большее один цвет пикселей любого такого заранее приготовленного изображения при конвертировании может принять значение ключевого цвета. Во втором случае в цветовом пространстве оверлейной поверхности существует такое значение цвета, которое лежит вне образа отображения φ. Если это значение взять в качестве ключевого цвета, то при конвертировании формата цвета пикселей заранее приготовленного изображения ни один цвет пикселей любого такого заранее приготовленного изображения при конвертировании не сможет принять значение ключевого цвета. Способ реализации такого выбора ключевого цвета очевиден: достаточно конвертировать массив всех цветов цветового пространства заранее приготовленных изображений в цветовое пространство оверлейной поверхности, упорядочить полученные значения по возрастанию и в качестве ключевого цвета выбрать любое значение, пропущенное в полученном массиве цветов. Если пропущенных значений нет, то отображение φ является биективным, и в качестве ключевого цвета можно взять любой цвет.
[http://rubygame. sourceforge.net/doc/1_1_0/classes/Rubygame/Surface.src/M000236.htrml].
В случае, когда приложение, осуществляющее вывод стереоизображений, предназначено для проигрывания заранее созданного стереофильма, для выбора ключевого цвета может быть использован способ, предложенный в  Он состоит в том, что ключевой цвет для каждого стереоизображения вычисляется заранее и записывается в соответствующий файл изображения. В этом случае при каждом формировании изображения для второго глаза значение цветового ключа устанавливают в соответствии с этим записанным изображением.
11. Синхронизация корректировки изображений и параметров оверлея со сменой кадров
[http://www.codenet.ru/progr/directx/read6.php].
[http://www.codenet.ru/progr/directx/read6.php].
[http://msdn.microsoft.com/en-us/library/ms796289.aspx].
Для синхронизации смены кадров на первичной поверхности и изменения оверлея со сменой кадров используют функцию WaitForVerticalBlank() с флагом DDWAITVB_BLOCKBEGIN, означающим, что производится ожидание события начала интервала бланкирования. Такая синхронизация необходима для устранения эффекта расхождения (tearing)  Отметим, что в версиях DirectDraw, предшествующих версии 6.0, по умолчанию производилась автоматическая синхронизация обновление экрана с завершением вертикальной развертки  Начиная с версии DirectX 6.0, эта задача возложена на драйверы видеокарт. При этом DirectDraw не препятствует использованию этих флагов ограничения количества смен кадров до обновления изображений с оверлейными поверхностями, но от драйверов не требуется следование флагам ограничений на максимальную задержку смены оверлея до n-го сигнала обратного хода луча (n=2, 3 или 4), даже если они реально выставляют биты возможностей DDCAPS2_FLIPINTERVAL или DDCAPS2_FLIPNOVSYNC. Драйверы могут выбирать следование этим флагам для оверлеев, если они имеют возможность, но для приложений использование этой возможности малоперспективно  Таким образом, качество синхронизации смены изображений для первого глаза и для второго глаза зависит от используемого драйвера.
Для синхронизации смены изображения на двух мониторах существенно то, что синхронизация смены кадров выполняется по инициативе видеокарты, а не мониторов, как это следует из архитектуры PanelLink, составляющей основу интерфейса между видеокартой и ЖК-мониторами. Общая схема архитектуры PanelLink приведена на фиг.5.