Добавляем анимацию

Определение параметров

Сначала определим параметры отображения окна:
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;
 
articles/lesson_3.txt · Последние изменения: 2006/05/10 14:01 (внешнее изменение)
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki