Введение в 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.zip | 2.33 кб |