diff options
Diffstat (limited to 'examples/opengl/legacy')
47 files changed, 4704 insertions, 0 deletions
diff --git a/examples/opengl/legacy/README b/examples/opengl/legacy/README new file mode 100644 index 0000000000..8d6cbdef2a --- /dev/null +++ b/examples/opengl/legacy/README @@ -0,0 +1,4 @@ +This directory contains legacy examples that use the fixed pipeline +and thus are not compatible with OpenGL ES 2.0+ and the core profile of +OpenGL 3.0+. They also rely on the Qt OpenGL module (e.g. QGLWidget) which +is not advisable in new application. diff --git a/examples/opengl/legacy/framebufferobject2/cubelogo.png b/examples/opengl/legacy/framebufferobject2/cubelogo.png Binary files differnew file mode 100644 index 0000000000..3ae0f9ba3f --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/cubelogo.png diff --git a/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro new file mode 100644 index 0000000000..e0067cf27f --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro @@ -0,0 +1,15 @@ +HEADERS += glwidget.h +SOURCES += glwidget.cpp main.cpp +RESOURCES += framebufferobject2.qrc + +QT += opengl widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/framebufferobject2 +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/framebufferobject2/framebufferobject2.qrc b/examples/opengl/legacy/framebufferobject2/framebufferobject2.qrc new file mode 100644 index 0000000000..9fc1a56a1a --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/framebufferobject2.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/res"> + <file>cubelogo.png</file> +</qresource> +</RCC> diff --git a/examples/opengl/legacy/framebufferobject2/glwidget.cpp b/examples/opengl/legacy/framebufferobject2/glwidget.cpp new file mode 100644 index 0000000000..32b9799a4a --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/glwidget.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#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} +}; + +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} +}; + +static GLint faceArray[][2] = { + {1, -1}, {1, 1}, {-1, 1}, {-1, -1} +}; + +static GLubyte colorArray[][4] = { + {102, 176, 54, 255}, + {81, 141, 41, 255}, + {62, 108, 32, 255}, + {45, 79, 23, 255} +}; + +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) +{ + // create the framebuffer object - make sure to have a current + // context before creating it + makeCurrent(); + fbo = new QGLFramebufferObject(512, 512); + timerId = startTimer(20); + setWindowTitle(tr("OpenGL framebuffer objects 2")); +} + +GLWidget::~GLWidget() +{ + glDeleteLists(pbufferList, 1); + delete fbo; +} + +void GLWidget::initializeGL() +{ + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_CULL_FACE); + + 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); + + 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); + 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); + + glPushMatrix(); // this state is popped back in the paintGL() function + } + glEndList(); + + for (int i = 0; i < 3; ++i) { + yOffs[i] = 0.0f; + xInc[i] = 0.005f; + rot[i] = 0.0f; + } + xOffs[0]= 0.0f; + xOffs[1]= 0.5f; + xOffs[2]= 1.0f; + + cubeTexture = bindTexture(QImage(":res/cubelogo.png")); + + glPushMatrix(); // push to avoid stack underflow in the first paintGL() call +} + +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() +{ + glPopMatrix(); // pop the matrix pushed in the pbuffer list + + // push the projection matrix and the entire GL state before + // doing any rendering into our framebuffer object + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glViewport(0, 0, fbo->size().width(), fbo->size().height()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1, 1, -1, 1, -99, 99); + glTranslatef(-0.5f, -0.5f, 0.0f); + glMatrixMode(GL_MODELVIEW); + + // render to the framebuffer object + fbo->bind(); + glBindTexture(GL_TEXTURE_2D, cubeTexture); + glCallList(pbufferList); + fbo->release(); + + // pop the projection matrix and GL state back for rendering + // to the actual widget + glPopAttrib(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D, fbo->texture()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // 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); + + // 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); + glPopMatrix(); +} + +void GLWidget::drawCube(int i, GLfloat z, GLfloat rotation, GLfloat jmp, GLfloat amp) +{ + 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; +} diff --git a/examples/opengl/legacy/framebufferobject2/glwidget.h b/examples/opengl/legacy/framebufferobject2/glwidget.h new file mode 100644 index 0000000000..2991a4fdf2 --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/glwidget.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtOpenGL> + +class GLWidget : public QGLWidget +{ +public: + GLWidget(QWidget *parent); + ~GLWidget(); + void initializeGL() Q_DECL_OVERRIDE; + void resizeGL(int w, int h) Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE { update(); } + void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE { killTimer(timerId); } + void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE { timerId = startTimer(20); } + + void drawCube(int i, GLfloat z, GLfloat ri, GLfloat jmp, GLfloat amp); + +private: + GLfloat rot[3], xOffs[3], yOffs[3], xInc[3]; + GLuint pbufferList; + GLuint cubeTexture; + int timerId; + + QGLFramebufferObject *fbo; +}; + diff --git a/examples/opengl/legacy/framebufferobject2/main.cpp b/examples/opengl/legacy/framebufferobject2/main.cpp new file mode 100644 index 0000000000..4c9aa9840f --- /dev/null +++ b/examples/opengl/legacy/framebufferobject2/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QMessageBox> +#include "glwidget.h" + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(framebufferobject2); + + QApplication a(argc, argv); + if (!QGLFormat::hasOpenGL() || !QGLFramebufferObject::hasOpenGLFramebufferObjects()) { + QMessageBox::information(0, "OpenGL framebuffer objects 2", + "This system does not support OpenGL/framebuffer objects."); + return -1; + } + + GLWidget widget(0); + widget.resize(640, 480); + widget.show(); + return a.exec(); +} + diff --git a/examples/opengl/legacy/grabber/glwidget.cpp b/examples/opengl/legacy/grabber/glwidget.cpp new file mode 100644 index 0000000000..abe3a8540a --- /dev/null +++ b/examples/opengl/legacy/grabber/glwidget.cpp @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" + +#include <QMouseEvent> +#include <QTimer> + +#include <math.h> + +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(parent) +{ + gear1 = 0; + gear2 = 0; + gear3 = 0; + xRot = 0; + yRot = 0; + zRot = 0; + gear1Rot = 0; + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(advanceGears())); + timer->start(20); +} + +GLWidget::~GLWidget() +{ + makeCurrent(); + glDeleteLists(gear1, 1); + glDeleteLists(gear2, 1); + glDeleteLists(gear3, 1); +} + +void GLWidget::setXRotation(int angle) +{ + normalizeAngle(&angle); + if (angle != xRot) { + xRot = angle; + emit xRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setYRotation(int angle) +{ + normalizeAngle(&angle); + if (angle != yRot) { + yRot = angle; + emit yRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::setZRotation(int angle) +{ + normalizeAngle(&angle); + if (angle != zRot) { + zRot = angle; + emit zRotationChanged(angle); + updateGL(); + } +} + +void GLWidget::initializeGL() +{ + static const GLfloat lightPos[4] = { 5.0f, 5.0f, 10.0f, 1.0f }; + static const GLfloat reflectance1[4] = { 0.8f, 0.1f, 0.0f, 1.0f }; + static const GLfloat reflectance2[4] = { 0.0f, 0.8f, 0.2f, 1.0f }; + static const GLfloat reflectance3[4] = { 0.2f, 0.2f, 1.0f, 1.0f }; + + glLightfv(GL_LIGHT0, GL_POSITION, lightPos); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + gear1 = makeGear(reflectance1, 1.0, 4.0, 1.0, 0.7, 20); + gear2 = makeGear(reflectance2, 0.5, 2.0, 2.0, 0.7, 10); + gear3 = makeGear(reflectance3, 1.3, 2.0, 0.5, 0.7, 10); + + glEnable(GL_NORMALIZE); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); +} + +void GLWidget::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotated(xRot / 16.0, 1.0, 0.0, 0.0); + glRotated(yRot / 16.0, 0.0, 1.0, 0.0); + glRotated(zRot / 16.0, 0.0, 0.0, 1.0); + + drawGear(gear1, -3.0, -2.0, 0.0, gear1Rot / 16.0); + drawGear(gear2, +3.1, -2.0, 0.0, -2.0 * (gear1Rot / 16.0) - 9.0); + + glRotated(+90.0, 1.0, 0.0, 0.0); + drawGear(gear3, -3.1, -1.8, -2.2, +2.0 * (gear1Rot / 16.0) - 2.0); + + glPopMatrix(); +} + +void GLWidget::resizeGL(int width, int height) +{ + int side = qMin(width, height); + glViewport((width - side) / 2, (height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslated(0.0, 0.0, -40.0); +} + +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + lastPos = event->pos(); +} + +void GLWidget::mouseMoveEvent(QMouseEvent *event) +{ + int dx = event->x() - lastPos.x(); + int dy = event->y() - lastPos.y(); + + if (event->buttons() & Qt::LeftButton) { + setXRotation(xRot + 8 * dy); + setYRotation(yRot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setXRotation(xRot + 8 * dy); + setZRotation(zRot + 8 * dx); + } + lastPos = event->pos(); +} + +void GLWidget::advanceGears() +{ + gear1Rot += 2 * 16; + updateGL(); +} + +GLuint GLWidget::makeGear(const GLfloat *reflectance, GLdouble innerRadius, + GLdouble outerRadius, GLdouble thickness, + GLdouble toothSize, GLint toothCount) +{ + const double Pi = 3.14159265358979323846; + + GLuint list = glGenLists(1); + glNewList(list, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance); + + GLdouble r0 = innerRadius; + GLdouble r1 = outerRadius - toothSize / 2.0; + GLdouble r2 = outerRadius + toothSize / 2.0; + GLdouble delta = (2.0 * Pi / toothCount) / 4.0; + GLdouble z = thickness / 2.0; + + glShadeModel(GL_FLAT); + + for (int i = 0; i < 2; ++i) { + GLdouble sign = (i == 0) ? +1.0 : -1.0; + + glNormal3d(0.0, 0.0, sign); + + glBegin(GL_QUAD_STRIP); + for (int j = 0; j <= toothCount; ++j) { + GLdouble angle = 2.0 * Pi * j / toothCount; + glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z); + glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z); + glVertex3d(r0 * cos(angle), r0 * sin(angle), sign * z); + glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta), sign * z); + } + glEnd(); + + glBegin(GL_QUADS); + for (int j = 0; j < toothCount; ++j) { + GLdouble angle = 2.0 * Pi * j / toothCount; + glVertex3d(r1 * cos(angle), r1 * sin(angle), sign * z); + glVertex3d(r2 * cos(angle + delta), r2 * sin(angle + delta), sign * z); + glVertex3d(r2 * cos(angle + 2 * delta), r2 * sin(angle + 2 * delta), sign * z); + glVertex3d(r1 * cos(angle + 3 * delta), r1 * sin(angle + 3 * delta), sign * z); + } + glEnd(); + } + + glBegin(GL_QUAD_STRIP); + for (int i = 0; i < toothCount; ++i) { + for (int j = 0; j < 2; ++j) { + GLdouble angle = 2.0 * Pi * (i + j / 2.0) / toothCount; + GLdouble s1 = r1; + GLdouble s2 = r2; + if (j == 1) + qSwap(s1, s2); + + glNormal3d(cos(angle), sin(angle), 0.0); + glVertex3d(s1 * cos(angle), s1 * sin(angle), +z); + glVertex3d(s1 * cos(angle), s1 * sin(angle), -z); + + glNormal3d(s2 * sin(angle + delta) - s1 * sin(angle), + s1 * cos(angle) - s2 * cos(angle + delta), 0.0); + glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), +z); + glVertex3d(s2 * cos(angle + delta), s2 * sin(angle + delta), -z); + } + } + glVertex3d(r1, 0.0, +z); + glVertex3d(r1, 0.0, -z); + glEnd(); + + glShadeModel(GL_SMOOTH); + + glBegin(GL_QUAD_STRIP); + for (int i = 0; i <= toothCount; ++i) { + GLdouble angle = i * 2.0 * Pi / toothCount; + glNormal3d(-cos(angle), -sin(angle), 0.0); + glVertex3d(r0 * cos(angle), r0 * sin(angle), +z); + glVertex3d(r0 * cos(angle), r0 * sin(angle), -z); + } + glEnd(); + + glEndList(); + + return list; +} + +void GLWidget::drawGear(GLuint gear, GLdouble dx, GLdouble dy, GLdouble dz, + GLdouble angle) +{ + glPushMatrix(); + glTranslated(dx, dy, dz); + glRotated(angle, 0.0, 0.0, 1.0); + glCallList(gear); + glPopMatrix(); +} + +void GLWidget::normalizeAngle(int *angle) +{ + while (*angle < 0) + *angle += 360 * 16; + while (*angle > 360 * 16) + *angle -= 360 * 16; +} diff --git a/examples/opengl/legacy/grabber/glwidget.h b/examples/opengl/legacy/grabber/glwidget.h new file mode 100644 index 0000000000..12071be173 --- /dev/null +++ b/examples/opengl/legacy/grabber/glwidget.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include <QGLWidget> + +class GLWidget : public QGLWidget +{ + Q_OBJECT + +public: + GLWidget(QWidget *parent = 0); + ~GLWidget(); + + int xRotation() const { return xRot; } + int yRotation() const { return yRot; } + int zRotation() const { return zRot; } + +public slots: + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + +signals: + void xRotationChanged(int angle); + void yRotationChanged(int angle); + void zRotationChanged(int angle); + +protected: + void initializeGL() Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void resizeGL(int width, int height) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private slots: + void advanceGears(); + +private: + GLuint makeGear(const GLfloat *reflectance, GLdouble innerRadius, + GLdouble outerRadius, GLdouble thickness, + GLdouble toothSize, GLint toothCount); + void drawGear(GLuint gear, GLdouble dx, GLdouble dy, GLdouble dz, + GLdouble angle); + void normalizeAngle(int *angle); + + GLuint gear1; + GLuint gear2; + GLuint gear3; + int xRot; + int yRot; + int zRot; + int gear1Rot; + + QPoint lastPos; +}; + +#endif // GLWIDGET_H diff --git a/examples/opengl/legacy/grabber/grabber.pro b/examples/opengl/legacy/grabber/grabber.pro new file mode 100644 index 0000000000..b8567580f0 --- /dev/null +++ b/examples/opengl/legacy/grabber/grabber.pro @@ -0,0 +1,16 @@ +HEADERS = glwidget.h \ + mainwindow.h +SOURCES = glwidget.cpp \ + main.cpp \ + mainwindow.cpp +QT += opengl widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/grabber +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/grabber/main.cpp b/examples/opengl/legacy/grabber/main.cpp new file mode 100644 index 0000000000..145e4120ef --- /dev/null +++ b/examples/opengl/legacy/grabber/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" + +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); +} diff --git a/examples/opengl/legacy/grabber/mainwindow.cpp b/examples/opengl/legacy/grabber/mainwindow.cpp new file mode 100644 index 0000000000..9f82ee10ba --- /dev/null +++ b/examples/opengl/legacy/grabber/mainwindow.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" +#include "mainwindow.h" + +#include <QtWidgets> + +MainWindow::MainWindow() +{ + centralWidget = new QWidget; + setCentralWidget(centralWidget); + + glWidget = new GLWidget; + pixmapLabel = new QLabel; + + glWidgetArea = new QScrollArea; + glWidgetArea->setWidget(glWidget); + glWidgetArea->setWidgetResizable(true); + glWidgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + glWidgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + glWidgetArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + glWidgetArea->setMinimumSize(50, 50); + + pixmapLabelArea = new QScrollArea; + pixmapLabelArea->setWidget(pixmapLabel); + pixmapLabelArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + pixmapLabelArea->setMinimumSize(50, 50); + + xSlider = createSlider(SIGNAL(xRotationChanged(int)), + SLOT(setXRotation(int))); + ySlider = createSlider(SIGNAL(yRotationChanged(int)), + SLOT(setYRotation(int))); + zSlider = createSlider(SIGNAL(zRotationChanged(int)), + SLOT(setZRotation(int))); + + createActions(); + createMenus(); + + QGridLayout *centralLayout = new QGridLayout; + centralLayout->addWidget(glWidgetArea, 0, 0); + centralLayout->addWidget(pixmapLabelArea, 0, 1); + centralLayout->addWidget(xSlider, 1, 0, 1, 2); + centralLayout->addWidget(ySlider, 2, 0, 1, 2); + centralLayout->addWidget(zSlider, 3, 0, 1, 2); + centralWidget->setLayout(centralLayout); + + xSlider->setValue(15 * 16); + ySlider->setValue(345 * 16); + zSlider->setValue(0 * 16); + + setWindowTitle(tr("Grabber")); + resize(400, 300); +} + +void MainWindow::renderIntoPixmap() +{ + QSize size = getSize(); + if (size.isValid()) { + QPixmap pixmap = glWidget->renderPixmap(size.width(), size.height()); + setPixmap(pixmap); + } +} + +void MainWindow::grabFrameBuffer() +{ + QImage image = glWidget->grabFrameBuffer(); + setPixmap(QPixmap::fromImage(image)); +} + +void MainWindow::clearPixmap() +{ + setPixmap(QPixmap()); +} + +void MainWindow::about() +{ + QMessageBox::about(this, tr("About Grabber"), + tr("The <b>Grabber</b> example demonstrates two approaches for " + "rendering OpenGL into a Qt pixmap.")); +} + +void MainWindow::createActions() +{ + renderIntoPixmapAct = new QAction(tr("&Render into Pixmap..."), this); + renderIntoPixmapAct->setShortcut(tr("Ctrl+R")); + connect(renderIntoPixmapAct, SIGNAL(triggered()), + this, SLOT(renderIntoPixmap())); + + grabFrameBufferAct = new QAction(tr("&Grab Frame Buffer"), this); + grabFrameBufferAct->setShortcut(tr("Ctrl+G")); + connect(grabFrameBufferAct, SIGNAL(triggered()), + this, SLOT(grabFrameBuffer())); + + clearPixmapAct = new QAction(tr("&Clear Pixmap"), this); + clearPixmapAct->setShortcut(tr("Ctrl+L")); + connect(clearPixmapAct, SIGNAL(triggered()), this, SLOT(clearPixmap())); + + exitAct = new QAction(tr("E&xit"), this); + exitAct->setShortcuts(QKeySequence::Quit); + connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + + aboutAct = new QAction(tr("&About"), this); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + + aboutQtAct = new QAction(tr("About &Qt"), this); + connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); +} + +void MainWindow::createMenus() +{ + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(renderIntoPixmapAct); + fileMenu->addAction(grabFrameBufferAct); + fileMenu->addAction(clearPixmapAct); + fileMenu->addSeparator(); + fileMenu->addAction(exitAct); + + helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(aboutAct); + helpMenu->addAction(aboutQtAct); +} + +QSlider *MainWindow::createSlider(const char *changedSignal, + const char *setterSlot) +{ + QSlider *slider = new QSlider(Qt::Horizontal); + slider->setRange(0, 360 * 16); + slider->setSingleStep(16); + slider->setPageStep(15 * 16); + slider->setTickInterval(15 * 16); + slider->setTickPosition(QSlider::TicksRight); + connect(slider, SIGNAL(valueChanged(int)), glWidget, setterSlot); + connect(glWidget, changedSignal, slider, SLOT(setValue(int))); + return slider; +} + +void MainWindow::setPixmap(const QPixmap &pixmap) +{ + pixmapLabel->setPixmap(pixmap); + QSize size = pixmap.size() / pixmap.devicePixelRatio(); + if (size - QSize(1, 0) == pixmapLabelArea->maximumViewportSize()) + size -= QSize(1, 0); + pixmapLabel->resize(size); +} + +QSize MainWindow::getSize() +{ + bool ok; + QString text = QInputDialog::getText(this, tr("Grabber"), + tr("Enter pixmap size:"), + QLineEdit::Normal, + tr("%1 x %2").arg(glWidget->width()) + .arg(glWidget->height()), + &ok); + if (!ok) + return QSize(); + + QRegExp regExp(tr("([0-9]+) *x *([0-9]+)")); + if (regExp.exactMatch(text)) { + int width = regExp.cap(1).toInt(); + int height = regExp.cap(2).toInt(); + if (width > 0 && width < 2048 && height > 0 && height < 2048) + return QSize(width, height); + } + + return glWidget->size(); +} diff --git a/examples/opengl/legacy/grabber/mainwindow.h b/examples/opengl/legacy/grabber/mainwindow.h new file mode 100644 index 0000000000..a7895bf4c4 --- /dev/null +++ b/examples/opengl/legacy/grabber/mainwindow.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +class QLabel; +class QMenu; +class QScrollArea; +class QSlider; +QT_END_NAMESPACE + +class GLWidget; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private slots: + void renderIntoPixmap(); + void grabFrameBuffer(); + void clearPixmap(); + void about(); + +private: + void createActions(); + void createMenus(); + QSlider *createSlider(const char *changedSignal, const char *setterSlot); + void setPixmap(const QPixmap &pixmap); + QSize getSize(); + + QWidget *centralWidget; + QScrollArea *glWidgetArea; + QScrollArea *pixmapLabelArea; + GLWidget *glWidget; + QLabel *pixmapLabel; + QSlider *xSlider; + QSlider *ySlider; + QSlider *zSlider; + + QMenu *fileMenu; + QMenu *helpMenu; + QAction *grabFrameBufferAct; + QAction *renderIntoPixmapAct; + QAction *clearPixmapAct; + QAction *exitAct; + QAction *aboutAct; + QAction *aboutQtAct; +}; + +#endif // MAINWINDOW_H diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp new file mode 100644 index 0000000000..3a9faaca5f --- /dev/null +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets> +#include <QtOpenGL> + +#include <math.h> + +#include "glwidget.h" +#include "qtlogo.h" + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +//! [0] +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) +{ + logo = 0; + xRot = 0; + yRot = 0; + zRot = 0; + + qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0); + qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0); +} +//! [0] + +//! [1] +GLWidget::~GLWidget() +{ +} +//! [1] + +//! [2] +QSize GLWidget::minimumSizeHint() const +{ + return QSize(50, 50); +} +//! [2] + +//! [3] +QSize GLWidget::sizeHint() const +//! [3] //! [4] +{ + return QSize(400, 400); +} +//! [4] + +static void qNormalizeAngle(int &angle) +{ + while (angle < 0) + angle += 360 * 16; + while (angle > 360 * 16) + angle -= 360 * 16; +} + +//! [5] +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != xRot) { + xRot = angle; + emit xRotationChanged(angle); + update(); + } +} +//! [5] + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != yRot) { + yRot = angle; + emit yRotationChanged(angle); + update(); + } +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != zRot) { + zRot = angle; + emit zRotationChanged(angle); + update(); + } +} + +//! [6] +void GLWidget::initializeGL() +{ + qglClearColor(qtPurple.dark()); + + logo = new QtLogo(this, 64); + logo->setColor(qtGreen.dark()); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glShadeModel(GL_SMOOTH); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_MULTISAMPLE); + static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 }; + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); +} +//! [6] + +//! [7] +void GLWidget::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); + glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); + glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); + glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); + logo->draw(); +} +//! [7] + +//! [8] +void GLWidget::resizeGL(int width, int height) +{ + int side = qMin(width, height); + glViewport((width - side) / 2, (height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); +#else + glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +//! [8] + +//! [9] +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + lastPos = event->pos(); +} +//! [9] + +//! [10] +void GLWidget::mouseMoveEvent(QMouseEvent *event) +{ + int dx = event->x() - lastPos.x(); + int dy = event->y() - lastPos.y(); + + if (event->buttons() & Qt::LeftButton) { + setXRotation(xRot + 8 * dy); + setYRotation(yRot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setXRotation(xRot + 8 * dy); + setZRotation(zRot + 8 * dx); + } + lastPos = event->pos(); +} +//! [10] diff --git a/examples/opengl/legacy/hellogl/glwidget.h b/examples/opengl/legacy/hellogl/glwidget.h new file mode 100644 index 0000000000..0989be1dc6 --- /dev/null +++ b/examples/opengl/legacy/hellogl/glwidget.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include <QGLWidget> + +class QtLogo; + +//! [0] +class GLWidget : public QGLWidget +{ + Q_OBJECT + +public: + GLWidget(QWidget *parent = 0); + ~GLWidget(); + + QSize minimumSizeHint() const Q_DECL_OVERRIDE; + QSize sizeHint() const Q_DECL_OVERRIDE; +//! [0] + +//! [1] +public slots: + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + +signals: + void xRotationChanged(int angle); + void yRotationChanged(int angle); + void zRotationChanged(int angle); +//! [1] + +//! [2] +protected: + void initializeGL() Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void resizeGL(int width, int height) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; +//! [2] + +//! [3] +private: + QtLogo *logo; + int xRot; + int yRot; + int zRot; + QPoint lastPos; + QColor qtGreen; + QColor qtPurple; +}; +//! [3] + +#endif diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro new file mode 100644 index 0000000000..500bd85b3c --- /dev/null +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -0,0 +1,21 @@ +VPATH += ../shared +INCLUDEPATH += ../shared + +HEADERS = glwidget.h \ + window.h \ + qtlogo.h +SOURCES = glwidget.cpp \ + main.cpp \ + window.cpp \ + qtlogo.cpp +QT += opengl widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/hellogl/main.cpp b/examples/opengl/legacy/hellogl/main.cpp new file mode 100644 index 0000000000..2e83a11e95 --- /dev/null +++ b/examples/opengl/legacy/hellogl/main.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QDesktopWidget> + +#include "window.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Window window; + window.resize(window.sizeHint()); + int desktopArea = QApplication::desktop()->width() * + QApplication::desktop()->height(); + int widgetArea = window.width() * window.height(); + if (((float)widgetArea / (float)desktopArea) < 0.75f) + window.show(); + else + window.showMaximized(); + return app.exec(); +} diff --git a/examples/opengl/legacy/hellogl/window.cpp b/examples/opengl/legacy/hellogl/window.cpp new file mode 100644 index 0000000000..2a85bbec57 --- /dev/null +++ b/examples/opengl/legacy/hellogl/window.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets> + +#include "glwidget.h" +#include "window.h" + +//! [0] +Window::Window() +{ + glWidget = new GLWidget; + + xSlider = createSlider(); + ySlider = createSlider(); + zSlider = createSlider(); + + connect(xSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setXRotation(int))); + connect(glWidget, SIGNAL(xRotationChanged(int)), xSlider, SLOT(setValue(int))); + connect(ySlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setYRotation(int))); + connect(glWidget, SIGNAL(yRotationChanged(int)), ySlider, SLOT(setValue(int))); + connect(zSlider, SIGNAL(valueChanged(int)), glWidget, SLOT(setZRotation(int))); + connect(glWidget, SIGNAL(zRotationChanged(int)), zSlider, SLOT(setValue(int))); +//! [0] + +//! [1] + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(glWidget); + mainLayout->addWidget(xSlider); + mainLayout->addWidget(ySlider); + mainLayout->addWidget(zSlider); + setLayout(mainLayout); + + xSlider->setValue(15 * 16); + ySlider->setValue(345 * 16); + zSlider->setValue(0 * 16); + setWindowTitle(tr("Hello GL")); +} +//! [1] + +//! [2] +QSlider *Window::createSlider() +{ + QSlider *slider = new QSlider(Qt::Vertical); + slider->setRange(0, 360 * 16); + slider->setSingleStep(16); + slider->setPageStep(15 * 16); + slider->setTickInterval(15 * 16); + slider->setTickPosition(QSlider::TicksRight); + return slider; +} +//! [2] + +void Window::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + close(); + else + QWidget::keyPressEvent(e); +} diff --git a/examples/opengl/legacy/hellogl/window.h b/examples/opengl/legacy/hellogl/window.h new file mode 100644 index 0000000000..900e6b13fc --- /dev/null +++ b/examples/opengl/legacy/hellogl/window.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QSlider; +QT_END_NAMESPACE +//! [0] +class GLWidget; + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(); + +protected: + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + +private: + QSlider *createSlider(); + + GLWidget *glWidget; + QSlider *xSlider; + QSlider *ySlider; + QSlider *zSlider; +}; +//! [0] + +#endif diff --git a/examples/opengl/legacy/legacy.pro b/examples/opengl/legacy/legacy.pro new file mode 100644 index 0000000000..0a74d50f7f --- /dev/null +++ b/examples/opengl/legacy/legacy.pro @@ -0,0 +1,16 @@ +requires(qtHaveModule(opengl)) + +TEMPLATE = subdirs + +!contains(QT_CONFIG, dynamicgl): !contains(QT_CONFIG, opengles2) { + # legacy desktop-only examples, no dynamic GL support + SUBDIRS = \ + grabber \ + hellogl \ + overpainting \ + pbuffers \ + framebufferobject2 \ + samplebuffers +} + +EXAMPLE_FILES = shared diff --git a/examples/opengl/legacy/overpainting/bubble.cpp b/examples/opengl/legacy/overpainting/bubble.cpp new file mode 100644 index 0000000000..dbcb72bc93 --- /dev/null +++ b/examples/opengl/legacy/overpainting/bubble.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bubble.h" + +Bubble::Bubble(const QPointF &position, qreal radius, const QPointF &velocity) + : position(position), vel(velocity), radius(radius) +{ + innerColor = randomColor(); + outerColor = randomColor(); + updateBrush(); +} + +void Bubble::updateBrush() +{ + QRadialGradient gradient(QPointF(radius, radius), radius, + QPointF(radius*0.5, radius*0.5)); + + gradient.setColorAt(0, QColor(255, 255, 255, 255)); + gradient.setColorAt(0.25, innerColor); + gradient.setColorAt(1, outerColor); + brush = QBrush(gradient); +} + +void Bubble::drawBubble(QPainter *painter) +{ + painter->save(); + painter->translate(position.x() - radius, position.y() - radius); + painter->setBrush(brush); + painter->drawEllipse(0, 0, int(2*radius), int(2*radius)); + painter->restore(); +} + +QColor Bubble::randomColor() +{ + int red = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); + int green = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); + int blue = int(205 + 50.0*qrand()/(RAND_MAX+1.0)); + int alpha = int(91 + 100.0*qrand()/(RAND_MAX+1.0)); + + return QColor(red, green, blue, alpha); +} + +void Bubble::move(const QRect &bbox) +{ + position += vel; + qreal leftOverflow = position.x() - radius - bbox.left(); + qreal rightOverflow = position.x() + radius - bbox.right(); + qreal topOverflow = position.y() - radius - bbox.top(); + qreal bottomOverflow = position.y() + radius - bbox.bottom(); + + if (leftOverflow < 0.0) { + position.setX(position.x() - 2 * leftOverflow); + vel.setX(-vel.x()); + } else if (rightOverflow > 0.0) { + position.setX(position.x() - 2 * rightOverflow); + vel.setX(-vel.x()); + } + + if (topOverflow < 0.0) { + position.setY(position.y() - 2 * topOverflow); + vel.setY(-vel.y()); + } else if (bottomOverflow > 0.0) { + position.setY(position.y() - 2 * bottomOverflow); + vel.setY(-vel.y()); + } +} + +QRectF Bubble::rect() +{ + return QRectF(position.x() - radius, position.y() - radius, + 2 * radius, 2 * radius); +} diff --git a/examples/opengl/legacy/overpainting/bubble.h b/examples/opengl/legacy/overpainting/bubble.h new file mode 100644 index 0000000000..10d24b8af7 --- /dev/null +++ b/examples/opengl/legacy/overpainting/bubble.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BUBBLE_H +#define BUBBLE_H + +#include <QPainter> + +class Bubble +{ +public: + Bubble(const QPointF &position, qreal radius, const QPointF &velocity); + + void drawBubble(QPainter *painter); + void updateBrush(); + void move(const QRect &bbox); + QRectF rect(); + +private: + QColor randomColor(); + + QBrush brush; + QPointF position; + QPointF vel; + qreal radius; + QColor innerColor; + QColor outerColor; +}; + +#endif // BUBBLE_H diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp new file mode 100644 index 0000000000..420ae3e881 --- /dev/null +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bubble.h" +#include "qtlogo.h" +#include "glwidget.h" + +#include <QMouseEvent> +#include <QTime> + +#include <math.h> +#include <stdlib.h> + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +//! [0] +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) +{ + QTime midnight(0, 0, 0); + qsrand(midnight.secsTo(QTime::currentTime())); + + logo = 0; + xRot = 0; + yRot = 0; + zRot = 0; + + qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0); + qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0); + + animationTimer.setSingleShot(false); + connect(&animationTimer, SIGNAL(timeout()), this, SLOT(animate())); + animationTimer.start(25); + + setAutoFillBackground(false); + setMinimumSize(200, 200); + setWindowTitle(tr("Overpainting a Scene")); +} +//! [0] + +//! [1] +GLWidget::~GLWidget() +{ +} +//! [1] + +static void qNormalizeAngle(int &angle) +{ + while (angle < 0) + angle += 360 * 16; + while (angle > 360 * 16) + angle -= 360 * 16; +} + +void GLWidget::setXRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != xRot) + xRot = angle; +} + +void GLWidget::setYRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != yRot) + yRot = angle; +} + +void GLWidget::setZRotation(int angle) +{ + qNormalizeAngle(angle); + if (angle != zRot) + zRot = angle; +} + +//! [2] +void GLWidget::initializeGL() +{ + glEnable(GL_MULTISAMPLE); + + logo = new QtLogo(this); + logo->setColor(qtGreen.dark()); +} +//! [2] + +void GLWidget::mousePressEvent(QMouseEvent *event) +{ + lastPos = event->pos(); +} + +void GLWidget::mouseMoveEvent(QMouseEvent *event) +{ + int dx = event->x() - lastPos.x(); + int dy = event->y() - lastPos.y(); + + if (event->buttons() & Qt::LeftButton) { + setXRotation(xRot + 8 * dy); + setYRotation(yRot + 8 * dx); + } else if (event->buttons() & Qt::RightButton) { + setXRotation(xRot + 8 * dy); + setZRotation(zRot + 8 * dx); + } + lastPos = event->pos(); +} + +void GLWidget::paintEvent(QPaintEvent *event) +{ + makeCurrent(); +//! [4] + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); +//! [4] + +//! [6] + qglClearColor(qtPurple.dark()); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_MULTISAMPLE); + static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 }; + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + + qreal pixelRatio = devicePixelRatio(); + setupViewport(width() * pixelRatio, height() * pixelRatio); +//! [6] + +//! [7] + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); + glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); + glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); + glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); + + logo->draw(); +//! [7] + +//! [8] + glShadeModel(GL_FLAT); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +//! [8] + +//! [10] + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + foreach (Bubble *bubble, bubbles) { + if (bubble->rect().intersects(event->rect())) + bubble->drawBubble(&painter); + } + drawInstructions(&painter); + painter.end(); +} +//! [10] + +//! [11] +void GLWidget::resizeGL(int width, int height) +{ + qreal pixelRatio = devicePixelRatio(); + setupViewport(width*pixelRatio, height*pixelRatio); +} +//! [11] + +//! [12] +void GLWidget::showEvent(QShowEvent *event) +{ + Q_UNUSED(event); + createBubbles(20 - bubbles.count()); +} +//! [12] + +QSize GLWidget::sizeHint() const +{ + return QSize(400, 400); +} + +void GLWidget::createBubbles(int number) +{ + for (int i = 0; i < number; ++i) { + QPointF position(width()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0))), + height()*(0.1 + (0.8*qrand()/(RAND_MAX+1.0)))); + qreal radius = qMin(width(), height())*(0.0125 + 0.0875*qrand()/(RAND_MAX+1.0)); + QPointF velocity(width()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0)), + height()*0.0125*(-0.5 + qrand()/(RAND_MAX+1.0))); + + bubbles.append(new Bubble(position, radius, velocity)); + } +} + +//! [13] +void GLWidget::animate() +{ + QMutableListIterator<Bubble*> iter(bubbles); + + while (iter.hasNext()) { + Bubble *bubble = iter.next(); + bubble->move(rect()); + } + update(); +} +//! [13] + +//! [14] +void GLWidget::setupViewport(int width, int height) +{ + int side = qMin(width, height); + glViewport((width - side) / 2, (height - side) / 2, side, side); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES + glOrthof(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0); +#else + glOrtho(-0.5, +0.5, -0.5, 0.5, 4.0, 15.0); +#endif + glMatrixMode(GL_MODELVIEW); +} +//! [14] + +//! [15] +void GLWidget::drawInstructions(QPainter *painter) +{ + QString text = tr("Click and drag with the left mouse button " + "to rotate the Qt logo."); + QFontMetrics metrics = QFontMetrics(font()); + int border = qMax(4, metrics.leading()); + + QRect rect = metrics.boundingRect(0, 0, width() - 2*border, int(height()*0.125), + Qt::AlignCenter | Qt::TextWordWrap, text); + painter->setRenderHint(QPainter::TextAntialiasing); + painter->fillRect(QRect(0, 0, width(), rect.height() + 2*border), + QColor(0, 0, 0, 127)); + painter->setPen(Qt::white); + painter->fillRect(QRect(0, 0, width(), rect.height() + 2*border), + QColor(0, 0, 0, 127)); + painter->drawText((width() - rect.width())/2, border, + rect.width(), rect.height(), + Qt::AlignCenter | Qt::TextWordWrap, text); +} +//! [15] diff --git a/examples/opengl/legacy/overpainting/glwidget.h b/examples/opengl/legacy/overpainting/glwidget.h new file mode 100644 index 0000000000..1d1d48458d --- /dev/null +++ b/examples/opengl/legacy/overpainting/glwidget.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include <QGLWidget> +#include <QTimer> + +class Bubble; +class QtLogo; + +//! [0] +class GLWidget : public QGLWidget +{ + Q_OBJECT + +public: + GLWidget(QWidget *parent = 0); + ~GLWidget(); +//! [0] + + QSize sizeHint() const Q_DECL_OVERRIDE; + int xRotation() const { return xRot; } + int yRotation() const { return yRot; } + int zRotation() const { return zRot; } + +public slots: + void setXRotation(int angle); + void setYRotation(int angle); + void setZRotation(int angle); + +//! [1] +protected: + void initializeGL() Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void resizeGL(int width, int height) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + +private slots: + void animate(); + +private: + void createBubbles(int number); + void drawInstructions(QPainter *painter); +//! [1] + void setupViewport(int width, int height); + + QColor qtGreen; + QColor qtPurple; + + GLuint object; + int xRot; + int yRot; + int zRot; + QPoint lastPos; +//! [4] + QtLogo *logo; + QList<Bubble*> bubbles; + QTimer animationTimer; +//! [4] +}; + +#endif // GLWIDGET_H diff --git a/examples/opengl/legacy/overpainting/main.cpp b/examples/opengl/legacy/overpainting/main.cpp new file mode 100644 index 0000000000..57c520b528 --- /dev/null +++ b/examples/opengl/legacy/overpainting/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" + +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + GLWidget window; + window.show(); + return app.exec(); +} diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro new file mode 100644 index 0000000000..c1bda7853d --- /dev/null +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -0,0 +1,23 @@ +QT += opengl widgets + +VPATH += ../shared +INCLUDEPATH += ../shared + +HEADERS = bubble.h \ + glwidget.h \ + qtlogo.h + +SOURCES = bubble.cpp \ + glwidget.cpp \ + main.cpp \ + qtlogo.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/overpainting +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/pbuffers/cube.cpp b/examples/opengl/legacy/pbuffers/cube.cpp new file mode 100644 index 0000000000..dc1bb23fea --- /dev/null +++ b/examples/opengl/legacy/pbuffers/cube.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "cube.h" +#include "glwidget.h" + +#include <QtGui/QImage> +#include <QtCore/QPropertyAnimation> + +static const qreal speeds[] = { 3.8f, 4.4f, 5.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); +} + +void Tile::draw() const +{ + QMatrix4x4 mat; + mat.translate(location); + mat.rotate(orientation); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMultMatrixf(mat.constData()); + 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) + , animGroup(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 animGroup; + animGroup = 0; + delete r; + r = 0; +} + +void Cube::startAnimation() +{ + if (r) + { + r->start(); + r->setCurrentTime(startx); + } + if (animGroup) + animGroup->start(); + if (rtn) + rtn->start(); +} + +void Cube::setAnimationPaused(bool paused) +{ + if (paused) + { + if (r) + r->pause(); + if (animGroup) + animGroup->pause(); + if (rtn) + rtn->pause(); + } + else + { + if (r) + r->resume(); + if (animGroup) + animGroup->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)); + + c->animGroup = new QSequentialAnimationGroup(c); + + // Animate movement from bottom to top + QPropertyAnimation *a_up = new QPropertyAnimation(c, "altitude", c->animGroup); + a_up->setEndValue(loc.y()); + a_up->setStartValue(loc.y() + amplitudes[ix]); + a_up->setDuration(d / speeds[ix]); + a_up->setLoopCount(1); + a_up->setEasingCurve(QEasingCurve(QEasingCurve::InQuad)); + + // Animate movement from top to bottom + QPropertyAnimation *a_down = new QPropertyAnimation(c, "altitude", c->animGroup); + a_down->setEndValue(loc.y() + amplitudes[ix]); + a_down->setStartValue(loc.y()); + a_down->setDuration(d / speeds[ix]); + a_down->setLoopCount(1); + a_down->setEasingCurve(QEasingCurve(QEasingCurve::OutQuad)); + + c->animGroup->addAnimation(a_up); + c->animGroup->addAnimation(a_down); + c->animGroup->setLoopCount(-1); + + // 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/legacy/pbuffers/cube.h b/examples/opengl/legacy/pbuffers/cube.h new file mode 100644 index 0000000000..05017cb376 --- /dev/null +++ b/examples/opengl/legacy/pbuffers/cube.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUBE_H +#define CUBE_H + +#include <QtOpenGL/qgl.h> +#include <QtCore/qvector.h> +#include <QtCore/qsequentialanimationgroup.h> +#include <QtGui/qmatrix4x4.h> +#include <QtGui/qvector3d.h> +#include <QtGui/qvector2d.h> + +QT_BEGIN_NAMESPACE +class QPropertyAnimation; +QT_END_NAMESPACE + +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 }; + explicit 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 *rtn; + QSequentialAnimationGroup *animGroup; + qreal startx; + friend class CubeBuilder; +}; + +class CubeBuilder : public TileBuilder +{ +public: + explicit 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/legacy/pbuffers/cubelogo.png b/examples/opengl/legacy/pbuffers/cubelogo.png Binary files differnew file mode 100644 index 0000000000..3ae0f9ba3f --- /dev/null +++ b/examples/opengl/legacy/pbuffers/cubelogo.png diff --git a/examples/opengl/legacy/pbuffers/glwidget.cpp b/examples/opengl/legacy/pbuffers/glwidget.cpp new file mode 100644 index 0000000000..b319951ccd --- /dev/null +++ b/examples/opengl/legacy/pbuffers/glwidget.cpp @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" +#include <math.h> + +#include "cube.h" + +#include <QGLPixelBuffer> + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +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) + , geom(0) + , cube(0) +{ + // create the pbuffer + QGLFormat pbufferFormat = format(); + pbufferFormat.setSampleBuffers(false); + pbuffer = new QGLPixelBuffer(QSize(512, 512), pbufferFormat, this); + setWindowTitle(tr("OpenGL pbuffers")); + initializeGeometry(); +} + +GLWidget::~GLWidget() +{ + pbuffer->releaseFromDynamicTexture(); + glDeleteTextures(1, &dynamicTexture); + delete pbuffer; + + qDeleteAll(cubes); + qDeleteAll(tiles); + delete cube; +} + +void GLWidget::initializeGL() +{ + 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(); + 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())); + } +} + +void GLWidget::paintGL() +{ + pbuffer->makeCurrent(); + 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); + 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 + glPushMatrix(); + glScalef(aspect, 1.0f, 1.0f); + for (int i = 0; i < tiles.count(); ++i) + tiles[i]->draw(); + glPopMatrix(); + + // draw the bouncing cubes + for (int i = 0; i < cubes.count(); ++i) + cubes[i]->draw(); +} + +void GLWidget::initializeGeometry() +{ + geom = new Geometry(); + CubeBuilder cBuilder(geom, 0.5); + cBuilder.setColor(QColor(255, 255, 255, 212)); + // build the 3 bouncing, spinning cubes + for (int i = 3; i > 0; --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() +{ + 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); + + geom->loadArrays(); +} + +void GLWidget::perspectiveProjection() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES + glFrustumf(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0); +#else + glFrustum(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0); +#endif + glMatrixMode(GL_MODELVIEW); +} + +void GLWidget::orthographicProjection() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef QT_OPENGL_ES + glOrthof(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0); +#else + glOrtho(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0); +#endif + glMatrixMode(GL_MODELVIEW); +} + +void GLWidget::resizeGL(int width, int height) +{ + glViewport(0, 0, width * devicePixelRatio(), height * devicePixelRatio()); + 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(); + + // generate a texture that has the same size/format as the pbuffer + dynamicTexture = pbuffer->generateDynamicTexture(); + + // bind the dynamic texture to the pbuffer - this is a no-op under X11 + hasDynamicTextureUpdate = pbuffer->bindToDynamicTexture(dynamicTexture); + 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/legacy/pbuffers/glwidget.h b/examples/opengl/legacy/pbuffers/glwidget.h new file mode 100644 index 0000000000..1d23b7772a --- /dev/null +++ b/examples/opengl/legacy/pbuffers/glwidget.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include <QGLWidget> + +class Geometry; +class Cube; +class Tile; +QT_BEGIN_NAMESPACE +class QGLPixelBuffer; +QT_END_NAMESPACE + +class GLWidget : public QGLWidget +{ +public: + GLWidget(QWidget *parent = 0); + ~GLWidget(); + +protected: + void initializeGL() Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void resizeGL(int width, int height) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE { setAnimationPaused(true); } + void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE { setAnimationPaused(false); } + +private: + void initializeGeometry(); + void initPbuffer(); + void initCommon(); + void perspectiveProjection(); + void orthographicProjection(); + void drawPbuffer(); + void setAnimationPaused(bool enable); + + qreal aspect; + GLuint dynamicTexture; + GLuint cubeTexture; + bool hasDynamicTextureUpdate; + QGLPixelBuffer *pbuffer; + Geometry *geom; + Cube *cube; + Tile *backdrop; + QList<Cube *> cubes; + QList<Tile *> tiles; + +}; +//! [3] + +#endif diff --git a/examples/opengl/legacy/pbuffers/main.cpp b/examples/opengl/legacy/pbuffers/main.cpp new file mode 100644 index 0000000000..8be6640e92 --- /dev/null +++ b/examples/opengl/legacy/pbuffers/main.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QMessageBox> +#include <QtOpenGL/QGLPixelBuffer> + +#include "glwidget.h" + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(pbuffers); + + QApplication a(argc, argv); + GLWidget widget(0); + widget.resize(640, 480); + widget.makeCurrent(); + + if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { + QMessageBox::information(0, "OpenGL pbuffers", + "This system does not support OpenGL/pbuffers."); + return -1; + } + + widget.show(); + return a.exec(); +} + diff --git a/examples/opengl/legacy/pbuffers/pbuffers.pro b/examples/opengl/legacy/pbuffers/pbuffers.pro new file mode 100644 index 0000000000..a349e39f68 --- /dev/null +++ b/examples/opengl/legacy/pbuffers/pbuffers.pro @@ -0,0 +1,17 @@ +HEADERS += glwidget.h \ + cube.h +SOURCES += glwidget.cpp \ + main.cpp \ + cube.cpp +RESOURCES += pbuffers.qrc +QT += opengl widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/pbuffers/pbuffers.qrc b/examples/opengl/legacy/pbuffers/pbuffers.qrc new file mode 100644 index 0000000000..9fc1a56a1a --- /dev/null +++ b/examples/opengl/legacy/pbuffers/pbuffers.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/res"> + <file>cubelogo.png</file> +</qresource> +</RCC> diff --git a/examples/opengl/legacy/pbuffers2/bubbles.svg b/examples/opengl/legacy/pbuffers2/bubbles.svg new file mode 100644 index 0000000000..51730124a2 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/bubbles.svg @@ -0,0 +1,215 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg width="20cm" height="15cm" viewBox="0 0 800 600" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink/" + baseProfile="tiny" version="1.2"> + <title>Spheres</title> + <desc>Semi-transparent bubbles on a colored background.</desc> + <defs> + <!-- Create radial gradients for each bubble. --> + <radialGradient id="blueBubble" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="25%" stop-color="#cdcdff" stop-opacity=".65" /> + <stop offset="100%" stop-color="#cdaacd" stop-opacity=".75" /> + </radialGradient> + <radialGradient id="redBubble" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="25%" stop-color="#ffcdcd" stop-opacity=".65" /> + <stop offset="100%" stop-color="#bbbb99" stop-opacity=".75" /> + </radialGradient> + <radialGradient id="greenBubble" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="25%" stop-color="#cdffcd" stop-opacity=".65" /> + <stop offset="100%" stop-color="#99aaaa" stop-opacity=".75" /> + </radialGradient> + <radialGradient id="yellowBubble" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="25%" stop-color="#ffffcd" stop-opacity=".65" /> + <stop offset="100%" stop-color="#bbbbaa" stop-opacity=".75" /> + </radialGradient> + <radialGradient id="background" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="400" fx="250" fy="250"> + <stop offset="0%" stop-color="#ffffee" /> + <stop offset="100%" stop-color="#ccccaa" /> + </radialGradient> + <linearGradient id="surface" gradientUnits="userSpaceOnUse" + x1="-100" y1="200" x2="400" y2="200"> + <stop offset="0%" stop-color="#ffffcc" /> + <stop offset="100%" stop-color="#bbbb88" /> + </linearGradient> + + <!-- Create radial gradients for each circle to make them look like + spheres. --> + <radialGradient id="blueSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="blue" /> + <stop offset="100%" stop-color="#222244" /> + </radialGradient> + <radialGradient id="redSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="red" /> + <stop offset="100%" stop-color="#442222" /> + </radialGradient> + <radialGradient id="greenSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="green" /> + <stop offset="100%" stop-color="#113311" /> + </radialGradient> + <radialGradient id="yellowSphere" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="-50"> + <stop offset="0%" stop-color="white" /> + <stop offset="75%" stop-color="yellow" /> + <stop offset="100%" stop-color="#444422" /> + </radialGradient> + <radialGradient id="shadowGrad" gradientUnits="userSpaceOnUse" + cx="0" cy="0" r="100" fx="-50" fy="50"> + <stop offset="0%" stop-color="black" stop-opacity="1.0" /> + <stop offset="100%" stop-color="black" stop-opacity="0.0" /> + </radialGradient> + + <!-- Define a shadow for each sphere. --> + <circle id="shadow" fill="url(#shadowGrad)" cx="0" cy="0" r="100" /> + <g id="bubble"> + <circle fill="black" cx="0" cy="0" r="50" /> + <circle fill="#a6ce39" cx="0" cy="0" r="33" /> + <path fill="black" d="M 37,50 L 50,37 L 12,-1 L 22,-11 L 10,-24 L -24,10 + L -11,22 L -1,12 Z" /> + <circle cx="0" cy="0" r="100" /> + </g> + </defs> + <g> + <rect fill="url(#background)" x="0" y="0" width="800" height="600" /> + </g> + + <g transform="translate(200,700)"> + <use xlink:href="#bubble" fill="url(#blueBubble)" /> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="1s" dur="10s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(315,700)"> + <g transform="scale(0.5,0.5)"> + <use xlink:href="#bubble" fill="url(#redBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="3s" dur="7s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(80,700)"> + <g transform="scale(0.65,0.65)"> + <use xlink:href="#bubble" fill="url(#greenBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="5s" dur="9s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(255,700)"> + <g transform="scale(0.3,0.3)"> + <use xlink:href="#bubble" fill="url(#yellowBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="2s" dur="6s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(565,700)"> + <g transform="scale(0.4,0.4)"> + <use xlink:href="#bubble" fill="url(#blueBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="4s" dur="8s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(715,700)"> + <g transform="scale(0.6,0.6)"> + <use xlink:href="#bubble" fill="url(#redBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="1s" dur="4s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(645,700)"> + <g transform="scale(0.375,0.375)"> + <use xlink:href="#bubble" fill="url(#greenBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="0s" dur="11s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(555,700)"> + <g transform="scale(0.9,0.9)"> + <use xlink:href="#bubble" fill="url(#yellowBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="3s" dur="7.5s" fill="freeze" repeatCount="indefinite" /> + </g> + + <g transform="translate(360,700)"> + <g transform="scale(0.5,0.5)"> + <use xlink:href="#bubble" fill="url(#blueBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="3s" dur="6s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(215,700)"> + <g transform="scale(0.45,0.45)"> + <use xlink:href="#bubble" fill="url(#redBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="5.5s" dur="7s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(420,700)"> + <g transform="scale(0.75,0.75)"> + <use xlink:href="#bubble" fill="url(#greenBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="1s" dur="9s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(815,700)"> + <g transform="scale(0.6,0.6)"> + <use xlink:href="#bubble" fill="url(#yellowBubble)" /> + </g> + <animateTransform attributeName="transform" type="translate" additive="sum" + values="0,0; 0,-800" begin="2s" dur="9.5s" fill="freeze" repeatCount="indefinite" /> + </g> + + <g transform="translate(225,375)" > + <g transform="scale(1.0,0.5)" > + <path d="M 0 0 L 350 0 L 450 450 L -100 450 z" + fill="url(#surface)" stroke="none" /> + </g> + </g> + <g transform="translate(200,0)" > + <g transform="translate(200,490) scale(2.0,1.0) rotate(45)" > + <rect fill="#a6ce39" x="-69" y="-69" width="138" height="138" /> + <circle fill="black" cx="0" cy="0" r="50" /> + <circle fill="#a6ce39" cx="0" cy="0" r="33" /> + <path fill="black" d="M 37,50 L 50,37 L 12,-1 L 22,-11 L 10,-24 L -24,10 + L -11,22 L -1,12 Z" /> + <animateTransform attributeName="transform" type="rotate" additive="sum" values="0; 360" + begin="0s" dur="10s" fill="freeze" repeatCount="indefinite" /> + </g> + <g transform="translate(200,375)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#blueSphere)" cx="0" cy="0" r="100" /> + </g> + <g transform="translate(315,440)"> + <g transform="scale(0.5,0.5)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#redSphere)" cx="0" cy="0" r="100" /> + </g> + </g> + <g transform="translate(80,475)"> + <g transform="scale(0.65,0.65)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#greenSphere)" cx="0" cy="0" r="100" /> + </g> + </g> + <g transform="translate(255,525)"> + <g transform="scale(0.3,0.3)"> + <use xlink:href="#shadow" transform="translate(25,55) scale(1.0,0.5)" /> + <circle fill="url(#yellowSphere)" cx="0" cy="0" r="100" /> + </g> + </g> + </g> +</svg> diff --git a/examples/opengl/legacy/pbuffers2/designer.png b/examples/opengl/legacy/pbuffers2/designer.png Binary files differnew file mode 100644 index 0000000000..4f32d57496 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/designer.png diff --git a/examples/opengl/legacy/pbuffers2/glwidget.cpp b/examples/opengl/legacy/pbuffers2/glwidget.cpp new file mode 100644 index 0000000000..de30bb8b21 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/glwidget.cpp @@ -0,0 +1,325 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QImage> +#include "glwidget.h" + +#include <math.h> + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) +{ + setWindowTitle(tr("OpenGL pbuffers 2")); + + pbuffer = new QGLPixelBuffer(1024, 1024, format(), this); + + rot_x = rot_y = rot_z = 0.0f; + scale = 0.1f; + anim = new QTimeLine(750, this); + anim->setUpdateInterval(20); + connect(anim, SIGNAL(valueChanged(qreal)), SLOT(animate(qreal))); + connect(anim, SIGNAL(finished()), SLOT(animFinished())); + + svg_renderer = new QSvgRenderer(QLatin1String(":/res/bubbles.svg"), this); + connect(svg_renderer, SIGNAL(repaintNeeded()), this, SLOT(draw())); + + logo = QImage(":/res/designer.png"); + logo = logo.convertToFormat(QImage::Format_ARGB32); + + makeCurrent(); // need a current context to create the display list + tile_list = glGenLists(1); + glNewList(tile_list, GL_COMPILE); + glBegin(GL_QUADS); + { + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); + + glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); + + glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); + + glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); + glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); + glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); +} + glEnd(); + glEndList(); + + wave = new GLfloat[logo.width()*logo.height()]; + memset(wave, 0, logo.width()*logo.height()); + startTimer(30); // wave timer + + pbuffer->makeCurrent(); + dynamicTexture = pbuffer->generateDynamicTexture(); + + // bind the dynamic texture to the pbuffer - this is a no-op under X11 + hasDynamicTextureUpdate = pbuffer->bindToDynamicTexture(dynamicTexture); +} + +GLWidget::~GLWidget() +{ + delete[] wave; + glDeleteLists(tile_list, 1); + pbuffer->releaseFromDynamicTexture(); + glDeleteTextures(1, &dynamicTexture); + delete pbuffer; +} + +void GLWidget::paintEvent(QPaintEvent *) +{ + draw(); +} + +void GLWidget::draw() +{ + QPainter p(this); // used for text overlay + + // save the GL state set for QPainter + p.beginNativePainting(); + saveGLState(); + + // render the 'bubbles.svg' file into our pbuffer + QPainter pbuffer_painter(pbuffer); + svg_renderer->render(&pbuffer_painter); + pbuffer_painter.end(); + glFlush(); + + if (!hasDynamicTextureUpdate) + pbuffer->updateDynamicTexture(dynamicTexture); + + makeCurrent(); + // draw into the GL widget + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1, 1, -1, 1, 10, 100); + glTranslatef(0.0f, 0.0f, -15.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glViewport(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio()); + + glBindTexture(GL_TEXTURE_2D, dynamicTexture); + glEnable(GL_TEXTURE_2D); + glEnable(GL_MULTISAMPLE); + glEnable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // draw background + glPushMatrix(); + glScalef(1.7f, 1.7f, 1.7f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glCallList(tile_list); + glPopMatrix(); + + const int w = logo.width(); + const int h = logo.height(); + + glRotatef(rot_x, 1.0f, 0.0f, 0.0f); + glRotatef(rot_y, 0.0f, 1.0f, 0.0f); + glRotatef(rot_z, 0.0f, 0.0f, 1.0f); + glScalef(scale/w, scale/w, scale/w); + + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + + // draw the Qt icon + glTranslatef(-w+1, -h+1, 0.0f); + for (int y=h-1; y>=0; --y) { + uint *p = (uint*) logo.scanLine(y); + uint *end = p + w; + int x = 0; + while (p < end) { + glColor4ub(qRed(*p), qGreen(*p), qBlue(*p), uchar(qAlpha(*p)*.9)); + glTranslatef(0.0f, 0.0f, wave[y*w+x]); + if (qAlpha(*p) > 128) + glCallList(tile_list); + glTranslatef(0.0f, 0.0f, -wave[y*w+x]); + glTranslatef(2.0f, 0.0f, 0.0f); + ++x; + ++p; + } + glTranslatef(-w*2.0f, 2.0f, 0.0f); + } + + // restore the GL state that QPainter expects + restoreGLState(); + p.endNativePainting(); + + // draw the overlayed text using QPainter + p.setPen(QColor(197, 197, 197, 157)); + p.setBrush(QColor(197, 197, 197, 127)); + p.drawRect(QRect(0, 0, width(), 50)); + p.setPen(Qt::black); + p.setBrush(Qt::NoBrush); + const QString str1(tr("A simple OpenGL pbuffer example.")); + const QString str2(tr("Use the mouse wheel to zoom, press buttons and move mouse to rotate, double-click to flip.")); + QFontMetrics fm(p.font()); + p.drawText(width()/2 - fm.width(str1)/2, 20, str1); + p.drawText(width()/2 - fm.width(str2)/2, 20 + fm.lineSpacing(), str2); +} + +void GLWidget::mousePressEvent(QMouseEvent *e) +{ + anchor = e->pos(); +} + +void GLWidget::mouseMoveEvent(QMouseEvent *e) +{ + QPoint diff = e->pos() - anchor; + if (e->buttons() & Qt::LeftButton) { + rot_x += diff.y()/5.0f; + rot_y += diff.x()/5.0f; + } else if (e->buttons() & Qt::RightButton) { + rot_z += diff.x()/5.0f; + } + + anchor = e->pos(); + draw(); +} + +void GLWidget::wheelEvent(QWheelEvent *e) +{ + e->delta() > 0 ? scale += scale*0.1f : scale -= scale*0.1f; + draw(); +} + +void GLWidget::mouseDoubleClickEvent(QMouseEvent *) +{ + anim->start(); +} + +void GLWidget::animate(qreal val) +{ + rot_y = val * 180; + draw(); +} + +void GLWidget::animFinished() +{ + if (anim->direction() == QTimeLine::Forward) + anim->setDirection(QTimeLine::Backward); + else + anim->setDirection(QTimeLine::Forward); +} + +void GLWidget::saveGLState() +{ + glPushAttrib(GL_ALL_ATTRIB_BITS); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); +} + +void GLWidget::restoreGLState() +{ + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glPopAttrib(); +} + +#define PI 3.14159 + +void GLWidget::timerEvent(QTimerEvent *) +{ + if (QApplication::mouseButtons() != 0) + return; + + static bool scale_in = true; + + if (scale_in && scale > 35.0f) + scale_in = false; + else if (!scale_in && scale < .5f) + scale_in = true; + + scale = scale_in ? scale + scale*0.01f : scale-scale*0.01f; + rot_z += 0.3f; + rot_x += 0.1f; + + int dx, dy; // disturbance point + float s, v, W, t; + int i, j; + static float wt[128][128]; + const int width = logo.width(); + const int AMP = 5; + + dx = dy = width >> 1; + + W = .3f; + v = -4; // wave speed + + for (i = 0; i < width; ++i) { + for ( j = 0; j < width; ++j) { + s = sqrt((double) ((j - dx) * (j - dx) + (i - dy) * (i - dy))); + wt[i][j] += 0.1f; + t = s / v; + if (s != 0) + wave[i*width + j] = AMP * sin(2 * PI * W * (wt[i][j] + t)) / (0.2*(s + 2)); + else + wave[i*width + j] = AMP * sin(2 * PI * W * (wt[i][j] + t)); + } + } +} diff --git a/examples/opengl/legacy/pbuffers2/glwidget.h b/examples/opengl/legacy/pbuffers2/glwidget.h new file mode 100644 index 0000000000..20dd796a48 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/glwidget.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtOpenGL> +#include <QImage> +#include <QTimeLine> +#include <QSvgRenderer> + +class GLWidget : public QGLWidget +{ + Q_OBJECT + +public: + GLWidget(QWidget *parent); + ~GLWidget(); + + void saveGLState(); + void restoreGLState(); + + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *); + void mouseDoubleClickEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void timerEvent(QTimerEvent *); + void wheelEvent(QWheelEvent *); + +public slots: + void animate(qreal); + void animFinished(); + void draw(); + +private: + QPoint anchor; + float scale; + float rot_x, rot_y, rot_z; + GLuint tile_list; + GLfloat *wave; + bool hasDynamicTextureUpdate; + + QImage logo; + QTimeLine *anim; + QSvgRenderer *svg_renderer; + + GLuint dynamicTexture; + QGLPixelBuffer *pbuffer; +}; + diff --git a/examples/opengl/legacy/pbuffers2/main.cpp b/examples/opengl/legacy/pbuffers2/main.cpp new file mode 100644 index 0000000000..79fd88a3c8 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QMessageBox> +#include "glwidget.h" + +int main(int argc, char **argv) +{ + Q_INIT_RESOURCE(pbuffers2); + + QApplication a(argc, argv); + GLWidget widget(0); + widget.resize(640, 480); + widget.makeCurrent(); + if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) { + QMessageBox::information(0, "OpenGL pbuffers 2", + "This system does not support OpenGL/pbuffers."); + return -1; + } + widget.show(); + return a.exec(); +} + diff --git a/examples/opengl/legacy/pbuffers2/pbuffers2.pro b/examples/opengl/legacy/pbuffers2/pbuffers2.pro new file mode 100644 index 0000000000..f9dd269eea --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/pbuffers2.pro @@ -0,0 +1,15 @@ +QT += opengl svg widgets + +HEADERS += glwidget.h +SOURCES += glwidget.cpp main.cpp +RESOURCES += pbuffers2.qrc + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers2 +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/pbuffers2/pbuffers2.qrc b/examples/opengl/legacy/pbuffers2/pbuffers2.qrc new file mode 100644 index 0000000000..986f1ca385 --- /dev/null +++ b/examples/opengl/legacy/pbuffers2/pbuffers2.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/res"> + <file>bubbles.svg</file> + <file>designer.png</file> +</qresource> +</RCC> diff --git a/examples/opengl/legacy/samplebuffers/glwidget.cpp b/examples/opengl/legacy/samplebuffers/glwidget.cpp new file mode 100644 index 0000000000..28abf3d6c0 --- /dev/null +++ b/examples/opengl/legacy/samplebuffers/glwidget.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "glwidget.h" +#include <math.h> + +#ifndef GL_MULTISAMPLE +#define GL_MULTISAMPLE 0x809D +#endif + +GLWidget::GLWidget(QWidget *parent) + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) +{ + startTimer(40); + setWindowTitle(tr("Sample Buffers")); +} + +void GLWidget::initializeGL() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-.5, .5, .5, -.5, -1000, 1000); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + + makeObject(); +} + +void GLWidget::resizeGL(int w, int h) +{ + glViewport(0, 0, w, h); +} + +void GLWidget::paintGL() +{ + static float rot = 0.0; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glEnable(GL_MULTISAMPLE); + glTranslatef(-0.25f, -0.10f, 0.0f); + glScalef(0.75f, 1.15f, 0.0f); + glRotatef(rot, 0.0f, 0.f, 1.0f); + glCallList(list); + glPopMatrix(); + + glPushMatrix(); + glDisable(GL_MULTISAMPLE); + glTranslatef(0.25f, -0.10f, 0.0f); + glScalef(0.75f, 1.15f, 0.0f); + glRotatef(rot, 0.0f, 0.0f, 1.0f); + glCallList(list); + glPopMatrix(); + + rot += 0.2f; + + qglColor(Qt::black); + renderText(-0.35, 0.4, 0.0, "Multisampling enabled"); + renderText(0.15, 0.4, 0.0, "Multisampling disabled"); +} + +void GLWidget::timerEvent(QTimerEvent *) +{ + update(); +} + +void GLWidget::makeObject() +{ + QColor qtGreen(QColor::fromCmykF(0.40, 0.0, 1.0, 0.0)); + const double Pi = 3.14159265358979323846; + const int NumSectors = 15; + GLdouble x1 = +0.06; + GLdouble y1 = -0.14; + GLdouble x2 = +0.14; + GLdouble y2 = -0.06; + GLdouble x3 = +0.08; + GLdouble y3 = +0.00; + GLdouble x4 = +0.30; + GLdouble y4 = +0.22; + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + { + for (int i = 0; i < NumSectors; ++i) { + double angle1 = (i * 2 * Pi) / NumSectors; + GLdouble x5 = 0.30 * sin(angle1); + GLdouble y5 = 0.30 * cos(angle1); + GLdouble x6 = 0.20 * sin(angle1); + GLdouble y6 = 0.20 * cos(angle1); + + double angle2 = ((i + 1) * 2 * Pi) / NumSectors; + GLdouble x7 = 0.20 * sin(angle2); + GLdouble y7 = 0.20 * cos(angle2); + GLdouble x8 = 0.30 * sin(angle2); + GLdouble y8 = 0.30 * cos(angle2); + + qglColor(qtGreen); + quad(GL_QUADS, x5, y5, x6, y6, x7, y7, x8, y8); + qglColor(Qt::black); + quad(GL_LINE_LOOP, x5, y5, x6, y6, x7, y7, x8, y8); + } + + qglColor(qtGreen); + quad(GL_QUADS, x1, y1, x2, y2, y2, x2, y1, x1); + quad(GL_QUADS, x3, y3, x4, y4, y4, x4, y3, x3); + + qglColor(Qt::black); + quad(GL_LINE_LOOP, x1, y1, x2, y2, y2, x2, y1, x1); + quad(GL_LINE_LOOP, x3, y3, x4, y4, y4, x4, y3, x3); + } + glEndList(); +} + +void GLWidget::quad(GLenum primitive, GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2, + GLdouble x3, GLdouble y3, GLdouble x4, GLdouble y4) +{ + glBegin(primitive); + { + glVertex2d(x1, y1); + glVertex2d(x2, y2); + glVertex2d(x3, y3); + glVertex2d(x4, y4); + } + glEnd(); +} diff --git a/examples/opengl/legacy/samplebuffers/glwidget.h b/examples/opengl/legacy/samplebuffers/glwidget.h new file mode 100644 index 0000000000..494c5861df --- /dev/null +++ b/examples/opengl/legacy/samplebuffers/glwidget.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtOpenGL> + +class GLWidget : public QGLWidget +{ +public: + GLWidget(QWidget *parent); + +protected: + void initializeGL() Q_DECL_OVERRIDE; + void resizeGL(int w, int h) Q_DECL_OVERRIDE; + void paintGL() Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; + + void makeObject(); + void quad(GLenum primitive, GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2, + GLdouble x3, GLdouble y3, GLdouble x4, GLdouble y4); + +private: + GLuint list; +}; + diff --git a/examples/opengl/legacy/samplebuffers/main.cpp b/examples/opengl/legacy/samplebuffers/main.cpp new file mode 100644 index 0000000000..a1272af4db --- /dev/null +++ b/examples/opengl/legacy/samplebuffers/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QApplication> +#include <QtWidgets/QMessageBox> +#include "glwidget.h" + +int main(int argc, char **argv) +{ + QApplication a(argc, argv); + + QGLFormat f = QGLFormat::defaultFormat(); + f.setSampleBuffers(true); + QGLFormat::setDefaultFormat(f); + if (!QGLFormat::hasOpenGL()) { + QMessageBox::information(0, "OpenGL samplebuffers", + "This system does not support OpenGL."); + return 0; + } + + GLWidget widget(0); + + if (!widget.format().sampleBuffers()) { + QMessageBox::information(0, "OpenGL samplebuffers", + "This system does not have sample buffer support."); + return 0; + } + + widget.resize(640, 480); + widget.show(); + + return a.exec(); +} + diff --git a/examples/opengl/legacy/samplebuffers/samplebuffers.pro b/examples/opengl/legacy/samplebuffers/samplebuffers.pro new file mode 100644 index 0000000000..b57599aae4 --- /dev/null +++ b/examples/opengl/legacy/samplebuffers/samplebuffers.pro @@ -0,0 +1,14 @@ +HEADERS += glwidget.h +SOURCES += glwidget.cpp main.cpp + +QT += opengl widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/samplebuffers +INSTALLS += target + +contains(QT_CONFIG, opengles.) { + contains(QT_CONFIG, angle): \ + warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") + error("This example requires Qt to be configured with -opengl desktop") +} diff --git a/examples/opengl/legacy/shared/qtlogo.cpp b/examples/opengl/legacy/shared/qtlogo.cpp new file mode 100644 index 0000000000..608f5b3f2b --- /dev/null +++ b/examples/opengl/legacy/shared/qtlogo.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtlogo.h" + +#include <QGLWidget> +#include <QMatrix4x4> +#include <QVector3D> + +#include <qmath.h> + +static const qreal tee_height = 0.311126; +static const qreal cross_width = 0.25; +static const qreal bar_thickness = 0.113137; +static const qreal logo_depth = 0.10; + +//! [0] +struct Geometry +{ + QVector<GLushort> faces; + QVector<QVector3D> vertices; + QVector<QVector3D> normals; + void appendSmooth(const QVector3D &a, const QVector3D &n, int from); + void appendFaceted(const QVector3D &a, const QVector3D &n); + void finalize(); + void loadArrays() const; +}; +//! [0] + +//! [1] +class Patch +{ +public: + enum Smoothing { Faceted, Smooth }; + Patch(Geometry *); + void setSmoothing(Smoothing s) { sm = s; } + void translate(const QVector3D &t); + void rotate(qreal deg, QVector3D axis); + void draw() const; + void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n); + void addQuad(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d); + + GLushort start; + GLushort count; + GLushort initv; + + GLfloat faceColor[4]; + QMatrix4x4 mat; + Smoothing sm; + Geometry *geom; +}; +//! [1] + +static inline void qSetColor(float colorVec[], QColor c) +{ + colorVec[0] = c.redF(); + colorVec[1] = c.greenF(); + colorVec[2] = c.blueF(); + colorVec[3] = c.alphaF(); +} + +void Geometry::loadArrays() const +{ + glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); + glNormalPointer(GL_FLOAT, 0, normals.constData()); +} + +void Geometry::finalize() +{ + // TODO: add vertex buffer uploading here + + // Finish smoothing normals by ensuring accumulated normals are returned + // to length 1.0. + for (int i = 0; i < normals.count(); ++i) + normals[i].normalize(); +} + +void Geometry::appendSmooth(const QVector3D &a, const QVector3D &n, int from) +{ + // Smooth normals are achieved by averaging the normals for faces meeting + // at a point. First find the point in geometry already generated + // (working backwards, since most often the points shared are between faces + // recently added). + int v = vertices.count() - 1; + for ( ; v >= from; --v) + if (qFuzzyCompare(vertices[v], a)) + break; + + if (v < from) { + // The vertex was not found so add it as a new one, and initialize + // its corresponding normal + v = vertices.count(); + vertices.append(a); + normals.append(n); + } else { + // Vert found, accumulate normals into corresponding normal slot. + // Must call finalize once finished accumulating normals + normals[v] += n; + } + + // In both cases (found or not) reference the vertex via its index + faces.append(v); +} + +void Geometry::appendFaceted(const QVector3D &a, const QVector3D &n) +{ + // Faceted normals are achieved by duplicating the vertex for every + // normal, so that faces meeting at a vertex get a sharp edge. + int v = vertices.count(); + vertices.append(a); + normals.append(n); + faces.append(v); +} + +Patch::Patch(Geometry *g) + : start(g->faces.count()) + , count(0) + , initv(g->vertices.count()) + , sm(Patch::Smooth) + , geom(g) +{ + qSetColor(faceColor, QColor(Qt::darkGray)); +} + +void Patch::rotate(qreal deg, QVector3D axis) +{ + mat.rotate(deg, axis); +} + +void Patch::translate(const QVector3D &t) +{ + mat.translate(t); +} + +//! [2] +void Patch::draw() const +{ + glPushMatrix(); + glMultMatrixf(mat.constData()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); + + const GLushort *indices = geom->faces.constData(); + glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); + glPopMatrix(); +} +//! [2] + +void Patch::addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n) +{ + QVector3D norm = n.isNull() ? QVector3D::normal(a, b, c) : n; + + if (sm == Smooth) { + geom->appendSmooth(a, norm, initv); + geom->appendSmooth(b, norm, initv); + geom->appendSmooth(c, norm, initv); + } else { + geom->appendFaceted(a, norm); + geom->appendFaceted(b, norm); + geom->appendFaceted(c, norm); + } + + count += 3; +} + +void Patch::addQuad(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d) +{ + QVector3D norm = QVector3D::normal(a, b, c); + + if (sm == Smooth) { + addTri(a, b, c, norm); + addTri(a, c, d, norm); + } else { + // If faceted share the two common vertices + addTri(a, b, c, norm); + int k = geom->vertices.count(); + geom->appendSmooth(a, norm, k); + geom->appendSmooth(c, norm, k); + geom->appendFaceted(d, norm); + count += 3; + } +} + +static inline QVector<QVector3D> extrude(const QVector<QVector3D> &vertices, qreal depth) +{ + QVector<QVector3D> extr = vertices; + for (int v = 0; v < extr.count(); ++v) + extr[v].setZ(extr[v].z() - depth); + return extr; +} + +class Rectoid +{ +public: + void translate(const QVector3D &t) + { + for (int i = 0; i < parts.count(); ++i) + parts[i]->translate(t); + } + + void rotate(qreal deg, QVector3D axis) + { + for (int i = 0; i < parts.count(); ++i) + parts[i]->rotate(deg, axis); + } + + // No special Rectoid destructor - the parts are fetched out of this member + // variable, and destroyed by the new owner + QList<Patch *> parts; +}; + +class RectPrism : public Rectoid +{ +public: + RectPrism(Geometry *g, qreal width, qreal height, qreal depth); +}; + +RectPrism::RectPrism(Geometry *g, qreal width, qreal height, qreal depth) +{ + enum { bl, br, tr, tl }; + Patch *fb = new Patch(g); + fb->setSmoothing(Patch::Faceted); + + // front face + QVector<QVector3D> r(4); + r[br].setX(width); + r[tr].setX(width); + r[tr].setY(height); + r[tl].setY(height); + QVector3D adjToCenter(-width / 2.0, -height / 2.0, depth / 2.0); + for (int i = 0; i < 4; ++i) + r[i] += adjToCenter; + fb->addQuad(r[bl], r[br], r[tr], r[tl]); + + // back face + QVector<QVector3D> s = extrude(r, depth); + fb->addQuad(s[tl], s[tr], s[br], s[bl]); + + // side faces + Patch *sides = new Patch(g); + sides->setSmoothing(Patch::Faceted); + sides->addQuad(s[bl], s[br], r[br], r[bl]); + sides->addQuad(s[br], s[tr], r[tr], r[br]); + sides->addQuad(s[tr], s[tl], r[tl], r[tr]); + sides->addQuad(s[tl], s[bl], r[bl], r[tl]); + + parts << fb << sides; +} + +class RectTorus : public Rectoid +{ +public: + RectTorus(Geometry *g, qreal iRad, qreal oRad, qreal depth, int numSectors); +}; + +RectTorus::RectTorus(Geometry *g, qreal iRad, qreal oRad, qreal depth, int k) +{ + QVector<QVector3D> inside; + QVector<QVector3D> outside; + for (int i = 0; i < k; ++i) { + qreal angle = (i * 2 * M_PI) / k; + inside << QVector3D(iRad * qSin(angle), iRad * qCos(angle), depth / 2.0); + outside << QVector3D(oRad * qSin(angle), oRad * qCos(angle), depth / 2.0); + } + inside << QVector3D(0.0, iRad, 0.0); + outside << QVector3D(0.0, oRad, 0.0); + QVector<QVector3D> in_back = extrude(inside, depth); + QVector<QVector3D> out_back = extrude(outside, depth); + + // Create front, back and sides as separate patches so that smooth normals + // are generated for the curving sides, but a faceted edge is created between + // sides and front/back + Patch *front = new Patch(g); + for (int i = 0; i < k; ++i) + front->addQuad(outside[i], inside[i], + inside[(i + 1) % k], outside[(i + 1) % k]); + Patch *back = new Patch(g); + for (int i = 0; i < k; ++i) + back->addQuad(in_back[i], out_back[i], + out_back[(i + 1) % k], in_back[(i + 1) % k]); + Patch *is = new Patch(g); + for (int i = 0; i < k; ++i) + is->addQuad(in_back[i], in_back[(i + 1) % k], + inside[(i + 1) % k], inside[i]); + Patch *os = new Patch(g); + for (int i = 0; i < k; ++i) + os->addQuad(out_back[(i + 1) % k], out_back[i], + outside[i], outside[(i + 1) % k]); + parts << front << back << is << os; +} + +QtLogo::QtLogo(QObject *parent, int divisions, qreal scale) + : QObject(parent) + , geom(new Geometry()) +{ + buildGeometry(divisions, scale); +} + +QtLogo::~QtLogo() +{ + qDeleteAll(parts); + delete geom; +} + +void QtLogo::setColor(QColor c) +{ + for (int i = 0; i < parts.count(); ++i) + qSetColor(parts[i]->faceColor, c); +} + +//! [3] +void QtLogo::buildGeometry(int divisions, qreal scale) +{ + qreal cw = cross_width * scale; + qreal bt = bar_thickness * scale; + qreal ld = logo_depth * scale; + qreal th = tee_height *scale; + + RectPrism cross(geom, cw, bt, ld); + RectPrism stem(geom, bt, th, ld); + + QVector3D z(0.0, 0.0, 1.0); + cross.rotate(45.0, z); + stem.rotate(45.0, z); + + qreal stem_downshift = (th + bt) / 2.0; + stem.translate(QVector3D(0.0, -stem_downshift, 0.0)); + + RectTorus body(geom, 0.20, 0.30, 0.1, divisions); + + parts << stem.parts << cross.parts << body.parts; + + geom->finalize(); +} +//! [3] + +//! [4] +void QtLogo::draw() const +{ + geom->loadArrays(); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + for (int i = 0; i < parts.count(); ++i) + parts[i]->draw(); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} +//! [4] diff --git a/examples/opengl/legacy/shared/qtlogo.h b/examples/opengl/legacy/shared/qtlogo.h new file mode 100644 index 0000000000..5508372b01 --- /dev/null +++ b/examples/opengl/legacy/shared/qtlogo.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTLOGO_H +#define QTLOGO_H + +#include <QObject> +#include <QColor> + +class Patch; +struct Geometry; + +//! [0] +class QtLogo : public QObject +{ +public: + explicit QtLogo(QObject *parent, int d = 64, qreal s = 1.0); + ~QtLogo(); + void setColor(QColor c); + void draw() const; +private: + void buildGeometry(int d, qreal s); + + QList<Patch *> parts; + Geometry *geom; +}; +//! [0] + +#endif // QTLOGO_H |