Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2633

.pdf
Скачиваний:
6
Добавлен:
07.01.2021
Размер:
54.26 Mб
Скачать

Функция glTranslate(x, y, z) перемещает оси координат на указанные значения. Следующая строчка кода перемещает ось X на 1.5 единиц и ось Z на 6 единиц. Следует заметить, что перевод осей координат осуществляется не относительно центра экрана, а от их

текущего расположения:

 

glTranslatef(-1.5f,0.0f,-6.0f);

//Сдвиг влево на 1.5 единицы и в

экран на 6.0

 

Функция glBegin(GL_TRIANGLES) означает начало рисования треугольника. Далее следует перечисление его вершин. После указания всех вершин, производится вызов функции glEnd().

Первая строка после glBegin описывает первую вершину полигона. Функция glVertex3f() получает в качестве параметров ее X, Y и Z координаты. Первая вершина треугольника смещена только от оси Y на 1, таким образом, она расположится в центре и она будет самой верхней. Следующая вершина будет располагаться на оси Х слева от центра и на оси Y вниз от центра. Эта вершина располагается внизу слева. Третья вершина будет справа и снизу от центра. Функция glEnd() указывает, что вершин больше не будет. Результат данного кода – залитый цветом по умолчанию треугольник:

glBegin(GL_TRIANGLES);

 

glVertex3f( 0.0f, 1.0f, 0.0f);

// Вверх

glVertex3f(-1.0f,-1.0f, 0.0f);

// Слева снизу

glVertex3f( 1.0f,-1.0f, 0.0f);

// Справа снизу

glEnd();

 

Необходимо переместиться в левую часть, для этого используется функция glTranslate() (Прежнее перемещение было влево на 1.5 единицы, необходимо переместиться на 3.0 единицы вправо (1.5 единицы – это будет центр, еще 1.5 единицы для правого края)):

glTranslatef(3.0f,0.0f,0.0f);

// Сдвиг вправо на 3 единицы

Далее изображается квадрат:

 

glBegin(GL_QUADS);

 

glVertex3f(-1.0f, 1.0f, 0.0f);

// Слева вверху

glVertex3f( 1.0f, 1.0f, 0.0f);

// Справа вверху

glVertex3f( 1.0f,-1.0f, 0.0f);

// Справа внизу

glVertex3f(-1.0f,-1.0f, 0.0f);

// Слева внизу

glEnd();

 

}

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

53

быть получены на экране геометрическиефигуры треугольник и квадрат

(рис. 2).

Рис. 2. Ввывод геометрических фигур на экране

Контрольные вопросы

1.Какая функция устанавливает начало системы координат в центр экрана?

2.Каково назначение функции glTranslate(x, y, z)?

3.Какие параметры имеет функция glVertex3f() и за что отвечает каждый параметр?

4.В какой последовательности указываются вершины при рисовании квадрата?

2.3.Отображение цвета

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

Возможно использование предыдущего кода, изменив лишь процедуру DrawGLScene(), а именно, заменить, или добавить те строки, которые там отсутствуют:

GLvoid DrawGLScene(GLvoid)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity();

54

glTranslatef(-1.5f,0.0f,-6.0f); glBegin(GL_TRIANGLES);

В данной части кода описано рисование треугольника в левой части экрана.

Следующие строки кода используют команду glColor3f(r, g, b). Три ее параметра указывают насыщенность цвета красной, синей и зеленой составляющей. Каждый из них может принимать значение от

0.0f до 1.0f.

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

glColor3f(1.0f,0.0f,0.0f); // Красный цвет glVertex3f(0.0f, 1.0f, 0.0f);

Итак, теперь у нас отображена первая вершина и установлен для нее красный цвет. Теперь следует добавить следующую вершину (левую нижнею), но установить для нее уже зеленый цвет:

glColor3f(0.0f,1.0f,0.0f);

// Зеленый цвет

glVertex3f(-1.0f,-1.0f, 0.0f);

 

Далее проделаем те же операции с третьей и последней вершиной

(правый нижний угол):

 

glColor3f(0.0f,0.0f,1.0f);

// Синий цвет

glVertex3f(1.0f,-1.0f, 0.0f);

 

glEnd();

 

glTranslatef(3.0f,0.0f,0.0f);

 

Перед тем как отобразить

ее, следует установить синий цвет.

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

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

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

glColor3f(0.5f,0.5f,1.0f);

// Установление синего цвета только

один раз

 

55

glBegin(GL_QUADS); glVertex3f(-1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glEnd();

}

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

Измените координально цвет квадрата и треугольника.

Измените программу так, чтобы квадрат был залит смешанным цветом, а треугольник, наоборот – сплошным цветом, как представлено на рис. 4.

Рис. 3. Реализация смешанной заливки треугольника и окрашивания в яркий красные цвет квадрата

56

Рис. 4. Реализация градиентной заливки квадрата и окрашивание в яркий красные цвет треугольника

Контрольные вопросы

1.Какую цветовую модель реализует OpenGL?

2.Какие параметры использует команда glColor3f?

3.Какими значениями можно задавать насыщенность цветов функции glColor3f?

4.При установлении какого-либо цвета будут ли в дальнейшем примитивы отображаться именно этим цветом?

5.Какой цвет описывается данной командой glColor3f(0.0f,0.0f,1.0f)?

6.С какой целью используется команда void glClearColor?

7.Как получить линейную интерполяцию цветов по поверхности примитива?

8.Что означает команда void glShadeModel(GLenummode) и ее параметры GL_SMOOTH и GL_FLAT?

2.5. Реализации вращения фигур

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

#include <windows.h> //Заголовочный файл для Windows #include <gl\gl.h> //Заголовочный файл для OpenGL32

библиотеки

57

#include <gl\glu.h>

//Заголовочный файл для GLu32 библиотеки

#include <gl\glaux.h>

//Заголовочный файл для GLaux библиотеки

static HGLRC hRC;

//Постоянный контекст рендеринга

static HDC hDC;

//Приватный контекст устройства GDI

BOOL keys[256];

//Массив для процедуры обработки

клавиатуры

 

GLfloat rtri;

// Угол для треугольник

GLfloat rquad;

// Угол для четырехугольника

Вначале добавляются две переменные для хранения угла вращения каждого объекта. После строки с объявлением переменной BOOL keys[256] объявляются две переменные с плавающей запятой, которые используются для очень точного поворота объектов. Числа с плавающей запятой учитывают значения меньше единицы. Вместо использования 1, 2, 3 для угла, допустимо использование 1.1, 1.7, 2.3 или 1.015 для точности.

Необходимо модифицировать код в DrawGLScene(). Придется переписать всю процедуру:

GLvoid DrawGLScene(GLvoid)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Очистка экрана и буфера глубины

glLoadIdentity();

// Сброс просмотра

glTranslatef(-1.5f,0.0f,-6.0f);

// Сдвиг в глубь экрана и влево

Строка glRotatef(Angle,Xtrue,Ytrue,Ztrue) отвечает за вращения

объекта вдоль оси.

 

Угол – некоторое число

(обычно переменная), которое задает

насколько требуется повернуть объект. Xtrue, Ytrue и Ztrue или 0.0f или 1.0f. Если один из параметров равен 1.0f, OpenGL будет вращать объект вдоль соответствующей оси. Поэтому если glRotatef(10.0f,0.0f,1.0f,0.0f), объект будет поворачиваться на 10 градусов по оси Y. Если glRotatef(5.0f,1.0f,0.0f,1.0f), объект будет поворачиваться на 5 градусов по обеим осям X и Z.

В следующей строке кода, если rtri равно 7, будет вращение на 7 градусов по оси Y (слева направо):

glRotatef(rtri,0.0f,1.0f,0.0f); // Вращение треугольника по оси Y

Следующая часть кода не изменена. Здесь будет нарисован закрашенный сглаженный треугольник – треугольник будет нарисован с левой стороны экрана, и будет вращаться по оси Y слева направо:

glBegin(GL_TRIANGLES); //Начало рисования треугольника

glColor3f(1.0f,0.0f,0.0f);

// Верхняя точка – красная

glVertex3f( 0.0f, 1.0f, 0.0f);

// Первая точка

glColor3f(0.0f,1.0f,0.0f);

// Левая точка - зеленая

58

glVertex3f(-1.0f,-1.0f, 0.0f);

// Вторая

glColor3f(0.0f,0.0f,1.0f);

// Правая - синия

glVertex3f( 1.0f,-1.0f, 0.0f);

// Третья

glEnd();

// Конец рисования

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

Так как сцена сброшена, поэтому X идет слева направо, Y сверху вниз, Z от переднего плана и далее. Происходит движение на 1.5 вправо, вместо 3.0, как было в последней работе, чтобы оказаться в 0.0.

После того сдвига в новое место на правой стороне экрана, осуществляется вращение квадрата по оси X. Квадрат будет вращаться

верх и вниз:

 

glLoadIdentity();

 

glTranslatef(1.5f,0.0f,-6.0f);

// Сдвиг вправо на 1.5

glRotatef(rquad,1.0f,0.0f,0.0f);

// Вращение по оси X

Эта часть кода – завершение

предыдущей. Рисование синего

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

glColor3f(0.5f,0.5f,1.0f);

// Синий цвет

glBegin(GL_QUADS);

// Начнем

glVertex3f(-1.0f, 1.0f, 0.0f);

// Верх лево

glVertex3f( 1.0f, 1.0f, 0.0f);

// Верх право

glVertex3f( 1.0f,-1.0f, 0.0f);

// Низ право

glVertex3f(-1.0f,-1.0f, 0.0f);

// Низ лево

glEnd();

// Конец

Следующие две строки новые. rtri и rquad – контейнеры. Вначале нашей программы были сделаны контейнеры (GLfloat rtri и GLfloat rquad). Когда их построили, они были пусты.

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

С увеличением значения объект будет вращаться быстрее. С уменьшением значения будет вращаться медленнее:

rtri+=0.2f; // Увеличение переменной вращения для треугольнка

rquad-=0.15f;

// Уменьшение переменной вращения для

квадрата

 

}

 

Результат работы программы представлен на рис. 5.

59

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

Измините угол и скорость ващения фигур. Измените оси вращения для фигур.

Рис. 5 Вывод и вращение квадрата и треугольника

Контрольные вопросы

1.Каково назначение переменной rtri?

2.В коде ниже вызов glLoadIdentity() делается для инициализации просмотра.

3.Что делает функция glRotatef(Angle,Xtrue,Ytrue,Ztrue)?

4.Что означает данное выражение: glRotatef(10.0f,0.0f,1.0f,1.0f)?

5.Что означает строка «rquad-=0.15f»?

2.6.Создание фигур в 3D

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

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

60

GLvoid DrawGLScene(GLvoid)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Очистка экрана и буфера глубины

glLoadIdentity(); // Сброс просмотра glTranslatef(-1.5f,0.0f,-6.0f);// Сдвиг влево и вглубь экрана glRotatef(rtri,0.0f,1.0f,0.0f); // Вращение пирамиды по оси Y glBegin(GL_TRIANGLES); // Начало рисования пирамиды

Чтобы объект вращался вокруг оси, он должен быть разработан для вращения вокруг оси. Следует, помнить, что центр любого объекта должен быть в 0 для X, 0 для Y, 0 для Z.

Следующий код создаст пирамиду вокруг центральной оси:

glColor3f(1.0f,0.0f,0.0f);

// Красный

glVertex3f( 0.0f, 1.0f, 0.0f);

// Верх треугольника (Передняя)

glColor3f(0.0f,1.0f,0.0f);

// Зеленый

glVertex3f(-1.0f,-1.0f, 1.0f);

// Левая точка

glColor3f(0.0f,0.0f,1.0f);

// Синий

glVertex3f( 1.0f,-1.0f, 1.0f);

// Правая точка

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

Стоит отметить, что все треугольники рисуются с вращением против часовой стрелки.

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

Затем следует нарисовать правую грань. Стоит отметить, что две нижних точки нарисованы на единицу справа от центра, верхняя точка нарисована на единицу выше оси Y, и справа от середины оси X. Поэтому эта грань имеет наклон от центральной точки сверху вниз с правой стороны.

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

61

Важно отметить, что все четыре грани включены внутрь тех же самых glBegin(GL_TRIANGLES) и glEnd(), словно одна сторона.

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

не будет нарисован четырехугольник:

 

glColor3f(1.0f,0.0f,0.0f);

// Красная

glVertex3f( 0.0f, 1.0f, 0.0f);

// Верх треугольника (Правая)

glColor3f(0.0f,0.0f,1.0f);

// Синия

glVertex3f( 1.0f,-1.0f, 1.0f);

// Лево треугольника (Правая)

glColor3f(0.0f,1.0f,0.0f);

// Зеленная

glVertex3f( 1.0f,-1.0f, -1.0f);

// Право треугольника (Правая)

Далее строится задняя сторона. Снова переключаются цвета. Левая точка – зеленного цвета, поскольку этот угол так же и зеленый угол

правой грани:

 

glColor3f(1.0f,0.0f,0.0f);

// Красный

glVertex3f( 0.0f, 1.0f, 0.0f);

// Низ треугольника (Сзади)

glColor3f(0.0f,1.0f,0.0f);

// Зеленый

glVertex3f( 1.0f,-1.0f, -1.0f);

// Лево треугольника (Сзади)

glColor3f(0.0f,0.0f,1.0f);

// Синий

glVertex3f(-1.0f,-1.0f, -1.0f);

// Право треугольника (Сзади)

В завершении необходимо построить левую грань:

glColor3f(1.0f,0.0f,0.0f);

// Красный

glVertex3f( 0.0f, 1.0f, 0.0f);

// Верх треугольника (Лево)

glColor3f(0.0f,0.0f,1.0f);

// Синий

glVertex3f(-1.0f,-1.0f,-1.0f);

// Лево треугольника (Лево)

glColor3f(0.0f,1.0f,0.0f);

// Зеленный

glVertex3f(-1.0f,-1.0f, 1.0f);

// Право треугольника (Лево)

glEnd();

// Пирамида прорисована

Цвета переключаются в последний раз. Левая точка синего цвета, и смешивается с правой точкой на задней грани. Правая точка зеленного цвета, и смешивается с левой точкой на передней грани.

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

На данном этапе производится рисование куба. Чтобы сделать это надо шесть квадратов. Все квадраты рисуются против часовой стрелке.

62

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]