На этом шаге рассмотрим простой пример OpenGL-программы в Qt.
На рис. 1 показано приложение, которое отображает четырехугольник с вершинами разного цвета, со сглаживанием.
Рис.1. Сглаживание цветов вершин четырехугольника
Рассморим некотрые особенности данного приложения. В проектном файле в опции Qt указан параметр opengl. Это нужно для того, чтобы во время компоновки программы подсоединялся модуль QtOpenGL.
TEMPLATE = app QT += opengl HEADERS = OGLQuad.h SOURCES = OGLQuad.cpp \ main.cpp win32:TARGET = ../OGLQuad
В файле main.cpp создается объект класса OGLQuad, унаследованный от класса QGLWidget.
#include <QApplication> #include "OGLQuad.h" int main(int argc, char** argv) { QApplication app(argc, argv); app.setApplicationDisplayName("Пример OpenGL-программы"); OGLQuad oglQuad; oglQuad.resize(200, 200); oglQuad.show(); return app.exec(); }
В заголовочном файле OGLQuad.h класс OGLQuad определяется как класс, наследующий QGLWidget, в котором переопределены три метода: initializeGL(), resizeGL() и paintGL().
#ifndef _OGLQuad_h_ #define _OGLQuad_h_ #include <QGLWidget> class OGLQuad : public QGLWidget { protected: virtual void initializeGL( ); virtual void resizeGL (int nWidth, int nHeight); virtual void paintGL ( ); public: OGLQuad(QWidget* pwgt = 0); }; #endif //_OGLQuad_h_
Рассмотрим реализацию методов (файл OGLQuad.cpp):
#include "OGLQuad.h" /*Конструктор не имеет реализации, он передает указатель на объект предка pwgt конструктору наследуемого класса*/ OGLQuad::OGLQuad(QWidget* pwgt/*= 0*/) : QGLWidget(pwgt) { } /*virtual*/void OGLQuad::initializeGL() { qglClearColor(Qt::black);/*устанавливается цвет для очистки буфера изображения. Qt автоматически конвертирует значения QColor в цвета OpenGL, чтобы обеспечить разработчикам единообразный подход для разработки приложения. В OpenGL цвет очистки устанавливается при помощи функции glClearColor(). Использование метода qglClearColor() вместо этой функции дает возможность передавать цвета в объектах класса QColor.*/ } /*virtual*/void OGLQuad::resizeGL(int nWidth, int nHeight) { glMatrixMode(GL_PROJECTION);/*функция устанавливает матрицу проектирования текущей матрицей. Это означает, что все последующие преобразования будут влиять только на нее*/ glLoadIdentity();/*вызовом данной функции текущая матрица устанавливается в единичную. В OpenGL существуют две матрицы, применяющиеся для преобразования координат. Первая — матрица моделирования (modelview matrix) — служит для задания положения объекта и его ориентации, а вторая — матрица проектирования (projection matrix) — отвечает за выбранный способ проектирования. Способ проектирования может быть либо ортогональным, либо перспективным*/ glViewPort(0, 0, (GLint)nWidth, (GLint)nHeight);/*вызовом данной функции устанавливается видовое окно, представляющее собой прямоугольную область в пределах окна виджета (окно в окне). Наше видовое окно совпадает со всей областью виджета*/ glOrtho(0, 100, 100, 0, -1, 1);/*соотношение сторон видового окна задается параметрами данной функции. Первый и второй параметры задают положения левой и правой отсекающих плоскостей, третий и четвертый — верхней и нижней отсекающих плоскостей, пятый и шестой — передней и задней отсекающих плоскостей, соответственно*/ } /*virtual*/void OGLQuad::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/*перед формированием нового изображения нужно функцией glClear() очистить буферы изображения (GL_COLOR_BUFFER_BIT) и глубины (GL_DEPTH_BUFFER_BIT). Последний служит для удаления невидимых поверхностей. Для очистки буфера изображения будет использован цвет, установленный методом qglColor()*/ glBegin(GL_QUADS);/*единица информации OpenGL — вершина. Из вершин строятся сложные объекты, при создании которых нужно указать, каким образом они должны быть соединены друг с другом. Способом соединения вершин управляет функция glBegin(). Флаг GL_QUADS говорит о том, что на создаваемых вершинах должен быть построен четырехугольник*/ glColor3f(1, 0, 0); //при помощи функции glColor*() задается текущий glVertex2f(0, 0); //цвет, который распространяется на последующие //вызовы функции glVertex*() задающих расположение glColor3f(0, 1,0); //вершин. Функции задания вершин должны всегда glVertex2f(100, 0); //находиться между glBegin() и glEnd(). В нашем //примере каждая вершина имеет свой цвет, и, glColor3f(0, 0, 1); //поскольку по умолчанию в OpenGL включен режим glVertex2f(100, 100);//сглаживания цветов, приводит к созданию радужной //окраски области прямоугольника. Режимом glColor3f(1, 1, 1); //сглаживания цветов управляет функция glVertex2f(0, 100); //glShadeModel(). Ее вызов с флагом GL_FLAT //отключает режим сглаживания, а передача флага glEnd(); //GL_SMOOTH включает его }
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим графические примитивы OpenGL.