====== Добавляем анимацию ====== ===== Определение параметров ===== Сначала определим параметры отображения окна:\\ glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH); GLUT_DOUBLE - двойной буфер ===== Способ анимации ===== Теперь, надо определить каким способом будет проводиться анимация: через некоторый промежуток времени (с помощью таймера) или управлением с клавиатуры/мыши/других устройств. ==== Управление таймером ==== glutTimerFunc(20, @OnTimer, 0); Каждые 20 мс будет вызываться обработчик событий таймера OnTimer. Опишем его: procedure OnTimer(value: Integer); cdecl; begin glutPostRedisplay; // обновляем окно glutTimerFunc(20, @OnTimer, 0); end; ==== Управление клавиатурой ==== Слежение за специальными клавишами делается процедурой //glutSpecialFunc()//\\ glutSpecialFunc (@SpecialKeyboard); Опишем обрабочик событий //SpecialKeyboard//: procedure SpecialKeyboard(key, x,y: longint); cdecl; begin case key of GLUT_KEY_UP: begin MoveForward; glutPostRedisplay(); end; GLUT_KEY_DOWN: begin MoveBack; glutPostRedisplay(); end; GLUT_KEY_LEFT : begin MoveLeft; glutPostRedisplay(); end; GLUT_KEY_RIGHT : begin MoveRight; glutPostRedisplay(); end; end; end; end; Процедура //glutPostRedisplay()// немедленно вызовет процедуру прорисовки объекта. В процедуре обновления окна теперь заменяем //glFlush()// на //glutSwapBuffers()//. ==== Анимация в реальном времени ==== Ей занимается процедура glutIdleFunc()\\ glutIdleFunc(@idle); Idle - это то, что должно происходить "вхолостую". Как правило, это всякие расчёты. Опишем обработчик событий idle() : procedure idle(); cdecl; begin {расчёты, ...} glutPostRedisplay(); end; ===== Примеры ===== ==== с обработкой клавиатуры ==== **planet.pas** (*** << Planet demo >> ***) {$apptype GUI} {$mode objfpc} Uses GL, GLU, GLUT; const year: integer = 0; day: integer = 0; var oglWin : integer; procedure init(); begin glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_FLAT); end; procedure display(); cdecl; begin glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glPushMatrix(); glutWireSphere(1.0,20,16); glRotatef(year,0.0,1.0,0.0); (* draw sun *) glTranslatef(2.0,0.0,0.0); glRotatef(day,0.0,1.0,0.0); glutWireSphere(0.2,10,8); glPopMatrix(); (* draw smaller planet *) glutSwapBuffers(); end; procedure reshape(w: integer; h: integer); cdecl; begin glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, w / h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0); end; procedure kbd(key: byte; x,y: longint); cdecl; begin case Chr(key) of 'd': begin day:= (day+10) mod 360; glutPostRedisplay(); end; 'D': begin day:= (day-10) mod 360; glutPostRedisplay(); end; 'y': begin year:= (year+5) mod 360; glutPostRedisplay(); end; 'Y': begin year:= (year-5) mod 360; glutPostRedisplay(); end; #27: begin glutDestroyWindow (oglWin); halt(0); end; end; end; begin glutInit (@argc,argv); glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB); glutInitWindowSize(500,500); glutInitWindowPosition(100,100); oglWin := glutCreateWindow('Planet demo'); init(); glutDisplayFunc(@display); glutReshapeFunc(@reshape); glutKeyboardFunc(@kbd); glutMainLoop(); end. ==== с обработкой в реальном времени ==== function FMod(a,b: glFloat): glFloat; var x: Integer; begin x := Trunc (a / b); result := a - b * x; end; procedure idle(); cdecl; begin angle1:= fmod (angle1+0.8, 360.0); angle2:= fmod (angle2+1.1, 360.0); s += 0.5; glutPostRedisplay(); end;