Рисование листа

от автора

Добрый вечер хабр!

Сегодня я Вам продемонстрирую API правда устаревший(версии 1.0), для отрисовки растительного листика. В программе используется библиотека OpenGL и язык С++. Думаю что не стану перегружать Вас кодом который создает окно и контекст, будет лишь так сказать самая «вкуснятина» в виде разбора кода. Немного предыстории. Больше 10 лет назад я написал программу плеер для Windows и в нем помимо списка музыки и кнопок управления, были еще 3D объекты которые вращались — ну как бы под музыку ничего особенного. Я тогда только изучал это все и вот беда — код не сохранился. Осталась лишь одна программа и сейчас буквально за час, я попытался реверс-инженерингом восстановить один из 3D объектов. Я конечно не помню как я его делал столько времени прошло, но я помню идею которой руководствовался — это зеркальное отображение и масштабирование части изображения чтобы получить симметричный объект. Перейдем к коду:

void MyWidget::HalfList()//пол-листика точнее пол ответвления { glColor3f(0.0, 0.5, 0.0);//задаем цвет glBegin(GL_QUADS);//рисуем квадратами for (float i = -0.8; i < 0.8; i += 0.1)//в цикле пробегаем и рисуем праллелограммы { glVertex3f(0, i, 0); glVertex3f(0.1, i + 0.1, 0); glVertex3f(0.1, i + 0.2, 0); glVertex3f(0, i + 0.1, 0); } glEnd(); glBegin(GL_TRIANGLES);//рисуем треугольниками glVertex3f(0, 0.8, 0);//рисуем кончик листика glVertex3f(0.1, 0.9, 0); glVertex3f(0, 1.0, 0); glEnd(); glColor3f(0, 1.0, 0);//задаем цвет для скелета glLineWidth((GLfloat)1);//задаем толщину линий glBegin(GL_LINES);//рисуем линиями glVertex3f(0, -0.8, -0.01);//вертикальная линия glVertex3f(0, 1, -0.01); glVertex3f(0, -0.8, 0.01); glVertex3f(0, 1, 0.01); glEnd(); glBegin(GL_LINES);//рисуем линиями for (float i = -0.8; i < 0.9; i += 0.1) { glVertex3f(0, i, -0.01);//рисуем скелет листика glVertex3f(0.11, i + 0.1, -0.01); glVertex3f(0, i, 0.01); glVertex3f(0.11, i + 0.1, 0.01); } glEnd(); }  void MyWidget::FullList() { HalfList();//рисуем пол-ответвления glPushMatrix(); glRotatef(180, 0, 1, 0);//поворачиваем сцену на 180 градусов вокруг оси игрек HalfList();//дорисовываем вторую половину пол-ответвления glPopMatrix(); } void MyWidget::Show()//рисуем целый лист { glPushMatrix(); glScalef(0.7, 0.7, 1);//масштабируем весь объект glColor3f(0.0, 0.5, 0.0); glBegin(GL_TRIANGLES);//рисуем треугольниками glVertex3f(0,-0.8,0);//рисуем хвостик листика glVertex3f(-0.01,-1,0); glVertex3f(0.01, -1, 0); glEnd(); FullList();//вертикальная часть листа glPushMatrix(); glTranslatef(-0.2, -0.45, 0); glRotatef(30, 0, 0, 1); glScalef(0.6, 0.6, 1); FullList();//часть листа повернутая на 30 градусов glPopMatrix(); glPushMatrix(); glTranslatef(0.2,-0.45, 0); glRotatef(-30, 0, 0, 1); glScalef(0.6, 0.6, 1); FullList();//часть листа повернутая на -30 градусов glPopMatrix();  glPushMatrix(); glTranslatef(-0.3, -0.7, 0); glRotatef(60, 0, 0, 1); glScalef(0.4, 0.4, 1); FullList();//часть листа повернутая на 60 градусов glPopMatrix(); glPushMatrix(); glTranslatef(0.3, -0.7, 0); glRotatef(-60, 0, 0, 1);//часть листа повернутая на -60 градусов glScalef(0.4, 0.4, 1); FullList(); glPopMatrix();  glPushMatrix(); glTranslatef(-0.15, -0.9, 0); glRotatef(100, 0, 0, 1); glScalef(0.2, 0.2, 1); FullList();//часть листа повернутая на 100 градусов glPopMatrix(); glPushMatrix(); glTranslatef(0.15, -0.9, 0); glRotatef(-100, 0, 0, 1);//часть листа повернутая на -100 градусов glScalef(0.2, 0.2, 1); FullList(); glPopMatrix(); glPopMatrix(); } void MyWidget::paintGL() // рисование { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Show(); }

Собственно что такое пол-ответвления:

Я конечно не ботаник не знаю как эту часть назвать.

Вот скелет его и c кончиком и хвостиком:

Собственно дальше с помощью поворота масштабирования и параллельного переноса получается так

Здесь градусы вместо процентов.

Итоговый объект:

Ну и всё!

Не унывайте.


ссылка на оригинал статьи https://habr.com/ru/post/714942/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *