23
Interactive Graphics Applications with OpenGL Shading Language and Qt João Paulo Gois Harlen C. Batagelo Universidade Federal do ABC Contacts Harlen C. Batagelo: [email protected] João Paulo Gois: [email protected] Table of Contents 1 Qt SDK: Starting up a Qt project; 2 The class QGLWidget; 3 Extending QGLWidget; 4 Promoting a class; 5 Signals & Slots; 6 Loading a Geometric Model; 7 Encapsulating Resources; 8 Shaders and Qt; 9 Buer Objects; 10 Matrix and Vector Classes; 11 Signals & Slots – part 2; 12 The method QGLWidget::paintGL(); 13 Interface and OpenGL details; 14 Final Considerations. Simple Qt with OpenGL application: similar to GLUT? An improved Qt application with OpenGL - 1 An improved Qt application with OpenGL - 2

Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

  • Upload
    others

  • View
    22

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Interactive Graphics Applications with OpenGL

Shading Language and Qt

João Paulo Gois Harlen C. Batagelo

Universidade Federal do ABC

Contacts

Harlen C. Batagelo: [email protected]ão Paulo Gois: [email protected]

Table of Contents

1 Qt SDK: Starting up a Qt project;2 The class QGLWidget;3 Extending QGLWidget;4 Promoting a class;5 Signals & Slots;6 Loading a Geometric Model;7 Encapsulating Resources;8 Shaders and Qt;9 Buffer Objects;10 Matrix and Vector Classes;11 Signals & Slots – part 2;12 The method QGLWidget::paintGL();13 Interface and OpenGL details;14 Final Considerations.

Simple Qt with OpenGL application: similar to GLUT?

An improved Qt application with OpenGL - 1 An improved Qt application with OpenGL - 2

Page 2: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Qt Creator interface

Figure: Qt Creator interface.

Tip

Coding GuidelinesTo maintain the coherence with Qt style, we follow the Qt CodingGuidelines in our C++ files.

Startup a Qt GUI Project-1

Figure: File→New

Startup a Qt GUI Project-2

Figure: Project Name

Page 3: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Startup a Qt GUI Project-3

Figure: Target

Startup a Qt GUI Project-4

Figure: Informations

Original .pro File

1 QT += core gui

3 TARGET = myqtglproject

5 TEMPLATE = app

7 SOURCES += main.cpp\mainwindow.cpp

9HEADERS += mainwindow.h

11FORMS += mainwindow.ui

.pro File with Qt OpenGL Module

QT += core gui opengl2

TARGET = myqtglproject4

TEMPLATE = app6

SOURCES += main.cpp\8 mainwindow.cpp

10 HEADERS += mainwindow.h

12 FORMS += mainwindow.ui

Qt Creator with our new project: Edit Mode Qt Creator with our new project: Design Mode

Page 4: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

File mainwindow.h

#ifndef MAINWINDOW_H2 #define MAINWINDOW_H

4 #include <QMainWindow >

6 namespace Ui {class MainWindow;

8 }

10 class MainWindow : public QMainWindow{

12 Q_OBJECT

14 public:explicit MainWindow(QWidget *parent = �);

16 ~MainWindow ();

18 private:Ui:: MainWindow *ui;

20 };

22 #endif // MAINWINDOW_H

File mainwindow.cpp

#include "mainwindow.h"2 #include "ui_mainwindow.h"

4 MainWindow :: MainWindow(QWidget *parent) :QMainWindow(parent),

6 ui(new Ui:: MainWindow){

8 ui ->setupUi(this);}

10MainWindow ::~ MainWindow ()

12 {delete ui;

14 }

File main.cpp

#include <QtGui/QApplication >2 #include "mainwindow.h"

4 int main(int argc , char *argv []){

6 QApplication a(argc , argv);MainWindow w;

8 w.show();

10 return a.exec();}

Other libraries

There is also the possibility to include other libraries on the Qtproject, as in the following listing:

1INCLUDEPATH += /usr/local/include/foo/

3LIBS += -L/usr/local/lib/foo/ -lfoo -lbar

Run qmake again!

Details of Qt Creator

Figure: Design mode: on (A) components to design the UI, (B) UI

WYSIWYG editor, (C) hierarchy of currently created UI object

components and (D) their properties.

Objects and their Classes

Figure: Objects and their classes in designing the UI: Some of them were

automatically generated by Qt Creator and others we inserted to enhance

our application.

Page 5: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Extending the class QGLWidget – 1

To extend QGLWidget to our class GLWidget, we need to implement:

paintGL(): renders the OpenGL scene whenever the widgetneeds to be repainted. It is equivalent to the callback functionregistered through the GLUT function glutDisplayFunc().resizeGL(int width, int height): handles the resizing of theOpenGL window and repaints it. It is equivalent to thecallback function registered through the GLUT functionglutReshapeFunc().initializeGL(): It is evoked only once, whenever an OpenGLcontext is created. It is intended to contain the OpenGLinitialization code that comes before the first call of paintGL()

or resizeGL().

Extending the class QGLWidget – 2

Extending the class QGLWidget – 3 Extending the class QGLWidget – 4

File glwidget.h

1 #ifndef GLWIDGET_H#define GLWIDGET_H

3#include <QGLWidget >

5class GLWidget : public QGLWidget

7 {Q_OBJECT

9 public:explicit GLWidget(QWidget *parent = �);

11signals:

13public slots:

15};

17 #endif // GLWIDGET_H

File glwidget.cpp

1 #include "glwidget.h"

3 GLWidget :: GLWidget(QWidget *parent) :QGLWidget(parent)

5 {}

Page 6: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

File glwidget.h: Declare three methods in class GLWidget

...2 class GLWidget : public QGLWidget

{4 ...

protected:6 void initializeGL ();

void resizeGL(int width , int height);8 void paintGL ();

};

File glwidget.cpp: First implementations

1 void GLWidget :: initializeGL (){

3 }

5 void GLWidget :: resizeGL(int width , int height){

7 }

9 void GLWidget :: paintGL (){

11 glClear(GL_COLOR_BUFFER_BIT);}

Include Files

TipThere is an include file for each class of the QtOpenGL module.Several of these classes are used in our project. Instead of includingeach one, we can write #include <QtOpenGL> at glwidget.h.

Promoting the QWidget to GLWidget - 1

Promoting the QWidget to GLWidget - 2 Promoting the QWidget to GLWidget - 3

Page 7: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Behavior of MainWindow – 1

TipHow behaves widget when MainWindow is resized? By default, widget

has a fixed size. In order to change its size according to MainWindow’sresize, we must set the sizePolicy – Horizontal/Vertical of thewidget from the default option – Preferred – to Expanding. Otherresize policies are also available.

Behavior of MainWindow – 2

TipUI components can be consistently arranged within widgets using Qtlayout styles. We can choose, for instance, the Vertical, Horizontalor Grid layouts. In our first interface, the centralWidget is laid outvertically. In Design mode, this is done by clicking at centralWidget

and then either pressing Ctrl+L or clicking on the icon in the QtCreator toolbar.

Signals & Slots – 1

GLUT uses callbacks to the communication between functions.Qt introduces the concept of Signals and Slots.

Signals & Slots – 2

A signal is emitted when an event associated to some sender

object occurs, for instance, when a button is clicked at the UI.A slot, in turn, is a method of a receiver object and is called inresponse to a particular signal. Signals and slots are methodsof sender and receiver objects, respectively.

Signals & Slots – 3

Slots are qualified as private, protected or public;Signals are implicitly declared as protected;Signal and slots are type-safes, i.e., differently from callbackfunctions, the signature of a specific sender signal must matchthe signature of the receiver slot.

Signals & Slots - Example 1 – 1

Pre-defined signals and slots offered by Qt classes;Let us create an Exit push button that quits the application.

Page 8: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Signals & Slots - Example 1 – 2 Signals & Slots - Example 1 – 3

Signals & Slots - Example 1 – 4

Sender combo box: select object pushButton;Signal combo box: select the signal clicked() of objectpushButton;Receiver combo box: select object MainWindow;Slot combo box: select the signal close() of object MainWindow.

Signals & Slots - Example 2 – 1

Checkbox button that toggles the background color of thewidget;Signal consists of toggling the checkbox;Slot will be method of GLWidget that will change the OpenGLclear color;There is no predefined slot to change the background color.

Signals & Slots - Example 2 – 2

Sender combo box: select object checkBox;Signal combo box: select the signal toggled(bool) of objectcheckBox;Receiver combo box: select object widget;Slot combo box: select the signal toggleBackgroundColor(bool)of object widget.

Signals & Slots - Example 2 – 3

Page 9: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Signals & Slots - Example 2 – 4 Signals & Slots - Example 2 – 5

Signals & Slots - Example 2 – 6 Signals & Slots - Example 2 – 7

...2 class GLWidget : public QGLWidget

{4 ...

public slots:6 void toggleBackgroundColor(bool toBlack);

...8 };

#endif // GLWIDGET_H

Signals & Slots - Example 2 – 8

1 void GLWidget :: toggleBackgroundColor(bool toBlack){

3 if (toBlack)glClearColor (�, �, �, 1);

5 elseglClearColor (1, 1, 1, 1);

7updateGL (); // -> New command

9 }

Loading a Geometric Model – 1

Display a triangular mesh model loaded from a file of Object

File Format (OFF) formatSelect an OFF file from a file selection dialog, accessed by File→ Open on the menuBar.

Page 10: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Loading a Geometric Model – 2

At Design mode click at Type Here on the menuBar;Rename it to File;Qt Creator automatically creates the object menuFile of theclass QMenu and opens a submenu;Click at Type Here on the submenu and change it to Open;Qt Creator automatically creates the object actionOpen of theclass QAction;Whenever the user selects Open at menu bar, the emittedtriggered() signal connects to a slot that displays a fileselection dialog.

Loading a Geometric Model – 3

1 void GLWidget :: showFileOpenDialog (){

3 QByteArray fileFormat = "off";QString fileName;

5 fileName = QFileDialog :: getOpenFileName(this ,"Open File",

7 QDir:: homePath (),QString("%1 Files (*.%2)")

9 .arg(QString(fileFormat.toUpper ())).arg(QString(fileFormat)));

11 if (! fileName.isEmpty ()) {readOFFFile(fileName);

13genNormals ();

15 genTexCoordsCylinder ();genTangents ();

17createVBOs ();

19 createShaders ();

21 updateGL ();}

23 }

Loading a Geometric Model – 4

Sender combo box: select object actionOpen;Signal combo box: select the signal triggered() of objectactionOpen;Receiver combo box: select object widget;Slot combo box: select the signal showFileOpenDialog() ofobject widget.

Loading a Geometric Model – 5

1 void GLWidget :: readOFFFile(const QString &fileName){

3 std:: ifstream stream;stream.open(fileName.toAscii (), std:: ifstream ::in);

5if (! stream.is_open ()) {

7 qWarning("Cannot open file.");return;

9 }

11 std:: string line;

13 stream >> line;stream >> numVertices >> numFaces >> line;

15delete [] vertices;

17 vertices = new QVector4D[numVertices ];

19 delete [] indices;indices = new unsigned int[numFaces * 3];

21if (numVertices > �) {

23 double minLim = std:: numeric_limits <double >:: min();double maxLim = std:: numeric_limits <double >:: max();

25 QVector4D max(minLim , minLim , minLim , 1.�);QVector4D min(maxLim , maxLim , maxLim , 1.�);

Loading a Geometric Model – 6

1for (unsigned int i = �; i < numVertices; i++) {

3 double x, y, z;stream >> x >> y >> z;

5 max.setX(qMax(max.x(), x));max.setY(qMax(max.y(), y));

7 max.setZ(qMax(max.z(), z));min.setX(qMin(min.x(), x));

9 min.setY(qMin(min.y(), y));min.setZ(qMin(min.z(), z));

11vertices[i] = QVector4D(x, y, z, 1.�);

13 }

15 QVector4D midpoint = (min + max) * �.5;double invdiag = 1 / (max - min).length ();

17for (unsigned int i = �; i < numVertices; i++) {

19 vertices[i] = (vertices[i] - midpoint)*invdiag;vertices[i].setW (1);

21 }}

Loading a Geometric Model – 7

1 for (unsigned int i = �; i < numFaces; i++) {unsigned int a, b, c;

3 stream >> line >> a >> b >> c;indices[i * 3 ] = a;

5 indices[i * 3 + 1] = b;indices[i * 3 + 2] = c;

7 }

9 stream.close();}

TipAnother option to read a file is to use the Qt class QFile.

Page 11: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Loading a Geometric Model – 8

void GLWidget :: genNormals ()2 {

delete [] normals;4 normals = new QVector3D[numVertices ];

6 for (unsigned int i = �; i < numFaces; i++) {unsigned int i1 = indices[i * 3 ];

8 unsigned int i2 = indices[i * 3 + 1];unsigned int i3 = indices[i * 3 + 2];

10QVector3D v1 = vertices[i1]. toVector3D ();

12 QVector3D v2 = vertices[i2]. toVector3D ();QVector3D v3 = vertices[i3]. toVector3D ();

14QVector3D faceNormal = QVector3D :: crossProduct(v2 - v1,

v3 - v1);16 normals[i1] += faceNormal;

normals[i2] += faceNormal;18 normals[i3] += faceNormal;

}20

for (unsigned int i = �; i < numVertices; i++)22 normals[i]. normalize ();

}

Loading a Geometric Model – 9

1 void GLWidget :: genTexCoordsCylinder (){

3 delete [] texCoords;texCoords = new QVector2D[numVertices ];

5double minLim = std:: numeric_limits <double >:: min();

7 double maxLim = std:: numeric_limits <double >:: max();QVector2D max(minLim , minLim);

9 QVector2D min(maxLim , maxLim);

11 for (unsigned int i = �; i < numVertices; i++) {QVector2D pos = vertices[i]. toVector2D ();

13 max.setX(qMax(max.x(), pos.x()));max.setY(qMax(max.y(), pos.y()));

15 min.setX(qMin(min.x(), pos.x()));min.setY(qMin(min.y(), pos.y()));

17 }

19 QVector2D size = max - min;for (unsigned int i = �; i < numVertices; i++) {

21 double x = 2.�*( vertices[i].x() - min.x()) / size.x()-1.�;

texCoords[i] = QVector2D(acos(x) / M_PI ,23 (vertices[i].y()-min.y())/size.y());

}25 }

Loading a Geometric Model – 10

1 void GLWidget :: genTangents (){

3 delete [] tangents;

5 tangents = new QVector4D[numVertices ];QVector3D *bitangents = new QVector3D[numVertices ];

7for (unsigned int i = �; i < numFaces; i++) {

9 unsigned int i1 = indices[i * 3 ];unsigned int i2 = indices[i * 3 + 1];

11 unsigned int i3 = indices[i * 3 + 2];

13 QVector3D E = vertices[i1]. toVector3D ();QVector3D F = vertices[i2]. toVector3D ();

15 QVector3D G = vertices[i3]. toVector3D ();

17 QVector2D stE = texCoords[i1];QVector2D stF = texCoords[i2];

19 QVector2D stG = texCoords[i3];

21 QVector3D P = F - E;QVector3D Q = G - E;

23QVector2D st1 = stF - stE;

25 QVector2D st2 = stG - stE;

Loading a Geometric Model – 11

QMatrix2x2 M;2 M(�,�) = st2.y(); M(�,1) = -st1.y();

M(1,�) = -st2.x(); M(1,1) = st1.x();4 M *= (1.� / (st1.x()*st2.y() - st2.x()*st1.y()));

6 QVector4D T = QVector4D(M(�,�)*P.x() + M(�,1)*Q.x(),M(�,�)*P.y() + M(�,1)*Q.y(),

8 M(�,�)*P.z() + M(�,1)*Q.z(), �.�);

10 QVector3D B = QVector3D(M(1,�)*P.x() + M(1,1)*Q.x(),M(1,�)*P.y() + M(1,1)*Q.y(),

12 M(1,�)*P.z() + M(1,1)*Q.z());

14 tangents[i1] += T;tangents[i2] += T;

16 tangents[i3] += T;

18 bitangents[i1] += B;bitangents[i2] += B;

20 bitangents[i3] += B;}

Loading a Geometric Model – 12

1 for (unsigned int i = �; i < numVertices; i++) {const QVector3D& n = normals[i];

3 const QVector4D& t = tangents[i];

5 tangents[i] = (t - n *QVector3D :: dotProduct(n, t.toVector3D ())).

normalized ();7

QVector3D b = QVector3D :: crossProduct(n, t.toVector3D ());9 double hand = QVector3D :: dotProduct(b, bitangents[i]);

tangents[i].setW((hand < �.�) ? -1.� : 1.�);11 }

13 delete [] bitangents;}

Encapsulating Resources – 1

Resource System stores external binary and text files into theapplication executable, encapsulating both application andtheir resources in a single binary file;Icons, XML files, translate files or binary files, GLSL files ...

Page 12: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Encapsulating Resources – 2 Encapsulating Resources – 3

Encapsulating Resources – 3 Encapsulating Resources – 4

Obs 1Resource files embedded into the application executable are onlyaccessible by Qt classes. For instance, if we want to open atext file managed by the Resource System, we cannot do it usingstd::ifstream, instead we have to use QFile.

Obs 2If we try to run the application but Qt Creator produces an errormessage related to resource files, make sure to run Qmake by se-lecting on Qt Creator menu bar Build → Run qmake before youtry to run the application again.

OpenGL Shaders and Qt – 1

Qt provides facilities to handle GLSL shaders and shaderprograms;A built-in GLSL editor;Classes QGLShader and QGLShaderProgram.

OpenGL Shaders and Qt – 2

Gouraud shaded model;Phong shaded model;Phong shaded model with texture mapping;Phong shaded model with normal mapping.

Page 13: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

OpenGL Shaders and Qt – 3

The user selects a shader effect,Previously selected is first released from the OpenGL pipeline;The current effect to be compiled, linked and bound to theOpenGL application in running time.

OpenGL Shaders and Qt – 4

void GLWidget :: destroyShaders ()2 {

delete vertexShader;4 vertexShader = NULL;

6 delete fragmentShader;fragmentShader = NULL;

8if (shaderProgram) {

10 shaderProgram ->release ();delete shaderProgram;

12 shaderProgram = NULL;}

14 }

OpenGL Shaders and Qt – 5

void GLWidget :: createShaders ()2 {

destroyShaders ();4

QString vertexShaderFile [] = {6 ":/ shaders/vgouraud.glsl",

":/ shaders/vphong.glsl",8 ":/ shaders/vtexture.glsl",

":/ shaders/vnormal.glsl"10 };

QString fragmentShaderFile [] = {12 ":/ shaders/fgouraud.glsl",

":/ shaders/fphong.glsl",14 ":/ shaders/ftexture.glsl",

":/ shaders/fnormal.glsl"16 };

18 vertexShader = new QGLShader(QGLShader :: Vertex);if (! vertexShader ->compileSourceFile(vertexShaderFile[

currentShader ]))20 qWarning () << vertexShader ->log();

OpenGL Shaders and Qt – 6

fragmentShader = new QGLShader(QGLShader :: Fragment);2 if (! fragmentShader ->compileSourceFile(fragmentShaderFile[

currentShader ]))qWarning () << fragmentShader ->log();

4shaderProgram = new QGLShaderProgram;

6 shaderProgram ->addShader(vertexShader);shaderProgram ->addShader(fragmentShader);

8if (! shaderProgram ->link())

10 qWarning () << shaderProgram ->log() << endl;}

Buffer Objects – 1

For a long time, the OpenGL’s immediate mode and display

lists have been the standard approach to upload rendering datato the graphics server;But both features are now deprecated;OpenGL vertex arrays have been currently used to thispurpose;However, vertex arrays are stored at client side, which meansthat they must be sent to server every time the scene has tobe updated.

Buffer Objects – 2

The concept of Vertex Buffer Objects (VBOs), introduced onOpenGL 1.5, allows the direct manipulation of the data storedat server side;We create VBOs in our application using the Qt classQGLBuffer.

Page 14: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Buffer Objects – 3

vboVertices: vertex positions of type QVector4D;vboNormals: vertex normals of type QVector3D;vboTexCoords: texture coordinates of type QVector2D;vboTangents: tangent vectors of type QVector4D.

VBOs – 1

1 void GLWidget :: createVBOs (){

3 destroyVBOs ();

5 vboVertices = new QGLBuffer(QGLBuffer :: VertexBuffer);vboVertices ->create ();

7 vboVertices ->bind();vboVertices ->setUsagePattern(QGLBuffer :: StaticDraw);

9 vboVertices ->allocate(vertices , numVertices * sizeof(QVector4D));

delete [] vertices;11 vertices = NULL;

13 vboNormals = new QGLBuffer(QGLBuffer :: VertexBuffer);vboNormals ->create ();

15 vboNormals ->bind();vboNormals ->setUsagePattern(QGLBuffer :: StaticDraw);

17 vboNormals ->allocate(normals , numVertices * sizeof(QVector3D));

delete [] normals;19 normals = NULL;

VBOs – 2

vboTexCoords = new QGLBuffer(QGLBuffer :: VertexBuffer);2 vboTexCoords ->create ();

vboTexCoords ->bind();4 vboTexCoords ->setUsagePattern(QGLBuffer :: StaticDraw);

vboTexCoords ->allocate(texCoords , numVertices * sizeof(QVector2D));

6 delete [] texCoords;texCoords = NULL;

8vboTangents = new QGLBuffer(QGLBuffer :: VertexBuffer);

10 vboTangents ->create ();vboTangents ->bind();

12 vboTangents ->setUsagePattern(QGLBuffer :: StaticDraw);vboTangents ->allocate(tangents , numVertices * sizeof(

QVector4D));14 delete [] tangents;

tangents = NULL;

VBOs – 3

2 vboIndices = new QGLBuffer(QGLBuffer :: IndexBuffer);vboIndices ->create ();

4 vboIndices ->bind();vboIndices ->setUsagePattern(QGLBuffer :: StaticDraw);

6 vboIndices ->allocate(indices , numFaces * 3 * sizeof(unsignedint));

delete [] indices;8 indices = NULL;

}

VBOs – 4

1 void GLWidget :: destroyVBOs (){

3 if (vboVertices) {vboVertices ->release ();

5 delete vboVertices;vboVertices = NULL;

7 }

9 if (vboNormals) {vboNormals ->release ();

11 delete vboNormals;vboNormals = NULL;

13 }

15 if (vboTexCoords) {vboTexCoords ->release ();

17 delete vboTexCoords;vboTexCoords = NULL;

19 }

21 if (vboTangents) {vboTangents ->release ();

23 delete vboTangents;vboTangents = NULL;

25 }...

VBOs – 5

ObsBuffer objects are capable of mapping its data into the client side us-ing the map()/unmap() methods. These enable us to efficiently changeVBO data.vboVertices ->setUsagePattern(QGLBuffer :: DynamicDraw);

2 ...vboVertices ->bind();

4 QVector4D* pt = (QVector4D *) vboVertices ->map(QGLBuffer ::WriteOnly);

// change here the VBO data by directly manipulating pt array6 ...

vboVertices ->unmap();

Page 15: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Mouse and Keyboard Events – 1

void GLWidget :: keyPressEvent(QKeyEvent *event)2 {

switch(event ->key()){4 case Qt::Key_�:

currentShader = �;6 createShaders ();

updateGL ();8 break;

case Qt::Key_1:10 currentShader = 1;

createShaders ();12 updateGL ();

break;14 case Qt::Key_2:

currentShader = 2;16 createShaders ();

updateGL ();18 break;

case Qt::Key_3:20 currentShader = 3;

createShaders ();22 updateGL ();

break;24 case Qt:: Key_Escape:

qApp ->quit();26 }

}

Mouse and Keyboard Events – 2

ObsWidgets by default do not accept focus and, therefore will not re-ceive any event. In order to ensure that GLWidget is in focus, we set(in Design mode) the focusPolicy property to a policy different ofQt::NoFocus. In our application, we use Qt::StrongFocus, as itallows the widget to accept focus by both tabbing and clicking.

Mouse and Keyboard Events (Virtual Trackball)

1 void GLWidget :: mouseMoveEvent(QMouseEvent *event){

3 trackBall.mouseMove(event ->posF());}

5void GLWidget :: mousePressEvent(QMouseEvent *event)

7 {if (event ->button () & Qt:: LeftButton)

9 trackBall.mousePress(event ->posF());}

11void GLWidget :: mouseReleaseEvent(QMouseEvent *event)

13 {if (event ->button () == Qt:: LeftButton)

15 trackBall.mouseRelease(event ->posF());}

17void GLWidget :: wheelEvent(QWheelEvent *event)

19 {zoom += �.��1 * event ->delta();

21 }

Qt Matrix and Vector classes – 1

Qt provides classes QVector2D, QVector3D, QVector4D, QMatrix2x2,QMatrix2x3, . . . , QMatrix4x3, QMatrix4x4) to manipulategeometric transformations and camera settings;Their contents can be bound to shader attributes declared asnative data types vec2, vec3, vec4, mat2, mat3, mat4 or shaderarrays, using methods of the class QGLShaderProgram.

Qt Matrix and Vector classes – 2

In GLWidget we declare two QMatrix4x4 objects;modelViewMatrix and projectionMatrix.They correspond to the deprecated OpenGL matrix modesGL_MODELVIEW and GL_PROJECTION, respectively, but under theobject-oriented paradigm.

Qt Matrix and Vector classes – 2

1 void GLWidget :: resizeGL(int width , int height){

3 glViewport (�, �, width , height);

5 projectionMatrix.setToIdentity ();projectionMatrix.perspective (6�.�, static_cast <qreal >(width) /

static_cast <qreal >( height), �.1, 2�.�);7

trackBall.resizeViewport(width , height);9

updateGL ();11 }

Page 16: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Qt Matrix and Vector classes – 3

In the method resizeGL() we set up projectionMatrix;First we initialize the projection matrix to the identity matrix(equivalent to glLoadIdentity() underglMatrixMode(GL_PROJECTION));We then right-multiply itself by the matrix corresponding tothe perspective projection, using the methodQMatrix4x4::perspective();This method has the same sequence of parameters ofgluPerspective().

Qt Matrix and Vector classes – 4

In method paintGL() we set up modelViewMatrix;As projectionMatrix, we first we set it to identity matrix;After that, we use the method QMatrix4x4::lookAt() which,similar to gluLookAt(), creates a viewing matrix derived froman observer point, a look-at point and an up-vector;Two geometric transformations: first a rotation provided bythe trackball object and second a translation;Notice that it is in accordance to the order of the traditionalOpenGL geometric transformations(glTranslate/glRotate/glScale), where the geometrictransformations are applied from bottom to top.

Qt Matrix and Vector classes – 5

ObsQMatrix4x4 provides other useful methods: projection matricesfrustum(), ortho(), the geometric transformation scale(). Over-loaded operators for matrix-matrix and matrix-vector operations arealso provided.

Signals/Slots – Part 2 – 1

So far we learnt how to include signals/slots using Qt Creator;We show other objects, not directly related to UI, that also areable to intercommunicate using signals/slots;QTimer class, timer, declared in the GLWidget;It emits signals to widget in order to repaint the OpenGLwindow during the application’s idle time.

Signals/Slots – Part 2 – 2

We do that directly on the source code;Qt command connect connects the pre-defined signal timeout()emitted by timer to the custom slot animate() of the widget.We start the timer with a timeout interval of zero milliseconds,which means that a timeout signal will be emitted wheneverthe application is idle.

1 void GLWidget :: animate (){

3 updateGL ();}

Signals/Slots – Part 2 – 3

void GLWidget :: initializeGL ()2 {

glEnable(GL_DEPTH_TEST);4

QImage texColor= QImage(":/ textures/bricksDiffuse.png");6 QImage texNormal= QImage(":/ textures/bricksNormal.png");

glActiveTexture(GL_TEXTURE�);8 texID [�] = bindTexture(texColor);

glActiveTexture(GL_TEXTURE1);10 texID [1] = bindTexture(texNormal);

12 connect (&timer ,SIGNAL(timeout ()), this ,SLOT(animate ()));timer.start (�);

14 }

Page 17: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Signals/Slots – Emitting a signal – 1

Custom signal defined in our class GLWidget that connects to apre-defined slot;Show in the status bar the number of vertices and faces of theloaded mesh;We create the connection in Design mode, associating ourcustom signal statusBarMessage() from widget to thepre-defined slot showMessage() of statusBar;We also code the following listing:

Signals/Slots – Emitting a signal – 2

void GLWidget :: readOFFFile(const QString &fileName)2 {

...4 emit statusBarMessage(QString("Samples %1, Faces %2")

.arg(numVertices)6 .arg(numFaces));

}

Signals/Slots – Emitting a signal – 3

ObsSignals do not need to be defined, only declared: In this last examplewe do not define the method statusBarMessage(); it is only declaredin GLWidget using the signals reserved Qt keyword.

Texture Mapping

void GLWidget :: initializeGL ()2 {

glEnable(GL_DEPTH_TEST);4

QImage texColor= QImage(":/ textures/bricksDiffuse.png");6 QImage texNormal= QImage(":/ textures/bricksNormal.png");

glActiveTexture(GL_TEXTURE�);8 texID [�] = bindTexture(texColor);

glActiveTexture(GL_TEXTURE1);10 texID [1] = bindTexture(texNormal);

12 connect (&timer ,SIGNAL(timeout ()), this ,SLOT(animate ()));timer.start (�);

14 }

ObsThere is another option to manipulate textures on OpenGL with thePixel Buffer Object. In this case, Qt allows for manipulating textureswith the class QGLBuffer. One of the advantages of this approach isthe asynchronous communication between CPU and GPU.

The method paintGL() – 1

1 The model-view transformations;2 The binding of shader program;3 The uploading of uniform data to GPU;4 The binding of buffer objects and textures to GPU;5 The releasing of buffer objects and the shader program.

The method paintGL() – 2

ObsThe uploading of shader variables and the binding of shaderattributes in paintGL() is done irrespective of the shader effectcurrently set.This is acceptable because any variables and attributes notreferenced in the shader program are simply ignored.For instance, the shader program for rendering a non-texturedmodel with Phong shading does not require texturecoordinates or tangent vectors passed as attributes.In such case, the binding of the corresponding buffer objectsand textures are ignored.

Page 18: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

The method paintGL() – 3

ObsThe set up of shader attributes could be done outsidepaintGL() just after the model is loaded and the shaderprogram is created, assuming that our application is composedof only one mesh model rendered with only one shader effect.Also, since the contents of our textures do not change alongthe execution of our application, we could did the texturingwork only once.However, we opt to leave these commands at paintGL() as it isdone in more sophisticate applications with several meshmodels, shaders and textures.

The method paintGL() – 4

void GLWidget :: paintGL ()2 {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);4

if (! vboVertices)6 return;

8 modelViewMatrix.setToIdentity ();modelViewMatrix.lookAt(camera.eye ,camera.at ,camera.up);

10 modelViewMatrix.translate (�, �, zoom);modelViewMatrix.rotate(trackBall.getRotation ());

12shaderProgram ->bind();

14shaderProgram ->setUniformValue("modelViewMatrix",

modelViewMatrix);16 shaderProgram ->setUniformValue("projectionMatrix",

projectionMatrix);shaderProgram ->setUniformValue("normalMatrix",

modelViewMatrix.normalMatrix ());

The method paintGL() – 4

1 QVector4D ambientProduct = light.ambient * material.ambient;QVector4D diffuseProduct = light.diffuse * material.diffuse;

3 QVector4D specularProduct = light.specular * material.specular;

5 shaderProgram ->setUniformValue("lightPosition", light.position);

shaderProgram ->setUniformValue("ambientProduct",ambientProduct);

7 shaderProgram ->setUniformValue("diffuseProduct",diffuseProduct);

shaderProgram ->setUniformValue("specularProduct",specularProduct);

9 shaderProgram ->setUniformValue("shininess", static_cast <GLfloat >( material.

shininess));

The method paintGL() – 5

shaderProgram ->setUniformValue("texColorMap", �);2 shaderProgram ->setUniformValue("texNormalMap", 1);

4 glActiveTexture(GL_TEXTURE�);glBindTexture(GL_TEXTURE_2D , texID [�]);

6 glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D , texID [1]);

The method paintGL() – 6

1 vboVertices ->bind();shaderProgram ->enableAttributeArray("vPosition");

3 shaderProgram ->setAttributeBuffer("vPosition", GL_FLOAT , �,4, �);

5 vboNormals ->bind();shaderProgram ->enableAttributeArray("vNormal");

7 shaderProgram ->setAttributeBuffer("vNormal", GL_FLOAT , �, 3,�);

9 vboTexCoords ->bind();shaderProgram ->enableAttributeArray("vTexCoord");

11 shaderProgram ->setAttributeBuffer("vTexCoord", GL_FLOAT , �,2, �);

13 vboTangents ->bind();shaderProgram ->enableAttributeArray("vTangent");

15 shaderProgram ->setAttributeBuffer("vTangent", GL_FLOAT , �, 4,�);

The method paintGL() – 7

1 vboIndices ->bind();

3 glDrawElements(GL_TRIANGLES , numFaces * 3, GL_UNSIGNED_INT ,�);

5 vboIndices ->release ();vboTangents ->release ();

7 vboTexCoords ->release ();vboNormals ->release ();

9 vboVertices ->release ();

11 shaderProgram ->release ();

13 }

Page 19: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

Formatting OpenGL – 1

QGLFormat allows to specify the display format of an OpenGLcontext;Set double or single buffering (double buffering is default);Alpha channel (disabled by default);Stereo buffers (disabled by default);Color mode (rgba is the default);Depth buffer (enabled by default);Antialiasing (disabled by default).The goals of this class are loosely related to those of thefunction glutInitDisplayMode().

Formatting OpenGL – 2

1 #include <QtGui/QApplication >#include <QGLFormat >

3 #include "mainwindow.h"

5 int main(int argc , char *argv []){

7 QGLFormat format = QGLFormat :: defaultFormat ();format.setSampleBuffers(true);

9 format.setSamples (8);if (! format.sampleBuffers ())

11 qWarning("Multisample buffer is not supported.");QGLFormat :: setDefaultFormat(format);

13QApplication a(argc , argv);

15 MainWindow w;w.show();

17return a.exec();

19 }

Formatting OpenGL – 3

ObsThis process is done in the main() function before the creation ofthe MainWindow object. When the MainWindow object is defined, ourGLWidget creates an OpenGL context using the new default format.

Taking a Screenshot of the OpenGL scene – 1

Taking a Screenshot of the OpenGL scene – 2

1 void GLWidget :: takeScreenshot (){

3 QImage screenshot = grabFrameBuffer ();

5 QString fileName;fileName = QFileDialog :: getSaveFileName(this ,

7 "Save File As", QDir:: homePath (),QString("PNG Files (*. png)"));

9 if (fileName.length ()) {if (! fileName.contains(".png"))

11 fileName += ".png";if (screenshot.save(fileName , "PNG")) {

13 QMessageBox :: information(this , "Screenshot","Screenshot taken!",

15 QMessageBox ::Ok);}

17 }}

Final Considerations

The power of Qt for interactive graphics applications is notlimited to the scope of this presentation which relied on QtOpenGL Module;Specifically for 2D graphics applications, Qt provides the classQPainter;QPainter can be combined with QGLWidget (Show Boxes Demo);Qt framework 5.0 is to be released;This version will provide the Qt3D: a scene-graph using the QtMeta Language QML (Show Video)http://qt-project.org/wiki/Qt-5-Alpha

Page 20: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

I. GLWidget CLASS DECLARATION

1 #ifndef GLWIDGET_H#define GLWIDGET_H

3#include <QtOpenGL >

5#include <iostream >

7 #include <fstream >#include <limits >

9#include "camera.h"

11 #include "light.h"#include "material.h"

13 #include "trackball.h"

15 class GLWidget : public QGLWidget{

17 Q_OBJECTpublic:

19 explicit GLWidget(QWidget *parent = �);virtual ~GLWidget ();

21signals:

23 void statusBarMessage(QString ns);

25 public slots:void toggleBackgroundColor(bool toBlack);

27 void showFileOpenDialog ();void animate ();

29protected:

31 void initializeGL ();void resizeGL(int width , int height);

33 void paintGL ();void mouseMoveEvent(QMouseEvent *event);

35 void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);

37 void wheelEvent(QWheelEvent *event);void keyPressEvent(QKeyEvent *event);

39private:

41 void readOFFFile(const QString &fileName);void genNormals ();

43 void genTexCoordsCylinder ();void genTangents ();

45 void createVBOs ();void destroyVBOs ();

47 void createShaders ();void destroyShaders ();

49QPointF pixelPosToViewPos(const QPointF &p);

51unsigned int numVertices;

53 unsigned int numFaces;QVector4D *vertices;

55 QVector3D *normals;QVector2D *texCoords;

57 QVector4D *tangents;unsigned int *indices;

59QGLBuffer *vboVertices;

61 QGLBuffer *vboNormals;QGLBuffer *vboTexCoords;

63 QGLBuffer *vboTangents;QGLBuffer *vboIndices;

65QGLShader *vertexShader;

67 QGLShader *fragmentShader;QGLShaderProgram *shaderProgram;

69 unsigned int currentShader;

71 int texID [2];

73 QMatrix4x4 modelViewMatrix;QMatrix4x4 projectionMatrix;

75Camera camera;

77 Light light;Material material;

79TrackBall trackBall;

81double zoom;

83QTimer timer;

85 };

Listing 1. Class GLWidget.

II. CONSTRUCTOR AND DESTRUCTOR OF GLWIDGET

1 GLWidget :: GLWidget(QWidget *parent) :QGLWidget(parent)

3 {vertices = NULL;

5 normals = NULL;texCoords = NULL;

7 tangents = NULL;indices = NULL;

9vboVertices = NULL;

11 vboNormals = NULL;vboTexCoords = NULL;

13 vboTangents = NULL;vboIndices = NULL;

15shaderProgram = NULL;

17 vertexShader = NULL;fragmentShader = NULL;

19 currentShader = �;

21 zoom = �.�;

23 fpsCounter = �;}

25GLWidget ::~ GLWidget ()

27 {destroyVBOs ();

29 destroyShaders ();}

Listing 2. File glwidget.cpp: constructor and destructor of GLWidget.

III. GLSL SHADERS

attribute vec4 vPosition;2 attribute vec3 vNormal;

4 uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;

6 uniform mat3 normalMatrix;

8 uniform vec4 ambientProduct;uniform vec4 diffuseProduct;

10 uniform vec4 specularProduct;uniform float shininess;

12 uniform vec4 lightPosition;

14 void main(){

16 vec4 eyePosition = modelViewMatrix * vPosition;vec3 N = normalMatrix * vNormal;

18 vec3 L = lightPosition.xyz - eyePosition.xyz;vec3 E = -eyePosition.xyz;

20 vec3 R = reflect(-E, N);

22 N = normalize(N);L = normalize(L);

24 E = normalize(E);

26 float NdotL = dot(N, L);float Kd = max(NdotL , �.�);

28 float Ks = (NdotL < �.�) ? �.� : pow(max(dot(R, E), �.�), shininess);

30 vec4 diffuse = Kd * diffuseProduct;vec4 specular = Ks * specularProduct;

32 vec4 ambient = ambientProduct;

34 gl_Position = projectionMatrix * eyePosition;gl_FrontColor = ambient + diffuse + specular;

36 gl_FrontColor.a = 1.�;}

Listing 3. File vgouraud.glsl.

1 void main(){

3 gl_FragColor = gl_Color;}

Listing 4. File fgouraud.glsl.

attribute vec4 vPosition;2 attribute vec3 vNormal;

4 uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;

6 uniform mat3 normalMatrix;

8 uniform vec4 lightPosition;

Page 21: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

10 varying vec3 fN;varying vec3 fE;

12 varying vec3 fL;

14 void main(){

16 vec4 eyePosition = modelViewMatrix * vPosition;

18 fN = normalMatrix * vNormal;fL = lightPosition.xyz - eyePosition.xyz;

20 fE = -eyePosition.xyz;

22 gl_Position = projectionMatrix * eyePosition;}

Listing 5. File vphong.glsl.

1 varying vec3 fN;varying vec3 fE;

3 varying vec3 fL;

5 uniform vec4 ambientProduct;uniform vec4 diffuseProduct;

7 uniform vec4 specularProduct;uniform float shininess;

9void main()

11 {vec3 N = normalize(fN);

13 vec3 E = normalize(fE);vec3 L = normalize(fL);

15 vec3 R = normalize (2.� * dot(L, N) * N - L);

17 float NdotL = dot(N, L);float Kd = max(NdotL , �.�);

19 float Ks = (NdotL < �.�) ? �.� : pow(max(dot(R, E), �.�), shininess);

21 vec4 diffuse = Kd * diffuseProduct;vec4 specular = Ks * specularProduct;

23 vec4 ambient = ambientProduct;

25 gl_FragColor = ambient + diffuse + specular;gl_FragColor.a = 1.�;

27 }

Listing 6. File fphong.glsl.

1 attribute vec4 vPosition;attribute vec3 vNormal;

3 attribute vec2 vTexCoord;

5 uniform mat4 modelViewMatrix;uniform mat4 projectionMatrix;

7 uniform mat3 normalMatrix;

9 uniform vec4 lightPosition;

11 varying vec3 fN;varying vec3 fE;

13 varying vec3 fL;varying vec2 fTexCoord;

15void main()

17 {vec4 eyePosition = modelViewMatrix * vPosition;

19fN = normalMatrix * vNormal;

21 fL = lightPosition.xyz - eyePosition.xyz;fE = -eyePosition.xyz;

23 fTexCoord = vTexCoord;

25 gl_Position = projectionMatrix * eyePosition;}

Listing 7. File vtexture.glsl.

varying vec3 fN;2 varying vec3 fE;

varying vec3 fL;4 varying vec2 fTexCoord;

6 uniform vec4 ambientProduct;uniform vec4 diffuseProduct;

8 uniform vec4 specularProduct;uniform float shininess;

10uniform sampler2D texColorMap;

12void main()

14 {

vec3 N = normalize(fN);16 vec3 E = normalize(fE);

vec3 L = normalize(fL);18 vec3 R = normalize (2.� * dot(L, N) * N - L);

20 float NdotL = dot(N, L);float Kd = max(NdotL , �.�);

22 float Ks = (NdotL < �.�) ? �.� : pow(max(dot(R, E), �.�), shininess);

24 vec4 diffuse = Kd * diffuseProduct;vec4 specular = Ks * specularProduct;

26 vec4 ambient = ambientProduct;

28 gl_FragColor = (ambient + diffuse + specular) *texture2D(texColorMap , fTexCoord);

30 gl_FragColor.a = 1.�;}

Listing 8. File ftexture.glsl.

1 attribute vec4 vPosition;attribute vec3 vNormal;

3 attribute vec2 vTexCoord;attribute vec4 vTangent;

5uniform mat4 modelViewMatrix;

7 uniform mat4 projectionMatrix;uniform mat3 normalMatrix;

9uniform vec4 lightPosition;

11varying vec3 fE;

13 varying vec3 fL;varying vec2 fTexCoord;

15void main()

17 {vec3 bitangent = vTangent.w * cross(vNormal , vTangent.

xyz);19 vec3 T = normalMatrix * vTangent.xyz;

vec3 B = normalMatrix * bitangent;21 vec3 N = normalMatrix * vNormal;

23 mat3 TBN = mat3(T.x, B.x, N.x,T.y, B.y, N.y,

25 T.z, B.z, N.z);

27 vec4 eyePosition = modelViewMatrix * vPosition;fL = TBN * (lightPosition.xyz - eyePosition.xyz);

29 fE = TBN * (-eyePosition.xyz);

31 fTexCoord = vTexCoord;

33 gl_Position = projectionMatrix * eyePosition;}

Listing 9. File vnormal.glsl.

1 varying vec3 fE;varying vec3 fL;

3 varying vec2 fTexCoord;

5 uniform vec4 ambientProduct;uniform vec4 diffuseProduct;

7 uniform vec4 specularProduct;uniform float shininess;

9uniform sampler2D texColorMap;

11 uniform sampler2D texNormalMap;

13 void main(){

15 vec3 N = normalize(texture2D(texNormalMap , fTexCoord).rgb * 2.� - 1.�);

vec3 E = normalize(fE);17 vec3 L = normalize(fL);

vec3 R = normalize (2.� * dot(L, N) * N - L);19

float NdotL = dot(N, L);21 float Kd = max(NdotL , �.�);

float Ks = (NdotL < �.�) ? �.� : pow(max(dot(R, E), �.�), shininess);

23vec4 diffuse = Kd * diffuseProduct;

25 vec4 specular = Ks * specularProduct;vec4 ambient = ambientProduct;

27gl_FragColor = (ambient + diffuse + specular) *

29 texture2D(texColorMap , fTexCoord);gl_FragColor.a = 1.�;

31 }

Listing 10. File fnormal.glsl.

Page 22: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

IV. VIRTUAL TRACKBALL CLASS

Our implementation of the virtual trackball was basedon both the book by Angel and Shreiner [5] and on theBoxes Demo available on Qt framework 4.8 [26]. We usethe class QQuaternion to represent rotations in 3D space usingquaternions.

1 #ifndef TRACKBALL_H#define TRACKBALL_H

3#include <QVector3D >

5 #include <QQuaternion >#include <QTime >

7#include <cmath >

9class TrackBall

11 {public:

13 TrackBall ();void mouseMove(const QPointF& p);

15 void mousePress(const QPointF& p);void mouseRelease(const QPointF& p);

17 void resizeViewport(int width , int height);QQuaternion getRotation ();

19private:

21 QQuaternion rotation;QVector3D axis;

23 double velocity;

25 QVector3D lastPos3D;QTime lastTime;

27 bool trackingMouse;

29 double viewportWidth;double viewportHeight;

31const double rad2deg;

33QVector3D mousePosTo3D(const QPointF& p);

35 };

37 #endif

Listing 11. File trackball.h.

1 #include "trackball.h"

3 TrackBall :: TrackBall () : rad2deg (18�.� / M_PI){

5 velocity = �.�;trackingMouse = false;

7 lastTime = QTime:: currentTime ();}

9void TrackBall :: mouseMove(const QPointF &p)

11 {if (! trackingMouse)

13 return;

15 QTime currentTime = QTime:: currentTime ();int msecs = lastTime.msecsTo(currentTime);

17 if (msecs) {QVector3D vp = mousePosTo3D(p);

19 QVector3D currentPos3D = QVector3D(vp.x(), vp.y(),�.�);

double lenSqr = currentPos3D.lengthSquared ();21 (lenSqr >= 1.�) ? currentPos3D.normalize () :

currentPos3D.setZ(sqrt (1.� -lenSqr));

23axis = QVector3D :: crossProduct(lastPos3D ,

currentPos3D);25 double angle = rad2deg * axis.length ();

velocity = angle / msecs;27 axis.normalize ();

rotation = QQuaternion :: fromAxisAndAngle(axis , angle) * rotation;

29lastPos3D = currentPos3D;

31 lastTime = currentTime;}

33 }

35 void TrackBall :: mousePress(const QPointF &p){

37 rotation = getRotation ();trackingMouse = true;

39 lastTime = QTime:: currentTime ();

41 lastPos3D = mousePosTo3D(p);double lenSqr = lastPos3D.lengthSquared ();

43 (lenSqr >= 1.�) ? lastPos3D.normalize () :lastPos3D.setZ(sqrt (1.� - lenSqr));

45velocity = �.�;

47 }

49 void TrackBall :: mouseRelease(const QPointF &p){

51 mouseMove(p);trackingMouse = false;

53 }

55 void TrackBall :: resizeViewport(int width , int height){

57 viewportWidth = static_cast <double >(width);viewportHeight = static_cast <double >( height);

59 }

61 QQuaternion TrackBall :: getRotation (){

63 if (trackingMouse)return rotation;

65QTime currentTime = QTime:: currentTime ();

67 double angle = velocity * lastTime.msecsTo(currentTime);return QQuaternion :: fromAxisAndAngle(axis , angle) *

rotation;69 }

71 QVector3D TrackBall :: mousePosTo3D(const QPointF &p){

73 return QVector3D (2.� * p.x() / viewportWidth - 1.�,1.� - 2.� * p.y() / viewportHeight ,

75 �.�);}

Listing 12. File trackball.cpp.

V. AUXILIARY CLASSES FOR PHONG LIGHTING MODEL

#ifndef CAMERA_H2 #define CAMERA_H

4 #include <QVector3D >

6 class Camera{

8 public:Camera ();

10QVector3D eye;

12 QVector3D at;QVector3D up;

14 };#endif // CAMERA_H

Listing 13. File camera.h.

1 #include "camera.h"

3 Camera :: Camera (){

5 eye = QVector3D (�.�, �.�, 1.�);at = QVector3D (�.�, �.�, �.�);

7 up = QVector3D (�.�, 1.�, �.�);}

Listing 14. File camera.cpp

#ifndef LIGHT_H2 #define LIGHT_H

4 #include <QVector4D >

6 class Light{

8 public:Light();

10QVector4D position;

12 QVector4D ambient;QVector4D diffuse;

14 QVector4D specular;};

16#endif // LIGHT_H

Listing 15. File light.h.

Page 23: Contacts Interactive Graphics Applications with OpenGL Shading Language … · 2012-12-04 · An improved Qt application with OpenGL - 3 An improved Qt application with OpenGL - 4

1 #include "light.h"

3 Light::Light(){

5 position = QVector4D (3.�, 3.�, 3.�, �.�);ambient = QVector4D (�.1, �.1, �.1, 1.�);

7 diffuse = QVector4D (�.9, �.9, �.9, 1.�);specular = QVector4D (�.9, �.9, �.9, 1.�);

9 }

Listing 16. File light.cpp.

1 #ifndef MATERIAL_H#define MATERIAL_H

3#include <QVector4D >

5class Material

7 {public:

9 Material ();

11 QVector4D ambient;QVector4D diffuse;

13 QVector4D specular;double shininess;

15 };

17 #endif // MATERIAL_H

Listing 17. File material.h.

1 #include "material.h"

3 Material :: Material (){

5 ambient = QVector4D (1.�, 1.�, 1.�, 1.�);diffuse = QVector4D (�.6, �.6, �.6, 1.�);

7 specular = QVector4D (�.4, �.4, �.4, 1.�);shininess = 2��.�;

9 }

Listing 18. File material.cpp.

REFERENCES

[1] “Opengl – the industry standard for high performance graphics,” 2012.[Online]. Available: http://www.opengl.org/

[2] “Glut – the opengl utility toolkit,” 2012. [Online]. Available:http://www.opengl.org/resources/libraries/glut/

[3] Qt, “Qt–cross-platform application and ui framework,” 2012. [Online].Available: http://qt.nokia.com/

[4] ——, “Qt in use,” 2012. [Online]. Available: http://qt.nokia.com/qt-in-use

[5] E. Angel and D. Shreiner, Interactive Computer Graphics: A top-downapproach with shader-based opengl, 6th ed. Addison Wesley, 2011.

[6] M. P. B. Donald D Hearn and W. Carithers, Computer Graphics withOpenGL. Prentice Hall, 2010.

[7] D. Wolff, OpenGL 4.0 Shading Language Cookbook. Pactk Publishing,2011.

[8] R. Marroquim and A. Maximo, “Introduction to gpu programmingwith glsl,” in Computer Graphics and Image Processing (SIBGRAPITUTORIALS), 2009 Tutorials of the XXII Brazilian Symposium on, oct.2009, pp. 3 –16.

[9] “Off file format,” 2012. [Online]. Available: http://www.geomview.org/docs/html/OFF.html

[10] Qt, “Qtopengl module,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/qtopengl.html

[11] ——, “Developing qt,” 2012. [Online]. Available: http://qt-project.org/wiki/Category:Developing_Qt

[12] “qmake variable reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/qmake-variable-reference.html

[13] Qt, “Qglwidget class reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/QGLWidget.html

[14] ——, “Layout management,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/layout.html

[15] ——, “Signals & slots,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/signalsandslots.html

[16] ——, “Qfile class reference,” 2012. [Online]. Available: http://doc-snapshot.qt-project.org/4.8/qfile.html

[17] E. Lengyel, Mathematics for 3D Game Programming and ComputerGraphics, 3rd ed. Course Technology PTR, 2011.

[18] ——, “Computing tangent space basis vectors for an arbitrary mesh.terathon software 3d graphics library,” 2001. [Online]. Available:http://www.terathon.com/code/tangent.html

[19] Qt, “The qt resource system,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/resources.html

[20] M. J. Kilgard, “Modern opengl usage: using vertex buffer objectswell,” in ACM SIGGRAPH ASIA 2008 courses, ser. SIGGRAPH Asia’08. New York, NY, USA: ACM, 2008, pp. 49:1–49:19. [Online].Available: http://doi.acm.org/10.1145/1508044.1508093

[21] Qt, “Qglbuffer class reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/qglbuffer.html

[22] “The event system,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/eventsandfilters.html

[23] Qt, “Qmatrix4x4 class reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/qmatrix4x4.html

[24] QT, “Qglformat class reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/QGLFormat.html

[25] Qt, “Qpainter class reference,” 2012. [Online]. Available: http://qt-project.org/doc/qt-4.8/qpainter.html

[26] ——, “Boxes | documentation | qt developer network,” 2012. [Online].Available: http://qt-project.org/doc/qt-4.8/demos-boxes.html

[27] ——, “Qt3d module,” 2012. [Online]. Available: http://doc-snapshot.qt-project.org/5.0/qt3d-reference.html