Опубликован: 13.07.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 19:

Простая программа на OpenGL

Упражнение 3. Анимация прямоугольника с помощью OpenGL и GLUT (Bounce)

Усложним нашу программу, добавив возможность рисования квадрата так, чтобы он рикошетом отскакивал от сторон окна.

Добавьте к проекту новый файл. Для этого:

  • В панели Solution Explorer щелкните правой кнопкой мыши на узле проекта и через контекстное меню выполните команду Add/New Item
  • В открывшемся окне задайте имя файла Bounce, а тип и размещение выберите в соответствии со снимком

  • Нажмите кнопку Add и к проекту добавится новый пустой файл C++
  • Удалите из проекта прежний файл GLRect.cpp. Для этого в панели Solution Explorer щелкните правой кнопкой мыши на этом файле и через контекстное меню выполните команду Remove
  • Заполните файл Bounce.cpp следующим кодом
#include "stdafx.h"
  
// Прототипы глобальных функций
  void RenderScene(void);
  void SetupRC(void);
  void ChangeSize(int, int);
  void TimerFunction(int);
  
// Глобальные переменные:
  
  // Начальная позиция и размер прямоугольника (будет квадрат)
  GLfloat x = 0.0f;
  GLfloat y = 0.0f;
  GLfloat rsize = 25;
  
  // Величина шага в направлениях x и y (в пикселах)
  GLfloat xstep = 3.0f;
  GLfloat ystep = 3.0f;
  
  // Текущие ширина и высота клиентской области окна приложения
  GLfloat windowWidth;
  GLfloat windowHeight;
  
//**********************************************************
// Точка входа приложения
void main(int argc, char* argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(600,300);
  glutCreateWindow("Bounce");
  glutDisplayFunc(RenderScene);
  glutReshapeFunc(ChangeSize);
  glutTimerFunc(33, TimerFunction, 1);
  
  SetupRC();
  
  glutMainLoop();
}
  
//**********************************************************
// Рисование сцены
void RenderScene(void)
{
  // Очистка окна текущим цветом
  glClear(GL_COLOR_BUFFER_BIT);
  
  // Установка цвета рисования в модели RGB (красный)
  glColor3f(1.0f, 0.0f, 0.0f);
  
  // Рисование и заливка красным
  glRectf(x, y, x + rsize, y - rsize);
  
  // Переключение буфера с очисткой очереди команд
  glutSwapBuffers();
}
  
//**********************************************************
// Вызывается по таймеру библиотекой GLUT в спокойном состоянии,
// когда не меняются размеры окна приложения и нет перемещений
void TimerFunction(int value)
{
  // Меняем направление перемещения на противоположное
  // при подходе к левому или правому краю окна
  if(x > windowWidth - rsize || x < -windowWidth)
    xstep = -xstep;
  
  // Меняем направление перемещения на противоположное
  // при подходе к верхнему или нижнему краю окна
  if(y > windowHeight || y < -windowHeight + rsize)
    ystep = -ystep;
  
  // Перемещаем прямоугольник в новую позицию
  x += xstep;
  y += ystep;
  
  // Проверка на случай, если прямоугольник окажется больше окна  
  // или за пределами  объема отсекающего параллелепипеда
  if(x > (windowWidth - rsize + xstep))
    x = windowWidth - rsize - 1;
  else if(x < -(windowWidth + xstep))
    x = -windowWidth - 1;
  
  if(y > (windowHeight + ystep))
    y = windowHeight - 1; 
  else if(y < -(windowHeight - rsize + ystep))
    y = -windowHeight + rsize - 1;
  
  // Перерисовываем сцену с новыми координатами
  glutPostRedisplay();
  // Запускаем новый таймер
  glutTimerFunc(33,TimerFunction, 1);
}
  
//**********************************************************
// Установка состояния рендеринга (визуализации)
void SetupRC(void)
{
  // Устанавливаем синий цвет очистки 
  glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
  
//**********************************************************
// Вызывается библиотекой GLUT при изменении размеров окна
// приложения. Осталась такой же, как в примере GLRect,
// только в вызовы glOrtho() поставили переменные
void ChangeSize(int width, int height)
{
  GLfloat aspectRatio;
  
  // Предотвращаем деление на нуль
  if(height == 0)
    height = 1;
  
  // Устанавливаем поле просмотра с размерами окна
  glViewport(0, 0, width, height);
  
  // Устанавливает матрицу преобразования в режим проецирования
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  // Устанавливаем размеры перспективы (отсекающего объема)
  // (left, right, bottom, top, near, far)
  aspectRatio = (GLfloat)width / (GLfloat)height;
  if (width <= height) 
  {
    windowWidth = 100;
    windowHeight = 100 / aspectRatio;
    glOrtho (-100.0, 100.0, 
        -windowHeight, windowHeight, 1.0, -1.0);
  }
  else 
  {
    windowWidth = 100 * aspectRatio;
    windowHeight = 100;
    glOrtho (-windowWidth, windowWidth, 
        -100.0, 100.0, 1.0, -1.0);
  }
  
  // Восстановливает матрицу преобразования в исходный режим вида
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}
Листинг 19.27. Усложненный файл реализации Bounce.cpp
  • Запустите приложение и убедитесь, что результат совпадает с задуманным
Александр Очеретяный
Александр Очеретяный
Украина, Киев
Анастасия Балыбердина
Анастасия Балыбердина
Украина, Киев, НТУУ КПИ