Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Геом моделирование 2D объектов бис бис.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
772 Кб
Скачать
☆

3.4 Использование стековой памяти

После размещения второго объекта – повернутой стрелки – нужно перейти к отображению третьего объекта. Координаты начала его ОСК – (0.5,0.5). Однако просто применить команду glTranslate с такими параметрами не получится, так как перед этим в процессе установки второй стрелки положение ОСК было изменено. Напомним, что команды сдвига, поворота и масштабирования выполняют свои преобразования ОСК относительно ее предыдущего состояния, то есть работают по приращениям. Значит, для установки третьей стрелки нужно найти такие параметры сдвига, поворота и масштабирования, которые позволят перейти от состояния ОСК второй стрелки к состоянию ОСК третьей стрелки, что, в общем случае, непросто. Гораздо проще было бы задать положение третьей стрелки, отталкиваясь от исходного состояния ОСК, то есть в центре экрана, без поворота, без масштабирования. Для этого можно было бы после установки второй стрелки вернуть ОСК в исходное состояние, выполнив обратные геометрические преобразования, а затем приступить к установке третьей стрелки. Однако это неэффективный прием, так как наборы преобразований, в общем случае, могут быть большими. В библиотеке OpenGL есть аппарат стековой памяти, специально созданный для выполнения этой работы.

Стек – это память, действующая по принципу «последним вошел – первым вышел». Если в некоторый момент выполнения программы применить команду

glPushMatrix(); ,

то состояние системы координат, действующее на данный момент, будет запомнено. Далее это состояние можно изменять командами сдвига, поворота, масштабирования, но запомненное исходное состояние будет храниться в стеке. И в нужный момент времени запомненное состояние ОСК может быть возвращено – считано из стека – беспараметрической командой

glPopMatrix(); .

В принципе, объем стека позволяет, если это необходимо, сохранять в нем несколько состояний системы координат – на разные моменты времени. Для этого каждый раз применяется команда glPushMatrix. Для извлечения из стека очередного состояния ОСК каждый раз применяется команда glPopMatrix.

Работа со стеком имеет одну особенность. После того, как командой glPopMatrix некоторое состояние ОСК извлекается из стека, оно становится доступным для изменения (сдвига, поворота, масштабирования), но в самом стеке оно пропадает – стирается. Следовательно, если это состояние ОСК в будущем понадобится еще раз, его нужно еще раз запомнить с помощью команды glPushMatrix.

Применив аппарат стековой памяти, расстановку стрелок в соответствии с рисунком 1 можно описать следующим образом.

//запоминание исходного состояния ОСК

glPushMatrix();

//отображение первой стрелки

glCallList(2);

//установка второй стрелки

glTranslatef(-0.5,0.5,0.0);

glRotatef(135,0.0,0.0,1.0);

glScalef(0.5,0,5,1.0);

//отображение второй стрелки

glCallList(2);

//возврат исходного состояния ОСК

glPopMatrix();

//повторное запоминание исходного состояния ОСК

glPushMatrix();

//установка третьей стрелки

glTranslatef(0.5, -0.5,0.0);

glScalef(0.5,0,5,1.0);

//отображение третьей стрелки

glCallList(2);

С помощью стека можно запоминать и возвращать любое состояние системы координат. Однако часто бывает необходимо установить именно исходное состояние ОСК – без каких-либо сдвигов, поворотов и масштабных изменений. Для этого служит команда

glLoadIdentity(); .

Ее удобно использовать в начале программы. Дело в том, что в процессе работы программы часто возникает необходимость выполнить ее тело еще раз, то есть перерисовать изображение. Это происходит, например, при изменении размеров окна вывода или его сворачивании–разворачивании. При перерисовке в программе сохраняется текущее состояние ОСК, которое существовало на момент завершения предыдущего цикла рисования. Это означает, что последующие геометрические преобразованияначнутся не от исходного состояния ОСК, и их выполнение не приведет к желаемому результату. Команда glLoadIdentity позволяет предотвратить такую неправильность работы программы.