Добавил 1/8/2015 Мои видео-уроки:
001 Qt C++ OpenGL GLSL Рисуем треугольникПривет!
Пример представляет из себя медленно падающий квадрат, который мы можем перемещать влево и вправо с помощью стрелок.
Инструкция-
Установка Qt-
Переключение Qt Creator'a на английский-
Создание нового проекта- Скопируем код заготовки в Scene.h и Scene.cpp (см. ниже)
- Запускаем приложение. Мы видим падающий вниз квадрат, который мы можем перемещать влево и вправо
Scene.h
C++ (Qt)
#ifndef SCENE_H
#define SCENE_H
#include <QGLWidget>
#include <QTimer>
#include <QKeyEvent>
class Scene : public QGLWidget
{
Q_OBJECT
public:
Scene( QWidget *parent = 0 );
private slots:
void slotMove();
private:
void initializeGL();
void paintGL();
void resizeGL( int w, int h );
void keyPressEvent( QKeyEvent * event );
private:
// Square position and size
int x;
int y;
const int rsize;
// Step size in x and y directions
// (number of pixels to move each time)
int xstep;
int 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 ),
y( 100 ),
rsize( 25 ),
xstep( 25 ),
ystep( 1 )
{
timer = new QTimer( this );
connect( timer, SIGNAL( timeout() ),
this, SLOT( slotMove() ) );
timer->start( 33 );
this->setFocusPolicy( Qt::StrongFocus );
}
void Scene::slotMove()
{
y -= ystep;
updateGL();
}
void Scene::initializeGL()
{
glClearColor( 0.8f, 0.8f, 0.6f, 1.0f );
}
void Scene::paintGL()
{
// Clear the window with current clearing color
glClear( GL_COLOR_BUFFER_BIT );
// Set current drawing color
glColor3f( 0.0f, 0.5f, 0.5f );
// 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();
}
void Scene::keyPressEvent( QKeyEvent *event )
{
switch( event->key() ) {
case Qt::Key_Left:
x -= xstep;
break;
case Qt::Key_Right:
x += xstep;
break;
}
}
Краткие объяснения основных моментовПримечание. Начало координат находится в середине окна.
- paintGL() - выполняется автоматически, когда приложению надо перерисовать окно. К примеру, если мы свернём окно и развернём, то тело этой функции выполнится. Или если перекроем наше окно каким-то другим. Или изменим размер нашего окна. В этой функции мы рисуем квадрат с помощью такой функции:
C++ (Qt)
glRectf( x, y, x + rsize, y - rsize );
Здесь:
x - глобальная переменная, которая хранит x-координату левого верхнего угла прямоугольника
y - глобальная переменная, которая хранит y-координату левого верхнего угла прямоугольника
rsize - глобальная константа, которая хранит размер стороны квадрата
(x + rsize) - x-координата правого нижнего угла квадрата
(y - rsize) - y-координата правого нижнего угла квадрата
- slotMove() - выполняется примерно 30 раз в секунду. Главное, чтобы было больше, чем 24 кадра в секунду. В этой функции мы меняем координаты квадрата (глобальные переменные x и y) и вызываем updateGL(), чтобы спровоцировать вызов paintGL() и тем самым перерисовать квадрат с новыми координатами
- keyPressEvent - вызывается при нажатии любой клавиши. В заготовке мы используем только стрелки: "влево" и "вправо". При нажатии кнопки "влево" нам надо уменьшить координату x, а если переместить вправо, то увеличить y
- "Почему квадрат падает?" Потому что каждые "30 раз в секунду" вызывается функция slotMove() и уменьшает глобальную переменную y, которая хранит y-координату нашего квадрата
- windowWidth и windowHeight - глобальные переменные, которые хранят актуальные размеры клиентской области (области, в которой мы рисуем)
- glClearColor( 0.3f, 0.3f, 1.0f, 1.0f ) - с помощью этой функции мы задаём цвет фона. Первые три параметра - это соответственно: красный, зелёный, синий. Их можно менять в диапазоне [0.0, 1.0]. Четвёрный параметр нам не нужен, поэтому мы его выставляем в значение поумолчанию - в единицу
- glColor3f( 0.0f, 0.5f, 0.5f ); - с помощью этой функции мы задаём цвет нашего квадрата. Здесь так же: красный, зелёный, синий
- resizeGL() - не обращайте внимания на содержимое этой функции. Просто не трогайте её.
Продолжение: http://www.prog.org.ru/topic_27563_0.htmlЛитература:-
OpenGL Суперкнига (
диск к книге)
-
Beginning OpenGL Game Programming, 2nd edition, 2009 (book+code)P.S. Эта же тема под другим ракурсом:
-
http://www.gamedev.ru/code/forum/?id=193241-
http://programmersforum.ru/showthread.php?t=265504