Содержание

Слайд 2

Полигональные сетки (Polygonal meshes) Полигональные сетки – набор полигонов (граней), которые

Полигональные сетки (Polygonal meshes)

Полигональные сетки – набор полигонов (граней), которые в

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

Достоинства полигональных сеток Основаны на простоте использования полигонов: Легко представлять и

Достоинства полигональных сеток

Основаны на простоте использования полигонов:
Легко представлять и преобразовывать
Обладают

простыми свойствами
Единственный вектор нормали
Четко определенные внутренняя и внешняя области
Простота рисования
подпрограмма закрашивания полигонов или наложения текстуры на плоскую грань
Полигональные сетки позволяют представлять трехмерные объекты практически любой степени сложности
Слайд 4

Пример:

Пример:

Слайд 5

Монолитные объекты и тонкие оболочки Полигональные сетки позволяют задавать объекты двух

Монолитные объекты и тонкие оболочки

Полигональные сетки позволяют задавать объекты двух типов:
Монолитные

(solid) объекты
полигональные грани плотно примыкают друг к другу и ограничивают некоторое пространство
Примеры: куб, сфера
Тонкие оболочки
Полигональные грани примыкают друг к другу без ограничения пространства, представляя собой поверхность бесконечно малой толщины
Пример: график функции z=f(x,y)
Слайд 6

Примеры:

Примеры:

Слайд 7

Вершины полигона Каждый полигон определяется путем перечисления его вершин Вершина задается

Вершины полигона

Каждый полигон определяется путем перечисления его вершин
Вершина задается при помощи

перечисления ее координат в пространстве
Слайд 8

Пример представления вершины полигона struct Vertex { GLfloat x; GLfloat y; GLfloat z; };

Пример представления вершины полигона

struct Vertex
{
GLfloat x;
GLfloat y;
GLfloat z;
};

Слайд 9

Нормаль к полигону Вектор нормали задает направление перпендикуляра грани При рисовании

Нормаль к полигону

Вектор нормали задает направление перпендикуляра грани
При рисовании объекта эта

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

Пример представления нормали полигона struct Normal { GLfloat x; GLfloat y; GLfloat z; };

Пример представления нормали полигона

struct Normal
{
GLfloat x;
GLfloat y;
GLfloat z;
};

Слайд 11

Нормали в вершинах и нормали в поверхностях Использование нормалей к грани

Нормали в вершинах и нормали в поверхностях

Использование нормалей к грани плохо

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

В OpenGL нормаль является атрибутом вершины С т.з. быстродействия выгоднее хранить

В OpenGL нормаль является атрибутом вершины
С т.з. быстродействия выгоднее хранить отдельную

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

Пример структур данных для хранения сеток struct Vector3d { GLfloat x,

Пример структур данных для хранения сеток

struct Vector3d
{
GLfloat x, y, z;
};

struct Mesh
{
GLuint

numVertices;
Vertex *pVertices;
GLuint numFaces;
Face *pFaces;
};

struct Vertex
{
Vector3d position;
Vector3d normal;
// …
};

struct Face
{
GLushort v0;
GLushort v1;
GLushort v2;
};

Слайд 14

Возможные вариации Если полигональная сетка задается при помощи однотипных примитивов, например,

Возможные вариации

Если полигональная сетка задается при помощи однотипных примитивов, например, треугольников,

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

Пример struct Vector3d { GLfloat x, y, z; }; struct Mesh

Пример

struct Vector3d
{
GLfloat x, y, z;
};

struct Mesh
{
GLuint numVertices;
Vertex *pVertices;
GLenum primitiveType;
GLuint numIndices;
GLushort *pIndices;
};

struct

Vertex
{
Vector3d position;
Vector3d normal;
// …
};

void DrawMesh(Mesh *pMesh)
{
glBegin(pMesh->primitiveType);
for (GLuint i = 0; i < pMesh.numIndices; ++i)
{
GLushort v = pIndices[i];
glNormalfv(&(pMesh->pVertices[v].normal.x));
glVertex3fv(&(pMesh->pVertices[v].position.x));
}
glEnd();
}

Слайд 16

Лицевые и нелицевые стороны граней Каждая плоская грань (полигон) имеет две

Лицевые и нелицевые стороны граней

Каждая плоская грань (полигон) имеет две стороны:
лицевую

(видна извне объекта)
нелицевую (видна изнутри объекта)
В один момент времени с заданной точки видна только одна сторона грани
Снаружи монолитного объекта видны только лицевые грани
OpenGL позволяет эффективно отбрасывать лицевые или нелицевые грани, что ускоряет процесс рисования
Слайд 17

Определение видимой стороны грани Для определения стороны грани, повернутой к наблюдателю,

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

Для определения стороны грани, повернутой к наблюдателю, OpenGL

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

Обход сторон куба против часовой стрелки

Обход сторон куба против часовой стрелки

Слайд 19

Команда glFrontFace Задает направление обхода вершин грани, соответствующее ее лицевой стороне

Команда glFrontFace

Задает направление обхода вершин грани, соответствующее ее лицевой стороне (Front

face):
void glFrontFace(GLenum mode) где mode:
GL_CW – по часовой стрелке (Clockwise)
GL_CCW – против часовой стрелки (Counter clockwise), это значение по умолчанию
Слайд 20

Режим отбраковки граней (Face culling) После того, как направление обхода вершин

Режим отбраковки граней (Face culling)

После того, как направление обхода вершин грани

установлено, OpenGL может произвести ее отбраковку
Для этого необходимо включить режим отбраковки граней и указать какие из граней должны быть отбракованы
Слайд 21

Управление режимом отбраковки граней glEnable(GL_CULL_FACE) glDisable(GL_CULL_FACE) void glCullFace(GLenum mode) где mode: GL_FRONT GL_BACK GL_FRONT_AND_BACK

Управление режимом отбраковки граней

glEnable(GL_CULL_FACE)
glDisable(GL_CULL_FACE)
void glCullFace(GLenum mode) где mode:
GL_FRONT
GL_BACK
GL_FRONT_AND_BACK

Слайд 22

Нахождение нормальных векторов (нормалей) Координаты нормалей для каждой вершины можно задавать:

Нахождение нормальных векторов (нормалей)

Координаты нормалей для каждой вершины можно задавать:
вручную (в

процессе моделирования)
вычислять аналитически (перпендикуляр к криволинейной поверхности, описываемой функционально)
вычислять на основе полигональной сетки
Слайд 23

Задание нормалей вручную Позволяет задать нормали к поверхности способом, лучшим с

Задание нормалей вручную

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

зрения дизайнера
Основной недостаток – он очень утомителен и во многих случаях может быть заменен на методы автоматического генерирования нормалей
Слайд 24

Редактирование нормалей в программе 3D Studio Max

Редактирование нормалей в программе 3D Studio Max

Слайд 25

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

Аналитический метод нахождения нормалей

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

совпадает с вектором градиента в точке поверхности
Слайд 26

Вычисление нормалей для плоских граней полигональной сетки Для плоских граней сетки

Вычисление нормалей для плоских граней полигональной сетки

Для плоских граней сетки достаточно

вычислить перпендикуляр к каждой грани и связать его с каждой из вершин этой грани
Использование векторного произведения векторов, соединяющих соседние вершины граней
Проблемы:
Большие погрешности вычисления в случае выбора почти параллельных векторов
Проблемы с гранями, имеющими больше 3 вершин
Слайд 27

Метод Ньюэла для нахождения нормали к плоской грани Разработан Мартином Ньюэллом Решает указанные проблемы простого способа

Метод Ньюэла для нахождения нормали к плоской грани

Разработан Мартином Ньюэллом
Решает указанные

проблемы простого способа
Слайд 28

Нахождение нормали к вершинам сетки, описывающим криволинейную поверхность Грани сетки, описывающей

Нахождение нормали к вершинам сетки, описывающим криволинейную поверхность

Грани сетки, описывающей криволинейную

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

Свойства сеток Монолитность Совокупность грани сетки заключает в себе некоторое пространство

Свойства сеток

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

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

Моделирование поверхностей вращения Поверхность вращения образуется посредством вращательной развертки с заметанием

Моделирование поверхностей вращения

Поверхность вращения образуется посредством вращательной развертки с заметанием профильной

кривой C вокруг некоторой оси
Тор
Пешка
Сфера
Купол церкви
Рюмки, тарелки
Колба лампы накаливания
Слайд 31

Создание поверхности вращения

Создание поверхности вращения

Слайд 32

Поверхности на базе функций двух переменных Некоторые поверхности однозначны в одном

Поверхности на базе функций двух переменных

Некоторые поверхности однозначны в одном измерении,

поэтому могут быть явно выражены функции двух независимых переменных
Такие функции еще называют полем высот и задают в виде формулы следующего типа:
y=f(x, z)
Для визуализации таких поверхностей обычно вычисляют значение y в узлах равномерной сетки вдоль осей x и z, а затем рисуют последовательность ячеек полученной сетки
Слайд 33

Пример поверхности заданной, функцией sinc с круговой симметрией

Пример поверхности заданной, функцией sinc с круговой симметрией

Слайд 34

Визуализация трехмерных сцен

Визуализация трехмерных сцен

Слайд 35

Задачи Для визуализации трехмерной сцены при помощи OpenGL необходимо решить ряд

Задачи

Для визуализации трехмерной сцены при помощи OpenGL необходимо решить ряд задач:
Очистка

буфера кадра
Настройка порта просмотра и матрицы проецирования
Установка и ориентирование камеры
Размещение объектов на сцене
Визуализация объектов
Сокрытие невидимых поверхностей
К счастью OpenGL позволяет эффективно решить все эти задачи
Слайд 36

Очистка буфера кадра Очистка буфера кадра осуществляет заполнение одного или нескольких

Очистка буфера кадра

Очистка буфера кадра осуществляет заполнение одного или нескольких буферов,

входящих в состав буфера кадра, заданными значениями
Буфер цвета (color buffer)
Буфер глубины (depth buffer)
Буфер трафарета (stencil buffer)
Буфер аккумулятора (accumulation buffer)
Слайд 37

Команда glClear Выполняет очистку одного или нескольких указанных буферов: void glClear(GLbitfield

Команда glClear

Выполняет очистку одного или нескольких указанных буферов:
void glClear(GLbitfield mask) где mask

– комбинация одного или нескольких значений:
GL_COLOR_BUFFER_BIT
GL_DEPTH_BUFFER_BIT
GL_ACCUM_BUFFER_BIT
GL_STENCIL_BUFFER_BIT
Слайд 38

Команда glClearColor Задает значение цвета, используемого при очистке буфера цветов void

Команда glClearColor

Задает значение цвета, используемого при очистке буфера цветов
void glClearColor( GLclampf red,

GLclampf green, GLclampf blue, GLclampf alpha)
По умолчанию все значения равны 0
Слайд 39

Команда glClearDepth Задает значение глубины, используемое для очистки буфера глубины void

Команда glClearDepth

Задает значение глубины, используемое для очистки буфера глубины
void glClearDepth(GLclampd depth)
По

умолчанию это значение равно 1.0
Слайд 40

Команда glClearStencil Устанавливает целочисленное значение, используемое для очистки буфера трафарета void

Команда glClearStencil

Устанавливает целочисленное значение, используемое для очистки буфера трафарета
void glClearStencil(GLint stencil)
Допустимые

значения – от 0 до 2m, где m – разрядность буфера трафарета
Значение по умолчанию - 0
Слайд 41

Установка порта просмотра и матрицы проецирования Порт просмотра задает область окна,

Установка порта просмотра и матрицы проецирования

Порт просмотра задает область окна, в

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

Команда glViewPort Устанавливает положение и размеры порта просмотра, осуществляя аффинное преобразование

Команда glViewPort

Устанавливает положение и размеры порта просмотра, осуществляя аффинное преобразование вершин

из нормализованных координат устройства в оконные координаты
void glViewPort( GLint x, GLint y, GLint width, GLint height)
x,y – координаты левого нижнего угла порта просмотра относительно левого нижнего угла окна (0,0 по умолчанию)
width, height – размеры порта просмотра
Слайд 43

Установка матрицы перспективного преобразования OpenGL позволяет построить матрицу перспективного преобразования несколькими

Установка матрицы перспективного преобразования

OpenGL позволяет построить матрицу перспективного преобразования несколькими способами:
По

координатам плоскостей, задающих усеченную пирамиду, при помощи функции glFrustum
По углу просмотра и пропорциям сторон отображаемого объема при помощи функции gluPerspective
Слайд 44

Команда glFrustum Задает перспективное преобразование отображаемого объема по заданным координатам ограничивающих

Команда glFrustum

Задает перспективное преобразование отображаемого объема по заданным координатам ограничивающих этот

объем плоскостей
void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble znear, GLdouble zfar )
Слайд 45

Геометрический смысл параметров glFrustum znear zfar bottom top right left

Геометрический смысл параметров glFrustum

znear

zfar

bottom

top

right

left

Слайд 46

Точность хранения значений в буфере глубины Точность хранения значений в буфере

Точность хранения значений в буфере глубины

Точность хранения значений в буфере глубины

определяется не только разрядностью буфера, но и значениями ближней и дальней плоскостей отсечения
Чем меньше отношение r = zfar / znear тем выше точность
грубо говоря, log2r бит разрядности буфера глубины теряется
zfar и znear должны быть положительными
zfar > znear
Слайд 47

Команда gluPerspective Задает матрицу перспективного проецирования по заданному углу обзора вдоль

Команда gluPerspective

Задает матрицу перспективного проецирования по заданному углу обзора вдоль оси

Y, соотношению ширины и высоты отображаемого объема и расстояниям до плоскостей отсечения
void gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
Слайд 48

Установка и ориентирование камеры Библиотека утилит OpenGL (GLU) позволяет задать положение

Установка и ориентирование камеры

Библиотека утилит OpenGL (GLU) позволяет задать положение наблюдателя,

зная координаты его глаза, точки просмотра и вектора «вверх»
void gluLookAt( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble lookX, GLdouble lookY, GLdouble lookZ, GLdouble upX, GLdouble upY, GLdouble upZ)
Матрица, задающая положение камеры умножается на текущую матрицу
Слайд 49

Пример установки камеры // текущая матрица – матрица моделирования-вида glMatrixMode(GL_MODELVEIW); //

Пример установки камеры

// текущая матрица – матрица моделирования-вида
glMatrixMode(GL_MODELVEIW);
// сбрасываем ранее заданные

преобразования
glLoadIdentity();
// устанавливаем положение и ориентацию камеры
gluLookAt(0,0,0, 1,1,-10, 0,1,0);
// задаем объекты сцены...
Слайд 50

Размещение объектов на сцене Ориентацию и положение объектов на сцене можно

Размещение объектов на сцене

Ориентацию и положение объектов на сцене можно задать

при помощи аффинных преобразований и функций OpenGL для работы с такими преобразованиями:
glTranslate
glRotate
glScale
Слайд 51

Пример // устанавливаем матрицу камеры // .. // перенос объекта glTranslated(3,

Пример

// устанавливаем матрицу камеры
// ..
// перенос объекта
glTranslated(3, 3, 2);
// вращение на

30 градусов вокруг оси x
glRotated(30, 1, 0, 0);
// вращение на 90 градусов вокруг оси y
glRotated(90, 0, 1, 0);
// Рисование объекта...

Обратите внимание на тот факт, что для преобразования объекта команды преобразований применяются в обратном порядке.

Слайд 52

Комбинация матричных преобразований Каждая вершина примитива умножается на некоторую матрицу T

Комбинация матричных преобразований

Каждая вершина примитива умножается на некоторую матрицу T равную: T

= P x V x M
P – матрица проецирования
P = P1 [x P2 [x P3 ...]]
V x M – матрица моделирования-вида
V – матрица камеры
V = V1 [x V2 [x V3 ...]]
M – матрица преобразований объектов
M = M1 [x M2 [x M3 ...]]
Слайд 53

Визуализация объектов Визуализация объектов заключатся в рисовании примитивов, составляющих этот объект

Визуализация объектов

Визуализация объектов заключатся в рисовании примитивов, составляющих этот объект
Выполнение серий

командных скобок glBegin()/glEnd()
Разработка функций визуализирующих полигональные сетки
Слайд 54

Пример: void DrawSomeObject() { glBegin(GL_TRIANGLES); glNormald(1, 0, 0); glColor3f(0.1f, 1, 1);

Пример:

void DrawSomeObject()
{
glBegin(GL_TRIANGLES);
glNormald(1, 0, 0);
glColor3f(0.1f, 1, 1);
glVertex3f(3, 2, 3);
//...
glEnd();
// ...
}

Слайд 55

Сокрытие невидимых линий и поверхностей Объекты, расположенные ближе к наблюдателю, могут

Сокрытие невидимых линий и поверхностей

Объекты, расположенные ближе к наблюдателю, могут полностью

или частично перекрывать объекты, расположенные дальше
Самый простой способ решения данной задачи – включить тест глубины командой
glEnable(GL_DEPTH_TEST)