Анимация GLUT с glTimerFunc

Я попробовал несколько простых рисунков и анимаций с помощью freeglut (в Linux на виртуальной машине). До сих пор все строилось и работало просто отлично. Моя последняя попытка заключалась в перемещении квадрата с помощью glTimerFunc. Хотя с gcc stack.c -lGL -lglut -o stack строится без ошибок, сама анимация не работает. Я просмотрел все примеры анимации с перенасыщением, которые смог найти, но не заметил никаких проблем с моим кодом. Может ли кто-нибудь объяснить мне, в чем моя ошибка?

(изменить: рабочий код см. ниже)

#include <stdio.h>
#include <stdlib.h>
#include <GL/freeglut.h>

int dx = 0;

#define TIMERSECS 100

void animate(int value) {
  glutTimerFunc(TIMERSECS, animate, 1);
  if (dx > 0.5) {
    dx = -0.5;
  }
  else {
    dx += 0.1;
  }
  glutPostRedisplay();
}

void display(void) {
  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(0.0, 0.0, 0.5);

  glBegin(GL_POLYGON);
    glVertex2d(-0.5+dx, 0.5);
    glVertex2d(-0.5+dx, -0.5);
    glVertex2d(0.5+dx, -0.5);
    glVertex2d(0.5+dx, 0.5);
  glEnd();

  glutSwapBuffers();
}

void initialize(void) {
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glShadeModel(GL_SMOOTH);
}

void main(int argc, char *argv[]) {

  glutInit(&argc, argv);
  glutInitWindowPosition(100, 100);
  glutInitWindowSize(500, 500);

  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  glutCreateWindow(argv[0]);

  initialize();
  glutDisplayFunc(display);
  glutTimerFunc(TIMERSECS, animate, 0);
  glutPostRedisplay();

  glutMainLoop();
}

РЕДАКТИРОВАТЬ

@datenwolf: я посмотрел на другой вопрос, на который вы ответили более внимательно, на этот раз и взял немного кода оттуда, прекрасно работает!

Вот новая версия:

#include <stdio.h>
#include <stdlib.h>
#include <GL/freeglut.h>

int factor=100; // factor the animation is slowed down by

double dx = 0;

void animate(double speed);

static double ftime(void) {
    struct timeval t;
    gettimeofday(&t, NULL);

    return 1.0*t.tv_sec + 1e-6*t.tv_usec;
}

static double last_T;

static void idle(void) {
  const double now_T = ftime();
  const double delta_T = now_T - last_T;
  last_T = now_T;

  const double speed = delta_T * 60;

  animate(speed);

  glutPostRedisplay();
}

void animate(double speed) {
  if (dx > 1.5) {
    dx = -1.5;
  }
  else {
    dx += speed/factor;
  }
  glutPostRedisplay();
}

void display(void) {
  glClear(GL_COLOR_BUFFER_BIT);

  glColor3f(0.0, 0.0, 0.5);

  glBegin(GL_POLYGON);
    glVertex2d(-0.5+dx, 0.5);
    glVertex2d(-0.5+dx, -0.5);
    glVertex2d(0.5+dx, -0.5);
    glVertex2d(0.5+dx, 0.5);
  glEnd();

  glutSwapBuffers();
}

void initialize(void) {
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glShadeModel(GL_SMOOTH);
}

void main(int argc, char *argv[]) {

  glutInit(&argc, argv);
  glutInitWindowPosition(100, 100);
  glutInitWindowSize(500, 500);

  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  glutCreateWindow(argv[0]);

  initialize();
  glutDisplayFunc(display);
  glutIdleFunc(idle);
  glutPostRedisplay();

  glutMainLoop();
}

Dankeschön für deine Hilfe!


person Community    schedule 20.08.2012    source источник


Ответы (1)


Вы не должны использовать таймер событий для анимации. Вместо этого вы должны вызывать glutPostDisplay из функции бездействия и измерять время между вызовами функции отображения и основывать на этом время анимации.

person datenwolf    schedule 20.08.2012
comment
Вы имеете в виду glutPostRedisplay? Должен ли я анимировать с помощью glutIdleFunc? (Что я пробовал, но тоже не сработало) - person ; 20.08.2012
comment
@teashorts: вы должны вызвать glutPostRedisplay в функции ожидания или зарегистрировать ее как функцию ожидания. Затем вы измеряете время между вызовами функции отображения; используйте для этого глобальную переменную. - person datenwolf; 20.08.2012