На этом шаге рассмотрим графические примитивы OpenGL.
OpenGL предоставляет средства для рисования графических примитивов, таких как точки, линии, ломаные и полигоны, которые задаются одной или несколькими вершинами. Для этого необходимо передать список вершин. Окно программы, показанное на рис. 1, отображает различные фигуры, построенные на одних и тех же вершинах.
Рис.1. Отображение фигур
Описываем класс OGLDraw, который наследуется от класса QGLWidget и перезаписывает три его виртуальных метода: initializeGL(), resizeGL() и paintGL(). В классе определяем метод draw(), получающий координаты х и y, с которых нужно начинать строить фигуру. Тип фигуры задается третьим параметром.
class OGLDraw : public QGLWidget { protected: virtual void initializeGL( ); virtual void resizeGL (int nWidth, int nHeight); virtual void paintGL ( ); public: OGLDraw(QWidget* pwgt = 0); void draw(int xOffset, int yOffset, GLenum type); };
Рассмотрим реализацию данных методов:
/*конструктор класса OGLDraw, который не выполняет никаких действий, а просто передает указатель на объект-предок в конструктор класса QGLWidget*/ OGLDraw::OGLDraw(QWidget* pwgt/*= 0*/) : QGLWidget(pwgt) { } /*virtual*/void OGLDraw::initializeGL() { //устанавливается белый цвет для очистки буфера изображения qglClearColor(Qt::white); } //действия метода resizeGL() аналогичны действиям, рассмотренным в шаге 245 /*virtual*/void OGLDraw::resizeGL(int nWidth, int nHeight) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, (GLint)nWidth, (GLint)nHeight); glOrtho(0, 400, 200, 0, -1, 1); } /*virtual*/void OGLDraw::paintGL() { //очистка буферов изображения и глубины glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*в метод draw() передаются координаты x и y, с которых будет начинаться рисование фигуры. Тип фигуры передается третьим параметром*/ draw(0, 0, GL_POINTS); //отображаются только точки draw(100, 0, GL_TRIANGLES);//каждые три вершины задают треугольник draw(200, 0, GL_TRIANGLE_STRIP);/*задает треугольники с общей стороной. Каждая вершина, начиная с третьей, комбинируется с двумя предыдущими и определяет очередную ячейку*/ draw(300, 0, GL_LINE_LOOP);/*задает ломаную линию, последняя ее точка соединяется с первой*/ draw(0, 100, GL_LINE_STRIP);/*задает ломаную линию и используется, в основном, для аппроксимации кривых. Если требуется получить замкнутый контур, то нужно указать одну и ту же вершину в начале и в конце серии вершин*/ draw(100, 100, GL_QUADS);//каждые четыре вершины задают четырехугольник draw(200, 100, GL_POLYGON);//задает многоугольник draw(300, 100, GL_LINES);/*каждая пара вершин задает отрезки, которые, как правило, не соединяются друг с другом*/ } /*метод draw() осуществляет построение фигуры заданного типа type с позиции, определяемой переданными координатами*/ void OGLDraw::draw(int xOffset, int yOffset, GLenum type) { int n = 8; glPointSize(4);//задает размер точки glBegin(type); glColor3f(0.75,0.25,0.5);//устанавливает черный цвет для вершин for (int i = 0; i < n; ++i) { float fAngle = 2 * 3.14 * i / n; int x = (int)(50 + cos(fAngle) * 40 + xOffset); int y = (int)(50 + sin(fAngle) * 40 + yOffset); glVertex2f(x, y);//задает расположение вершин } glEnd(); }
Файлы приложения можно взять здесь.
На следующем шаге рассмотрим пример трехметной графики в Qt.