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

Last change on this file since 374 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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