Как фотографировать крещение ребенка. Как снимать крестины

Как фотографировать крещение ребенка. Как снимать крестины
Как фотографировать крещение ребенка. Как снимать крестины

Часть 1 Первоначальная установка и main()

1) Установка OpenGL

  • Начните с этой статьи по установке OpenGL на ваш компьютер. Если OpenGL и компилятор С у вас уже есть, можете пропустить этот шаг.

2) Создание нового файла

  • В любимом текстовом редакторе создайте новый файл и сохраните его как mycube.c

3) #includes

  • Собственно, вот основные директивы #include, которые нам понадобятся. Важно помнить, что директивы для разных операционных систем - разные, а потому выбирать надо все, чтобы программу можно было запустить на любой системе.
    
    // Includes
    #include <stdio.h>
    #include <stdarg.h>
    #include <math.h>
    #define GL_GLEXT_PROTOTYPES
    #ifdef __APPLE__
    #include <GLUT/glut.h>
    #else
    #include <GL/glut.h>
    #endif
    
    

4) Функциональные прототипы и глобальыне переменные

  • Пора бы и объявить функциональные прототипы.
    
    // Функциональные прототипы
    void display();
    void specialKeys();
    // Глобальные переменные
    double rotate_y=0; 
    double rotate_x=0;
    
    
  • Подробнее каждая из этих функций и переменных будет объяснена чуть позднее, а пока что важно уже то, что мы их объявили.

5) Работа с функцией main()

  • 
    int main(int argc, char argv[]){
     
    //  Инициализируем GLUT и обрабатываем пользовательские параметры
    glutInit(&argc,argv);
     
    //  Запрашиваем окно с поддержкой двойной буферизации, z-буферизации и цветовой схемы True Color
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    
    
  • Это - настройка нашей среды разработки. Важно помнить, что, работая над созданием программ OpenGL, вам нужно все. Вам нужно хорошо понимать, как будет работать ваша программа, вам нужно хорошо понимать, какой для этого функционал необходим. В этой строке мы настраиваем отображение с двойной буферизацией, поддержкой цветов по RGB и Z-буферизацией.

  • Двойная буферизация - это прием, позволяющий графическим программам избежать потенциальной проблемы с отображением изображений. Проблема, о которой мы говорим, может возникнуть в связи с тем, что при каждой перерисовке сцены необходимо сперва очистить дисплей, только потом можно выводить новую информацию. Без двойной буферизации, увы, экран будет очищаться и зарисовываться снова и снова.

    Решение простое, добавляется второй буфер для отрисовки. Изображение, соответственно, отрисовывается в первом буфере, который и выводится на экран. Следующий кадр будет отрисован уже во втором буфере, после чего кадры поменяются местами. Мы сразу же увидим содержимое второго буфера, а первый буфер, скрытый от нас вторым, будет в это самое время очищен и заполнен третьим кадром. И так далее...

  • Кроме того, нам нужна поддержка цветов по схеме RGB. Подробнее об использовании цветов в OpenGL - чуть позже.

  • Z-buffering - это, собственно, то, что и создает эффект трехмерности. OpenGL использует трехмерную пространственную систему координат с осями x, y и z. Приближение объекта к зрителю, удаление его от зрителя - изменение дистанции по оси z. Подробнее об этом - тоже позднее.

6) Создание окна

  • Теперь нам надо создать окно, в котором и будет отрисован куб. Назовем его просто и без изысков - "Awesome Cube", то есть “Шикарный куб”.
    
    // Создаем окно
    glutCreateWindow("Awesome Cube");
    
    

7) Активация теста глубины

  • OpenGL - язык довольно строгий, подразумевающий, что ничего особенного не активировано. Нам же, чтобы должным образом отобразить трехмерный объект с помощью z-буфера, необходим тест глубины. Изучая OpenGL дальше, вы откроете для себя еще много чего такого, что нужно активировать (освещение, текстуры и так далее).
    
    //  Активируем тест глубины Z-буферизации
    glEnable(GL_DEPTH_TEST);
    
    

8) Функции обратного вызова

  • Вот функции обратного вызова для созданных нами ранее прототипов. Эти функции будут вызываться через основной цикл программы. Функция display будет перерисовывать сцену исходя из изменения значений переменных, которые были сделаны после прошлого их вызова. Функция specialKeys, в свою очередь, позволит нам взаимодействовать с программой.
    
    // Функции обратного вызова
    glutDisplayFunc(display);
    glutSpecialFunc(specialKeys);
    
    

9) Функции обратного вызова

  • Последний шаг настройки - запуск MainLoop, основного цикла, с помощью чего мы будем вызвать основную функцию до тех пор, пока программа не будет закрыта.
    
    //  Передаем контроль над событиями в GLUT 
    glutMainLoop();
     
    //  Возвращаемся в ОС
    return 0;
     
    }
    
    

Часть 2 Функция display()

  • Вся работа с отрисовкой куба ляжет на хрупкие строчки этой фукнции. В общем и целом, куб будет представлен как 6 отдельных граней, размещенных в соответствующих координатах.

  • Соответственно, каждая грань будет иметь по 4 стороны и 4 угла, что позволит OpenGL соединить линии и заполнить область между ними цветом. Об этом мы тоже расскажем.

1) glClear()

  • Первым делом, работая с этой функцией, нам надо очистить цвет и Z-буфер. Без этого под новым рисунком будет виднеться старый, а нарисованные программой объекты будут расположены неправильно.
    
    void display(){
     
    //  Очищаем экран и z-буферизацию
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    

2) glBegin() и glEnd()

  • OpenGL понимает под “объектом” комбинации различных полигонов. Команда glBegin() позволит нам с вами нарисовать объект - это как бы карандаш в ваших руках. Чтобы начать рисовать этим карандашом что-то новое, нужна команда glEnd(). В данной статье мы будем использовать GL_POLYGON для отрисовки каждой гарни куба, хотя для создания других форм можно воспользоваться и параметрами вроде GL_LINE, GL_QUAD или GL_TRIANGLE.

  • Начинаем с передней стороны куба. Позже мы добавим цвет к каждой из 6 граней.
    
    // Многоцветная сторона - ПЕРЕДНЯЯ
    glBegin(GL_POLYGON);
     
    // Вертексы добавим в следующем шаге
     
    glEnd();
    
    

3) glVertex3f()

  • Теперь, когда мы объяснили программе, что хотим начать полигон, нам надо задать вертексы объекта. У функции glVertex есть несколько форм, использовании которых определяется намерениями программиста.

  • Первое - во скольких измерениях вы будете работать? Цифра 3 в in glVertex3f указывает на три измерения. Впрочем, можно работать и в 2, и в 4 измерениях. Буква f, в свою очередь, указывает на то, что мы работаем с цифрами с плавающей запятой. Впрочем, тут вы можете использовать и данные типов integer, double и short.

  • Заметьте, что все точки задаются против часовой стрелки. Пока это еще не очень важно, но когда пойдет освещение, текстурирование обработка нецелевых граней, то привычка прописывать все против часовой стрелки вам очень пригодится.

  • Добавляем вертексы между линиями glBegin() и glEnd() lines.
    
    // Многоцветная сторона - ПЕРЕДНЯЯ
    glBegin(GL_POLYGON);
     
    glVertex3f( -0.5, -0.5, -0.5);       // P1
    glVertex3f( -0.5,  0.5, -0.5);       // P2
    glVertex3f(  0.5,  0.5, -0.5);       // P3
    glVertex3f(  0.5, -0.5, -0.5);       // P4
     
    glEnd();
    
    

4) glColor3f()

  • glColor действует во многом аналогично glVertex. Тип точек можно указывать данными типов short, integer, double или float. У каждого цвета есть значение от 0 до 1. Все нули - это черный цвет, все единицы, соответственно, белый. Цифра 3 в glColor3f() указывает на цветовую схему RGB без альфа-канала. Напоминаем, что альфа-канал цвета отвечает за его прозрачность. Чтобы изменить значение альфа-канала, используйте glColor4f() с последним параметром от 0 до 1, то есть от непрозрачности до прозрачности.

  • Вызывая glColor3f(), мы отрисовываем каждый вертекс от указанной точки в указанном цвете.Иными словами, если все четыре вертекса должны быть красные, то просто один-единственный раз задайте значение цвета до вызова команд glVertex3f(), и все вертексы будут красные

  • На примере заданной ниже передней стороны мы можем увидеть, как задается новый цвет каждого вертекса. Когда мы делаем так, мы можем познакомиться с интересной особенностью цветов OpenGL. Так как каждый вертекс полигона имеет свой цвет, то OpenGL автоматически смешивает цвета! Код, размещенный дальше, показывает, как создать 4 вертекса с одинаковым цветом.
    
    // Многоцветная сторона - ПЕРЕДНЯЯ
    glBegin(GL_POLYGON);
     
    glColor3f( 1.0, 0.0, 0.0 );     glVertex3f(  0.5, -0.5, -0.5 );      // P1 is red
    glColor3f( 0.0, 1.0, 0.0 );     glVertex3f(  0.5,  0.5, -0.5 );      // P2 is green
    glColor3f( 0.0, 0.0, 1.0 );     glVertex3f( -0.5,  0.5, -0.5 );      // P3 is blue
    glColor3f( 1.0, 0.0, 1.0 );     glVertex3f( -0.5, -0.5, -0.5 );      // P4 is purple
     
    glEnd();
    
    

5) Другие грани куба

  • Лучше, конечно, если вы сами найдете местоположение остальных граней куба и каждого из их вертексов. Впрочем, простоты ради, все уже сделано для вас. Код приведен в финальной функции display(), размещенной ниже.
    
    // Белая сторона - ЗАДНЯЯ
    glBegin(GL_POLYGON);
    glColor3f(   1.0,  1.0, 1.0 );
    glVertex3f(  0.5, -0.5, 0.5 );
    glVertex3f(  0.5,  0.5, 0.5 );
    glVertex3f( -0.5,  0.5, 0.5 );
    glVertex3f( -0.5, -0.5, 0.5 );
    glEnd();
     
    // Фиолетовая сторона - ПРАВАЯ
    glBegin(GL_POLYGON);
    glColor3f(  1.0,  0.0,  1.0 );
    glVertex3f( 0.5, -0.5, -0.5 );
    glVertex3f( 0.5,  0.5, -0.5 );
    glVertex3f( 0.5,  0.5,  0.5 );
    glVertex3f( 0.5, -0.5,  0.5 );
    glEnd();
     
    // Зеленая сторона - ЛЕВАЯ
    glBegin(GL_POLYGON);
    glColor3f(   0.0,  1.0,  0.0 );
    glVertex3f( -0.5, -0.5,  0.5 );
    glVertex3f( -0.5,  0.5,  0.5 );
    glVertex3f( -0.5,  0.5, -0.5 );
    glVertex3f( -0.5, -0.5, -0.5 );
    glEnd();
     
    // Синяя сторона - ВЕРХНЯЯ
    glBegin(GL_POLYGON);
    glColor3f(   0.0,  0.0,  1.0 );
    glVertex3f(  0.5,  0.5,  0.5 );
    glVertex3f(  0.5,  0.5, -0.5 );
    glVertex3f( -0.5,  0.5, -0.5 );
    glVertex3f( -0.5,  0.5,  0.5 );
    glEnd();
     
    // Красная сторона - НИЖНЯЯ
    glBegin(GL_POLYGON);
    glColor3f(   1.0,  0.0,  0.0 );
    glVertex3f(  0.5, -0.5, -0.5 );
    glVertex3f(  0.5, -0.5,  0.5 );
    glVertex3f( -0.5, -0.5,  0.5 );
    glVertex3f( -0.5, -0.5, -0.5 );
    glEnd();
     
    glFlush();
    glutSwapBuffers();
     
    }
    
    
  • Обратите внимание на две последние строки. Это функции glFlush(); и glutSwapBuffers();, которые и дают эффект двойной буферизации.

Часть 3 Интерактивность программы

1) specialKeys()

  • В принципе, все уже почти готово, куб отрисовывается на ура… но не вращается. Для этого надо создатьфункцию specialKeys(), которая позволит нам взаимодействовать с кубом по нажатию на клавиши-стрелки!

  • Именно ради этой функции мы объявляли глобальные переменные rotate_x и rotate_y. Когда мы будем нажимать на правую и левую клавишу-стрелку, значение rotate_y будет увеличиваться или уменьшаться на 5 градусов. Аналогичным образом будем меняться и значение rotate_x, но уже при нажатии на клавиши-стрелки “вверх” и “вниз”.
    
    void specialKeys( int key, int x, int y ) {
     
    //  Правая стрелка - увеличение вращения на 5 градусов
    if (key == GLUT_KEY_RIGHT)
      rotate_y += 5;
     
    //  Левая стрелка - уменьшение вращения на 5 градусов
    else if (key == GLUT_KEY_LEFT)
      rotate_y -= 5;
     
    else if (key == GLUT_KEY_UP)
      rotate_x += 5;
     
    else if (key == GLUT_KEY_DOWN)
      rotate_x -= 5;
     
    //  Запрос обновления экрана
    glutPostRedisplay();
     
    }
    
    

2) glRotate()

  • Последнее, что мы сделаем, так это добавим строку, которая позволит нам вращать объект. Вернитесь к функции display() и перед описанием ПЕРЕДНЕЙ стороны добавьте:
    
    // Сброс трансформаций
    glLoadIdentity();
     
    // Вращение при изменении пользователем значений rotate_x и rotate_y
    glRotatef( rotate_x, 1.0, 0.0, 0.0 );
    glRotatef( rotate_y, 0.0, 1.0, 0.0 );
     
    // Многоцветная сторона - ПЕРЕДНЯЯ
    ....
    
    
  • Обратите внимание на синтаксис glRotatef(), который схож с синтаксисом glColor3f() и glVertex3f(), но всегда требует указания 4 параметров. Первый - угол вращения в градусах. Следующие три - оси, по которым идет вращение, в порядке x > y > z. Пока что нам надо вращать куб по двум осям, x и у.

  • Для всех трансформаций, которые мы задаем в программе, требуются аналогичные строки. По сути, мы представляем вращение объекта по оси х как изменение значения rotate_x, а вращение по оси у - как изменение значения rotate_y. Впрочем, OpenGL объединит все в одну матрицу трансформации. Всякий раз, вызывая функцию display, мы будем создавать матрицу трансформации, и glLoadIdentity() позволит нам начинать каждый раз с новой матрицы.

  • Другие функции трансформации, которым мы могли воспользоваться, это glTranslatef() и glScalef(). Они аналогичны glRotatef(), но лишь с тем исключением, что требуют лишь 3 параметра: значения x, y и z для изменения и масштабирования объекта.

  • Чтобы все отображалось правильно, когда все три трансформации применены к одному объекту, нужно задавать трансформации в соответствующем порядке, а именно glTranslate, glRotate, glScale - и никогда иначе. OpenGL трансформирует объект, читая программу “снизу вверх”. Чтобы лучше это понять, представьте, как куб 1x1x1 будет выглядеть после всех трансформаций, если бы OpenGL применял их в том порядке, как те указаны (сверху вниз), а потом подумайте, как OpenGL обработает куб, читая инструкции снизу вверх.

  • Добавьте следующие команды для двухкратного масштабирования куба по осям х и у, для вращения куба на 180 градусов по оси у, а также для перемещения куба на 0.1 по оси х. Убедитесь, что все соответствующие команды, включая ранее заданные команды glRotate(), указаны в правильном порядке. Если боитесь ошибиться, смотрите финальную версию программы
    
    // Другие трансформации
    glTranslatef( 0.1, 0.0, 0.0 );
    glRotatef( 180, 0.0, 1.0, 0.0 );
    glScalef( 2.0, 2.0, 0.0 );
    
    

Компиляция

  • Чем заканчивается любой проект на OpenGL? Чем закончится ваш первый проект на OpenGL? Правильно, кнопкой compile and run your code (компилировать и запустить). Допустим, в качестве компилятора у вас gcc, поэтому введите в терминал следующие команды:
    
    На Linux:
    gcc cube.c -o cube -lglut -lGL
     
    ./ mycube
     
    На Mac:
    gcc -o foo foo.c -framework GLUT -framework OpenGL
    ./ mycube
     
    На Windows:
    gcc -Wall -ofoo foo.c -lglut32cu -lglu32 -lopengl32
    ./ mycube
    
    

Часть 4 Финальный код

  • Итак, свершилось! Готова ваша первая программа на OpenGL! Вот исходный код от автора статьи, в котором не переведены комментарии и все прочее.
    
    //
    // File:        mycube.c
    // Author:      Matt Daisley
    // Created:     4/25/2012
    // Project:     Source code for Make a Cube in OpenGL
    // Description: Creates an OpenGL window and draws a 3D cube
    //              That the user can rotate using the arrow keys
    // 
    // Controls:    Left Arrow  - Rotate Left
    //              Right Arrow - Rotate Right
    //              Up Arrow    - Rotate Up
    //              Down Arrow  - Rotate Down     
     
    // ----------------------------------------------------------
    // Includes
    // ----------------------------------------------------------
    #include <stdio.h>
    #include <stdarg.h>
    #include <math.h>
    #define GL_GLEXT_PROTOTYPES
    #ifdef __APPLE__
    #include <GLUT/glut.h>
    #else
    #include <GL/glut.h>
    #endif
     
    // ----------------------------------------------------------
    // Function Prototypes
    // ----------------------------------------------------------
    void display();
    void specialKeys();
     
    // ----------------------------------------------------------
    // Global Variables
    // ----------------------------------------------------------
    double rotate_y=0; 
    double rotate_x=0;
     
    // ----------------------------------------------------------
    // display() Callback function
    // ----------------------------------------------------------
    void display(){
     
      //  Clear screen and Z-buffer
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
     
      // Reset transformations
      glLoadIdentity();
     
      // Other Transformations
      // glTranslatef( 0.1, 0.0, 0.0 );      // Not included
      // glRotatef( 180, 0.0, 1.0, 0.0 );    // Not included
     
      // Rotate when user changes rotate_x and rotate_y
      glRotatef( rotate_x, 1.0, 0.0, 0.0 );
      glRotatef( rotate_y, 0.0, 1.0, 0.0 );
     
      // Other Transformations
      // glScalef( 2.0, 2.0, 0.0 );          // Not included
     
      //Multi-colored side - FRONT
      glBegin(GL_POLYGON);
     
      glColor3f( 1.0, 0.0, 0.0 );     glVertex3f(  0.5, -0.5, -0.5 );      // P1 is red
      glColor3f( 0.0, 1.0, 0.0 );     glVertex3f(  0.5,  0.5, -0.5 );      // P2 is green
      glColor3f( 0.0, 0.0, 1.0 );     glVertex3f( -0.5,  0.5, -0.5 );      // P3 is blue
      glColor3f( 1.0, 0.0, 1.0 );     glVertex3f( -0.5, -0.5, -0.5 );      // P4 is purple
     
      glEnd();
     
      // White side - BACK
      glBegin(GL_POLYGON);
      glColor3f(   1.0,  1.0, 1.0 );
      glVertex3f(  0.5, -0.5, 0.5 );
      glVertex3f(  0.5,  0.5, 0.5 );
      glVertex3f( -0.5,  0.5, 0.5 );
      glVertex3f( -0.5, -0.5, 0.5 );
      glEnd();
     
      // Purple side - RIGHT
      glBegin(GL_POLYGON);
      glColor3f(  1.0,  0.0,  1.0 );
      glVertex3f( 0.5, -0.5, -0.5 );
      glVertex3f( 0.5,  0.5, -0.5 );
      glVertex3f( 0.5,  0.5,  0.5 );
      glVertex3f( 0.5, -0.5,  0.5 );
      glEnd();
     
      // Green side - LEFT
      glBegin(GL_POLYGON);
      glColor3f(   0.0,  1.0,  0.0 );
      glVertex3f( -0.5, -0.5,  0.5 );
      glVertex3f( -0.5,  0.5,  0.5 );
      glVertex3f( -0.5,  0.5, -0.5 );
      glVertex3f( -0.5, -0.5, -0.5 );
      glEnd();
     
      // Blue side - TOP
      glBegin(GL_POLYGON);
      glColor3f(   0.0,  0.0,  1.0 );
      glVertex3f(  0.5,  0.5,  0.5 );
      glVertex3f(  0.5,  0.5, -0.5 );
      glVertex3f( -0.5,  0.5, -0.5 );
      glVertex3f( -0.5,  0.5,  0.5 );
      glEnd();
     
      // Red side - BOTTOM
      glBegin(GL_POLYGON);
      glColor3f(   1.0,  0.0,  0.0 );
      glVertex3f(  0.5, -0.5, -0.5 );
      glVertex3f(  0.5, -0.5,  0.5 );
      glVertex3f( -0.5, -0.5,  0.5 );
      glVertex3f( -0.5, -0.5, -0.5 );
      glEnd();
     
      glFlush();
      glutSwapBuffers();
     
    }
     
    // ----------------------------------------------------------
    // specialKeys() Callback Function
    // ----------------------------------------------------------
    void specialKeys( int key, int x, int y ) {
     
      //  Right arrow - increase rotation by 5 degree
      if (key == GLUT_KEY_RIGHT)
        rotate_y += 5;
     
      //  Left arrow - decrease rotation by 5 degree
      else if (key == GLUT_KEY_LEFT)
        rotate_y -= 5;
     
      else if (key == GLUT_KEY_UP)
        rotate_x += 5;
     
      else if (key == GLUT_KEY_DOWN)
        rotate_x -= 5;
     
      //  Request display update
      glutPostRedisplay();
     
    }
     
    // ----------------------------------------------------------
    // main() function
    // ----------------------------------------------------------
    int main(int argc, char argv[]){
     
      //  Initialize GLUT and process user parameters
      glutInit(&argc,argv);
     
      //  Request double buffered true color window with Z-buffer
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
     
      // Create window
      glutCreateWindow("Awesome Cube");
     
      //  Enable Z-buffer depth test
      glEnable(GL_DEPTH_TEST);
     
      // Callback functions
      glutDisplayFunc(display);
      glutSpecialFunc(specialKeys);
     
      //  Pass control to GLUT for events
      glutMainLoop();
     
      //  Return to OS
      return 0;
     
    }
    
    
Как фотографировать крещение ребенка. Как снимать крестины 82
Мастер класс. Как сшить римские шторы своими руками
Как фотографировать крещение ребенка. Как снимать крестины 60
Cached
Как фотографировать крещение ребенка. Как снимать крестины 33
Как сказать о любви красиво и необычно: «100 причин
Как фотографировать крещение ребенка. Как снимать крестины 36
Как отбелить белые вещи в домашних условиях: способы против
Как фотографировать крещение ребенка. Как снимать крестины 79
Новогодние поделки из бумаги своими руками: 60 схем
Как фотографировать крещение ребенка. Как снимать крестины 11
Три девушки на пляже в кабинке переодеваются
Как фотографировать крещение ребенка. Как снимать крестины 4
Как фотографировать крещение ребенка. Как снимать крестины 17
Как фотографировать крещение ребенка. Как снимать крестины 61
Как фотографировать крещение ребенка. Как снимать крестины 6
Как фотографировать крещение ребенка. Как снимать крестины 61
Как фотографировать крещение ребенка. Как снимать крестины 21
Как фотографировать крещение ребенка. Как снимать крестины 45
Как фотографировать крещение ребенка. Как снимать крестины 85
Как фотографировать крещение ребенка. Как снимать крестины 6
Как фотографировать крещение ребенка. Как снимать крестины 98