source: trunk/examples/opengl/pbuffers/glwidget.cpp@ 1168

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "glwidget.h"
42#include <math.h>
43
44#include "cube.h"
45
46#include <QGLPixelBuffer>
47
48#ifndef GL_MULTISAMPLE
49#define GL_MULTISAMPLE 0x809D
50#endif
51
52static GLfloat colorArray[][4] = {
53 {0.243f, 0.423f, 0.125f, 1.0f},
54 {0.176f, 0.31f, 0.09f, 1.0f},
55 {0.4f, 0.69f, 0.212f, 1.0f},
56 {0.317f, 0.553f, 0.161f, 1.0f}
57};
58
59GLWidget::GLWidget(QWidget *parent)
60 : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
61 , geom(0)
62 , cube(0)
63{
64 // create the pbuffer
65 QGLFormat pbufferFormat = format();
66 pbufferFormat.setSampleBuffers(false);
67 pbuffer = new QGLPixelBuffer(QSize(512, 512), pbufferFormat, this);
68 setWindowTitle(tr("OpenGL pbuffers"));
69 initializeGeometry();
70}
71
72GLWidget::~GLWidget()
73{
74 pbuffer->releaseFromDynamicTexture();
75 glDeleteTextures(1, &dynamicTexture);
76 delete pbuffer;
77
78 qDeleteAll(cubes);
79 qDeleteAll(tiles);
80 delete cube;
81}
82
83void GLWidget::initializeGL()
84{
85 initCommon();
86 glShadeModel(GL_SMOOTH);
87 glEnable(GL_LIGHTING);
88 glEnable(GL_LIGHT0);
89 static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
90 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
91 initPbuffer();
92 cube->startAnimation();
93 connect(cube, SIGNAL(changed()), this, SLOT(update()));
94 for (int i = 0; i < 3; ++i)
95 {
96 cubes[i]->startAnimation();
97 connect(cubes[i], SIGNAL(changed()), this, SLOT(update()));
98 }
99}
100
101void GLWidget::paintGL()
102{
103 pbuffer->makeCurrent();
104 drawPbuffer();
105 // On direct render platforms, drawing onto the pbuffer context above
106 // automatically updates the dynamic texture. For cases where rendering
107 // directly to a texture is not supported, explicitly copy.
108 if (!hasDynamicTextureUpdate)
109 pbuffer->updateDynamicTexture(dynamicTexture);
110 makeCurrent();
111
112 // Use the pbuffer as a texture to render the scene
113 glBindTexture(GL_TEXTURE_2D, dynamicTexture);
114
115 // set up to render the scene
116 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
117 glLoadIdentity();
118 glTranslatef(0.0f, 0.0f, -10.0f);
119
120 // draw the background
121 glPushMatrix();
122 glScalef(aspect, 1.0f, 1.0f);
123 for (int i = 0; i < tiles.count(); ++i)
124 tiles[i]->draw();
125 glPopMatrix();
126
127 // draw the bouncing cubes
128 for (int i = 0; i < cubes.count(); ++i)
129 cubes[i]->draw();
130}
131
132void GLWidget::initializeGeometry()
133{
134 geom = new Geometry();
135 CubeBuilder cBuilder(geom, 0.5);
136 cBuilder.setColor(QColor(255, 255, 255, 212));
137 // build the 3 bouncing, spinning cubes
138 for (int i = 0; i < 3; ++i)
139 cubes.append(cBuilder.newCube(QVector3D((float)(i-1), -1.5f, 5 - i)));
140
141 // build the spinning cube which goes in the dynamic texture
142 cube = cBuilder.newCube();
143 cube->removeBounce();
144
145 // build the background tiles
146 TileBuilder tBuilder(geom);
147 tBuilder.setColor(QColor(Qt::white));
148 for (int c = -2; c <= +2; ++c)
149 for (int r = -2; r <= +2; ++r)
150 tiles.append(tBuilder.newTile(QVector3D(c, r, 0)));
151
152 // graded backdrop for the pbuffer scene
153 TileBuilder bBuilder(geom, 0.0f, 2.0f);
154 bBuilder.setColor(QColor(102, 176, 54, 210));
155 backdrop = bBuilder.newTile(QVector3D(0.0f, 0.0f, -1.5f));
156 backdrop->setColors(colorArray);
157}
158
159void GLWidget::initCommon()
160{
161 qglClearColor(QColor(Qt::darkGray));
162
163 glEnable(GL_DEPTH_TEST);
164 glEnable(GL_CULL_FACE);
165 glEnable(GL_MULTISAMPLE);
166
167 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
168 glEnable(GL_BLEND);
169
170 glEnable(GL_TEXTURE_2D);
171
172 geom->loadArrays();
173}
174
175void GLWidget::perspectiveProjection()
176{
177 glMatrixMode(GL_PROJECTION);
178 glLoadIdentity();
179#ifdef QT_OPENGL_ES
180 glFrustumf(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0);
181#else
182 glFrustum(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0);
183#endif
184 glMatrixMode(GL_MODELVIEW);
185}
186
187void GLWidget::orthographicProjection()
188{
189 glMatrixMode(GL_PROJECTION);
190 glLoadIdentity();
191#ifdef QT_OPENGL_ES
192 glOrthof(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0);
193#else
194 glOrtho(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0);
195#endif
196 glMatrixMode(GL_MODELVIEW);
197}
198
199void GLWidget::resizeGL(int width, int height)
200{
201 glViewport(0, 0, width, height);
202 aspect = (qreal)width / (qreal)(height ? height : 1);
203 perspectiveProjection();
204}
205
206void GLWidget::drawPbuffer()
207{
208 orthographicProjection();
209
210 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
211 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
212
213 glDisable(GL_TEXTURE_2D);
214 backdrop->draw();
215 glEnable(GL_TEXTURE_2D);
216
217 glBindTexture(GL_TEXTURE_2D, cubeTexture);
218 glDisable(GL_CULL_FACE);
219 cube->draw();
220 glEnable(GL_CULL_FACE);
221
222 glFlush();
223}
224
225void GLWidget::initPbuffer()
226{
227 pbuffer->makeCurrent();
228
229 cubeTexture = bindTexture(QImage(":res/cubelogo.png"));
230
231 initCommon();
232
233 // generate a texture that has the same size/format as the pbuffer
234 dynamicTexture = pbuffer->generateDynamicTexture();
235
236 // bind the dynamic texture to the pbuffer - this is a no-op under X11
237 hasDynamicTextureUpdate = pbuffer->bindToDynamicTexture(dynamicTexture);
238 makeCurrent();
239}
240
241void GLWidget::setAnimationPaused(bool enable)
242{
243 cube->setAnimationPaused(enable);
244 for (int i = 0; i < 3; ++i)
245 cubes[i]->setAnimationPaused(enable);
246}
Note: See TracBrowser for help on using the repository browser.