source: trunk/demos/boxes/glbuffers.cpp@ 603

Last change on this file since 603 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 13.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 demonstration applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "glbuffers.h"
43#include <QtGui/qmatrix4x4.h>
44
45//============================================================================//
46// GLTexture //
47//============================================================================//
48
49GLTexture::GLTexture() : m_texture(0), m_failed(false)
50{
51 glGenTextures(1, &m_texture);
52}
53
54GLTexture::~GLTexture()
55{
56 glDeleteTextures(1, &m_texture);
57}
58
59//============================================================================//
60// GLTexture2D //
61//============================================================================//
62
63GLTexture2D::GLTexture2D(int width, int height)
64{
65 glBindTexture(GL_TEXTURE_2D, m_texture);
66 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
67 GL_BGRA, GL_UNSIGNED_BYTE, 0);
68
69 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
70 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
71 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
72 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
73 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
74 //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
75 glBindTexture(GL_TEXTURE_2D, 0);
76}
77
78
79GLTexture2D::GLTexture2D(const QString& fileName, int width, int height)
80{
81 // TODO: Add error handling.
82 QImage image(fileName);
83
84 if (image.isNull()) {
85 m_failed = true;
86 return;
87 }
88
89 image = image.convertToFormat(QImage::Format_ARGB32);
90
91 //qDebug() << "Image size:" << image.width() << "x" << image.height();
92 if (width <= 0)
93 width = image.width();
94 if (height <= 0)
95 height = image.height();
96 if (width != image.width() || height != image.height())
97 image = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
98
99 glBindTexture(GL_TEXTURE_2D, m_texture);
100
101 // Works on x86, so probably works on all little-endian systems.
102 // Does it work on big-endian systems?
103 glTexImage2D(GL_TEXTURE_2D, 0, 4, image.width(), image.height(), 0,
104 GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
105
106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
110 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
111 //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
112 glBindTexture(GL_TEXTURE_2D, 0);
113}
114
115void GLTexture2D::load(int width, int height, QRgb *data)
116{
117 glBindTexture(GL_TEXTURE_2D, m_texture);
118 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
119 GL_BGRA, GL_UNSIGNED_BYTE, data);
120 glBindTexture(GL_TEXTURE_2D, 0);
121}
122
123void GLTexture2D::bind()
124{
125 glBindTexture(GL_TEXTURE_2D, m_texture);
126 glEnable(GL_TEXTURE_2D);
127}
128
129void GLTexture2D::unbind()
130{
131 glBindTexture(GL_TEXTURE_2D, 0);
132 glDisable(GL_TEXTURE_2D);
133}
134
135
136//============================================================================//
137// GLTexture3D //
138//============================================================================//
139
140GLTexture3D::GLTexture3D(int width, int height, int depth)
141{
142 GLBUFFERS_ASSERT_OPENGL("GLTexture3D::GLTexture3D", glTexImage3D, return)
143
144 glBindTexture(GL_TEXTURE_3D, m_texture);
145 glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0,
146 GL_BGRA, GL_UNSIGNED_BYTE, 0);
147
148 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
149 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
150 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
151 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
152 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
153 //glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
154 //glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP, GL_TRUE);
155 glBindTexture(GL_TEXTURE_3D, 0);
156}
157
158void GLTexture3D::load(int width, int height, int depth, QRgb *data)
159{
160 GLBUFFERS_ASSERT_OPENGL("GLTexture3D::load", glTexImage3D, return)
161
162 glBindTexture(GL_TEXTURE_3D, m_texture);
163 glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0,
164 GL_BGRA, GL_UNSIGNED_BYTE, data);
165 glBindTexture(GL_TEXTURE_3D, 0);
166}
167
168void GLTexture3D::bind()
169{
170 glBindTexture(GL_TEXTURE_3D, m_texture);
171 glEnable(GL_TEXTURE_3D);
172}
173
174void GLTexture3D::unbind()
175{
176 glBindTexture(GL_TEXTURE_3D, 0);
177 glDisable(GL_TEXTURE_3D);
178}
179
180//============================================================================//
181// GLTextureCube //
182//============================================================================//
183
184GLTextureCube::GLTextureCube(int size)
185{
186 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
187
188 for (int i = 0; i < 6; ++i)
189 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 4, size, size, 0,
190 GL_BGRA, GL_UNSIGNED_BYTE, 0);
191
192 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
193 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
194 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
195 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
196 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
197 //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
198 //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
199 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
200}
201
202GLTextureCube::GLTextureCube(const QStringList& fileNames, int size)
203{
204 // TODO: Add error handling.
205
206 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
207
208 int index = 0;
209 foreach (QString file, fileNames) {
210 QImage image(file);
211 if (image.isNull()) {
212 m_failed = true;
213 break;
214 }
215
216 image = image.convertToFormat(QImage::Format_ARGB32);
217
218 //qDebug() << "Image size:" << image.width() << "x" << image.height();
219 if (size <= 0)
220 size = image.width();
221 if (size != image.width() || size != image.height())
222 image = image.scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
223
224 // Works on x86, so probably works on all little-endian systems.
225 // Does it work on big-endian systems?
226 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, image.width(), image.height(), 0,
227 GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
228
229 if (++index == 6)
230 break;
231 }
232
233 // Clear remaining faces.
234 while (index < 6) {
235 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, size, size, 0,
236 GL_BGRA, GL_UNSIGNED_BYTE, 0);
237 ++index;
238 }
239
240 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
241 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
242 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
243 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
244 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
245 //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
246 //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
247 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
248}
249
250void GLTextureCube::load(int size, int face, QRgb *data)
251{
252 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
253 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, 4, size, size, 0,
254 GL_BGRA, GL_UNSIGNED_BYTE, data);
255 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
256}
257
258void GLTextureCube::bind()
259{
260 glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture);
261 glEnable(GL_TEXTURE_CUBE_MAP);
262}
263
264void GLTextureCube::unbind()
265{
266 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
267 glDisable(GL_TEXTURE_CUBE_MAP);
268}
269
270//============================================================================//
271// GLFrameBufferObject //
272//============================================================================//
273
274GLFrameBufferObject::GLFrameBufferObject(int width, int height)
275 : m_fbo(0)
276 , m_depthBuffer(0)
277 , m_width(width)
278 , m_height(height)
279 , m_failed(false)
280{
281 GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::GLFrameBufferObject",
282 glGenFramebuffersEXT && glGenRenderbuffersEXT && glBindRenderbufferEXT && glRenderbufferStorageEXT, return)
283
284 // TODO: share depth buffers of same size
285 glGenFramebuffersEXT(1, &m_fbo);
286 //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
287 glGenRenderbuffersEXT(1, &m_depthBuffer);
288 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
289 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height);
290 //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer);
291 //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
292}
293
294GLFrameBufferObject::~GLFrameBufferObject()
295{
296 GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::~GLFrameBufferObject",
297 glDeleteFramebuffersEXT && glDeleteRenderbuffersEXT, return)
298
299 glDeleteFramebuffersEXT(1, &m_fbo);
300 glDeleteRenderbuffersEXT(1, &m_depthBuffer);
301}
302
303void GLFrameBufferObject::setAsRenderTarget(bool state)
304{
305 GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::setAsRenderTarget", glBindFramebufferEXT, return)
306
307 if (state) {
308 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
309 glPushAttrib(GL_VIEWPORT_BIT);
310 glViewport(0, 0, m_width, m_height);
311 } else {
312 glPopAttrib();
313 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
314 }
315}
316
317bool GLFrameBufferObject::isComplete()
318{
319 GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::isComplete", glCheckFramebufferStatusEXT, return false)
320
321 return GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
322}
323
324//============================================================================//
325// GLRenderTargetCube //
326//============================================================================//
327
328GLRenderTargetCube::GLRenderTargetCube(int size)
329 : GLTextureCube(size)
330 , m_fbo(size, size)
331{
332}
333
334void GLRenderTargetCube::begin(int face)
335{
336 GLBUFFERS_ASSERT_OPENGL("GLRenderTargetCube::begin",
337 glFramebufferTexture2DEXT && glFramebufferRenderbufferEXT, return)
338
339 m_fbo.setAsRenderTarget(true);
340 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
341 GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_texture, 0);
342 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_fbo.m_depthBuffer);
343}
344
345void GLRenderTargetCube::end()
346{
347 m_fbo.setAsRenderTarget(false);
348}
349
350void GLRenderTargetCube::getViewMatrix(QMatrix4x4& mat, int face)
351{
352 if (face < 0 || face >= 6) {
353 qWarning("GLRenderTargetCube::getViewMatrix: 'face' must be in the range [0, 6). (face == %d)", face);
354 return;
355 }
356
357 static int perm[6][3] = {
358 {2, 1, 0},
359 {2, 1, 0},
360 {0, 2, 1},
361 {0, 2, 1},
362 {0, 1, 2},
363 {0, 1, 2},
364 };
365
366 static float signs[6][3] = {
367 {-1.0f, -1.0f, -1.0f},
368 {+1.0f, -1.0f, +1.0f},
369 {+1.0f, +1.0f, -1.0f},
370 {+1.0f, -1.0f, +1.0f},
371 {+1.0f, -1.0f, -1.0f},
372 {-1.0f, -1.0f, +1.0f},
373 };
374
375 mat.fill(0.0f);
376 for (int i = 0; i < 3; ++i)
377 mat(i, perm[face][i]) = signs[face][i];
378 mat(3, 3) = 1.0f;
379}
380
381void GLRenderTargetCube::getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ)
382{
383 static const QMatrix4x4 reference(
384 1.0f, 0.0f, 0.0f, 0.0f,
385 0.0f, 1.0f, 0.0f, 0.0f,
386 0.0f, 0.0f, 0.0f, 0.0f,
387 0.0f, 0.0f, -1.0f, 0.0f);
388
389 mat = reference;
390 mat(2, 2) = (nearZ+farZ)/(nearZ-farZ);
391 mat(2, 3) = 2.0f*nearZ*farZ/(nearZ-farZ);
392}
Note: See TracBrowser for help on using the repository browser.