Уроки OpenGL. Часть 2. Рисование основных 2D-фигур.

Продолжаем учебный курс по работе с графикой при помощи OpenGL! И сегодня мы займемся рисованием основных 2D-фигур, таких как треугольник, прямоугольник, линия итд. Первый урок, посвященный OpenGL можно найти тут – ссылка. Итак, приступим…

Создадим пустой проект и добавим в него класс MainScene, как в предыдущей статье, а в сам класс – три пустые функции:

void MainScene::initializeGL()
{
}

void MainScene::resizeGL(int nWidth, int nHeight)
{
}

void MainScene::paintGL()
{
}

Напоминаю, что я использую в качестве среды разработки Qt Creator, соответственно при создании класса мне нужно наследоваться от QGLWidget.

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

glClearColor(1.0, 1.0, 1.0, 1.0);

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

В функции main() добавляем создание сцены (объекта нашего класса) и задаем его размеры:

MainScene scene;
scene.resize(600, 600);
scene.show();

Собираем проект, запускаем и видим… Абсолютно черный экран. В чем же дело?

А дело в том, что командой glClearColor() мы только задали цвет очистки экрана, но не произвели непосредственно очистку. Давайте добавим в функцию paintGL():

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

Итак, загружаем в матрицу проекции единичную матрицу и вызываем функцию glOrtho(). Эта функция преобразует изображение в соответствии с плоскостями отсечения, которые передаются в функцию в качестве аргументов. Допустим мы хотим, чтобы левая граница экрана соответствовала координате x = 0, а правая – x = 1. В свою очередь верх экрана – y = 1, а низ – y = 0. Ось z в нашем примере будет отвечать за расположение объектов относительно друг друга (чем ближе к нам объект, тем больше координата z, соответственно, ближние к нам объекты будут заслонять дальние). Зададим отображение по z от -1 – до 1:

void MainScene::resizeGL(int nWidth, int nHeight)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
	glViewport(0, 0, (GLint)nWidth, (GLint)nHeight);
}

Командой glViewport() мы устанавливаем размер сцены равным размеру окна нашего виджета (600 * 600, как мы указали в функции main()). Поскольку весь этот код мы поместили в функцию resizeGL(), теперь при изменениях размеров окна наше изображение также будет изменяться и подстраиваться под новые размеры.

Пришло время перейти к рисованию! Давайте первый делом попробуем нарисовать треугольник. Вот полный код:

void MainScene::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT);

	glColor3f(0.25, 0.87, 0.81);
	glBegin(GL_TRIANGLES);

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

	glEnd();
}

Для начала задаем цвет – пусть будет бирюзовый 😉 Рисование будет производиться при помощи функций glBegin(), glEnd(). В качестве аргумента первой из этих функций мы передаем тип рисуемой фигуры, а все, что содержится между функциями – точки фигуры, в нашем случае – три вершины треугольника. Запускаем программу и вот он результат:

Рисование в OpenGL.

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

void MainScene::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT);

	glColor3f(0.25, 0.87, 0.81);
	glBegin(GL_TRIANGLES);

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

	glEnd();

	glColor3f(0.13, 0.56, 0.13);
	glBegin(GL_QUADS);

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

	glEnd();
}

Получаем квадрат, расположенный в соответствии с заданными нами координатами:

Рисование фигур в OpenGL.

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

void MainScene::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT);

	glColor3f(0.25, 0.87, 0.81);
	
	glBegin(GL_TRIANGLES);
	glVertex2f(0.0, 0.0);
	glVertex2f(1.0, 1.0);
	glVertex2f(1.0, 0.0);
	glEnd();

	glColor3f(0.13, 0.56, 0.13);
	
	glBegin(GL_QUADS);
	glVertex2f(0.0, 0.5);
	glVertex2f(0.0, 1.0);
	glVertex2f(0.5, 1.0);
	glVertex2f(0.5, 0.5);
	glEnd();

	glLineWidth(2.0);
	glColor3f(0.65, 0.16, 0.16);
	
	glBegin(GL_LINE_STRIP);
	glVertex2f(0.0, 0.5);
	glVertex2f(0.5, 1.0);
	glVertex2f(1.0, 0.5);
	glVertex2f(0.5, 0);
	glVertex2f(0.0, 0.5);
	glEnd();
}

Помимо цвета, также зададим толщину линии.

Ломаная линия в OpenGL.

Вот, что в итоге получилось 🙂

Конечно, рисование при помощи glBegin() / glEnd() является очень простым и удобным, но строго говоря с точки зрения быстродействия этот способ не очень оптимален. Гораздо большего можно добиться, используя массивы вершин, массивы индексов и массивы цветов. Именно этому и будет посвящен следующий наш урок, не пропустите и до скорых встреч на нашем сайте!

Полный проект с примером из статьи – OpenGLTest.

Поделиться!

Подписаться
Уведомление о
guest
1 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
Руслан
Руслан
2 лет назад

У меня всплывает два окна и два белых

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Июль 2020
Пн Вт Ср Чт Пт Сб Вс
« Июн    
 12345
6789101112
13141516171819
20212223242526
2728293031  

© 2013-2020 MicroTechnics.ru