Что такое полигон в графике
Перейти к содержимому

Что такое полигон в графике

  • автор:

Полигоны: их назначение, создание и применение в различных областях

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

Полигоны: их назначение, создание и применение в различных областях обновлено: 27 ноября, 2023 автором: Научные Статьи.Ру

Помощь в написании работы

Введение

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

Нужна помощь в написании работы?

Мы — биржа профессиональных авторов (преподавателей и доцентов вузов). Наша система гарантирует сдачу работы к сроку без плагиата. Правки вносим бесплатно.

Что такое полигон

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

Полигон может иметь различные формы и размеры. Он может быть выпуклым, когда все его углы меньше 180 градусов, или невыпуклым, когда есть углы больше 180 градусов. Также полигон может быть правильным, когда все его стороны и углы равны, или неправильным, когда стороны и углы могут быть разными.

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

История полигонов

История полигонов уходит своими корнями в древние времена. Уже в древней Греции и Риме геометры и математики изучали и классифицировали различные формы и фигуры, включая полигоны.

Одним из первых известных математиков, который изучал полигоны, был Евклид, живший в 3 веке до нашей эры. В его знаменитом труде “Начала” он ввел определение полигона и изучал их свойства и связи.

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

В 19 и 20 веках с развитием математики и науки полигоны стали изучаться более глубоко и систематически. Были разработаны новые методы и теории, позволяющие анализировать и решать задачи, связанные с полигонами.

С появлением компьютеров и развитием компьютерной графики полигоны стали широко использоваться в 3D-моделировании и визуализации. Они стали основным инструментом для создания и отображения сложных трехмерных объектов и сцен.

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

Различные виды полигонов

Полигоны могут быть различных форм и размеров. Вот некоторые из наиболее распространенных видов полигонов:

Треугольник

Треугольник – это полигон с тремя сторонами и тремя углами. Он является самым простым и основным видом полигона. Треугольники широко используются в компьютерной графике и 3D-моделировании, так как они могут быть легко обработаны и отображены.

Квадрат

Квадрат – это полигон с четырьмя равными сторонами и четырьмя прямыми углами. Он является прямоугольником с равными сторонами и является одним из наиболее простых и распространенных видов полигонов.

Пятиугольник

Пятиугольник – это полигон с пятью сторонами и пятью углами. Он может иметь различные формы и размеры, включая правильный пятиугольник, у которого все стороны и углы равны.

Многоугольник

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

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

Назначение полигонов

Полигоны имеют широкий спектр применений в различных областях. Вот некоторые из них:

Геометрия

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

Компьютерная графика

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

Архитектура

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

Игровая индустрия

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

Машиностроение и робототехника

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

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

Основные элементы полигона

Полигон – это геометрическая фигура, состоящая из ребер и вершин. Вот основные элементы, которые составляют полигон:

Вершины

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

Ребра

Ребра – это отрезки, соединяющие вершины полигона. Они образуют границы полигона и определяют его форму и размеры.

Углы

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

Площадь

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

Периметр

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

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

Процесс создания полигона

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

Определение количества вершин

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

Задание координат вершин

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

Соединение вершин ребрами

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

Проверка на правильность

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

Расчет площади и периметра

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

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

Применение полигонов в различных областях

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

Геометрия

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

Компьютерная графика

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

Игровая индустрия

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

Архитектура

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

Географические информационные системы

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

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

Преимущества и недостатки полигонов

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

1. Гибкость: Полигоны могут быть использованы для представления различных форм и размеров объектов. Они могут быть простыми или сложными, с прямыми или изогнутыми границами. Это позволяет более точно и детально описывать объекты и их характеристики.

2. Визуализация: Полигоны могут быть легко визуализированы на картах и других графических представлениях. Они позволяют наглядно представить географические объекты и их связи, что облегчает понимание и анализ данных.

3. Анализ: Полигоны позволяют проводить различные анализы и расчеты на основе географических данных. Например, можно определить площадь полигона, вычислить его периметр, провести сравнительный анализ разных полигонов и т. д.

4. Интеграция: Полигоны могут быть легко интегрированы с другими географическими данными и информационными системами. Это позволяет создавать комплексные модели и анализировать данные из разных источников.

Недостатки:

1. Сложность создания: Создание полигонов может быть сложным и требовать специальных навыков и инструментов. Необходимо учитывать геометрические принципы и правила для правильного определения границ полигона.

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

3. Ограничения точности: Полигоны могут иметь ограничения в точности представления объектов. Например, при использовании полигонов для представления кривых или изогнутых границ, может возникнуть потеря точности и детализации.

4. Сложность анализа: Анализ полигонов может быть сложным и требовать специальных методов и инструментов. Необходимо учитывать географические и статистические аспекты для корректного интерпретации данных и получения достоверных результатов.

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

Будущее полигонов

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

Улучшение точности и детализации

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

Использование искусственного интеллекта

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

Интеграция с другими технологиями

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

Развитие визуализации и взаимодействия

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

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

Таблица по теме “Полигоны”

  • Имеет конечное число сторон
  • Все стороны и углы полигона могут быть различными
  • Сумма внутренних углов полигона всегда равна (n-2) * 180 градусов, где n – количество сторон
  • Сумма углов треугольника всегда равна 180 градусов
  • Может быть различных типов: равносторонний, равнобедренный, разносторонний
  • Стороны прямоугольника могут быть различной длины
  • Диагонали прямоугольника равны по длине и делят его на два равных треугольника
  • Сумма углов пятиугольника всегда равна 540 градусов
  • Может быть выпуклым или невыпуклым

Заключение

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

Полигоны: их назначение, создание и применение в различных областях обновлено: 27 ноября, 2023 автором: Научные Статьи.Ру

Нашли ошибку? Выделите текст и нажмите CRTL + Enter

Аватар

Тагир С.

Экономист-математик, специалист в области маркетинга, автор научных публикаций в Киберленинка (РИНЦ).

Полигон (в 3D-графике)

Музыка

Полиго́н (от греч. πολύγωνος – многоугольный), единица геометрического построения вершин, рёбер и граней, которые определяют форму объекта в трёхмерной графике при объёмном моделировании. Полигонами обычно являются треугольники , четырёхугольники или другие простые выпуклые многоугольники.

Редакция массовой культуры и медиа

Опубликовано 28 июля 2023 г. в 17:42 (GMT+3). Последнее обновление 28 июля 2023 г. в 17:42 (GMT+3). Связаться с редакцией

Информация

Музыка

Области знаний: Компьютерные технологии

  • Научно-образовательный портал «Большая российская энциклопедия»
    Свидетельство о регистрации СМИ ЭЛ № ФС77-84198,
    выдано Федеральной службой по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор) 15 ноября 2022 года.
    ISSN: 2949-2076
  • Учредитель: Автономная некоммерческая организация «Национальный научно-образовательный центр «Большая российская энциклопедия»
    Главный редактор: Кравец С. Л.
    Телефон редакции: +7 (495) 917 90 00
    Эл. почта редакции: secretar@greatbook.ru
  • © АНО БРЭ, 2022 — 2024. Все права защищены.
  • Условия использования информации. Вся информация, размещенная на данном портале, предназначена только для использования в личных целях и не подлежит дальнейшему воспроизведению.
    Медиаконтент (иллюстрации, фотографии, видео, аудиоматериалы, карты, скан образы) может быть использован только с разрешения правообладателей.
  • Условия использования информации. Вся информация, размещенная на данном портале, предназначена только для использования в личных целях и не подлежит дальнейшему воспроизведению.
    Медиаконтент (иллюстрации, фотографии, видео, аудиоматериалы, карты, скан образы) может быть использован только с разрешения правообладателей.

3ds Max. Часть 4. Основы полигонального моделирования

Без знания основ полигонального моделирования невозможно спроектировать чуть более сложные объекты, чем примитивы. Разбираемся с вертексами и рёбрами.

Степан Степанов

Степан Степанов

Автор статей по дизайну. В веб-дизайн пришёл в 2013 году, осознанно начал заниматься с 2015 года. Параллельно освоил вёрстку. Время от времени публикую переводы на Habr.

Перед тем как начать моделирование такого сложного 3D-объекта, как автомобиль, нужно понимать основные принципы полигонального моделирования и знать назначение и функциональные возможности инструментов.

Что такое полигон

Полигон — плоскость, состоящая из нескольких точек в пространстве, соединённых рёбрами.

Что такое полигональное моделирование (polygonal modeling)

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

Разбираемся с полигональным моделированием на примере

Давайте создадим примитив box, конвертируем его в Editable Poly (редактируемые полигоны) и на этом примере детально рассмотрим, что такое полигон и из чего он состоит. В этом уроке вы можете посмотреть, как создать примитив.

Чтобы конвертировать объект в редактируемые полигоны, нажмите правой кнопкой мыши в активном окне проекции и в контекстном меню выберите Convert To — Convert to Editable Poly.

Итак, вы создали примитив box и перевели его в Editable Poly. Далее рассмотрим, из каких подобъектов состоит Editable Poly.

Уровень подобъектов Editable Poly

Нажмите стрелку на командной панели во вкладке Modify перед названием Editable Poly, чтобы перейти на уровень подобъектов. Их мы и будем сейчас разбирать.

Vertex (вершины)

Чтобы работать с этим уровнем подобъектов, нажмите клавишу 1 на клавиатуре. Вершина — это одномерный объект (точка) в пространстве. Если соединить, например, две вершины, получится ребро.

Edge (рёбра)

Нажмите на клавишу 2 на клавиатуре, чтобы работать с этим уровнем подобъектов. Ребро — это двумерный объект, который определяется двумя вершинами и представляет собой линию. Три ребра и более образуют многоугольник.

Border (граница)

Нажмите на клавишу 3 на клавиатуре, чтобы работать с этим уровнем подобъектов.

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

Перейдите на подобъект, выделите любой видимый полигон и удалите его по нажатию на Del на клавиатуре. Теперь края удалённого полигона и будут тем самым бордером.

Polygon (полигон)

Polygon вызывается по клавише 4 на клавиатуре. Состоит из трёх и более рёбер.

Element (элемент)

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

В свитке Selection иконками представлены все подобъекты Editable Poly. Когда вы выбираете один из подобъектов, там активируется нужная иконка, и наоборот: когда вы нажимаете на какую-либо из иконок, у вас будет выделяться один из подобъектов в списке.

Все эти подобъекты нужны при создании полигональной сетки 3Dобъекта. Чтобы выполнять с ними какие-либо действия, нужно использовать базовые инструменты для работы с подобъектами, которые находятся на командной панели во вкладке Modify ниже окна объекта Editable Poly.

Заключение

Всё полигональное моделирование основано на взаимодействии с рассмотренными подобъектами — вершинами, рёбрами, полигонами и так далее. Посредством Editable Poly создаются большинство моделей и сцен, которые можно применить где угодно — от анимационной презентации архитектурной застройки до локаций для игр.

Введение в компьютерную графику

Как известно, трехмерная графика формируется из треугольных полигонов (face). Они имеют различные материалы, параметры освещенности и текстуры (изображения).

Иллюстрация построения трехмерной графики из треугольных полигонов

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

Обычно для этого используют низкополигональные модели (до 50 тысяч полигонов на модель).

Обмен данными между центральным процессором (CPU) и видеокартой (GPU)

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

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

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

Вершины

Видеокарта персонального компьютера позволяет на аппаратном уровне рисовать на экране треугольные полигоны, заданные тремя трехмерными координатами (x,y,z). Координаты вершин обычно задают в формате float.

Системы координат

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

Иллюстрация принципа формирования координат точек в локальной системе координат объекта

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

Нормали

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

Иллюстрация эффекта выгнутости треугольного полигона путем задания ему трех несонаправленных нормалей.

Координаты каждой нормали (Nx, Ny, Nz) также задаются в локальной системе координат. Длина вектора нормали должна быть равна 1.

Материалы

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

Источники света

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

Текстуры

Для закраски полигона могут использоваться текстуры (изображения). Изображения всех текстур загружается в память видеокарты на этапе загрузки сцены. Каждой загруженной текстуре присваивается дескриптор (порядковый номер) текстуры. При рисовании текстуры процессор указывает лишь этот дескриптор.

Важное требование – размер изображения текстуры по длине и ширине должен быть кратен степени 2. Т.е. подходят размеры 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048. Некоторые современные видеокарты (отнюдь не все!) поддерживают расширение ARB_texture_non_power_two, позволяющее отображать текстуры, размер которых не кратен степени 2. Однако для совместимости со всеми видеокартами желательно все же использовать текстуры, кратные степени 2.

Желательно чтобы размер текстуры был не более, чем 512×512. Использование текстур больших размеров связан с дополнительными ограничениями скорости отрисовки таких текстур, т.к. видеокарта размещает такую текстуру в разные аппаратные блоки.

Текстурные координаты

Чтобы разместить текстуру на объекте у каждой вершины полигона задаются текстурные координаты (u,v). Текстурная координата u вершины – это нормированная координата X в системе координат изображения, соответствующая данной вершине. А координата v – это координата Y в системе координат изображения. Нормировка производится длиной и шириной изображения соответственно по u и по v.

Иллюстрация использования текстурных координат

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

Индекс-буферы

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

Заметьте, что, например, у сферы каждая вершина используется как минимум 4 смежными полигонами, а полюса 32 сегментной сферы – аж 32 полигонами! Зачем каждому их этих полигонов хранить и всякий раз при рисовании пересчитывать координаты этой общей вершины? Можно отдельно хранить и расчитывать координаты всех вершин, нормалей и текстурных координат (вертекс-буфер), а отдельно хранить последовательность соединения этих вершин полигонами (индекс-буфер).

В индекс-буфере хранится массив номеров вершин. Размер массива всегда кратен 3. Каждые три числа их этого массива формируют номера вершин для рисования одного полигона.

Иногда индекс буфер рассматривают как массив из n троек чисел. Каждую такую тройку номеров вершин называют face.

Пояснение понятия индекс-буфера

Отсечение невидимых поверхностей. Z-буфер

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

Иллюстрация отсечение невидимых поверхностей с помощью технологии Z-буфера.

На рисунке цветовой буфер совмещен с Z-буфером. Цифра в ячейках показывает значение, записанное в пиксель Z-буфера. Цвет ячейки позывает значение цвета, записанное в пиксель цветового буфера. Полигоны 1, 2, 3 выводились на экран в указанной последовательности. При этом глубина всех пикселей полигона 1 равна 5 условных единиц глубины, глубина всех пикселей полигона 2 равна 9, а глубина всех пикселей полигона 3 равна 2. Заметьте, что при попытке нарисовать полигон 2 в пикселях, перекрытых полигоном 1, рисование не производилось, т.к. в буфере глубины в данных пикселях было значение (5) меньше, чем глубина (9) пикселей полигона 2. При рисовании полигона 3 проверка глубины во всех случаях завершилась успехом, и все пиксели полигона были отрисованы в цветовом буфере.

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

Отсечение невидимых поверхностей по технологии CULL_FACE

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

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

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

Отсечение невидимых полигонов, повернутых к камере своей задней стороной, называется технологией CULL_FACE или технологией односторонних полигонов.

Создание трехмерных моделей

Разработка моделей с помощью трехмерных редакторов

Координаты полигонов можно задавать непосредственно в коде программы, однако такой способ рисования очень не удобен. Попробуйте задать координаты 100000 треугольных полигонов вручную!

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

При подобном подходе встает вопрос об описании формата хранения трехмерной сцены.

Соображения о формате хранения трехмерной сцены

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

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

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

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

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

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

Для формирования локальной системы координат трехмерного объекта удобно использовать матрицы преобразования 4×4. Причем у каждого объекта удобно хранить две матрицы преобразования: локальную матрицу преобразования (matrix), которая определяет положение и ориентацию объекта относительно своего родительского объекта, а также мировую матрицу преобразования (worldMatrix), которая определяет положение объекта в мировой системе координат. Мировые матрицы преобразования будут автоматически рассчитываться перед рисованием очередного кадра на основе информации локальных матриц преобразования.

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

Рекомендуемый формат описания 3D-сцены

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

Во главе структуры стоит объект CScene. В нет размещена ссылка на все трехмерные объекты (objects) и ссылка на менеджер текстур.

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

Текстуры организованы в виде двунаправленной очереди. Каждая текстура имеет ссылку на следующую текстуру очереди (next) и предыдущую текстуру очереди (prev).

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

Трехмерные объекты (CObject3D) организованы в виде дерева. Свойства child и parent указывают соответственно на дочерний (привязанный) и родительский объект. Свойство next и prev указывают на объекты одного уровня иерархии.

Объект может содержать ссылку на камеру (camera), источник света (light) или на геометрический объект (mesh). Кроме того объект хранит локальную матрицу преобразования (matrix) и мировую матрицу преобразования (worldMatrix).

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

Мировая матрица преобразования используется только на этапе прорисовки сцены (render). Первый этапом прорисовки с помощью метода object->UpdateMatrix() производится пересчет мировых матриц всех объектов по информации, хранимой в локальных матрицах преобразования (matrix).

Кроме всего прочего объект хранит свое название, которое ему дали в 3D Studio MAX.

Камеры сцены содержат поле FOV — угол обзора. Также имеется ссылка объект, к которому принадлежит камера. Объект сцена (CScene) содержит ссылку на активную камеру сцены. Камер на сцене может быть несколько, но только одна активная. По умолчанию активная камера задается в 3D Studio MAX.

Источники света содержат информацию о цвете (color) источника, признак включения/выключения (onOff), а также прочие свойства источников света. Также класс CLight содержит указатель на объект, к которому он принадлежит.

Геометрические объекты (CMesh) имеют ссылку на один или несколько индексных буферов, а также на вершины, нормали и текстурные координаты (вертексный буфер). Вертексный буфер для совместимости с возможностью загрузки информации на видеокарту организован специальным образом — выделяется единый непрерывный блок памяти для хранения в нем вершинных координат, нормалей и текстурных координат. Таким образом ссылка vertices указывает на начало этого буфера, а normals и texCoords указывают на части этого буфера. Количество вершин, нормалей и текстурных координат одинаково и равно vCount.

Вертексный буфер может быть размещен в памяти видеокарты. В этом случае дескриптор handle класса CMesh указывает на данный буфер в видеопамяти. При загрузке вертексного буфера в память видеокарты из памяти центрального процессора он удаляется (ссылки vertices, normals, texCoords указывают на NULL).

Индексный буфер содержит информацию о порядке соединения вершин полигонами (face). Каждый индексный буфер отвечает за нанесение на объект одного из материалов.

Индексный буфер содержит ссылку на массив индексов indices из count элементов (count всегда кратно 3). Каждая тройка индексов из этого массива содержит номера вершин, соединив которые образуется очередной трехмерный полигон. Все полигоны одного индексного буфера имеют один и тот же материал. Также индексный буфер содержит ссылки на материал (material) и следующий индексный буфер (next), если он есть у данной mesh. Последний индексный буфер данного mesh указывает на NULL.

Индексный буфер может быть загружен в память видеокарты. В этом случае дескриптор handle класса CIndexBuffer указывает на данный буфер в памяти видеокарты. Если индексный буфер находится в памяти видеокарты, то массив индексов из памяти центрального процесса удаляется, а указатель indices класса CIndexBuffer указывает на NULL.

Материал (CMaterial) содержит 4 цвета материала (ambientColor — цвет в тени, diffuseColor — основной цвет объекта, specularColor — цвет блика, emmisionColor — цвет самосвечения), параметр глянца (glossiness), свойство twoSided сообщающее OpenGL о необходимости использования двухсторонних материалов. Также материал содержит указатель на текстуру (если она есть) и матрицу преобразования данной текстуры (matrix). Матрица преобразования текстуры содержит информацию о повороте, повторе и смещения текстуры.

Рекомендуемый формат описания 3D-сцены. В скачиваемом файле представлен код заголовочного файла (h-файла), в котором может быть описана 3D-сцена. Студент должен самостоятельно создать соответствующий cpp-файл, в котором будут реализованы предлагаемые функции и методы классов, заголовок которых описан в h-файле.

#ifndef glUnitH #define glUnitH #include #include  #include  #include #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.lib") #pragma warning( disable: 4996 ) #pragma warning( disable: 4244 ) #pragma warning( disable: 4312 ) #pragma warning( disable: 4311 ) typedef struct < float x,y,z; > VECTOR; typedef struct < float u,v; > TEXCOORD; typedef struct < float r,g,b,a; > COLOR3D; // MATRIX A;  typedef union < struct < VECTOR rowX; float zero0; VECTOR rowY; float zero1; VECTOR rowZ; float zero2; VECTOR position; float one; > rows; > MATRIX; class CTextureManager; class CMesh; class CObject3D; class CScene; class CTexture < public: >; class CTextureManager < public: CTexture *Get(const char *texName); >; class CMaterial < public: >; class CIndexBuffer < public: >; class CMesh < public: void SetVCount(int n, bool isNormals, bool isTexCoord); >; class CLight < public: void Render(int n); >; class CCamera < public: CCamera(CObject3D *obj); ~CCamera(); >; class CObject3D < public: CObject3D *next,*prev,*child,*parent; CObject3D *id; void SetParent(CObject3D *newParent); void UpdateTransform(); void RenderLights(int *n); void Render(); CObject3D *FindObject(const char *Name); void Translate(float x, float y, float z); void RotateX(float a); void RotateY(float a); void RotateZ(float a); >; void MatrixMul(MATRIX &res, const MATRIX &M1, const MATRIX &M2); class CScene < public: void UploadToGPU(); >; #endif 

Код инициализации OpenGL

Предлагаемый код инициализации OpenGL:

 #include #include  . dc = DC; width = w; height = h; PIXELFORMATDESCRIPTOR PFD; memset(&PFD,0,sizeof(PFD)); PFD.nSize=sizeof(PFD); PFD.nVersion = 1; PFD.dwFlags=PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; PFD.iPixelType = PFD_TYPE_RGBA; PFD.iLayerType = PFD_MAIN_PLANE; PFD.cColorBits = 32; PFD.cDepthBits = 32; int f = ChoosePixelFormat(dc, &PFD); if (!f) ; SetPixelFormat(dc, f, &PFD); rc = wglCreateContext(dc); wglMakeCurrent(dc, rc); glViewport(0,0,width, height); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_GREATER,0.3f); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); ; >

Предлагаемый код деинициализации 3D:

 child) child; textureManager.Clear(); wglMakeCurrent(0, 0); if (rc) < wglDeleteContext(rc); rc = 0; >>

Пример рисования в OpenGL. Простой, но медленный код

Далее приводится пример рисования произвольных фигур в OpenGL. Данный код медленный, поэтому использовать его не рекомендуется.

// рисование произвольных фигур из треугольников // установить матрицу преобразования glMatrixMode( GL_MODELVIEW); // режим матриц сцены glPushMatrix(); // запоминить текущую матрицу glMultMatrixf( obj->worldMatrix.m[0] ); // домножить на матрицу объекта material->Bind(); // установить материал glBegin(GL_TRIANGLE); // начать создание фигуры // треугольник 1 glNormal3f( normal1A.x, normal1A.y, normal1A.z); // нормаль точки 1 glTexCoord2f( texCoord1A.x, texCoord1A.y, texCoord1A.z); // текст. координаты точки 1 glVertex3f( vertex1A.x, vertex1A.y, vertex1A.z); // вертекст точки 1 glNormal3f( normal1B.x, normal1B.y, normal1B.z); // нормаль точки 2 glTexCoord2f( texCoord1A.x, texCoord1A.y, texCoord1B.z); // текст. координаты точки 2 glVertex3f( vertex1B.x, vertex1B.y, vertex1B.z); // вертекст точки 2 glNormal3f( normal1C.x, normal1C.y, normal1C.z); // нормаль точки 3 glTexCoord2f( texCoord1C.x, texCoord1C.y, texCoord1C.z); // текст. координаты точки 3 glVertex3f( vertex1C.x, vertex1C.y, vertex1C.z); // вертекст точки 3 // треугольник 2 glNormal3f( normal2A.x, normal2A.y, normal2A.z); // нормаль точки 1 glTexCoord2f( texCoord2A.x, texCoord2A.y, texCoord2A.z); // текст. координаты точки 1 glVertex3f( vertex2A.x, vertex2A.y, vertex2A.z); // вертекст точки 1 glNormal3f( normal2B.x, normal2B.y, normal2B.z); // нормаль точки 2 glTexCoord2f( texCoord1A.x, texCoord2A.y, texCoord2B.z); // текст. координаты точки 2 glVertex3f( vertex2B.x, vertex2B.y, vertex2B.z); // вертекст точки 2 glNormal3f( normal2C.x, normal2C.y, normal2C.z); // нормаль точки 3 glTexCoord2f( texCoord2C.x, texCoord2C.y, texCoord2C.z); // текст. координаты точки 3 glVertex3f( vertex2C.x, vertex2C.y, vertex2C.z); // вертекст точки 3 . glEnd(); glPopMatrix(); // восстановить матрицу

Данный способ рисования подходит для рисования отдельных небольших объектов, например, для рисования различных эффектов, 3D-элементов интерфейса, наложенного поверх трехмерного изображения и т.п.

Рекомендуемый быстрый способ рисования трехмерных фигур

Данный способ рисования трехмерных фигур подразумевает наличие вертексных-буферов и индекс-буферов, поэтому наиболее подходит для предлагаемой структуры 3D-сцены. Кроме того, т.к. вся геометрия загружается в GPU одним массивом (одной командой), данный код позволяет сократить число обращений к видеокарте, а, следовательно, ускорить прорисовку.

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

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

CMaterial defMaterial; // материал по умолчанию // отрисовка индекс-буфера void CIndexBuffer::Render(CMesh *mesh) < if (material) material->Bind(); // установить материал индекс-буфера, если есть else < // установить материал по умолчанию, установив ему цвет объекта defMaterial.ambientColor = mesh->wireColor; defMaterial.deffuseColor = mesh->wireColor; defMaterial.Bind(); > if (!handle) < // отрировать, если индекс-буфер не загружен в GPU if (isOpenGL11) < // быстрая прорисовка glDisableClientState(GL_INDEX_ARRAY); glDrawElements(GL_TRIANGLES, сount, GL_UNSIGNED_INT, indices); >else < // если нет поддержки быстрой прорисовки. Прорисовка первым методом: int i; glBegin(GL_TRIANGLES); for(i = 0; i < count; i++) < if(mesh->hasNormals) glNormal3fv(&mesh->normals[ indices[i] ].x); if(mesh->hasTexCoord) glTexCoord2fv(&mesh->texCoords[ indices[i] ].u); glVertex3fv(&mesh->vertices[indices[i] ].x); > glEnd(); > > else <  // отрировать, если индекс-буфер загружен в GPU // (в случае использования расширения openGL) /* glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, handle); glEnableClientState(GL_INDEX_ARRAY); glIndexPointer(GL_UNSIGNED_INT, 0, 0); glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, NULL); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); */  > > void CMesh::Render(CObject3D *obj) < // установить матрицу преобразования glMatrixMode( GL_MODELVIEW); // режим матриц сцены glPushMatrix(); // запоминить текущую матрицу glMultMatrixf( obj->worldMatrix.m[0] ); // домножить на матрицу объекта if (isOpenGL11) < // если есть поддержка быстрой прорисовки // установить вертекс-буфер glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); // применить вертексные буфера if (!handle) < // если геометрия не загружена в GPU glVertexPointer(3, GL_FLOAT, 0, vertices); glEnableClientState(GL_VERTEX_ARRAY); if (hasNormals) < glNormalPointer(GL_FLOAT, 0, normals); glEnableClientState(GL_NORMAL_ARRAY); >if (hasTexCoords) < glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_TEXCOORD_ARRAY); >> else <  // если геометрия была загружена в GPU /* int offset = 0; // установить текущий аппаратный буфер glBindBufferARB(GL_ARRAY_BUFFER, handle); // установить в OpenGL смещение вертекс-буфера glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, (void*)offset); offset += (int)sizeof(VECTOR) * vCount; // установить в OpenGL смещение буфера нормалей if (hasNormals) < glNormalPointer(GL_FLOAT, 0, (void*)offset); glEnableClientState(GL_NORMAL_ARRAY); offset += (int)sizeof(VECTOR) * vCount; >// установить в OpenGL смещение буфера текстурных координат if (hasTexCoords) < glTexCoordPointer(2, GL_FLOAT, 0, (void*)offset); glEnableClientState(GL_TEXCOORD_ARRAY); >*/  > > // установить направление обхода if (ccw) glCullFace(GL_FRONT); else glCullFace(GL_BACK); // разрешить Z-буфер (мало ли кто его запретил) glDepthMask(TRUE); glEnable(GL_DEPTH_TEST); // рисуем индекс-буферы CIndexBuffer *ibuf = indexBuffers; while(ibuf) < ibuf->Render( this ); ibuf = ibuf->next; > // деинициализация аппаратного буфера if (handle) glBindBufferARB(GL_ARRAY_BUFFER, 0); // вернуть прошлые атрибуты if (isOpenGL11) glPopClientAttrib(); glPopMatrix(); // восстановить матрицу >

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

Далее приводится код проверки совместимости видеокарты:

bool isOpenGL11 = false; const char * extensions = (const char *) glGetString ( GL_EXTENSIONS ); if (strstr(extensions, "GL_EXT_draw_range_elements")) < // проверка пойдена isOpenGL11 = true; >

Экспорт моделей из 3D Studio MAX

С помощью данного скрипта на языке MAX Script можно экспортировать модели из 3D Studio MAX в простой и удобный бинарный формат.

Описание формата файла экспорта.

    Один раз за сеанс работы 3D Studio MAX запустите скрипт cg.ms.

Первый пункт можно не выполнять, если файл cg.ms скопировать в подпапку scripts/startup в директории 3D Studio MAX. В этом случае данный скрипт попадет в автозагрузку 3D Studio MAX.

Шаблон кода загрузчика cg-файлов

Приведенный ниже пример кода поможет написать загрузчик cg-файла:

  unit3D.h"; .  *fileName) < FILE *f;   *body;  f = fopen(fileName, "; fseek(f, 0, SEEK_END); // указатель чтения из файла на конец файла bodySize=( if (bodySize < 4) < fclose(f); ; > body = (*)malloc( bodySize ); fread( body, bodySize, 1, f); fclose(f); int objectCount; CObject3D **objects = NULL;  CObject3D *obj = NULL; CMesh *mesh = NULL; CIndexBuffer *indexBuffer = NULL; CMaterial *material = NULL;      memcpy(&tagName, body + pos, 4); pos+=4; if (strcmp(tagName, "; > memcpy(&tagName, body + pos, 4); pos+=4; memcpy(&tagSize, body + pos, 4); pos+=4; tagPos = pos;   bodySize)   obj =   obj->SetName( buf ); memcpy(&obj->id, body + pos, 4); pos+=4; memcpy(&obj->parent, body + pos, 4); parent не действительный указатель. //т.к. мы прочитали в 32-битный адрес объекта 32-битный //индентификатор объекта. Но другого специального буфера //для временного хранения идентификатора родительского объекта //у нас нет, в то время как сам указатель obj->parent //нам на этапе чтения файла не нужен. //После чтения всего файла необходимо будет связать объекты, //используя считанные в поле obj->parent идентификаторы. pos+=4; memcpy(&obj->matrix.rows.row0, body + pos, 12); pos+=12; memcpy(&obj->matrix.rows.row1, body + pos, 12); pos+=12; memcpy(&obj->matrix.rows.row2, body + pos, 12); pos+=12; memcpy(&obj->matrix.rows.position, body + pos, 12); pos+=12; > mesh = mesh; . > >  int n; memcpy(&n, body + pos, 4); pos+=4; indexBuffer->SetCount(n); memcpy(indexBuffer->indices, body + pos, n *  ")==0) < material = material; . > >  ")==0) <    material->texture = scene->textureManager.Get(buf); memcpy(&material->matrix.rows.row0, body + pos, 12); pos+=12; memcpy(&material->matrix.rows.row1, body + pos, 12); pos+=12; memcpy(&material->matrix.rows.row2, body + pos, 12); pos+=12; memcpy(&material->matrix.rows.position, body + pos, 12); pos+=12; > >  int n; memcpy(&n, body + pos, 4); pos+=4; mesh->SetVCount(n, mesh->normals != texCoord != memcpy(mesh->vertices, body + pos, n *  int n; memcpy(&n, body + pos, 4); pos+=4; mesh->SetVCount(n, texCoord != memcpy(mesh->normals, body + pos, n *  int n; memcpy(&n, body + pos, 4); pos+=4; mesh->SetVCount(n, mesh->normals != memcpy(mesh->texCoords, body + pos, n *  ")==0) < . > . > . > . > pos = tagPos + tagSize; > free(body); parent) < CObject3D *searchID = objects[i]->parent; objects[i]->parent = NULL; id == searchID) < objects[i]->SetParent( objects[j] ); parent) objects[i]->SetParent( scene->objects ); > free(objects); ; >

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

  *body,     ) ( p++; > str[i] = 0; *pos = p + 1; 

Для продвинутых студентов: расширения OpenGL

Студентам, которые хотят изучить возможности OpenGL сверх программы курса "Компьютерная графика", предлагается установить расширения OpenGL.

Данный архив сдедует распаковать в папку с проектом, подключить с помощью директивы #include бибиотеку glext.h и libExt.h, а также включить в проект файл libExt.cpp

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

Все расширения OpenGL можно разбить:

  • общие расширения, поддерживаемые всеми производителями видеокарт (функции и константы этого расширения имеют окончание _EXT или _ARB, например GL_COMBINE_EXT);
  • на расширения, поддерживаемые картами nVidia (расширения имеют окончание _NV);
  • на расширения, поддерживаемые картами ATI (расширения имеют окончание _ATI).

Рекомендуется использовать только общие расширения (_EXT или _ARB). В этом случае разработанное приложение будет работать на всех современных видеокартах.

Полное описание расширений можно найти в google.

Проверка поддержки аппаратных вертекс-буферов и индекс-буферов

#include #include #include #include "libExt.h" #include "glExt.h" . initExtensions(); if (isExtensionSupported("GL_ARB_vertex_buffer_object")) < // имеется поддежка аппаратных буферов >

Пример загрузки индекс-буфера в GPU

GLuint handle; // переменная, объявленная в классе CIndexBuffer . glGenBuffersARB(1, &handle); // создать один буфер и записать его дескриптор в handle glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, handle); // сделать буфер текущим // передать данные из массива indices в аппаратный буфер в GPU glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 4 * indexCount, indices, GL_STATIC_DRAW_ARB); // сделать текущим пустой буфер glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); // освободить память от индексов, т.к. они записаны в GPU, и в CPU они больше не нужны free(indices); indices = NULL;

Пример загрузки вертексов, нормалей и текстурных координат в GPU

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

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

GLuint handle; // переменная, объявленная в классе CMesh . // определить размер вертекс-буфера в зависимости от наличия нормалей и текст. координат int sz = sizeof(VECTOR) * vCount; if (hasNormals) sz+=sizeof(VECTOR) * vCount; if (hasTexCoords) sz+=sizeof(TEXCOORD) * vCount; glGenBuffersARB(1, &handle); // создать один буфер и записать его дескриптор в handle glBindBufferARB(GL_ARRAY_BUFFER_ARB, handle); // сделать буфер текущим // передать данные из буфера vertices (в нем же нормали и текстурные координаты) в аппаратный буфер в GPU glBufferDataARB(GL_ARRAY_BUFFER_ARB, sz, vertices, GL_STATIC_DRAW_ARB); // сделать текущим пустой буфер glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); // освободить память от буфера, т.к. массив уже записан в GPU, и в CPU он больше не нужен free(vertices); vertices = NULL; normals = NULL; texCoords = NULL;

Следует отметить, что константу GL_STATIC_DRAW_ARB имеет смысл заменить на GL_DYNAMIC_DRAW_ARB, если подразумевается дальнейшая манипуляция координатами геометрии, например, в случае с Skin.

Удаление аппаратного буфера

if (handle) glDeleteBuffersARB(1, &handle);

Пример простейшей программы под windows для Microsoft Visual C++

Если разрабатывается проект на Microsoft Visual C++, то следует сначала создать минимальную программу под Windows, в которую будет внедрен код отрисовки. Пример такой программы приведен ниже:

#include // #include "glUnit.h" // подключение Вашего модуля с графикой //----- глобальные переменные ----- HINSTANCE instance; // дескриптор приложения HWND gWnd; // дескриптор главного окна HDC gDC; // дескриптор холста (device context) главного окна //---- на каждое событие назначим функцию обработки данного события ---- // событие создания окна void OnCreate(HWND wnd) < gWnd = wnd; gDC = GetDC(wnd); // получить device context окна // инициализация графики //. >// событие изменение размеров окна void OnResize() < // получить новые размеры окна RECT r; GetClientRect(gWnd, &r); // установить размер окна для графики r.right x r.bottom //. >// холостой ход приложения (отсутствие событий) void OnIdle() < // Отрисовать кадры // . >// Событие закрытие приложения. void OnClose() < // деинициализация графики // . ReleaseDC(gWnd, gDC); >// Событие нажатия клавиши на клавиатуре void OnKeyDown(short key) < switch(key) < case VK_ESCAPE: // клавиша ESC CloseWindow(hWnd); break; >> //----- функция обработки событий главного окна ---------- LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) < switch(msg) < case WM_CREATE: OnCreate(wnd); break; case WM_SIZE: OnResize(); break; case WM_KEYDOWN: OnKeyDown((short)wParam); break; case WM_CLOSE: OnClose(); DestroyWindow(wnd); PostQuitMessage(0); break; >return DefWindowProc(wnd, msg, wParam, lParam); > //--------------- главная функция приложения ------------------ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) < // запомнить декриптор приложения instance = hInstance; // зарегистрировать класс главного окна WNDCLASS cls; cls.cbClsExtra = 0; cls.cbWndExtra = 0; cls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); cls.hCursor = LoadCursor(0, IDC_ARROW); cls.hIcon = 0; cls.hInstance = instance; cls.lpfnWndProc = WindowProc; cls.lpszClassName = "MyClass"; cls.lpszMenuName = NULL; cls.style = 0; RegisterClass(&cls); // создать главное окно HWND wnd = CreateWindowEx(0, cls.lpszClassName, "Моя первая программа", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, 0, 0, instance, 0); ShowWindow(wnd, SW_SHOW); // главный цикл приложения MSG msg; while(1) < if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) // есть событие для приложения? < // Обработать событие if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); >else < // нет события - холостой ход OnIdle(); >> // выход return 0; >;

Следует отметить, что данная программа для простоты не использует Unicode-кодировку. Для этого следует перед компиляцией в свойствах проекта (меню "Project | xxx Properties. ") отключить UNICODE-кодировку (В списке "Configuration Properties -> General" найти свойство "Character Set" и установить его равным "Use Multi-Byte Character Set").

Демонстрационный проект

Демострационный проект, позволяющий воспроизводить 3D-графику средствами OpenGL с применением аппаратных буферов:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *