Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Я код на C++ набрал сам. Строил кривую Безье, но "прилипал" к нулю. То есть я задаю точки далеко от нуля, а он строил из нуля, а потом только обходил предложенные точки. Потом я нашёл Ваш сайт и эту статью. Оказалось, что я забыл возвести t в...
просто я не так понял, здесь мы вращаем точки куба что вращает сам куб. Мне нужно вращать просто 3д объект , данный способ не подходит
Задавайте объект в мировых координатах. Вращайте его относительно мировой системы координат. А при отрисовке преобразуйте в экранные координаты. Посмотрите пример преобразования в экранные координаты.
Это вращение по мировым осям ? Если да то как сделать по осям объекта ?
Добрый вечер! Область прорисовки остается пустой. Чего-то не хватает. Объясните плз, чего? Рамиль.

Счетчики и рейтинг

Рейтинг@Mail.ru
Среда программирования: 
Qt

Введение в OpenGL на Qt/C++. Часть 2.

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

Все действия (масштабирование, вращение) будут производиться с помощью мышки, поэтому нам надо переопределить некоторые методы событий для работы с мышкой, поэтому в файл widget.h добавим следующие строки:

void mousePressEvent(QMouseEvent* pe);   // нажатие на клавишу мыши
void mouseMoveEvent(QMouseEvent* pe);    // перемещение мыши
void mouseReleaseEvent(QMouseEvent* pe); // отжатие клавиши мыши
void wheelEvent(QWheelEvent *);          // вращение колесика

Еще нам надо определить некоторые переменные в нашем классе:

int xRotation,yRotation,zRotation,scale; // переменные поворота и масштаба
QPoint mousePos; // переменная для запоминания позиции нажатия мышки

Теперь приведем реализацию этих методов:

void Widget::mousePressEvent(QMouseEvent* pe) // нажатие клавиши мыши
{
   // запоминаем координату нажатия мыши
   mousePos = pe->pos();
}

void Widget::mouseMoveEvent(QMouseEvent* pe) // изменение положения стрелки мыши
{
   xRotation += 180/scale*(GLfloat)(pe->y()-mousePos.y())/height(); // вычисляем углы поворота
   zRotation += 180/scale*(GLfloat)(pe->x()-mousePos.x())/width();
 
   mousePos = pe->pos();
 
   updateGL(); // обновляем изображение
}

void Widget::mouseReleaseEvent(QMouseEvent *pe)
{
}

void Widget::wheelEvent(QWheelEvent* pe) // вращение колёсика мыши
{
    // если колесико вращаем вперед -- умножаем переменную масштаба на 1.1
    // иначе -- делим на 1.1
    if ((pe->delta())>0) scale*=1.1; else if ((pe->delta())<0) scale/=1.1;
 
    updateGL();
}

Для удобства осознания положения фигуры в 3d пространстве, добавим отрисовку второго квадрата, расположенного напротив первого квадрата, и оси х,у,z.
Второй квадрат задается точно так же как и первой, за исключением некоторых координат:

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);

Вынесем отрисовку осей в отдельную функцию:

void Widget::drawAxis()
{
    glLineWidth(3.0f); // устанавливаем ширину линии
 
    glColor4f(1.00f, 0.00f, 0.00f, 1.0f); // устанавливается цвет последующих линий
    // ось x
    glBegin(GL_LINES); // построение линии
        glVertex3f( 1.0f,  0.0f,  0.0f); // первая точка
        glVertex3f(-1.0f,  0.0f,  0.0f); // вторая точка
    glEnd();
 
    QColor halfGreen(0, 128, 0, 255);
    qglColor(halfGreen);
    glBegin(GL_LINES);
        // ось y
        glVertex3f( 0.0f,  1.0f,  0.0f);
        glVertex3f( 0.0f, -1.0f,  0.0f);
 
        glColor4f(0.00f, 0.00f, 1.00f, 1.0f);
        // ось z
        glVertex3f( 0.0f,  0.0f,  1.0f);
        glVertex3f( 0.0f,  0.0f, -1.0f);
    glEnd();
}

Таким образом, мы научились изменять переменные поворота и масштаба, добавили функцию отрисовки осей, осталось только задействовать это всё в методе paintGL(), который мы реализовывали в прошлом уроке.
Теперь paintGL принимает следующий вид:

void Widget::paintGL() // рисование
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очистка буфера изображения и глубины
 
   glMatrixMode(GL_MODELVIEW); // устанавливает положение и ориентацию матрице моделирования
   glLoadIdentity();           // загружает единичную матрицу моделирования
 
   glScalef(scale, scale, scale);        // масштабирование
   glRotatef(xRotation, 1.0f, 0.0f, 0.0f); // поворот по X
   glRotatef(yRotation, 0.0f, 1.0f, 0.0f); // поворот по Y
   glRotatef(zRotation, 0.0f, 0.0f, 1.0f); // поворот по Z
 
   drawAxis();
 
   QColor clr(128, 128, 0, 255);
   qglColor(clr);
   glBegin(GL_QUADS);
   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);
 
   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();
}

Несложно заметить, что начать использовать OpenGL под Qt/C++ -- совсем легко. Я надеюсь, что данные уроки помогут людям понять это, и они начнут программировать с использованием Qt.

Примеры работы программы:


Прикрепленный файлРазмер
KatyaOGL_pt2.zip2.33 кб