Добрый вечер, Хабр!
Сегодня я Вам продемонстрирую 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 кончиком и хвостиком:
Собственно дальше с помощью поворота масштабирования и параллельного переноса получается так
Здесь градусы вместо процентов.
Итоговый объект:
Ну и всё!
Не унывайте.
Комментарии (13)
Paranoich
05.02.2023 18:05А яндекс узнал изображенное на рисунке и даже сказал, что «нажмите, чтобы выбрать товар на этом изображении».
Финальное изображение ведь случайно получилось именно такое, верно? И уголы именно такие (вместо ожидаемых 120 — 100). Случайно ведь?
Полагаю, что пользователи оценили.AllKnowerHou Автор
05.02.2023 19:24-2Что-то заминусовали без обратной связи непонятно
BadHandycap
05.02.2023 20:05+3Вы серьезно не понимаете за что минусы? Статья очень маленькая. OpenGL старый. Результат дерьмовый.
AllKnowerHou Автор
05.02.2023 20:06-3Статья очень маленькая
Краткость сестра таланта
BadHandycap
05.02.2023 20:12+1Явно не на этом ресурсе.
AllKnowerHou Автор
05.02.2023 20:29-2Чисто поржать
randomsimplenumber
05.02.2023 23:58+2А в каком месте можно начинать смеяться? ;)
Код, состоящий из волшебных констант более чем полностью - это не смешно.
Moskus
06.02.2023 00:15Идите почитайте что студенты на эту тему напрограммировали в Университете Калгари http://algorithmicbotany.org/
Изобретать велосипед вообще с нуля в современной ситуации - несколько глупо. "Сделать что-то своё", при этом, может быть намного интереснее, если знаешь, что уже сделано.
CrashLogger
06.02.2023 23:16Лучше на шейдерах сделай такое. Кому нужен OpenGl 1.0 в 2023 году ?
AllKnowerHou Автор
07.02.2023 00:13да там надо скомпилить библиотеки опенжл, я как то не особо разбираюсь в гите khronos group не пойму где там ветка - там много всяких штук
nin-jin
Это называется лента. И ленты проще рисовать не кучей
QUADS
, а одним TRIANGLE_STRIP.