Данный урок основан на предыдущем уроке №1.
У нас есть окно OpenGL с белым треугольником. Мы будем его анимировать. Для анимации нужно задействовать двойную буферизацию. Функция glutIdleFunc позволяет зарегистрировать функцию обратного вызова, которая будет вызываться когда само приложение находится в режиме ожидания.
void glutIdleFunc(void (*func)(void));
Параметры:
*func - имя функции, которая будет вызываться всякий раз, когда приложение находится в режиме ожидания.
Итак, функция main теперь выглядит следующим образом:
int main(int argc, char **argv) { // инициализация glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("Урок 3"); // регистрация glutDisplayFunc(renderScene); glutReshapeFunc(changeSize); // новая функция для регистрации glutIdleFunc(renderScene); // основной цикл glutMainLoop(); return 1; }
Объявим переменную angle, и инициализировать его в 0.0. Затем мы добавляем необходимые значения в renderScene.
float angle = 0.0f;
void renderScene(void) { // очистка буфера цвета и глубины glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // обнуление трансформации glLoadIdentity(); // установка камеры gluLookAt( 0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); glRotatef(angle, 0.0f, 1.0f, 0.0f); glBegin(GL_TRIANGLES); glVertex3f(-2.0f,-2.0f, 0.0f); glVertex3f( 0.0f, 2.0f, 0.0); glVertex3f( 2.0f,-2.0f, 0.0); glEnd(); angle+=0.1f; glutSwapBuffers(); }
Замечание о двойной буферизации.
Как вы помните, мы устанавливаем режим отображения в main - режим двойной буферизации. Эта функция обеспечивает два буфера для отображения. первый показывается на экране, второй просчитывается, потом происходит смена буфера. и процесс обработки повторяется. GlutSwapBuffers вызывает смену переднего и заднего буферов, создавая эфект анимированного изображения. Синтаксис выглядит следующим образом:
void glutSwapBuffers();
Итоговый код:
#include <glut.h> float angle = 0.0f; void changeSize(int w, int h) { // предотвращение деления на ноль if (h == 0) h = 1; float ratio = w * 1.0 / h; // используем матрицу проекции glMatrixMode(GL_PROJECTION); // обнуляем матрицу glLoadIdentity(); // установить параметры вьюпорта glViewport(0, 0, w, h); // установить корректную перспективу gluPerspective(45.0f, ratio, 0.1f, 100.0f); // вернуться к матрице проекции glMatrixMode(GL_MODELVIEW); } void renderScene(void) { // очистка буфера цвета и глубины glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // обнуление трансформации glLoadIdentity(); // установка камеры gluLookAt( 0.0f, 0.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); glRotatef(angle, 0.0f, 1.0f, 0.0f); glBegin(GL_TRIANGLES); glVertex3f(-2.0f,-2.0f, 0.0f); glVertex3f( 0.0f, 2.0f, 0.0); glVertex3f( 2.0f,-2.0f, 0.0); glEnd(); angle+=0.1f; glutSwapBuffers(); } int main(int argc, char **argv) { // Инициализация GLUT и создание окна glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow("Урок 3"); // регистрация glutDisplayFunc(renderScene); glutReshapeFunc(changeSize); glutIdleFunc(renderScene); // основной цикл glutMainLoop(); return 1; }
Результат работы программы: окно размером 400*400 пикселей с заголовком "Урок 3" и вращающимся треугольником.