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

2633

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

значение – GLU_NONE и GLU_FLAT. Далее осуществим включение

текстурирования на квадратичном объекте:

 

 

 

quadratic=gluNewQuadric();

 

// Создает

указатель на

квадратичный объект

 

 

 

 

gluQuadricNormals(quadratic, GLU_SMOOTH);

// Создает

плавные нормали

 

 

 

 

gluQuadricTexture(quadratic, GL_TRUE);

//

Создает

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

 

 

 

 

Код прорисовки куба приведен ниже:

 

 

 

GLvoid glDrawCube() // Прорисовка куба

 

 

{

 

 

 

 

glBegin(GL_QUADS);

// Прорисовка четырехугольников

// Передняя сторона

 

 

 

 

glNormal3f( 0.0f, 0.0f, 1.0f);// Нормаль вперед

 

glTexCoord2f(0.0f, 0.0f);

 

 

 

 

glVertex3f(-1.0f, -1.0f, 1.0f);// Низ Лево на текстуре и

четырехугольнике

 

 

 

 

glTexCoord2f(1.0f, 0.0f);

 

 

 

 

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

// Низ Право на текстуре и

четырехугольнике

 

 

 

 

glTexCoord2f(1.0f, 1.0f);

 

 

 

 

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

// Верх Право на текстуре и

четырехугольнике

 

 

 

 

glTexCoord2f(0.0f, 1.0f);

 

 

 

 

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

// Верх Лево на текстуре и

четырехугольнике

 

 

 

 

// Задняя сторона

 

 

 

 

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

 

// Обратная нормаль

glTexCoord2f(1.0f, 0.0f);

 

 

 

 

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

// Низ Право на текстуре и

четырехугольнике

 

 

 

 

glTexCoord2f(1.0f, 1.0f);

 

 

 

 

glVertex3f(-1.0f, 1.0f, -1.0f);// Верх Право на текстуре и

четырехугольнике

 

 

 

 

glTexCoord2f(0.0f, 1.0f);

 

 

 

 

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

// Верх Лево на текстуре и

четырехугольнике glTexCoord2f(0.0f, 0.0f);

glVertex3f(1.0f, -1.0f, -1.0f);// Низ Лево на текстуре и четырехугольнике

// Верхняя грань

glNormal3f( 0.0f, 1.0f, 0.0f);// Нормаль вверх

143

glTexCoord2f(0.0f, 1.0f);

glVertex3f(-1.0f, 1.0f, -1.0f);// Верх Лево на текстуре и четырехугольнике

glTexCoord2f(0.0f, 0.0f);

glVertex3f(-1.0f, 1.0f, 1.0f); // Низ Лево на текстуре и четырехугольнике

glTexCoord2f(1.0f, 0.0f);

glVertex3f( 1.0f, 1.0f, 1.0f); // Низ Право на текстуре и четырехугольнике

glTexCoord2f(1.0f, 1.0f);

glVertex3f( 1.0f, 1.0f, -1.0f);// Верх Право на текстуре и четырехугольнике

// Нижняя грань

glNormal3f( 0.0f,-1.0f, 0.0f);// Нормаль направлена вниз glTexCoord2f(1.0f, 1.0f);

glVertex3f(-1.0f, -1.0f, -1.0f); // Верх Право на текстуре и четырехугольнике

glTexCoord2f(0.0f, 1.0f);

glVertex3f( 1.0f, -1.0f, -1.0f); // Верх Лево на текстуре и четырехугольнике

glTexCoord2f(0.0f, 0.0f);

glVertex3f( 1.0f, -1.0f, 1.0f); // Низ Лево на текстуре и четырехугольнике

glTexCoord2f(1.0f, 0.0f);

glVertex3f(-1.0f, -1.0f, 1.0f); // Низ Право на текстуре и четырехугольнике

// Правая грань

glNormal3f( 1.0f, 0.0f, 0.0f); // Нормаль направлена вправо glTexCoord2f(1.0f, 0.0f);

glVertex3f( 1.0f, -1.0f, -1.0f); // Низ Право на текстуре и четырехугольнике

glTexCoord2f(1.0f, 1.0f);

glVertex3f( 1.0f, 1.0f, -1.0f); // Верх Право на текстуре и четырехугольнике

glTexCoord2f(0.0f, 1.0f);

glVertex3f( 1.0f, 1.0f, 1.0f); // Верх Лево на текстуре и четырехугольнике

glTexCoord2f(0.0f, 0.0f);

glVertex3f( 1.0f, -1.0f, 1.0f); // Низ Лево на текстуре и четырехугольнике

// Левая грань

glNormal3f(-1.0f, 0.0f, 0.0f); // Нормаль направлена влево

144

glTexCoord2f(0.0f, 0.0f);

glVertex3f(-1.0f, -1.0f, -1.0f); // Низ Лево на текстуре и четырехугольнике

glTexCoord2f(1.0f, 0.0f);

glVertex3f(-1.0f, -1.0f, 1.0f); // Низ Право на текстуре и четырехугольнике

glTexCoord2f(1.0f, 1.0f);

glVertex3f(-1.0f, 1.0f, 1.0f); // Верх Право на текстуре и четырехугольнике

glTexCoord2f(0.0f, 1.0f);

glVertex3f(-1.0f, 1.0f, -1.0f); // Верх Лево на текстуре и четырехугольнике

glEnd(); // Заканчиваем рисование четырехугольников

}

Следующая функция DrawGLScene. case – оператор для рисования разных объектов:

int DrawGLScene(GLvoid) // Прорисовка

{

// Очистка видео буфера и буфера глубины glClear(GL_COLOR_BUFFER_BIT |

GL_DEPTH_BUFFER_BIT);

 

glLoadIdentity();

// Сбрасывает вид

glTranslatef(0.0f,0.0f,z);

// Перемещается вглубь экрана

glRotatef(xrot,1.0f,0.0f,0.0f);// Вращение по оси X glRotatef(yrot,0.0f,1.0f,0.0f);// Вращение по оси Y glBindTexture(GL_TEXTURE_2D, texture[filter]);

//Выбирает фильтрацию текстуре

//Далее следует новая секция кода

switch(object)

// Проверяет, какой объект рисовать

{

 

 

case 0:

 

// Рисует первый объект

glDrawCube();

// Рисует куб

break;

 

// Конец

Второй создаваемый объект – цилиндр:

case 1:

 

// Рисует второй объект

glTranslatef(0.0f,0.0f,-1.5f); // Центр цилиндра

gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32);// Рисует цилиндр

break;

// Конец

 

Первый параметр (1.0f) – радиус основания цилиндра (низ). Второй параметр (1.0f) –это радиус цилиндра сверху. Третий параметр (3.0f) – это высота цилиндра (какой он длины). Четвертый параметр (32)

– это сколько делений будет "вокруг" оси Z, и пятый (32) – количество

145

делений "вдоль" оси Z. Большее количество делений приведет к увеличению детализации объекта.

Третий объект – поверхность в виде CD-диска:

case 2:

// Рисует третий объект

gluDisk(quadratic,0.5f,1.5f,32,32); // Рисует диск (в виде CD)

break;

// Конец

Первый параметр диска (0.5f) – внутренний радиус цилиндра. Его значение может быть нулевым, что будет означать, что внутри нет отверстия. Чем больше будет внутренний радиус – тем больше будет отверстие внутри диска. Второй параметр (1.5f) - внешний радиус. Третий параметр (32) – количество частей, из которых состоит диск. Четвертый параметр (32) – это число колец, которые составляют диск (можно задать – одно кольцо). Кольца похожи на треки на записи. Круги внутри кругов. Эти кольца делят диск со стороны внутреннего радиуса к внешнему радиусу, улучшая детализацию.

Четвертый объект – это сфера:

case 3:

// Рисует четвертый объект

gluSphere(quadratic,1.3f,32,32); // Рисует сферу

break;

// Конец

Первый параметр –

это радиус сферы. Дальше идет количество

разбиений "вокруг" оси Z (32), и количество разбиений "вдоль" оси Z (32). Большее количество придаст сфере большую гладкость. Для того, чтобы сфера была достаточно гладкой, обычно необходимо большое количество разбиений.

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

case 4: // Рисует пятый объект glTranslatef(0.0f,0.0f,-1.5f); // Центр конуса. Конус с нижним

радиусом 5 и высотой 2 gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32);

break;

// Конец

Шестой объект создан с помощью gluParticalDisc:

case 5:

// Рисует шестой объект

part1+=p1;

// Увеличивает стартовый угол

part2+=p2;

// Увеличивает конечный угол

if(part1>359)

// 360 градусов

{

 

p1=0;

// Закончить увеличивать начальный угол

part1=0;

// Устанавливает начальный угол в 0

p2=1;

// Начинает увеличивать конечный угол

part2=0;

// Начиная с 0

146

}

 

if(part2>359)

// 360 градусов

{

 

p1=1;

// Начинает увеличивать начальный угол

p2=0;

// Перестает увеличивать конечный угол

}

gluPartialDisk(quadratic,0.5f,1.5f,32,32,part1,part2-part1);

break;

// Конец

};

 

xrot+=xspeed;

// Увеличивает угол поворота вокруг оси X

yrot+=yspeed;

// Увеличивает угол поворота вокруг оси Y

return TRUE;

// Продолжает

}

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

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

if (keys[' '] && !sp)

// Нажата клавиша "пробел"?

{

 

sp=TRUE;

// Если так, то устанавливает sp в TRUE

object++;

// Цикл по объектам

if(object>5)

// Номер объекта больше 5?

object=0;

// Если да, то устанавливает 0

}

 

if (!keys[' '])

// Клавиша "пробел" отпущена?

{

 

sp=FALSE

// Если да, то устанавливает sp в FALSE

}

 

Результаты работы программы представлены на рис. 26-33. Измените текстуру объетов.

Измените прозрачность текстуры, наложенной на объекты.

147

Рис. 26. Куб, созданный как сложный объект

Рис. 27. Цилиндр, созданный как сложный объект

148

Рис. 28. CD-диск, созданный как сложный объект

Рис. 29. Сфера, созданный как сложный объект

149

Рис. 30. Конус, созданный как сложный объект

Рис. 31. Сложный объект, созданный с помощью gluParticalDisc

В приложении 1 приведен листинг программы, моделирующей стеклянную 3D вазу, которая реализована на языке Microsoft Visual C++ в консольном режиме с помощью библиотеки OPENGL в рамках курсового проекта. Пояснения к программе указаны в листинге в виде комментариев.

Результаты работы программы представлены на рис. 32,33. При прорисовке вазы с гранями были изменены: радиусы цилиндра, высоту и количество полигонов и очищен экран в серый цвет: gluCylinder(quadratic,0.4f,0.8f,2.8f,8,8);

gluDisk(quadratic,0.0f,0.4f,8,8);

150

//Изменяем радиус дна и количество полигонов

glClearColor(0.8f, 0.8f, 0.8f, 0.0f); //Очищаем экран в серый цвет

Рис. 32 Стеклянная 3D ваза, созданная как сложный объект цилиндр

Рис. 33 Стеклянная 3D ваза, созданная с использованием полигонов

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

1.В какой части программы происходит инициализация квадратичного объекта?

2.Каково предназначение команды gluPartialDisk()?

3.Какие параметры может иметь команда gluCylinder() ?

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

151

2.18. Машина моделирования частиц

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

Рассмотрим пример создания машин моделирования частиц

(Particle Engine).

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

#include <windows.h> //

Заголовочный файл для Windows

#include <stdio.h>

// Заголовочный файл для стандартной

библиотеки ввода/вывода (Новая строка)

#include <gl\gl.h>

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

OpenGL32

 

 

#include <gl\glu.h>

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

#include <gl\glaux.h>

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

#define MAX_PARTICLES 1000 // Число частиц для создания

(Новая строка)

 

 

HDC hDC=NULL;

// Контекст устройства GDI

HGLRC hRC=NULL; // Постоянный контекст рендеринга

HWND hWnd=NULL;// Сохраняет дескриптор окна

HINSTANCE hInstance;

// Сохраняет экземпляр приложения

bool keys[256]; // Массив для работы с клавиатурой

bool active=TRUE;

// Флаг активации окна, по умолчанию =

TRUE

 

 

bool fullscreen=TRUE;// Флаг полноэкранного режима

bool rainbow=true;

// Режим радуги? (Новая строка)

bool sp;

// Пробел нажат? (Новая строка)

bool rp;

// Ввод нажат? (Новая строка)

Первая строка (stdio.h)

позволяет читать данные из файлов. Во

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

sp и rp – переменные, которые будут использоваться для предотвращения автогенерации повторений нажатия клавиш 'пробел' или 'ввод' (enter), когда они нажаты.

В следующих четырех строках – разнообразные переменные. Переменная slowdown (торможение) контролирует, как быстро

152

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