Работа 2. Интерфейс в широком смысле формально определенная логическая и физическая границы между взаимодействующими независимыми объектами.
Скачать 7.06 Mb.
|
Графические APIИнтерфейс прикладного программирования (ApplicationProgrammingInterface, API), предоставляют разработчикам приложений некую стандартизированную совокупность команд (и сервисов), с помощью которых можно программировать работу всевозможных устройств от разных производителей. В настоящее время существует несколько графических API — Direct 3D (фирма Microsoft), OpenGL (фирма SGI) и уже не используемый Glide (фирма 3Dfx). Glide поддерживается только набором микросхем, выпускавшихся фирмой 3Dfx. Остальные API поддерживаются большинством современных видеоадаптеров. Direct 3D является частью API, называемого DirectX. Microsoft DirectXDirectX — это набор программных интерфейсов для разработки мультимедийных и игровых приложений для ПК. Это сложнейший инструмент, организующий взаимодействие игры с аппаратной частью компьютера, в первую очередь — с видеокартой, но также и со звуковой картой, с манипуляторами и сетевыми подключениями для многопользовательской игры. В DirectX есть два режима работы — HAL и HEL. HAL (HardwareAbstractionLayer) — уровень абстракции аппаратного обеспечения. Этот режим задействуется, когда аппаратные средства поддерживают функции, необходимые в данный момент для исполнения программы. HEL (HardwareEmulationLayer) — уровень эмуляции аппаратного обеспечения. Если невозможно поручить работу аппаратуре (к примеру, видеокарта поддерживает лишь DirectX 8, тогда как в игре требуется DirectX 9), система пытается восполнить недостающие средства с помощью имитации, нагружая работой центральный процессор. Именно этот режим и позволяет создавать программные продукты будущего, но для нормальной игры, как правило, не годится. Процессору и так есть, чем заняться, и попытка заставить его помогать видеокарте способна привести лишь к полному затормаживанию компьютера. Обычно игра автоматически определяет, какая версия DirectX поддерживается аппаратно и либо отключает спецэффекты, требующие более современной версии, либо не запускается вовсе, если несоответствие слишком значительно. Поэтому, когда говорят, что некая видеокарта полностью совместима с требованиями, к примеру, DirectX 10, значит, она способна принять на исполнение (в режиме HAL) все команды, которые могут содержаться в игре, требующей для своего запуска данную версию DirectX. Поскольку DirectX относится к уровню аппаратных абстракций (Hardware Abstraction Layer — HAL), разработчикам программного обеспечения необходимо использовать функции DirectX, а не обращаться напрямую к видеоадаптеру, звуковой карте, джойстику и другому оборудованию. DirectX также относится к уровню аппаратной эмуляции (Hardware Emulation Layer — HEL), что позволяет разработчику программно эмулировать те функции, которые не реализованы аппаратным обеспечением. Уровень HEL «медленнее», чем HAL, но лучше иметь не реализованную аппаратно функцию (пусть даже медленную), чем не иметь ничего. Отношения между аппаратным, программным обеспечением и DirectX можно продемонстрировать следующей схемой: Аппаратное обеспечение => DirectX => Программное обеспечение Обновление DirectX можно выполнять независимо от операционной системы. DirectX состоит из «основного» слоя, который обеспечивает доступ к звуковым устройствам, устройствам двухмерной и трехмерной графики, устройствам ввода и процедурам установки. Если вы на своем ПК из командной строки Windows запустите программку dxdiag, то сможете увидеть, из каких модулей состоит DirectX. Для последней версии это модули: Direct3D/DirectDraw, отвечающий за отрисовку на экране 3D/2D-изображений; DirectSound, осуществляющий взаимодействие между программами и звуковой подсистемой ПК; DirectMusic, в чьи функции входит, в основном, воспроизведение музыкальных MIDI-файлов и микширование всевозможных звуков; DirectInput, управляющий клавиатурами, мышками, игровыми контроллерами и прочим; и, наконец, DirectPlay, предназначенный преимущественно для поддержки сетевых игр. Поколения 3D-ускорителей DirectXДо появления DirectX программистам приходилось в коде своих приложений учитывать всю совокупность возможного оборудования у пользователей. Грубо говоря, для каждой «железки», с некоторой вероятностью установленной в ПК, писать свой участок кода, напрямую управляющий ее работой. И такого оборудования (видео- и звуковых карт, клавиатур, мышей и игровых манипуляторов и т.п.) становилось с каждым годом все больше и больше. Но и это еще не все. Появление и широкое распространение Microsoft Windows 95 должно было еще более усложнить жизнь разработчикам софта. В отличие от MS-DOS, бывшей в то время основной программной платформой, Windows 95 функционировала в так называемом защищенном режиме работы процессора, что, конечно, значительно увеличивало устойчивость к сбоям операционной системы, однако и ограничивало возможности программ по прямому управлению устройствами. В общем, заколдованный круг. И в Microsoft придумали, как одним махом решить обе проблемы. Во-первых, всех производителей соответствующего оборудования призвали (фактически, обязали) писать для своих устройств DirectX__7'>DirectX-совместимые драйверы. Во-вторых, разработчикам программ дали стандартизированный API DirectX, то есть новый инструмент (фактически, язык), используя который, они отныне уже не забивали себе голову вопросом, какие конкретно «железки» могут быть установлены в компьютерах потенциальных пользователей, а писали свои программы для неких идеальных DirectX-совместимых устройств, безотносительно тонкостей их конкретной реализации. В общем, в августе 1995 года на рынке появилась ОС Windows 95, а уже в октябре — и первый API DirectX, носивший изначально название Windows Game SDK. Что недвусмысленно указывает на его назначение: в Microsoft очень хотели, чтобы Windows 95 стала самой популярной игровой платформой, отняв это звание у безнадежно устаревшей DOS. Поколения ускорителей в видеокартах можно считать по версии DirectX, которую они поддерживают. Различают следующие поколения: DirectX 7 — карта не поддерживает шейдеры, все картинки рисуются наложением текстур. DirectX 8 — поддержка пиксельных шейдеров версий 1.0, 1.1 и 1.2. DirectX 9 — поддержка пиксельных шейдеров версий 2.0, 2.0a и 2.0b, 3.0. DirectX 10. DirectX в части Direct3D, наиболее востребованного модуля для современных игр, был придуман, чтобы разработчик не задумывался над тем, какая видеокарта и с какими возможностями работы с 3D стоит в компьютере пользователя. И даже будет ли видеокарта вообще поддерживать 3D! (Direct3D способен выводить 3D-изображение на экран вообще без аппаратной поддержки, только программными средствами. Правда, производительность такого варианта будет катастрофически мала.) Однако в последние годы подходы ведущих производителей графических процессоров (прежде всего Intel, NVIDIA и ATI) к проектированию своих чипов настолько разошлись, что программистам вновь пришлось для видео каждого производителя писать в своих приложениях отдельные ветки кода (этим объясняется тот факт, что если программа «дружит» с определенным чипостроителем, и на нем «летает», то под другим запросто может «затормозить»). DirectX 10 призван в значительной степени разрулить эту ситуацию, так как выдвигает значительно более определенные требования к «железу», то есть включает в себя жесткие аппаратные спецификации. Более того, введены новые наборы инструкций (High Level Shader Language — HLSL 10), по большому счету служащие той же цели. Также в Microsoft серьезно переработали принципы отрисовки 3D-картинки, что привело к существенному снижению числа команд, требуемого для формирования каждого кадра и, как следствие, к некоторому повышению производительности. И, наконец, дали разработчикам игр новые возможности программирования через унификацию архитектуры шейдеров и потоковый ввод-вывод. Архитектура DirectX10Давайте рассмотрим компоненты графического конвейера DirectX, общая схема которого приведена на следующем рисунке: InputAssemblerStage — блок, отвечающий за поставку графических данных в конвейер, например, константы, треугольники и/или цвета конкретных точек. Задача этого блока — собрать входные данные от программы и сформировать всю информацию в «примитивы» (элементарные конструкции, которые могут обрабатываться в других блоках). По сути, он формирует информацию для более удобной работы последующих блоков, в частности «шейдерных», то есть GS, VS и PS. Vertex-ShaderStage (VS) отвечает за преобразование каркасов объектов. В игре все действующие лица и статичные объекты хранятся в памяти в виде каркасов с ячейками треугольной формы (как будто на каждый объект накинута паутина). Перед выводом каждого кадра необходимо спроецировать эти каркасы на плоскость экрана в зависимости от того, куда направлен взгляд игрока в данный момент. Плюс в таких объектах, как вода, деревья, персонажи игры, каркасы не являются постоянными, и нуждаются в перестраивании для каждого кадра (листья колышутся, по воде идут волны) по особой программе, называемой вершинным шейдером. Взгляните на следующий рисунок: На нем демонстрируется элементарное преобразование двух треугольников по четырем вершинам: у двух треугольников всего шесть вершин, но так как две из них совпадают, то получаем четыре. Преобразование состоит в расчете координат каждой вершины, что может быть как элементарным действием (например, для статичного объекта), так и очень сложным — например, для разрушаемых объектов, передачи мимики персонажей, детального изображения структуры кожи или шерсти; реалистичность воды в играх тоже создается с использованием вершинного шейдера. Geometry-ShaderStage (GS) — геометрический шейдер, который в отличие от вершинного может не только проводить операции над треугольниками, но и генерировать на выходе новые (используя смежные грани треугольников) и удалять существующие. GS, получив на входе один треугольник, способен сгенерировать на выходе один преобразованный и/или раздробить его на большее количество новых примитивов. В частности, вместо увеличения размеров треугольников в нашем примере, можно было бы увеличить их количество вдвое, оставив размеры каждого минимальными, что для наблюдателя проявилось бы в более детальной передачи складок кожи и повышении общей четкости изображения. На следующем рисунке видно, что для геометрической «самостоятельности» каждого треугольника необходимо хранить координаты всего трех дополнительных вершин, что позволяет на основании этих данных, раздробив этот треугольник на несколько более мелких, «встроить» полученные ячейки в существующий каркас и, напротив, при укрупнении каркаса использовать дополнительные точки в качестве координат нового треугольника. Если ранее, пользуясь вершинными шейдерами, программисты производили только преобразования, то с появлением геометрического шейдера в DirectX 10 появилась возможность обеспечить в играх более высокую реалистичность, особенно заметную при рассматривании объектов с близкого расстояния. Возникли и принципиально новые подходы к программированию игровых движков. Так, геометрическим шейдерам можно поручить «выращивание растений». Трава, деревья и их составляющие (корни, листья и ветки) будут увеличиваться в размерах с сохранением детальности каркаса, согласно командам, загруженным в графический ускоритель, то есть «бесплатно» с точки зрения центрального процессора, а это всегда приветствуется разработчиками. Геометрический шейдер, пожалуй, — ключевое нововведение DirectX 10, появление которого можно считать новым шагом в развитии компьютерной графики, сравнимым с появлением вершинных и пиксельных шейдеров. StreamOutputStage разработан для переброски простых данных из графического конвейера в память. В задачу блока входит увеличение скорости работы приложений за счет уменьшения потерь времени при загрузке данных, уже имеющихся в памяти видеокарты, и обеспечение более тесного взаимодействия между центральным и графическим процессорами, что может быть полезно, в частности, для физических и прочих «неграфических» вычислений. Подчеркнем, что этот блок, как и GS, впервые появился в DirectX10. RasterizerStage— стадия, при которой происходит отсечение невидимых примитивов. Это необходимо для экономии ресурсов системы. Например, в кадр попало детализированное здание с внутренними помещениями, однако, поскольку мы в данный момент находимся снаружи, совсем необязательно рассчитывать ежесекундно каркасы этих помещений — достаточно показать внешний вид дома. Именно на этой стадии мы получаем на данный момент времени готовый для отображения на экране каркас всех объектов, который предстоит «растеризовать», то есть покрыть текстурами — кусочками простых (растровых, состоящих из пикселей) изображений поверхностей, кожи, листьев, камня и т.п. Pixel-ShaderStage (PS) — на этой стадии исполняются пиксельные шейдеры, программы, которые могут управлять любыми пикселями в примитиве, то есть если у нас есть треугольник, на который натянута текстура, мы можем применить для любого из пикселей, входящих в этот треугольник, свой цвет, яркость и/или прозрачность. Благодаря PS, стало возможным управление каждым пикселем в сцене. Самый заметный эффект, появившийся в играх с приходом PS — это перелив света (блеск) на округлых поверхностях при смене либо угла просмотра, либо позиции источника света. Поддержка PS появилась еще в DirectX 8 и от версии к версии происходит усложнение допустимых преобразований, которые позволяют получать все более сложные эффекты. OutputMergerStage — финальный этап, на котором определяется, какие пиксели и в каком порядке выводить на экран. После отсечения невидимых примитивов аналогичную операцию надо провести на уровне пикселей — вполне возможно, что на границах объектов, треугольники, принадлежащие каркасам разных объектов, перекрываются лишь частично, и на экран надо вывести изображение того объекта, который находится ближе к наблюдателю. Этот вопрос решается с помощью так называемого Z-буфера, в котором хранятся координаты глубины всех точек изображения. Direct X 11В D3D11 добавляется 3 дополнительных стадии конвейера визуализации, целью введения которых является эффективная тесселяция поверхностей. Конвейер D3D11 включает три новых стадии между стадиями вершинного и геометрического шейдера. Две из них являются программируемыми (стадии оболочечного (hull shader) и domain шейдеров) и одна — конфигурируемая (стадия тесселяции). Представленный конвейер оперирует сетками, заданными поверхностными патчами. Основными примитивами D3D11 являются треугольные и квадратные патчи. Форма каждого патча определяется числом контрольных точек. В вершинном шейдере эти точки трансформируются, скинятся и (или) морфятся последовательно. Оболочечный шейдер вызывается для каждого патча. В качестве входных данных используются контрольные точки патча из вершинного шейдера. Оболочечный шейдер имеет два основных применения. Первое (опционально) — это конвертирование контрольных точек из одного представления в другое. После этого шейдера контрольные точки пересылаются напрямую дальше, минуя тесселятор. Другое применение — вычисление подходящего параметра тесселяции, который затем передаётся на стадию тесселяции. Такой подход позволяет делать адаптивную тесселяцию, которая может быть использована в случае видозависимых уровней детализации (LOD). Параметр тесселяции определяется для каждой грани патча и варьируются в диапазоне от 2 до 64. Это означает, что каждая грань треугольного (или квадратного) патча может быть разбита на 2 (или максимум 64) грани. Стадия тесселятора представлена фиксированным набором функции (хорошо конфигурируема), которые используют параметр тесселяции для подразбиения патча на несколько треугольников или квадов. Тесселятор не имеет доступа к контрольным точкам — все решения о разбиении принимаются на основе конфигурационных и тесселяционных параметров, передаваемых из оболочечного шейдера. Каждая вершина после стадии тесселяции передаётся в domain шейдер, причём передаются только координаты параметризации (parametrization coordinates). Domain shader оперирует parametrization coordinates патча для каждой вершины раздельно, хотя имеется возможность получить доступ к трансформированным контрольным точкам для всего патча. Domain шейдер отправляет всю информацию о вершине (позицию, текстурные координаты, и т.п.) в геометрический шейдер (или на стадию клипирования, если геометрический шейдер не задан). По сути дела, он оценивает представление поверхности в каждой точке. На данной стадии может быть применён метод карт смещения (displacement mapping). |