Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: 8Observer8 от Сентябрь 05, 2014, 17:19



Название: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 05, 2014, 17:19
Привет!

Буду потихоньку переписывать примеры из SuperBible (3-го издания) на Qt и выкладывать здесь. Внизу этого сообщения прикрепил проект, в котором (грубо говоря) будет изменяться только содержимое файлов: Scene.h, Scene.cpp и название проекта.

Диск к книге (кроме исходников есть дополнительные материалы для самостоятельного разбора): http://rutracker.org/forum/viewtopic.php?t=742207

Отдельно исходники (внизу страницы) http://www.openglsuperbible.com/previous-editions/

Вот здесь переписывают уроки из SuperBible 6-ого издания: http://www.prog.org.ru/topic_27475_0.html

Инструменты
- Qt 5.3.2 for Windows 32-bit (MinGW 4.8.2, OpenGL, 737 MB)
- OS Win7

Содержание

Подготовка к разработке и создание нового проекта
- Установка Qt (http://www.prog.org.ru/index.php?topic=27563.msg200249#msg200249)
- Переключение Qt Creator'a на английский (http://www.prog.org.ru/index.php?topic=27563.msg200251#msg200251)
- Создание нового проекта (http://www.prog.org.ru/index.php?topic=27563.msg200255#msg200255)

Глава 2. Используя OpenGL
- Simple. Пустое окно (http://www.prog.org.ru/index.php?topic=27563.msg200257#msg200257)
- GLRect. Квадрат (http://www.prog.org.ru/index.php?topic=27563.msg200259#msg200259)
- Bounce. Анимированный квадрат (http://www.prog.org.ru/index.php?topic=27563.msg200260#msg200260)

Глава 3. Рисование в пространстве: геометрические примитивы и буферы
- Points. Вращение с помощью стрелок 3D-спирали из точек (http://www.prog.org.ru/index.php?topic=27563.msg200261#msg200261)
- Pointsz. Спираль, точки которой увеличиваются от минимально возможной по размеру до максимально возможной (http://www.prog.org.ru/index.php?topic=27563.msg200273#msg200273)
- Lines. Отображает набор линий, веером расходящихся по окружности (http://www.prog.org.ru/index.php?topic=27563.msg200278#msg200278)
- LStrips. Аппроксимация кривых прямолинейными отрезками (http://www.prog.org.ru/index.php?topic=27563.msg200279#msg200279)
- Linesw. Рисует линии переменной ширины (http://www.prog.org.ru/index.php?topic=27563.msg200289#msg200289)
- LStipple. Пунктирные линии (http://www.prog.org.ru/index.php?topic=27563.msg200319#msg200319)
- Triangle. Конус, составленный из вееров треугольников (http://www.prog.org.ru/index.php?topic=27563.msg200332#msg200332)
- PStipple (Polygin Stippling). Наложение на многоугольник монохромного растрового изображения 32x32 (фактура) (http://www.prog.org.ru/index.php?topic=27563.msg202000#msg202000)
- Star. Активизация и диактивизация отображения сторон многоугольников с помощью функции glEdgeFlag( GLboolean flag ) (http://www.prog.org.ru/index.php?topic=27563.msg202082#msg202082)
- Scissor. Вырезание прямоугольника, в котором выполняется визуализация (http://www.prog.org.ru/index.php?topic=27563.msg202126#msg202126)

Глава 4. Геометрические преобразования: конвейер


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 05, 2014, 17:24
Установка Qt

- Скачайте и установите: "Qt 5.3.1 for Windows 32-bit (MinGW 4.8.2, OpenGL, 735 MB)" отсюда: http://qt-project.org/downloads

Примечание. Когда перейдёте по ссылке выше, то там надо будет нажать "Show downloads"


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 05, 2014, 18:05
Переключение Qt Creator'a на английский

- Если у Вас Qt Creator на русском, то переключите на английский. Для этого выбираем в меню "Инструменты" -> "Параметры..."

- В окне "Параметры" слева выбираем "Среда" -> открываем вкладку "Основные" -> выбираем в выпадающем списке "English" -> нажимаем кнопку "OK" -> перезапускаем Qt Creator


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 05, 2014, 18:36
Создание нового проекта

- В меню Qt Creator'а выбираем "File" -> "New File or Project..."

- В разделе "Projects" выбираем "Applications" -> во второй колонке выбираем "Qt Widgets Application" -> нажимаем кнопку "Choose..."

- В поле "Name" пишем: Simple -> нажимаем кнопку "Browse..." и указываем путь, где будет создан наш проект -> нажимаем два раза кнопку "Next" и выбираем в списке "Base class" значение "QDialog" -> нажимаем последовательно: два раза "Next", "Finish"

- В разделе "Projects" кликаем правой кнопкой мыши по имени проекта и выбираем "Add new..." -> выбираем "C++" -> выбираем "C++ Class" -> нажимаем кнопку "Choose..."

- Вводим имя класса Scene ( соответствующие файлы должны называться: Scene.h и Scene.cpp ) -> нажимаем кнопку "Finish"

- Копируем содержимое файлов (лучше стараться набирать самому, так легче понять)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
#include "Scene.h"
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent )
{
}
 
void Scene::initializeGL()
{
   glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
}
 
void Scene::paintGL()
{
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
}
 

- Дважды кликаем по файлу "Simple.pro" и дописываем opengl, вот так:
Код
C++ (Qt)
QT       += core gui opengl
 

- Дважды кликаем по файлу "Dialog.ui" -> с левой панели перетаскиваем элемент "Widget" на форму

- Один раз кликаем на форму, чтобы выделить -> на панели инструментов (сверху) нажимаем кнопку с тремя горизонтальными голубыми чертами "Lay Out Vertically" (или Ctrl+L)

- Кликаем правой кнопкой мыши по элементу "Widget" -> выбираем "Promote to ..."

- В поле "Promoted class name" пишем: Scene -> нажимаем кнопку "Add" -> нажимаем кнопку "Promote"

- Запускаем приложение, для этого нажимаем зелёный треугольник слева внизу


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 09:20
02. Simple. Пустое окно

(http://i6.pixs.ru/storage/0/1/6/Simplepng_7047076_13715016.png)

Simple.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
};
 
#endif // SCENE_H
 

Simple.cpp
Код
C++ (Qt)
#include "Scene.h"
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent )
{
}
 
void Scene::initializeGL()
{
   glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
}
 
void Scene::paintGL()
{
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: Igors от Сентябрь 06, 2014, 12:00
Резкий переход от синего к красному - один из самых неприятных для человеческого глаза. Вообще использование красной заливки называется
Цитировать
дурачок красненькое любит
:)


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 13:40
02. GLRect. Квадрат

(http://i.pixs.ru/storage/4/8/8/GLRectpng_1482821_13715488.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
#include "Scene.h"
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent )
{
}
 
void Scene::initializeGL()
{
   glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
}
 
void Scene::paintGL()
{
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Set current drawing color to red
   //   R G   B
   glColor3f( 1.0f, 0.0f, 0.0f );
 
   // Draw a filled rectangle with current color
   glRectf( -25.0f, 25.0f, 25.0f, -25.0f );
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset coordinate system
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   GLfloat aspectRatio = ( GLfloat )w / ( GLfloat )h;
   if ( w <= h ) {
       glOrtho( -100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio,
                 1.0, -1.0);
   } else {
       glOrtho( -100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0,
                1.0, -1.0 );
   }
 
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 13:41
02. Bounce. Анимированный квадрат

(http://i6.pixs.ru/storage/8/6/4/Bouncepng_7771646_13715864.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QTimer>
 
class Scene : public QGLWidget
{
   Q_OBJECT
 
public:
   Scene( QWidget *parent = 0 );
 
private slots:
   void slotMoveRect();
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
private:
   // Square position and size
   GLfloat x;
   GLfloat y;
   GLfloat rsize;
 
   // Step size in x and y directions
   // (number of pixels to move each time)
   GLfloat xstep;
   GLfloat ystep;
 
   // Keep track of windows changing width and height
   GLfloat windowWidth;
   GLfloat windowHeight;
 
   // Timer
   QTimer *timer;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include "Scene.h"
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   x( 0.0f ),
   y( 0.0f ),
   rsize( 25.0f ),
   xstep( 1.0f ),
   ystep( 1.0f )
{
   timer = new QTimer( this );
   connect( timer, SIGNAL( timeout() ),
            this, SLOT( slotMoveRect() ) );
   timer->start( 33 );
}
 
void Scene::slotMoveRect()
{
   // Reverse direction when you reach left or right edge
   if( x > windowWidth - rsize || x < -windowWidth ) {
       xstep = -xstep;
   }
 
   // Reverse direction when you reach top or bottom edge
   if( y > windowHeight || y < -windowHeight + rsize ) {
       ystep = -ystep;
   }
 
   // Actually move the square
   x += xstep;
   y += ystep;
 
   // Check bounds. This is in case the window is made
   // smaller while the rectangle is bouncing and the
   // rectangle suddenly finds itself outside the new
   // clipping volume
   if( x > ( windowWidth-rsize + xstep ) ) {
       x = windowWidth - rsize - 1;
   } else if( x < -( windowWidth + xstep ) ) {
       x = -windowWidth - 1;
   }
 
   if( y > ( windowHeight + ystep ) ) {
       y = windowHeight - 1;
   } else if( y < -( windowHeight - rsize + ystep ) ) {
       y = -windowHeight + rsize - 1;
   }
 
   updateGL();
}
 
void Scene::initializeGL()
{
   glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
}
 
void Scene::paintGL()
{
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Set current drawing color to red
   glColor3f( 1.0f, 0.0f, 0.0f );
 
   // Draw a filled rectangle with current color
   glRectf( x, y, x + rsize, y - rsize );
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if ( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset coordinate system
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   GLfloat aspectRatio = ( GLfloat ) w / ( GLfloat ) h;
 
   if ( w <= h ) {
       windowWidth = 100.0f;
       windowHeight = 100.0f / aspectRatio;
       glOrtho( -100.0, 100.0, -windowHeight, windowHeight,
                1.0, -1.0 );
   } else {
       windowWidth = 100.0 * aspectRatio;
       windowHeight = 100.0;
       glOrtho( -windowWidth, windowWidth, -100.0, 100.0,
                1.0, -1.0 );
   }
 
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 13:41
03. Points. Вращение с помощью стрелок 3D-спирали из точек

(http://i6.pixs.ru/storage/6/3/2/Pointspng_7972066_13721632.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
}
 
void Scene::paintGL()
{
   // Storeage for coordinates and angles
   GLfloat x, y, z, angle;
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Call only once for all remaining points
   glBegin( GL_POINTS );
 
   z = -50.0f;
   for( angle = 0.0f; angle <= ( 2.0f * GL_PI ) * 3.0f; angle += 0.1f )
   {
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle  );
 
       // Specify the point and move the Z value up a little
       glVertex3f( x, y, z );
       z += 0.5f;
   }
 
   // Done drawing points
   glEnd();
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 15:51
Pointsz. Спираль, точки которой увеличиваются от минимально возможной по размеру до максимально возможной

(http://i.pixs.ru/storage/1/9/8/Pointszpng_6141483_13726198.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
}
 
void Scene::paintGL()
{
   GLfloat x, y, z, angle;    // Storeage for coordinates and angles
   GLfloat sizes[2];          // Store supported point size range
   GLfloat step;              // Store supported point size increments
   GLfloat curSize;           // Store current size
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Get supported point size range and step size
   glGetFloatv( GL_POINT_SIZE_RANGE, sizes );
   glGetFloatv( GL_POINT_SIZE_GRANULARITY, &step );
 
   // Set the initial point size
   curSize = sizes[0];
 
   // Set beginning z coordinate
   z = -50.0f;
 
   // Loop around in a circle three times
   for( angle = 0.0f; angle <= ( 2.0f * 3.1415f ) * 3.0f; angle += 0.1f ) {
       // Calculate x and y values on the circle
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle );
 
       // Specify the point size before the primative is specified
       glPointSize( curSize );
 
       // Draw the point
       glBegin( GL_POINTS );
       glVertex3f( x, y, z );
       glEnd();
 
       // Bump up the z value and the point size
       z += 0.5f;
       curSize += step;
   }
 
   // Restore matrix state
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: Igors от Сентябрь 06, 2014, 16:49
Pointsz. Спираль, точки которой увеличиваются от минимально возможной по размеру до максимально возможной
Браво, первое проявление хоть какого-то творчества. Только вот что ее ось растет так уныло - по прямой снизу вверх? Гораздо интереснее по кривой - ну или хотя бы по кругу. Радиус самой спирали уменьшить и использовать GL_LINES (вместо GL_POINTS).

[off]Безнадюга конечно - зубрилки таких задач не решают. Ну а вдруг?[/off]


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 17:16
Igors, если у вас ещё возникнут задачи, то пишите! Как у меня накопятся мысли, то я создам дополнительную побочную тему с примерами. Не хочется в этой дискутировать :)


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 20:00
03. Lines. Отображает набор линий, веером расходящихся по окружности

(http://i6.pixs.ru/storage/4/1/0/Linespng_5392890_13729410.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
}
 
void Scene::paintGL()
{
   // Storeage for coordinates and angles
   GLfloat x, y, z, angle;
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Call only once for all remaining points
   glBegin( GL_LINES );
 
   z = 0.0f;
   for( angle = 0.0f; angle <= GL_PI; angle += ( GL_PI / 20.0f ) ) {
       // Top half of the circle
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle );
       glVertex3f( x, y, z );
 
       // Bottom half of the circle
       x = 50.0f * sin( angle + GL_PI);
       y = 50.0f * cos( angle + GL_PI );
       glVertex3f( x, y, z );
   }
 
   // Done drawing points
   glEnd();
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 06, 2014, 21:43
03. LStrips. Аппроксимация кривых прямолинейными отрезками

(http://i7.pixs.ru/storage/5/5/0/LStripspng_9520698_13730550.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
}
 
void Scene::paintGL()
{
   // Storeage for coordinates and angles
   GLfloat x, y, z, angle;
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Call only once for all remaining points
   glBegin( GL_LINE_STRIP );
 
   z = -50.0f;
   for( angle = 0.0f; angle <= ( 2.0f*3.1415f )*3.0f; angle += 0.1f ) {
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle );
 
       // Specify the point and move the Z value up a little
       glVertex3f( x, y, z );
       z += 0.5f;
   }
 
   // Done drawing points
   glEnd();
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: Igors от Сентябрь 07, 2014, 08:47
Igors, если у вас ещё возникнут задачи, то пишите! Как у меня накопятся мысли, то я создам дополнительную побочную тему с примерами. Не хочется в этой дискутировать :)
Та что там жалкие 2 десятка строк дискутировать.


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 07, 2014, 13:48
03. Linesw. Рисует линии переменной ширины

(http://i6.pixs.ru/storage/3/5/4/Lineswpng_4075255_13737354.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
}
 
void Scene::paintGL()
{
   GLfloat y;                  // Storeage for varying Y coordinate
   GLfloat fCurrSize;          // Save current size
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Save the smallest value
   glGetFloatv( GL_LINE_WIDTH_GRANULARITY, &fCurrSize );
 
   // Step up Y axis 20 units at a time
   for( y = -90.0f; y < 90.0f; y += 20.0f ) {
       // Set the line width
       glLineWidth( fCurrSize );
 
       // Draw the line
       glBegin( GL_LINES );
       glVertex2f( -80.0f, y );
       glVertex2f( 80.0f, y );
       glEnd();
 
       // Increase the line width
       fCurrSize += 1.0f;
   }
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 08, 2014, 15:22
03. LStipple. Пунктирные линии

(http://i6.pixs.ru/storage/7/6/6/LStipplepn_9846018_13752766.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
   this->setFocusPolicy( Qt::StrongFocus );
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
 
   // Enable Stippling
   glEnable( GL_LINE_STIPPLE );
}
 
void Scene::paintGL()
{
   GLfloat y;                  // Storeage for varying Y coordinate
   GLint factor = 3;           // Stippling factor
   GLushort pattern = 0x5555;  // Stipple pattern
 
   // Clear the window with current clearing color
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Step up Y axis 20 units at a time
   for( y = -90.0f; y < 90.0f; y += 20.0f ) {
       // Reset the repeat factor and pattern
       glLineStipple( factor, pattern );
 
       // Draw the line
       glBegin( GL_LINES );
       glVertex2f( -80.0f, y );
       glVertex2f( 80.0f, y );
       glEnd();
 
       factor++;
   }
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Сентябрь 08, 2014, 19:09
03. Triangle. Конус, составленный из вееров треугольников

(http://i7.pixs.ru/storage/5/7/6/Trianglepn_8436321_13755576.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
   Q_OBJECT
 
public:
   Scene( QWidget *parent = 0 );
 
private slots:
   void slotShowContextMenu( const QPoint &pos );
 
private:
   void initializeGL();
   void paintGL();
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
 
   // Flags for effects
   int iCull;
   int iOutline;
   int iDepth;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include <QAbstractScrollArea>
#include <QMenu>
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f ),
   iCull( 0 ),
   iOutline( 0 ),
   iDepth( 0 )
{
   this->setFocusPolicy( Qt::StrongFocus );
   this->setContextMenuPolicy( Qt::CustomContextMenu );
 
   connect( this, SIGNAL( customContextMenuRequested( QPoint ) ),
            this, SLOT( slotShowContextMenu( QPoint ) ) );
}
 
void Scene::slotShowContextMenu(const QPoint &pos)
{
   QPoint globalPos;
   if ( sender()->inherits( "QAbstractScrollArea" ) ) {
       globalPos = ( ( QAbstractScrollArea* )sender() )->
               viewport()->mapToGlobal( pos );
   }
   else {
       globalPos = ( ( QWidget* )sender() )->mapToGlobal( pos );
   }
 
   QString depthTestText( "Toggle depth test" );
   QString cullBackfaceText( "Toggle cull backface" );
   QString outlineBackText( "Toggle outline back" );
 
   QMenu menu;
   QAction *actionDepthTest = new QAction( depthTestText, this );
   QAction *actionCullBackface = new QAction( cullBackfaceText, this );
   QAction *actionOutlineBack = new QAction( outlineBackText, this );
   menu.addAction( actionDepthTest );
   menu.addAction( actionCullBackface );
   menu.addAction( actionOutlineBack );
 
   QAction* selectedItem = menu.exec( globalPos );
 
   if ( selectedItem == 0 ) {
       return;
   }
 
   if ( selectedItem->text() == depthTestText ) {
       iDepth = !iDepth;
   } else if ( selectedItem->text() == cullBackfaceText ) {
       iCull = !iCull;
   } else if ( selectedItem->text() == outlineBackText ) {
       iOutline = !iOutline;
   }
}
 
void Scene::initializeGL()
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
 
   // Set color shading model to flat
   glShadeModel( GL_FLAT );
 
   // Clock wise wound polygons are front facing, this is reversed
   // because we are using triangle fans
   glFrontFace( GL_CW );
}
 
void Scene::paintGL()
{
   GLfloat x, y, angle;  // Storage for coordinates and angles
   int iPivot = 1;     // Used to flag alternating colors
 
   // Clear the window and the depth buffer
   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 
   // Turn culling on if flag is set
   if( iCull ) {
       glEnable( GL_CULL_FACE );
   } else {
       glDisable( GL_CULL_FACE );
   }
 
   // Enable depth testing if flag is set
   if( iDepth ) {
       glEnable( GL_DEPTH_TEST );
   } else {
       glDisable( GL_DEPTH_TEST );
   }
 
   // Draw back side as a polygon only, if flag is set
   if( iOutline ) {
       glPolygonMode( GL_BACK, GL_LINE );
   } else {
       glPolygonMode( GL_BACK, GL_FILL );
   }
 
   // Save matrix state and do the rotation
   glPushMatrix();
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Begin a triangle fan
   glBegin( GL_TRIANGLE_FAN );
 
   // Pinnacle of cone is shared vertex for fan, moved up Z axis
   // to produce a cone instead of a circle
   glVertex3f( 0.0f, 0.0f, 75.0f );
 
   // Loop around in a circle and specify even points along the circle
   // as the vertices of the triangle fan
   for( angle = 0.0f; angle < ( 2.0f*GL_PI ); angle += ( GL_PI/8.0f ) ) {
       // Calculate x and y position of the next vertex
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle );
 
       // Alternate color between red and green
       if( ( iPivot %2 ) == 0 ) {
           glColor3f(0.0f, 1.0f, 0.0f);
       } else {
           glColor3f(1.0f, 0.0f, 0.0f);
       }
 
       // Increment pivot to change color next time
       iPivot++;
 
       // Specify the next vertex for the triangle fan
       glVertex2f( x, y );
   }
 
   // Done drawing fan for cone
   glEnd();
 
   // Begin a new triangle fan to cover the bottom
   glBegin( GL_TRIANGLE_FAN );
 
   // Center of fan is at the origin
   glVertex2f( 0.0f, 0.0f );
   for(angle = 0.0f; angle < ( 2.0f*GL_PI ); angle += ( GL_PI/8.0f ) ) {
       // Calculate x and y position of the next vertex
       x = 50.0f * sin( angle );
       y = 50.0f * cos( angle );
 
       // Alternate color between red and green
       if( ( iPivot %2 ) == 0 ) {
           glColor3f( 0.0f, 1.0f, 0.0f );
       } else {
           glColor3f( 1.0f, 0.0f, 0.0f );
       }
 
       // Increment pivot to change color next time
       iPivot++;
 
       // Specify the next vertex for the triangle fan
       glVertex2f( x, y );
   }
 
   // Done drawing the fan that covers the bottom
   glEnd();
 
   // Restore transformations
   glPopMatrix();
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho ( -nRange, nRange, -nRange*h/w, nRange*h/w,
                 -nRange, nRange );
   } else {
       glOrtho ( -nRange*w/h, nRange*w/h, -nRange, nRange,
                 -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key() ) {
   case Qt::Key_Up:
       xRot -= 5.0f;
       break;
   case Qt::Key_Down:
       xRot += 5.0f;
       break;
   case Qt::Key_Left:
       yRot -= 5.0f;
       break;
   case Qt::Key_Right:
       yRot += 5.0f;
       break;
   }
 
   if( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if( yRot > 356.0f) {
       yRot = 0.0f;
   }
 
   if( yRot < -1.0f) {
       yRot = 355.0f;
   }
 
   updateGL();
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Октябрь 13, 2014, 07:39
03. PStipple (Polygin Stippling). Наложение на многоугольник монохромного растрового изображения 32x32 (фактура)

(http://i6.pixs.ru/storage/8/7/6/393png_3102039_14240876.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
   Q_OBJECT
 
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL( );
   void paintGL( );
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
 
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
// Bitmap of camp fire
GLubyte fire[128] = { 0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0x00,
                     0x00, 0x00, 0x00, 0xc0,
                     0x00, 0x00, 0x01, 0xf0,
                     0x00, 0x00, 0x07, 0xf0,
                     0x0f, 0x00, 0x1f, 0xe0,
                     0x1f, 0x80, 0x1f, 0xc0,
                     0x0f, 0xc0, 0x3f, 0x80,
                     0x07, 0xe0, 0x7e, 0x00,
                     0x03, 0xf0, 0xff, 0x80,
                     0x03, 0xf5, 0xff, 0xe0,
                     0x07, 0xfd, 0xff, 0xf8,
                     0x1f, 0xfc, 0xff, 0xe8,
                     0xff, 0xe3, 0xbf, 0x70,
                     0xde, 0x80, 0xb7, 0x00,
                     0x71, 0x10, 0x4a, 0x80,
                     0x03, 0x10, 0x4e, 0x40,
                     0x02, 0x88, 0x8c, 0x20,
                     0x05, 0x05, 0x04, 0x40,
                     0x02, 0x82, 0x14, 0x40,
                     0x02, 0x40, 0x10, 0x80,
                     0x02, 0x64, 0x1a, 0x80,
                     0x00, 0x92, 0x29, 0x00,
                     0x00, 0xb0, 0x48, 0x00,
                     0x00, 0xc8, 0x90, 0x00,
                     0x00, 0x85, 0x10, 0x00,
                     0x00, 0x03, 0x00, 0x00,
                     0x00, 0x00, 0x10, 0x00 };
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f )
{
}
 
void Scene::initializeGL( )
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 1.0f, 0.0f, 0.0f );
 
   // Enable polygon stippling
   glEnable( GL_POLYGON_STIPPLE );
 
   // Specify a specific stipple pattern
   glPolygonStipple( fire );
}
 
void Scene::paintGL( )
{
   // Clear the window
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Save matrix state and do the rotation
   glPushMatrix( );
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Begin the stop sign shape,
   // use a standard polygon for simplicity
   glBegin( GL_POLYGON );
   glVertex2f( -20.0f, 50.0f );
   glVertex2f( 20.0f, 50.0f );
   glVertex2f( 50.0f, 20.0f );
   glVertex2f( 50.0f, -20.0f );
   glVertex2f( 20.0f, -50.0f );
   glVertex2f( -20.0f, -50.0f );
   glVertex2f( -50.0f, -20.0f );
   glVertex2f( -50.0f, 20.0f );
   glEnd( );
 
   // Restore transformations
   glPopMatrix( );
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if ( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity( );
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho( -nRange, nRange, -nRange * h / w, nRange * h / w,
                -nRange, nRange );
   } else {
       glOrtho( -nRange * w / h, nRange * w / h, -nRange, nRange,
                -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity( );
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key( ) ) {
       case Qt::Key_Up:
           xRot -= 5.0f;
           break;
       case Qt::Key_Down:
           xRot += 5.0f;
           break;
       case Qt::Key_Left:
           yRot -= 5.0f;
           break;
       case Qt::Key_Right:
           yRot += 5.0f;
           break;
   }
 
   if ( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if ( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if ( yRot > 356.0f ) {
       yRot = 0.0f;
   }
 
   if ( yRot < -1.0f ) {
       yRot = 355.0f;
   }
 
   updateGL( );
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Октябрь 14, 2014, 14:06
03. Star. Активизация и диактивизация отображения сторон многоугольников с помощью функции glEdgeFlag( GLboolean flag )

(http://i6.pixs.ru/storage/7/4/2/394png_7836987_14259742.png)

(http://i6.pixs.ru/storage/9/1/1/395png_2245519_14259911.png)

(http://i6.pixs.ru/storage/9/1/9/396png_3039667_14259919.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
#include <QKeyEvent>
 
class Scene : public QGLWidget
{
   Q_OBJECT
 
public:
   Scene( QWidget *parent = 0 );
 
private slots:
   void slotShowContextMenu( const QPoint &pos );
 
private:
   void initializeGL( );
   void paintGL( );
   void resizeGL( int w, int h );
 
   void keyPressEvent( QKeyEvent *event );
 
private:
   // Rotation amounts
   GLfloat xRot;
   GLfloat yRot;
 
   int iMode;
   GLboolean bEdgeFlag;
 
   // Flags for effects
   int iCull;
   int iOutline;
   int iDepth;
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
#include <QAbstractScrollArea>
#include <QMenu>
#include <math.h>
#include "Scene.h"
 
// Define a constant for the value of PI
#define GL_PI 3.1415f
 
// Flags for effects
#define MODE_SOLID 0
#define MODE_LINE  1
#define MODE_POINT 2
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent ),
   xRot( 0.0f ),
   yRot( 0.0f ),
   iCull( 0 ),
   iOutline( 0 ),
   iDepth( 0 )
{
   iMode = MODE_SOLID;
   bEdgeFlag = TRUE;
 
   this->setFocusPolicy( Qt::StrongFocus );
   this->setContextMenuPolicy( Qt::CustomContextMenu );
 
   connect( this, SIGNAL( customContextMenuRequested( QPoint ) ),
            this, SLOT( slotShowContextMenu( QPoint ) ) );
}
 
void Scene::slotShowContextMenu( const QPoint &pos )
{
   QPoint globalPos;
   if ( sender( )->inherits( "QAbstractScrollArea" ) ) {
       globalPos = ( ( QAbstractScrollArea* ) sender( ) )->
                   viewport( )->mapToGlobal( pos );
   } else {
       globalPos = ( ( QWidget* ) sender( ) )->mapToGlobal( pos );
   }
 
   QString solidText( "Solid" );
   QString outlineText( "Outline" );
   QString pointsText( "Points" );
 
   QString onEdgesText( "On" );
   QString offEdgesText( "Off" );
 
   QMenu *menu = new QMenu( );
   QAction *solidAction = new QAction( solidText, this );
   QAction *outlineAction = new QAction( outlineText, this );
   QAction *pointsAction = new QAction( pointsText, this );
   QAction *onEdgesAction = new QAction( onEdgesText, this );
   QAction *offEdgesAction = new QAction( offEdgesText, this );
 
   QMenu *modeSubmenu = menu->addMenu( "Mode" );
   QMenu *edgesSubmenu = menu->addMenu( "Edges" );
   modeSubmenu->addAction( solidAction );
   modeSubmenu->addAction( outlineAction );
   modeSubmenu->addAction( pointsAction );
   edgesSubmenu->addAction( onEdgesAction );
   edgesSubmenu->addAction( offEdgesAction );
 
   QAction* selectedItem = menu->exec( globalPos );
 
   if ( selectedItem == 0 ) {
       return;
   }
 
   if ( selectedItem->text( ) == solidText ) {
       iMode = MODE_SOLID;
   } else if ( selectedItem->text( ) == outlineText ) {
       iMode = MODE_LINE;
   } else if ( selectedItem->text( ) == pointsText ) {
       iMode = MODE_POINT;
   } else if ( selectedItem->text( ) == onEdgesText ) {
       bEdgeFlag = TRUE;
   } else if ( selectedItem->text( ) == offEdgesText ) {
       bEdgeFlag = FALSE;
   }
}
 
void Scene::initializeGL( )
{
   // Black background
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
 
   // Set drawing color to green
   glColor3f( 0.0f, 1.0f, 0.0f );
 
   // Set color shading model to flat
   glShadeModel( GL_FLAT );
 
   // Clock wise wound polygons are front facing, this is reversed
   // because we are using triangle fans
   glFrontFace( GL_CW );
}
 
void Scene::paintGL( )
{
   // Clear the window
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Draw back side as a polygon only, if flag is set
   if ( iMode == MODE_LINE )
       glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
 
   if ( iMode == MODE_POINT )
       glPolygonMode( GL_FRONT_AND_BACK, GL_POINT );
 
   if ( iMode == MODE_SOLID )
       glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
 
   // Save matrix state and do the rotation
   glPushMatrix( );
   glRotatef( xRot, 1.0f, 0.0f, 0.0f );
   glRotatef( yRot, 0.0f, 1.0f, 0.0f );
 
   // Begin the triangles
   glBegin( GL_TRIANGLES );
 
   glEdgeFlag( bEdgeFlag );
   glVertex2f( -20.0f, 0.0f );
   glEdgeFlag( TRUE );
   glVertex2f( 20.0f, 0.0f );
   glVertex2f( 0.0f, 40.0f );
 
   glVertex2f( -20.0f, 0.0f );
   glVertex2f( -60.0f, -20.0f );
   glEdgeFlag( bEdgeFlag );
   glVertex2f( -20.0f, -40.0f );
   glEdgeFlag( TRUE );
 
   glVertex2f( -20.0f, -40.0f );
   glVertex2f( 0.0f, -80.0f );
   glEdgeFlag( bEdgeFlag );
   glVertex2f( 20.0f, -40.0f );
   glEdgeFlag( TRUE );
 
   glVertex2f( 20.0f, -40.0f );
   glVertex2f( 60.0f, -20.0f );
   glEdgeFlag( bEdgeFlag );
   glVertex2f( 20.0f, 0.0f );
   glEdgeFlag( TRUE );
 
   // Center square as two triangles
   glEdgeFlag( bEdgeFlag );
   glVertex2f( -20.0f, 0.0f );
   glVertex2f( -20.0f, -40.0f );
   glVertex2f( 20.0f, 0.0f );
 
   glVertex2f( -20.0f, -40.0f );
   glVertex2f( 20.0f, -40.0f );
   glVertex2f( 20.0f, 0.0f );
   glEdgeFlag( TRUE );
 
   // Done drawing Triangles
   glEnd( );
 
   // Restore transformations
   glPopMatrix( );
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if ( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity( );
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho( -nRange, nRange, -nRange * h / w, nRange * h / w,
                -nRange, nRange );
   } else {
       glOrtho( -nRange * w / h, nRange * w / h, -nRange, nRange,
                -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity( );
}
 
void Scene::keyPressEvent( QKeyEvent *event )
{
   switch ( event->key( ) ) {
       case Qt::Key_Up:
           xRot -= 5.0f;
           break;
       case Qt::Key_Down:
           xRot += 5.0f;
           break;
       case Qt::Key_Left:
           yRot -= 5.0f;
           break;
       case Qt::Key_Right:
           yRot += 5.0f;
           break;
   }
 
   if ( xRot > 356.0f ) {
       xRot = 0.0f;
   }
 
   if ( xRot < -1.0f ) {
       xRot = 355.0f;
   }
 
   if ( yRot > 356.0f ) {
       yRot = 0.0f;
   }
 
   if ( yRot < -1.0f ) {
       yRot = 355.0f;
   }
 
   updateGL( );
}
 


Название: Re: Примеры из SuperBible (3-го издания) на Qt
Отправлено: 8Observer8 от Октябрь 14, 2014, 19:24
03. Scissor. Вырезание прямоугольника, в котором выполняется визуализация

(http://img.pixs.ru/storage/5/5/8/397png_8606728_14264558.png)

Scene.h
Код
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
 
#include <QGLWidget>
 
class Scene : public QGLWidget
{
   Q_OBJECT
 
public:
   Scene( QWidget *parent = 0 );
 
private:
   void initializeGL( );
   void paintGL( );
   void resizeGL( int w, int h );
};
 
#endif // SCENE_H
 

Scene.cpp
Код
C++ (Qt)
#include <QAbstractScrollArea>
#include <QMenu>
#include <math.h>
#include "Scene.h"
 
Scene::Scene( QWidget *parent ) :
   QGLWidget( parent )
{
}
 
void Scene::initializeGL( )
{
}
 
void Scene::paintGL( )
{
   // Clear blue window
   glClearColor( 0.0f, 0.0f, 1.0f, 0.0f );
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Now set scissor to smaller red sub region
   glClearColor( 1.0f, 0.0f, 0.0f, 0.0f );
   glScissor( 100, 100, 600, 400 );
   glEnable( GL_SCISSOR_TEST );
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Finally, an even smaller green rectangle
   glClearColor( 0.0f, 1.0f, 0.0f, 0.0f );
   glScissor( 200, 200, 400, 200 );
   glClear( GL_COLOR_BUFFER_BIT );
 
   // Turn scissor back off for next render
   glDisable( GL_SCISSOR_TEST );
}
 
void Scene::resizeGL( int w, int h )
{
   // Prevent a divide by zero
   if ( h == 0 ) {
       h = 1;
   }
 
   // Set Viewport to window dimensions
   glViewport( 0, 0, w, h );
 
   // Reset projection matrix stack
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity( );
 
   GLfloat nRange = 100.0f;
 
   // Establish clipping volume (left, right, bottom, top, near, far)
   if ( w <= h ) {
       glOrtho( -nRange, nRange, -nRange * h / w, nRange * h / w,
                -nRange, nRange );
   } else {
       glOrtho( -nRange * w / h, nRange * w / h, -nRange, nRange,
                -nRange, nRange );
   }
 
   // Reset Model view matrix stack
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity( );
}