summaryrefslogtreecommitdiffstats
path: root/examples/opengl
diff options
context:
space:
mode:
authorSarah Smith <sarah.j.smith@nokia.com>2009-10-01 15:49:32 +1000
committerSarah Smith <sarah.j.smith@nokia.com>2009-10-01 15:49:32 +1000
commit059d40d3f918f658041ec20ba04f9d010cfc0fa7 (patch)
tree35e5d01fdbfdd941495e7955e538954ce9a00ac4 /examples/opengl
parent5496fbd5f4e5f272ba4f8150c909206ad409fd1d (diff)
Remove display lists and refactor ready for ES/ES2 port
Display lists, and a few other features dont work in ES/ES2. Refaoctor to allow redo of lighting and other non-fixed-function pipeline features. Also use QAnimation* classes instead of timers, and correct a few minor bugs (flipped texture). Include new screenshot (old one manifested bug). Reviewed-by: Rhys Weatherley
Diffstat (limited to 'examples/opengl')
-rw-r--r--examples/opengl/pbuffers/cube.cpp332
-rw-r--r--examples/opengl/pbuffers/cube.h147
-rw-r--r--examples/opengl/pbuffers/glwidget.cpp273
-rw-r--r--examples/opengl/pbuffers/glwidget.h43
-rw-r--r--examples/opengl/pbuffers/main.cpp2
-rw-r--r--examples/opengl/pbuffers/pbuffers.pro20
6 files changed, 649 insertions, 168 deletions
diff --git a/examples/opengl/pbuffers/cube.cpp b/examples/opengl/pbuffers/cube.cpp
new file mode 100644
index 0000000000..0f6d15fe86
--- /dev/null
+++ b/examples/opengl/pbuffers/cube.cpp
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cube.h"
+#include "glwidget.h"
+
+#include <QtGui/QImage>
+#include <QtCore/QPropertyAnimation>
+
+static const qreal FACE_SIZE = 0.4;
+
+static const qreal speeds[] = { 1.8f, 2.4f, 3.6f };
+static const qreal amplitudes[] = { 2.0f, 2.5f, 3.0f };
+
+static inline void qSetColor(float colorVec[], QColor c)
+{
+ colorVec[0] = c.redF();
+ colorVec[1] = c.greenF();
+ colorVec[2] = c.blueF();
+ colorVec[3] = c.alphaF();
+}
+
+int Geometry::append(const QVector3D &a, const QVector3D &n, const QVector2D &t)
+{
+ int v = vertices.count();
+ vertices.append(a);
+ normals.append(n);
+ texCoords.append(t);
+ faces.append(v);
+ colors.append(QVector4D(0.6f, 0.6f, 0.6f, 1.0f));
+ return v;
+}
+
+void Geometry::addQuad(const QVector3D &a, const QVector3D &b,
+ const QVector3D &c, const QVector3D &d,
+ const QVector<QVector2D> &tex)
+{
+ QVector3D norm = QVector3D::normal(a, b, c);
+ // append first triangle
+ int aref = append(a, norm, tex[0]);
+ append(b, norm, tex[1]);
+ int cref = append(c, norm, tex[2]);
+ // append second triangle
+ faces.append(aref);
+ faces.append(cref);
+ append(d, norm, tex[3]);
+}
+
+void Geometry::loadArrays() const
+{
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
+ glNormalPointer(GL_FLOAT, 0, normals.constData());
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
+ glColorPointer(4, GL_FLOAT, 0, colors.constData());
+}
+
+void Geometry::setColors(int start, GLfloat colorArray[4][4])
+{
+ int off = faces[start];
+ for (int i = 0; i < 4; ++i)
+ colors[i + off] = QVector4D(colorArray[i][0],
+ colorArray[i][1],
+ colorArray[i][2],
+ colorArray[i][3]);
+}
+
+Tile::Tile(const QVector3D &loc)
+ : location(loc)
+ , start(0)
+ , count(0)
+ , useFlatColor(false)
+ , geom(0)
+{
+ qSetColor(faceColor, QColor(Qt::darkGray));
+}
+
+void Tile::setColors(GLfloat colorArray[4][4])
+{
+ useFlatColor = true;
+ geom->setColors(start, colorArray);
+}
+
+static inline void qMultMatrix(const QMatrix4x4 &mat)
+{
+ if (sizeof(qreal) == sizeof(GLfloat))
+ glMultMatrixf((GLfloat*)mat.constData());
+#ifndef QT_OPENGL_ES
+ else if (sizeof(qreal) == sizeof(GLdouble))
+ glMultMatrixd((GLdouble*)mat.constData());
+#endif
+ else
+ {
+ GLfloat fmat[16];
+ qreal const *r = mat.constData();
+ for (int i = 0; i < 16; ++i)
+ fmat[i] = r[i];
+ glMultMatrixf(fmat);
+ }
+}
+
+void Tile::draw() const
+{
+ QMatrix4x4 mat;
+ mat.translate(location);
+ mat.rotate(orientation);
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ qMultMatrix(mat);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor);
+ glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, geom->indices() + start);
+ glPopMatrix();
+}
+
+TileBuilder::TileBuilder(Geometry *g, qreal depth, qreal size)
+ : verts(4)
+ , tex(4)
+ , start(g->count())
+ , count(0)
+ , geom(g)
+{
+ // front face - make a square with bottom-left at origin
+ verts[br].setX(size);
+ verts[tr].setX(size);
+ verts[tr].setY(size);
+ verts[tl].setY(size);
+
+ // these vert numbers are good for the tex-coords
+ for (int i = 0; i < 4; ++i)
+ tex[i] = verts[i].toVector2D();
+
+ // now move verts half cube width across so cube is centered on origin
+ for (int i = 0; i < 4; ++i)
+ verts[i] -= QVector3D(size / 2.0f, size / 2.0f, -depth);
+
+ // add the front face
+ g->addQuad(verts[bl], verts[br], verts[tr], verts[tl], tex);
+
+ count = g->count() - start;
+}
+
+void TileBuilder::initialize(Tile *tile) const
+{
+ tile->start = start;
+ tile->count = count;
+ tile->geom = geom;
+ qSetColor(tile->faceColor, color);
+}
+
+Tile *TileBuilder::newTile(const QVector3D &loc) const
+{
+ Tile *tile = new Tile(loc);
+ initialize(tile);
+ return tile;
+}
+
+Cube::Cube(const QVector3D &loc)
+ : Tile(loc)
+ , rot(0.0f)
+ , r(0), a(0)
+{
+}
+
+Cube::~Cube()
+{
+}
+
+void Cube::setAltitude(qreal a)
+{
+ if (location.y() != a)
+ {
+ location.setY(a);
+ emit changed();
+ }
+}
+
+void Cube::setRange(qreal r)
+{
+ if (location.x() != r)
+ {
+ location.setX(r);
+ emit changed();
+ }
+}
+
+void Cube::setRotation(qreal r)
+{
+ if (r != rot)
+ {
+ orientation = QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 1.0f, 1.0f), r);
+ emit changed();
+ }
+}
+
+void Cube::removeBounce()
+{
+ delete a;
+ a = 0;
+ delete r;
+ r = 0;
+}
+
+void Cube::startAnimation()
+{
+ if (r)
+ {
+ r->start();
+ r->setCurrentTime(startx);
+ }
+ if (a)
+ a->start();
+ if (rtn)
+ rtn->start();
+}
+
+void Cube::setAnimationPaused(bool paused)
+{
+ if (paused)
+ {
+ if (r)
+ r->pause();
+ if (a)
+ a->pause();
+ if (rtn)
+ rtn->pause();
+ }
+ else
+ {
+ if (r)
+ r->resume();
+ if (a)
+ a->resume();
+ if (rtn)
+ rtn->resume();
+ }
+}
+
+CubeBuilder::CubeBuilder(Geometry *g, qreal depth, qreal size)
+ : TileBuilder(g, depth)
+ , ix(0)
+{
+ for (int i = 0; i < 4; ++i)
+ verts[i].setZ(size / 2.0f);
+ // back face - "extrude" verts down
+ QVector<QVector3D> back(verts);
+ for (int i = 0; i < 4; ++i)
+ back[i].setZ(-size / 2.0f);
+
+ // add the back face
+ g->addQuad(back[br], back[bl], back[tl], back[tr], tex);
+
+ // add the sides
+ g->addQuad(back[bl], back[br], verts[br], verts[bl], tex);
+ g->addQuad(back[br], back[tr], verts[tr], verts[br], tex);
+ g->addQuad(back[tr], back[tl], verts[tl], verts[tr], tex);
+ g->addQuad(back[tl], back[bl], verts[bl], verts[tl], tex);
+
+ count = g->count() - start;
+}
+
+Cube *CubeBuilder::newCube(const QVector3D &loc) const
+{
+ Cube *c = new Cube(loc);
+ initialize(c);
+ qreal d = 4000.0f;
+ qreal d3 = d / 3.0f;
+ // Animate movement from left to right
+ c->r = new QPropertyAnimation(c, "range");
+ c->r->setStartValue(-1.3f);
+ c->r->setEndValue(1.3f);
+ c->startx = ix * d3 * 3.0f;
+ c->r->setDuration(d * 4.0f);
+ c->r->setLoopCount(-1);
+ c->r->setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve));
+ // Animate movement from bottom to top
+ c->a = new QPropertyAnimation(c, "altitude");
+ c->a->setEndValue(loc.y());
+ c->a->setStartValue(loc.y() + amplitudes[ix]);
+ c->a->setDuration(d / speeds[ix]);
+ c->a->setLoopCount(-1);
+ c->a->setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve));
+ // Animate rotation
+ c->rtn = new QPropertyAnimation(c, "rotation");
+ c->rtn->setStartValue(c->rot);
+ c->rtn->setEndValue(359.0f);
+ c->rtn->setDuration(d * 2.0f);
+ c->rtn->setLoopCount(-1);
+ c->rtn->setDuration(d / 2);
+ ix = (ix + 1) % 3;
+ return c;
+}
diff --git a/examples/opengl/pbuffers/cube.h b/examples/opengl/pbuffers/cube.h
new file mode 100644
index 0000000000..4f29b7d664
--- /dev/null
+++ b/examples/opengl/pbuffers/cube.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CUBE_H
+#define CUBE_H
+
+#include <QtOpenGl/qgl.h>
+#include <QtCore/qvector.h>
+#include <QtGui/qmatrix4x4.h>
+#include <QtGui/qvector3d.h>
+#include <QtGui/qvector2d.h>
+
+class QPropertyAnimation;
+
+class Geometry
+{
+public:
+ void loadArrays() const;
+ void addQuad(const QVector3D &a, const QVector3D &b,
+ const QVector3D &c, const QVector3D &d,
+ const QVector<QVector2D> &tex);
+ void setColors(int start, GLfloat colors[4][4]);
+ const GLushort *indices() const { return faces.constData(); }
+ int count() const { return faces.count(); }
+private:
+ QVector<GLushort> faces;
+ QVector<QVector3D> vertices;
+ QVector<QVector3D> normals;
+ QVector<QVector2D> texCoords;
+ QVector<QVector4D> colors;
+ int append(const QVector3D &a, const QVector3D &n, const QVector2D &t);
+ void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n);
+ friend class Tile;
+};
+
+class Tile
+{
+public:
+ void draw() const;
+ void setColors(GLfloat[4][4]);
+protected:
+ Tile(const QVector3D &loc = QVector3D());
+ QVector3D location;
+ QQuaternion orientation;
+private:
+ int start;
+ int count;
+ bool useFlatColor;
+ GLfloat faceColor[4];
+ Geometry *geom;
+ friend class TileBuilder;
+};
+
+class TileBuilder
+{
+public:
+ enum { bl, br, tr, tl };
+ TileBuilder(Geometry *, qreal depth = 0.0f, qreal size = 1.0f);
+ Tile *newTile(const QVector3D &loc = QVector3D()) const;
+ void setColor(QColor c) { color = c; }
+protected:
+ void initialize(Tile *) const;
+ QVector<QVector3D> verts;
+ QVector<QVector2D> tex;
+ int start;
+ int count;
+ Geometry *geom;
+ QColor color;
+};
+
+class Cube : public QObject, public Tile
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal range READ range WRITE setRange);
+ Q_PROPERTY(qreal altitude READ altitude WRITE setAltitude);
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation);
+public:
+ Cube(const QVector3D &loc = QVector3D());
+ ~Cube();
+ qreal range() { return location.x(); }
+ void setRange(qreal r);
+ qreal altitude() { return location.y(); }
+ void setAltitude(qreal a);
+ qreal rotation() { return rot; }
+ void setRotation(qreal r);
+ void removeBounce();
+ void startAnimation();
+ void setAnimationPaused(bool paused);
+signals:
+ void changed();
+private:
+ qreal rot;
+ QPropertyAnimation *r;
+ QPropertyAnimation *a;
+ QPropertyAnimation *rtn;
+ qreal startx;
+ friend class CubeBuilder;
+};
+
+class CubeBuilder : public TileBuilder
+{
+public:
+ CubeBuilder(Geometry *, qreal depth = 0.0f, qreal size = 1.0f);
+ Cube *newCube(const QVector3D &loc = QVector3D()) const;
+private:
+ mutable int ix;
+};
+
+#endif // CUBE_H
diff --git a/examples/opengl/pbuffers/glwidget.cpp b/examples/opengl/pbuffers/glwidget.cpp
index fbd551858d..56ba65b73d 100644
--- a/examples/opengl/pbuffers/glwidget.cpp
+++ b/examples/opengl/pbuffers/glwidget.cpp
@@ -40,216 +40,187 @@
****************************************************************************/
#include "glwidget.h"
-#include <QtGui/QImage>
-
#include <math.h>
-static GLint cubeArray[][3] = {
- {0, 0, 0}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0},
- {0, 0, 1}, {1, 0, 1}, {1, 1, 1}, {0, 1, 1},
- {0, 0, 0}, {1, 0, 0}, {1, 0, 1}, {0, 0, 1},
- {0, 1, 0}, {0, 1, 1}, {1, 1, 1}, {1, 1, 0},
- {0, 1, 0}, {0, 0, 0}, {0, 0, 1}, {0, 1, 1},
- {1, 0, 0}, {1, 1, 0}, {1, 1, 1}, {1, 0, 1}
-};
+#include "cube.h"
-static GLint cubeTextureArray[][2] = {
- {0, 0}, {1, 0}, {1, 1}, {0, 1},
- {0, 0}, {0, 1}, {1, 1}, {1, 0},
- {0, 0}, {1, 0}, {1, 1}, {0, 1},
- {1, 0}, {0, 0}, {0, 1}, {1, 1},
- {0, 0}, {1, 0}, {1, 1}, {0, 1},
- {1, 0}, {0, 0}, {0, 1}, {1, 1}
-};
+#include <QGLPixelBuffer>
-static GLint faceArray[][2] = {
- {1, -1}, {1, 1}, {-1, 1}, {-1, -1}
-};
+#ifndef GL_MULTISAMPLE
+#define GL_MULTISAMPLE 0x809D
+#endif
-static GLubyte colorArray[][4] = {
- {102, 176, 54, 255},
- {81, 141, 41, 255},
- {62, 108, 32, 255},
- {45, 79, 23, 255}
+static GLfloat colorArray[][4] = {
+ {0.243f, 0.423f, 0.125f, 1.0f},
+ {0.176f, 0.31f, 0.09f, 1.0f},
+ {0.4f, 0.69f, 0.212f, 1.0f},
+ {0.317f, 0.553f, 0.161f, 1.0f}
};
GLWidget::GLWidget(QWidget *parent)
- : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+ : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+ , geom(0)
+ , cube(0)
{
// create the pbuffer
pbuffer = new QGLPixelBuffer(QSize(512, 512), format(), this);
- timerId = startTimer(20);
setWindowTitle(tr("OpenGL pbuffers"));
+ initializeGeometry();
}
GLWidget::~GLWidget()
{
pbuffer->releaseFromDynamicTexture();
glDeleteTextures(1, &dynamicTexture);
- glDeleteLists(pbufferList, 1);
delete pbuffer;
+
+ qDeleteAll(cubes);
+ qDeleteAll(tiles);
+ delete cube;
}
void GLWidget::initializeGL()
{
- glMatrixMode(GL_MODELVIEW);
-
- glEnable(GL_CULL_FACE);
initCommon();
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
+ glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
initPbuffer();
-
- for (int i = 0; i < 3; ++i) {
- yOffs[i] = 0.0f;
- xInc[i] = 0.005f;
- rot[i] = 0.0f;
+ cube->startAnimation();
+ connect(cube, SIGNAL(changed()), this, SLOT(update()));
+ for (int i = 0; i < 3; ++i)
+ {
+ cubes[i]->startAnimation();
+ connect(cubes[i], SIGNAL(changed()), this, SLOT(update()));
}
- xOffs[0]= 0.0f;
- xOffs[1]= 0.5f;
- xOffs[2]= 1.0f;
-
- cubeTexture = bindTexture(QImage(":res/cubelogo.png"));
-}
-
-void GLWidget::resizeGL(int w, int h)
-{
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- float aspect = w/(float)(h ? h : 1);
- glFrustum(-aspect, aspect, -1, 1, 10, 100);
- glTranslatef(-0.5f, -0.5f, -0.5f);
- glTranslatef(0.0f, 0.0f, -15.0f);
}
void GLWidget::paintGL()
{
- // draw a spinning cube into the pbuffer..
pbuffer->makeCurrent();
- glBindTexture(GL_TEXTURE_2D, cubeTexture);
- glCallList(pbufferList);
- glFlush();
-
- // rendering directly to a texture is not supported on X11 and
- // some Windows implementations, unfortunately
+ drawPbuffer();
+ // On direct render platforms, drawing onto the pbuffer context above
+ // automatically updates the dynamic texture. For cases where rendering
+ // directly to a texture is not supported, explicitly copy.
if (!hasDynamicTextureUpdate)
pbuffer->updateDynamicTexture(dynamicTexture);
-
- // ..and use the pbuffer contents as a texture when rendering the
- // background and the bouncing cubes
makeCurrent();
+
+ // Use the pbuffer as a texture to render the scene
glBindTexture(GL_TEXTURE_2D, dynamicTexture);
+
+ // set up to render the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glLoadIdentity();
+ glTranslatef(0.0f, 0.0f, -10.0f);
// draw the background
- glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- glVertexPointer(2, GL_INT, 0, faceArray);
- glTranslatef(-1.2f, -0.8f, 0.0f);
- glScalef(0.2f, 0.2f, 0.2f);
- for (int y = 0; y < 5; ++y) {
- for (int x = 0; x < 5; ++x) {
- glTranslatef(2.0f, 0, 0);
- glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
- glDrawArrays(GL_QUADS, 0, 4);
- }
- glTranslatef(-10.0f, 2.0f, 0);
- }
- glVertexPointer(3, GL_INT, 0, cubeArray);
-
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
+ glScalef(aspect, 1.0f, 1.0f);
+ for (int i = 0; i < tiles.count(); ++i)
+ tiles[i]->draw();
glPopMatrix();
// draw the bouncing cubes
- drawCube(0, 0.0f, 1.5f, 2.5f, 1.5f);
- drawCube(1, 1.0f, 2.0f, 2.5f, 2.0f);
- drawCube(2, 2.0f, 3.5f, 2.5f, 2.5f);
+ for (int i = 0; i < cubes.count(); ++i)
+ cubes[i]->draw();
}
-void GLWidget::drawCube(int i, GLfloat z, GLfloat rotation, GLfloat jmp, GLfloat amp)
+void GLWidget::initializeGeometry()
{
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(xOffs[i], yOffs[i], z);
- glTranslatef(0.5f, 0.5f, 0.5f);
- GLfloat scale = 0.75 + i*(0.25f/2);
- glScalef(scale, scale, scale);
- glRotatef(rot[i], 1.0f, 1.0f, 1.0f);
- glTranslatef(-0.5f, -0.5f, -0.5f);
-
- glColor4f(1.0f, 1.0f, 1.0f, 0.8f);
- glDrawArrays(GL_QUADS, 0, 24);
-
- if (xOffs[i] > 1.0f || xOffs[i] < -1.0f) {
- xInc[i] = -xInc[i];
- xOffs[i] = xOffs[i] > 1.0f ? 1.0f : -1.0f;
- }
- xOffs[i] += xInc[i];
- yOffs[i] = qAbs(cos((-3.141592f * jmp) * xOffs[i]) * amp) - 1;
- rot[i] += rotation;
+ geom = new Geometry();
+ CubeBuilder cBuilder(geom, 0.5);
+ cBuilder.setColor(QColor(255, 255, 255, 212));
+ // build the 3 bouncing, spinning cubes
+ for (int i = 0; i < 3; ++i)
+ cubes.append(cBuilder.newCube(QVector3D((float)(i-1), -1.5f, 5 - i)));
+
+ // build the spinning cube which goes in the dynamic texture
+ cube = cBuilder.newCube();
+ cube->removeBounce();
+
+ // build the background tiles
+ TileBuilder tBuilder(geom);
+ tBuilder.setColor(QColor(Qt::white));
+ for (int c = -2; c <= +2; ++c)
+ for (int r = -2; r <= +2; ++r)
+ tiles.append(tBuilder.newTile(QVector3D(c, r, 0)));
+
+ // graded backdrop for the pbuffer scene
+ TileBuilder bBuilder(geom, 0.0f, 2.0f);
+ bBuilder.setColor(QColor(102, 176, 54, 210));
+ backdrop = bBuilder.newTile(QVector3D(0.0f, 0.0f, -1.5f));
+ backdrop->setColors(colorArray);
}
void GLWidget::initCommon()
{
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(3, GL_INT, 0, cubeArray);
- glTexCoordPointer(2, GL_INT, 0, cubeTextureArray);
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, colorArray);
+ qglClearColor(QColor(Qt::darkGray));
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_MULTISAMPLE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
+
glEnable(GL_TEXTURE_2D);
- glEnable(GL_DEPTH_TEST);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ geom->loadArrays();
}
-void GLWidget::initPbuffer()
+void GLWidget::perspectiveProjection()
{
- // set up the pbuffer context
- pbuffer->makeCurrent();
- initCommon();
-
- glViewport(0, 0, pbuffer->size().width(), pbuffer->size().height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(-1, 1, -1, 1, -99, 99);
- glTranslatef(-0.5f, -0.5f, 0.0f);
+ glFrustum(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0);
glMatrixMode(GL_MODELVIEW);
+}
+
+void GLWidget::orthographicProjection()
+{
+ glMatrixMode(GL_PROJECTION);
glLoadIdentity();
+ glOrtho(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0);
+ glMatrixMode(GL_MODELVIEW);
+}
+
+void GLWidget::resizeGL(int width, int height)
+{
+ glViewport(0, 0, width, height);
+ aspect = (qreal)width / (qreal)(height ? height : 1);
+ perspectiveProjection();
+}
+
+void GLWidget::drawPbuffer()
+{
+ orthographicProjection();
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glDisable(GL_TEXTURE_2D);
+ backdrop->draw();
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, cubeTexture);
+ glDisable(GL_CULL_FACE);
+ cube->draw();
+ glEnable(GL_CULL_FACE);
+
+ glFlush();
+}
+
+void GLWidget::initPbuffer()
+{
+ pbuffer->makeCurrent();
+
+ cubeTexture = bindTexture(QImage(":res/cubelogo.png"));
+
+ initCommon();
- pbufferList = glGenLists(1);
- glNewList(pbufferList, GL_COMPILE);
- {
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
- // draw cube background
- glPushMatrix();
- glLoadIdentity();
- glTranslatef(0.5f, 0.5f, -2.0f);
- glDisable(GL_TEXTURE_2D);
- glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(2, GL_INT, 0, faceArray);
- glDrawArrays(GL_QUADS, 0, 4);
- glVertexPointer(3, GL_INT, 0, cubeArray);
- glDisableClientState(GL_COLOR_ARRAY);
- glEnable(GL_TEXTURE_2D);
- glPopMatrix();
-
- // draw cube
- glTranslatef(0.5f, 0.5f, 0.5f);
- glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
- glTranslatef(-0.5f, -0.5f, -0.5f);
- glColor4f(0.9f, 0.9f, 0.9f, 1.0f);
- glDrawArrays(GL_QUADS, 0, 24);
- }
- glEndList();
// generate a texture that has the same size/format as the pbuffer
dynamicTexture = pbuffer->generateDynamicTexture();
@@ -258,3 +229,9 @@ void GLWidget::initPbuffer()
makeCurrent();
}
+void GLWidget::setAnimationPaused(bool enable)
+{
+ cube->setAnimationPaused(enable);
+ for (int i = 0; i < 3; ++i)
+ cubes[i]->setAnimationPaused(enable);
+}
diff --git a/examples/opengl/pbuffers/glwidget.h b/examples/opengl/pbuffers/glwidget.h
index 5b64b08b5c..991e8b9692 100644
--- a/examples/opengl/pbuffers/glwidget.h
+++ b/examples/opengl/pbuffers/glwidget.h
@@ -39,32 +39,49 @@
**
****************************************************************************/
-#include <QtOpenGL>
+#ifndef GLWIDGET_H
+#define GLWIDGET_H
+
+#include <QGLWidget>
+
+class Geometry;
+class Cube;
+class Tile;
class GLWidget : public QGLWidget
{
public:
- GLWidget(QWidget *parent);
+ GLWidget(QWidget *parent = 0);
~GLWidget();
+
+protected:
void initializeGL();
- void resizeGL(int w, int h);
void paintGL();
- void timerEvent(QTimerEvent *) { update(); }
- void mousePressEvent(QMouseEvent *) { killTimer(timerId); }
- void mouseReleaseEvent(QMouseEvent *) { timerId = startTimer(20); }
+ void resizeGL(int width, int height);
+ void mousePressEvent(QMouseEvent *) { setAnimationPaused(true); }
+ void mouseReleaseEvent(QMouseEvent *) { setAnimationPaused(false); }
- void drawCube(int i, GLfloat z, GLfloat ri, GLfloat jmp, GLfloat amp);
- void initCommon();
+private:
+ void initializeGeometry();
void initPbuffer();
+ void initCommon();
+ void perspectiveProjection();
+ void orthographicProjection();
+ void drawPbuffer();
+ void setAnimationPaused(bool enable);
-private:
- GLfloat rot[3], xOffs[3], yOffs[3], xInc[3];
- GLuint pbufferList;
+ qreal aspect;
GLuint dynamicTexture;
GLuint cubeTexture;
- int timerId;
bool hasDynamicTextureUpdate;
-
QGLPixelBuffer *pbuffer;
+ Geometry *geom;
+ Cube *cube;
+ Tile *backdrop;
+ QList<Cube *> cubes;
+ QList<Tile *> tiles;
+
};
+//! [3]
+#endif
diff --git a/examples/opengl/pbuffers/main.cpp b/examples/opengl/pbuffers/main.cpp
index cb9e161aae..4efe9a8fc3 100644
--- a/examples/opengl/pbuffers/main.cpp
+++ b/examples/opengl/pbuffers/main.cpp
@@ -41,6 +41,8 @@
#include <QtGui/QApplication>
#include <QtGui/QMessageBox>
+#include <QtOpenGL/QGLPixelBuffer>
+
#include "glwidget.h"
int main(int argc, char **argv)
diff --git a/examples/opengl/pbuffers/pbuffers.pro b/examples/opengl/pbuffers/pbuffers.pro
index 4f7740e8e7..1c21596520 100644
--- a/examples/opengl/pbuffers/pbuffers.pro
+++ b/examples/opengl/pbuffers/pbuffers.pro
@@ -1,13 +1,19 @@
-HEADERS += glwidget.h
-SOURCES += glwidget.cpp main.cpp
+HEADERS += glwidget.h \
+ cube.h
+SOURCES += glwidget.cpp \
+ main.cpp \
+ cube.cpp
RESOURCES += pbuffers.qrc
-
QT += opengl
# install
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers
-sources.files = $$SOURCES $$HEADERS $$RESOURCES pbuffers.pro *.png
+sources.files = $$SOURCES \
+ $$HEADERS \
+ $$RESOURCES \
+ pbuffers.pro \
+ *.png
sources.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers
-INSTALLS += target sources
-
-symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)
+INSTALLS += target \
+ sources
+symbian:include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri)