Уроки 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
2 Комментарий
старее
новее большинство голосов
Inline Feedbacks
View all comments
Руслан
Руслан
2 лет назад

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

Александр
Александр
44 минут назад

Спасибо за урок!!!

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

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Октябрь 2020
Пн Вт Ср Чт Пт Сб Вс
 1234
567891011
12131415161718
19202122232425
262728293031  

© 2013-2020 MicroTechnics.ru