diff options
author | Sarah Smith <sarah.j.smith@nokia.com> | 2009-10-01 05:49:32 (GMT) |
---|---|---|
committer | Sarah Smith <sarah.j.smith@nokia.com> | 2009-10-01 05:49:32 (GMT) |
commit | 059d40d3f918f658041ec20ba04f9d010cfc0fa7 (patch) | |
tree | 35e5d01fdbfdd941495e7955e538954ce9a00ac4 /examples/opengl | |
parent | 5496fbd5f4e5f272ba4f8150c909206ad409fd1d (diff) | |
download | Qt-059d40d3f918f658041ec20ba04f9d010cfc0fa7.zip Qt-059d40d3f918f658041ec20ba04f9d010cfc0fa7.tar.gz Qt-059d40d3f918f658041ec20ba04f9d010cfc0fa7.tar.bz2 |
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.cpp | 332 | ||||
-rw-r--r-- | examples/opengl/pbuffers/cube.h | 147 | ||||
-rw-r--r-- | examples/opengl/pbuffers/glwidget.cpp | 273 | ||||
-rw-r--r-- | examples/opengl/pbuffers/glwidget.h | 43 | ||||
-rw-r--r-- | examples/opengl/pbuffers/main.cpp | 2 | ||||
-rw-r--r-- | examples/opengl/pbuffers/pbuffers.pro | 20 |
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 0000000..0f6d15f --- /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 0000000..4f29b7d --- /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 fbd5518..56ba65b 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 5b64b08..991e8b9 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 cb9e161..4efe9a8 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 4f7740e..1c21596 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) |