Задания для самостоятельного выполнения

ЛАБОРАТОРНАЯ РАБОТА № 1

ЭЛЕМЕНТАРНОЕ ПРОГРАММИРОВАНИЕ ГРАФИКИ В OpenGL

 

Мировое окно и порт просмотра

В OpenGL геометрический объект создается в терминах мировой системы координат (МСК). Эта система координат в которой мыслит программист при создании геометрического объекта. В МСК координатные оси могут носить любой физический смысл, а единица по координатной оси может принимать любое значение – мм, см, м, км, мсек, сек, час, годы и т.д. В МСК программист выделяет прямоугольное окно – мировое окно, содержимое которого и будет отображаться в порт просмотра (viewport) на экране видеомонитора (ВМ). При этом мировое окно в МСК (прямоугольная область (r- l)´(t- b)) отображается с сохранением подобия в порт просмотра (viewport) размерами w ´ h в экранном окне (window). В отличие от мирового окна, размеры порта просмотра w и h всегда задаются как целое число пикселей. На рис. 1 показана схема отображения мирового окна в порт просмотра.

Следующие функции реализуют схему, показанную на рис. 1:

void gluOrtho 2 D (GLdouble l, GLdouble r, GLdouble b, GLdouble t) – установка мирового окна;

void glutInitWindowSize (int width, int height) – установка размеров window;

void glutInitWindowPosition (int a, int b) - установка положения window;

void glViewport (GLint x, GLint y, GLsizei w, GLsizei h) - установка viewport.

 

Геометрические примитивы OpenGL

 

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

Пример задания вершины glVertex2i(10, 20). Это один пример из большого количества модификаций задания вершины. Здесь вершина задается двумя параметрами (координатами) целого типа. В общем случае вершина задается функцией:

 

 

    Таблица 1. Типы и спецификаторы для их задания в командах OpenGL

Суффикс, задающий тип аргумента Описание типа Имя типа в OpenGL
b 8 – бит, целое GLbyte
s 16 – бит, целое GLshort
i 32 – бит, целое GLint, GLsizei
f 32 – бит, вещественное GLfloat, GLclampf
d 64 – бит, вещественное GLdouble, GLclampd
ub 8 – бит, целое, без знака GLubyte, GLboolean
us 16 – бит, целое, без знака GLushort
ui 32 – бит, целое, без знака GLuint, GLenum, GLbitfield

glVertex2s(2, 3) – точка с координатами x=2, y=3, z=0, w=1;

glVertex3d(0.0, 0.0, 3.14) - точка с координатами x=0.0, y=0.0, z=3.14, w=1.0;

glVertex4f(2.3, 1.0, -2.2, 2.0) - точка с координатами x=2.3, y=1.0, z=-2.2, w=2.0;

GLdouble dvect[3]={5.0, 9.0, 1992.0};

glVertex3dv(dvect) - точка с координатами x=5.0, y=9.0, z=1992.0, w=1.0.

Последовательность вершин, имеющих самостоятельный смысл, назовем примитивом. Примитивы или группы подобных примитивов задаются между функциями glBegin и glEnd. Пример для 2D (в этом примере * означает, что в это место должен быть подставлен какой либо из спецификаторов типа):

glBegin(mode);

glVertex2*(x1, y1);

glVertex2*(x2, y2);

. . . . . . . . . .

glVertex2*(xN, yN);

glEnd();

Прототипы функций glBegin и glEnd:

void glBegin (GLenum mode);

void glEnd (void).

Параметр mode может принимать одно из значений, приведенных в табл. 2. Там же описано, как при этом обрабатывается последовательность вершин, определенных между glBegin и glEnd.

Таблица 2. Значения и функциональный смысл параметра mode

Значение параметра mode Смысл параметра
GL_POINTS Обрабатывает каждую вершину как отдельную точку. Вершина n определяет точку n.
GL_LINES Обрабатывает каждую пару вершин как независимый линейный сегмент. Вершины 2n-1 и 2n определяют прямую n. Рисуется N/2 прямых.
GL_LINE_STRIP Рисует связанную группу линейных сегментов от первой вершины до последней. Вершины n и n+1 определяют прямую n. Рисуется N-1 прямых.
GL_LINE_LOOP Рисует связанную группу линейных сегментов от первой вершины до последней, а затем назад к первой. Вершины n и n+1 определяют прямую n. Последняя прямая определена вершинами 1 и N. Рисуется N прямых.
GL_TRIANGLES Обрабатывает тройку вершин как независимый треугольник. Вершины 3n-2, 3n-1и 3n определяют треугольник n. Рисуется N/3 треугольников.
GL_TRIANGLE_STRIP
2

Рисует связанную группу треугольников. Для нечетного значения n вершины n, n+1 и n+2 определяют треугольник n. Для четного значения n вершины n+1, n и n+2 определяют треугольник n. Рисуется N-2 треугольников.
GL_TRIANGLE_FAN Рисует связанную группу треугольников. Вершины 1, n+1 и n+2 определяют треугольник n. Рисуется N-2 треугольников.
GL_QUADS Обрабатывает каждую группу из четырех вершин в качестве независимого четырехугольника. Вершины 4n-3, 4n-2, 4n-1 и 4n определяют четырехугольник n. Рисуется N/4 четырехугольников.
GL_QUAD_STRIP Рисует связанную группу четырехугольников. Вершины 2n-1, 2n, 2n+2 и 2n+1 определяют четырехугольник n. Рисуется N/2-1 четырехугольников.
GL_POLYGON Рисует отдельный выпуклый многоугольник. Вершины от 1 до N определяют этот многоугольник.

 

Листинг 1. Пример программы OpenGL.

#include <GL/glut.h>

void init();

void draw();

 

void main(int argc, char **argv) //Главная функция

{ glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowSize(640, 480);

glutInitWindowPosition(50, 50);

glutCreateWindow("Myprog");

init( );

glutDisplayFunc(draw);

glutMainLoop( );

}

 

void init() //Функция инициализации

{ glClearColor(1.0, 1.0, 0.0, 0.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity( );

gluOrtho2D(0.0,2.0,0.0,1.0);

}

void draw() //Функция рисования

{ glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0, 0.0, 0.0);

glViewport(10, 10, 600, 400);

glBegin(GL_LINE_LOOP);

glVertex2f(0.0, 0.0); glVertex2f(0.0, 1.0);

    glVertex2f(2.0, 1.0); glVertex2f(2.0, 0.0);

glEnd( );

glColor3f(0.0, 1.0, 0.0);

glBegin(GL_LINE_STRIP);

    glVertex2f(1.0, 0.5); glVertex2f(1.1, 0.5);

    glVertex2f(1.1, 0.6); glVertex2f(1.2, 0.6);

glEnd( );

glColor3f(0.0, 0.0, 1.0);

glPointSize(4);

glBegin(GL_POINTS);

glVertex2f(0.2, 0.5); glVertex2f(1.8, 0.5);

glVertex2f(1.0, 0.1); glVertex2f(1.0, 0.9);

glEnd ( );

glFlush( );

}

Дадим краткое пояснение функциям, встречающимся в программе.

glutInit(&argc, argv) –инициализация библиотеки GLUT.

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB) – устанавливается режим дисплея: использовать один буфер для кадра; цвета представлять как смесь RGB.

glutInitWindowSize(640, 480) – устанавливается размер экранного окна window.

glutInitWindowPosition(50, 50) - устанавливается положение (позиция) экранного окна window.

glutCreateWindow("Myprog") – инициализируется открытие экранного окна window.

glutDisplayFunc(draw) – функция draw( ) регистрируется как функция обратного вызова для события открытия или обновления экранного окна.

glutMainLoop( ) – переводит программу в бесконечный цикл ожидания события.

glClearColor(1.0, 1.0, 0.0, 0.0) – назначает то значение буфера цвета экранного окна, которое будет установлено при его сбросе (очистке) функцией glClear(GL_COLOR_BUFFER_BIT). По существу это назначение цвета фона.

glMatrixMode(GL_PROJECTION) – в качестве текущей устанавливается матрица проецирования.

glLoadIdentity( ) – текущая матрица устанавливается в единицу.

gluOrtho2D(0.0, 2.0, 0.0, 1.0) – устанавливается мировое окно.

glColor3f(1.0, 0.0, 0.0) – устанавливается цвет рисования.

glViewport(10, 10, 600, 400) – устанавливается положение и размеры порта просмотра.

glFlush() – принудительное выполнение накопленных команд OpenGL. Различные реализации OpenGL буферизируют команды в нескольких различных местах. Команда glFlush() освобождает все эти буферы, заставляя все вызванные команды выполниться.

Приведенный ниже текст можно принять как простейший шаблон OpenGL программы для 2D. Этот шаблон в дальнейшем может пополняться и усложняться.

Листинг 2. Шаблон простейшей программы OpenGL.

#include <GL/glut.h>

void init();

void draw();

void main(int argc, char **argv)

{ glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

glutInitWindowSize(640, 480);

glutInitWindowPosition(50, 50);

glutCreateWindow("My program");

init();

glutDisplayFunc(draw);

glutMainLoop();

}

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

В функции glVertex*() параметры можно задавать выражением. Между glBegin и glEnd последовательность вершин можно задавать циклом.

Возможны такие конструкции:

void draw() { … . . . . . . . . . . . . . . . . . . . . . . .    glBegin(GL_LINE_STRIP);    for(…)    { x=<выражение1>;        y=<выражение2>;        glVertex2*(x, y);      }                 glEnd( );    .... . . . . . . . . . . . . . . . . . . . . . . . }          void draw() { . . . . .. . . . . . . . . . . . . . . . . . . . . . .    glBegin(GL_LINE_STRIP);    for(…)    { glVertex2*(<выражение1>,                           <выражение2>);    }                 glEnd( );    . . . . . . . . . . . . . . . . . . . . . . . .. . . .. . }  

В window возможно создать несколько (много) портов просмотра. Приведенный ниже код покрывает окно window размером 600´480 портами просмотра размером 60´60. Фигура из мирового окна отображается в цикле в каждый из портов просмотра. В результате на экране мозаика.

Листинг 3. Пример построения мозаики.

void draw()

{ GLfloat l = -100, r = 100, b = -100, t = 100;

GLint x = 0, y = 0, w = 60, h = 60;

glClear(GL_COLOR_BUFFER_BIT);

gluOrtho2D(l, r, b, t);

for(x = 0; x <= 600; x += w)

    for(y = 0; y <= 480; y += h)

    { glViewport(x, y, w, h);

glColor3f(1.0, 0.0, 0.0);

         glBegin(GL_LINES);

              <Рисуется любая фигура>

         glEnd();

    }

glFlush();

}

 

 

Задания для самостоятельного выполнения

 

1. Создайте программу, рисующую на экране график функции:

1) y(x) = sin(wx) /wx, где w – const;  

2) y(t) = sin(w1t)cos(w2t), где w1, w2 – const;

3) y(t) = e-atSin(wt), где e, a, w – const;

4) x(t) = sin(wt); y(t) = cos(wt), где w – const;

5) x(t) = Asin(wt); y(t) = Bcos(wt), где A, B, w – const;

6) y(x) = Ax3 + Bx2 +Cx +D, где A, B, C, D – const.

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

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


Дата добавления: 2021-07-19; просмотров: 392; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!