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

Вход на сайт

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

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

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

КРУГОВОЙ ФРАКТАЛ -ОШИБОЧНАЯ ПРОГРАММА! ПАПА ЗибЕрт
Можешь обяснить подробно что как работает, и почему массу не задаем
Здравствуйте, Ильгиз. Математика - царица наук (Карл Гаусс). Изучение математики начинается с детского сада, когда нас учат считать и выполнять простые арифметические операции. Любой, даже самый простейший алгоритм будет связан с арифметическими...
Я хотел узнать математика это обязательно в программирование. Пять лет назад просто из любопытства я увлекся HTML потом изучил CSS и JvaScript потом изучил PHP и Java. Как то не задумывался и начал смотреть форумы и узнал что без математики не...
Все верно, но так же необходимо зайти в: Компоновщик -> Ввод -> Дополнительные зависимости Здесь необходимо нажать изменить и в Дополнительные зависимости прописать это: SDL2.lib SDL2main.lib SDL2test.lib Без этого не заработает. (MVS 2015)

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

Яндекс.Метрика Рейтинг@Mail.ru
Скриншот к примеру
Среда программирования: 
Qt

Хотелось бы объяснить использование OpenGL в Qt для вращения трехмерной фигуры.
В данном примере приведен измененный код из статьи "Введение в OpenGL на Qt/C++" для отрисовки разноцветного икосаэдра.
Цвета задаются рандомно, а сама отрисовка производится через встроенные функции отрисовки по массивам координат.

Код программы: 

// widget.cpp
#include "widget.h"
 
GLfloat VerMas[12][3]; // массив вершин
GLubyte IndMas[20][3]; // массив индексов
GLfloat ClrMas[12][3]; // массив цветов граней
const static float pi=3.141593, k=pi/180;
 
Widget::Widget(QWidget *parent)
    : QGLWidget(parent)
{
    resize(300,300);
    xRotation = 0;
    yRotation = 0;
    zRotation = 0;
    scale = 1;
}
 
void Widget::initializeGL()
{
   // инициализация OpenGL
   qglClearColor(Qt::white);
   glEnable(GL_DEPTH_TEST);
   glShadeModel(GL_FLAT);
   glEnable(GL_CULL_FACE);
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
 
   initVerMas(); // инициализация массива вершин
   initColorMas(); // инициализация массива цветов
   initIndMas();  // инициализация массива индексов
 
   glEnableClientState(GL_VERTEX_ARRAY); // активизация массива вершин
   glEnableClientState(GL_COLOR_ARRAY);  // активизация массива цветов
}
 
void Widget::resizeGL(int nWidth, int nHeight)
{
    // что будем делать при изменении размера окна
    glViewport(0, 0, nHeight, nHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
}
 
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);
   // извлечение данных о массиве вершин
   glVertexPointer(3, GL_FLOAT, 0, VerMas);
   // извлечение данных о цветах
   glColorPointer(3, GL_FLOAT, 0, ClrMas);
   // построение поверхности, используя массив индексов
   glDrawElements(GL_TRIANGLES, 60, GL_UNSIGNED_BYTE, IndMas);
 
}
 
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::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();
}
 
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();
}
 
void Widget::initIndMas()   // массив индексов
{
   // задаем индексы каждого из треугольников
   IndMas[0][0]=0; // индекс первой вершины
   IndMas[0][1]=2; // индекс второй вершины
   IndMas[0][2]=1; // индекс третьей вершины
 
   IndMas[1][0]=0;
   IndMas[1][1]=3;
   IndMas[1][2]=2;
 
   IndMas[2][0]=0;
   IndMas[2][1]=4;
   IndMas[2][2]=3;
 
   IndMas[3][0]=0;
   IndMas[3][1]=5;
   IndMas[3][2]=4;
 
   IndMas[4][0]=0;
   IndMas[4][1]=1;
   IndMas[4][2]=5;
 
   IndMas[5][0]=6;
   IndMas[5][1]=1;
   IndMas[5][2]=7;
 
   IndMas[6][0]=7;
   IndMas[6][1]=1;
   IndMas[6][2]=2;
 
   IndMas[7][0]=7;
   IndMas[7][1]=2;
   IndMas[7][2]=8;
 
   IndMas[8][0]=8;
   IndMas[8][1]=2;
   IndMas[8][2]=3;
 
   IndMas[9][0]=8;
   IndMas[9][1]=3;
   IndMas[9][2]=9;
 
   IndMas[10][0]=9;
   IndMas[10][1]=3;
   IndMas[10][2]=4;
 
   IndMas[11][0]=9;
   IndMas[11][1]=4;
   IndMas[11][2]=10;
 
   IndMas[12][0]=10;
   IndMas[12][1]=4;
   IndMas[12][2]=5;
 
   IndMas[13][0]=10;
   IndMas[13][1]=5;
   IndMas[13][2]=6;
 
   IndMas[14][0]=6;
   IndMas[14][1]=5;
   IndMas[14][2]=1;
 
   IndMas[15][0]=7;
   IndMas[15][1]=11;
   IndMas[15][2]=6;
 
   IndMas[16][0]=8;
   IndMas[16][1]=11;
   IndMas[16][2]=7;
 
   IndMas[17][0]=9;
   IndMas[17][1]=11;
   IndMas[17][2]=8;
 
   IndMas[18][0]=10;
   IndMas[18][1]=11;
   IndMas[18][2]=9;
 
   IndMas[19][0]=6;
   IndMas[19][1]=11;
   IndMas[19][2]=10;
}
 
void Widget::initVerMas() // определить массив вершин
{
   GLfloat R=0.75; // радиус сферы
 
   // начальные значения
   GLfloat a=4*R/sqrt(10+2*sqrt(5)); // сторона икосаэдра
   GLfloat alpha=acos((1-a*a/2/R/R)); // первый угол поворота по тэта
 
   // точки икосаэдра
   VerMas[0][0]=0;   // x
   VerMas[0][1]=0;   // y
   VerMas[0][2]=R;   // z
 
   VerMas[1][0]=R*sin(alpha)*sin(0);
   VerMas[1][1]=R*sin(alpha)*cos(0);
   VerMas[1][2]=R*cos(alpha);
 
   VerMas[2][0]=R*sin(alpha)*sin(72*k);
   VerMas[2][1]=R*sin(alpha)*cos(72*k);
   VerMas[2][2]=R*cos(alpha);
 
   VerMas[3][0]=R*sin(alpha)*sin(2*72*k);
   VerMas[3][1]=R*sin(alpha)*cos(2*72*k);
   VerMas[3][2]=R*cos(alpha);
 
   VerMas[4][0]=R*sin(alpha)*sin(3*72*k);
   VerMas[4][1]=R*sin(alpha)*cos(3*72*k);
   VerMas[4][2]=R*cos(alpha);
 
   VerMas[5][0]=R*sin(alpha)*sin(4*72*k);
   VerMas[5][1]=R*sin(alpha)*cos(4*72*k);
   VerMas[5][2]=R*cos(alpha);
 
   VerMas[6][0]=R*sin(pi-alpha)*sin(-36*k);
   VerMas[6][1]=R*sin(pi-alpha)*cos(-36*k);
   VerMas[6][2]=R*cos(pi-alpha);
 
   VerMas[7][0]=R*sin(pi-alpha)*sin(36*k);
   VerMas[7][1]=R*sin(pi-alpha)*cos(36*k);
   VerMas[7][2]=R*cos(pi-alpha);
 
   VerMas[8][0]=R*sin(pi-alpha)*sin((36+72)*k);
   VerMas[8][1]=R*sin(pi-alpha)*cos((36+72)*k);
   VerMas[8][2]=R*cos(pi-alpha);
 
   VerMas[9][0]=R*sin(pi-alpha)*sin((36+2*72)*k);
   VerMas[9][1]=R*sin(pi-alpha)*cos((36+2*72)*k);
   VerMas[9][2]=R*cos(pi-alpha);
 
   VerMas[10][0]=R*sin(pi-alpha)*sin((36+3*72)*k);
   VerMas[10][1]=R*sin(pi-alpha)*cos((36+3*72)*k);
   VerMas[10][2]=R*cos(pi-alpha);
 
   VerMas[11][0]=0;
   VerMas[11][1]=0;
   VerMas[11][2]=-R;
}
 
void Widget::initColorMas() // задание цветов граней
{
   for (int i=0; i<12; i++)
   {
      // цвета генерируем рандомно
      ClrMas[i][0]=0.1f*(qrand()%10);
      ClrMas[i][1]=0.1f*(qrand()%10);
      ClrMas[i][2]=0.1f*(qrand()%10);
   }
}

Прикрепленный файлРазмер
openGL_qt.zip5.76 кб