КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
GlScalef(1.0, -1.0, 1.0); ⇐ ПредыдущаяСтр 2 из 2 fig0(); //glPopMatrix( ); glFlush(); //glutSwapBuffers(); //f+=30; if(f==360) f=0; //Sleep(200); }
void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(640, 480); glutInitWindowPosition(20, 20); glutCreateWindow("Myprog"); glutReshapeFunc(reshape); glutDisplayFunc(scene); //glutIdleFunc(scene); init(); glutMainLoop(); }
Некоторые дополнительные функции: void glPushMatrix(void) – проталкивает текущую матрицу в стек матриц, текущая матрица всегда в вершине стека, т.о. после вызова этой функции, матрица, которая находится в вершине стека, идентична той, что под ней. void glPopMatrix(void) – выталкивает данные из текущего стека матриц, замещая текущую матрицу на ту, что находится под ней. void glutSwapBuffers(void) – буфер в котором выполнялось рисование делается отображаемым и наоборот. void glutReshapeFunc(void (*func)(int width, int height) – регистрирует функцию func, которая должна вызываться всякий раз, когда изменяются размеры окна или оно перемещено. Параметр func есть указатель на функцию, которая ожидает два параметра: новые значения ширины width и высоты height окна. void glutIdleFunc(void (*func)(void)) – регистрирует функцию, которая будет выполняться в отсутствии событий. Как пользоваться этими функциями? Рассмотрим это на примере приведенной выше программы. 1) Наберите программу Пример 2 со всеми закомментированными строками. Выполните ее. На экране увидите изображение как на рис.1. Измените размер экранного окна, потянув мышкой за его границу. Вы увидите, что вся сцена изменит свое положение. Причина этого в том, что при первом вызове функция scene( ) стартует при VM=1 и фигура в положении Fig.0 нарисуется при VM=1, а в положении Fig.1 при VM=T*R*S. При изменении размеров window будет заново вызвана функция scene( ) и она стартует уже при VM= T*R*S, а затем примет значение VM=VM*T*R*S =T*R*S*T*R*S. И так VM будет накапливать все предыдущие преобразования при каждом вызове функции scene( ). Раскомментируйте строки glPushMatrix( ) и glPopMatrix( ) в функции scene( ) и заново запустите программу. Вы убедитесь, что сцена не будет изменяться при повторных вызовах функции scene( ). Функция glPushMatrix( ) при вызове scene( ) сохранит в стеке VM=1, затем установится VM = T*R*S, будет нарисована фигура в положении Fig.1, а затем функция glPopMatrix( ) вытолкнет из вершины стека текущую матрицу и заменит ее сохраненной VM=1. При этом, сколько бы раз мы не вызывали функцию scene( ), стартовать она будет всегда при VM=1. 2) Раскомментируйте строку glutIdleFunc(scene) в функции main( ) и строку f+=30; if(f==360) f=0; в функции scene( ) и запустите программу. Замысел здесь в том, чтобы scene( ) вызывалась постоянно и каждый раз с новым параметром f. Ожидаемый эффект – фигура в положении Fig.1 должна постоянно вращаться. Однако ожидаемого эффекта мы не достигнем – на экране будет мерцающее, плохо понятное изображение. Причина этого в том, что установлен режим использования одного буфера кадра как для рисования, так и для отображения (glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)), а новое рисование вызывается сразу же как завершено предыдущее. 3) Закомментируйте glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB), раскомментируйте glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB), раскомментируйте glutSwapBuffers(). Тем самым вы установите режим двойной буферизации (в одном буфере кадра выполняется рисование, другой отображается) и переключение буферов. На экране вы увидите устойчивую картинку сцены с быстро вращающейся фигурой в положении Fig.1. 4) Раскомментируйте строку Sleep(200) – это задержка. Так вы регулируете частоту смены кадров. Запустите программу и на экране вы увидите плавно вращающуюся фигуру в положении Fig.1. Программу Пример 2 мы понимали таким образом: - функция fig0( ) описывает фигуру в МСК в положении Fig.0, далее везде МСК будет обозначаться как СК0; - последовательность вызовов, выделенная жирным в функции scene( ), формирует преобразование модели (матрицу VM), эквивалентное композиции масштабирования, вращения и затем перемещения, VM= T*R*S; - применение полученной матрицы VM к fig0( ) переводит фигуру в положение Fig.1. Эту же программу можно понимать и другим образом: - функция fig0( ) описывает фигуру в некоторой локальной системе координат СКL; - последовательность вызовов, выделенная жирным в функции scene( ), формирует матрицу VM, которую можно понимать как координатный фрейм FL0, эквивалентный композиции координатных фреймов FL0 =F10*F21*FL2, где F10 = T, F21=R, FL2=S. - применение полученной матрицы VM к fig0( ) осуществляет преобразование координат вершин fig0( ) из СКL в СК0. На Рис. 2 показана локальная СКL и все промежуточные в соответствии с преобразованием FL0 =F10*F21*FL2, при F10 = T, F21=R, FL2=S.
|