source: trunk/demos/boxes/glbuffers.h@ 561

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

trunk: Merged in qt 4.6.1 sources.

File size: 11.2 KB
RevLine 
[2]1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]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**
[561]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.
[2]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**
[561]36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
[2]38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef GLBUFFERS_H
43#define GLBUFFERS_H
44
45//#include <GL/glew.h>
46#include "glextensions.h"
47
48#include <QtGui>
49#include <QtOpenGL>
50
51#define BUFFER_OFFSET(i) ((char*)0 + (i))
52#define SIZE_OF_MEMBER(cls, member) sizeof(static_cast<cls *>(0)->member)
53
54#define GLBUFFERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \
55if (m_failed || !(assertion)) { \
56 if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \
57 m_failed = true; \
58 returnStatement; \
59}
60
[561]61QT_BEGIN_NAMESPACE
62class QMatrix4x4;
63QT_END_NAMESPACE
64
[2]65class GLTexture
66{
67public:
68 GLTexture();
69 virtual ~GLTexture();
70 virtual void bind() = 0;
71 virtual void unbind() = 0;
72 virtual bool failed() const {return m_failed;}
73protected:
74 GLuint m_texture;
75 bool m_failed;
76};
77
78class GLFrameBufferObject
79{
80public:
81 friend class GLRenderTargetCube;
82 // friend class GLRenderTarget2D;
83
84 GLFrameBufferObject(int width, int height);
85 virtual ~GLFrameBufferObject();
86 bool isComplete();
87 virtual bool failed() const {return m_failed;}
88protected:
89 void setAsRenderTarget(bool state = true);
90 GLuint m_fbo;
91 GLuint m_depthBuffer;
92 int m_width, m_height;
93 bool m_failed;
94};
95
96class GLTexture2D : public GLTexture
97{
98public:
99 GLTexture2D(int width, int height);
100 GLTexture2D(const QString& fileName, int width = 0, int height = 0);
101 void load(int width, int height, QRgb *data);
102 virtual void bind();
103 virtual void unbind();
104};
105
106class GLTexture3D : public GLTexture
107{
108public:
109 GLTexture3D(int width, int height, int depth);
110 // TODO: Implement function below
111 //GLTexture3D(const QString& fileName, int width = 0, int height = 0);
112 void load(int width, int height, int depth, QRgb *data);
113 virtual void bind();
114 virtual void unbind();
115};
116
117class GLTextureCube : public GLTexture
118{
119public:
120 GLTextureCube(int size);
121 GLTextureCube(const QStringList& fileNames, int size = 0);
122 void load(int size, int face, QRgb *data);
123 virtual void bind();
124 virtual void unbind();
125};
126
127// TODO: Define and implement class below
128//class GLRenderTarget2D : public GLTexture2D
129
130class GLRenderTargetCube : public GLTextureCube
131{
132public:
133 GLRenderTargetCube(int size);
134 // begin rendering to one of the cube's faces. 0 <= face < 6
135 void begin(int face);
136 // end rendering
137 void end();
138 virtual bool failed() {return m_failed || m_fbo.failed();}
139
[561]140 static void getViewMatrix(QMatrix4x4& mat, int face);
141 static void getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ);
[2]142private:
143 GLFrameBufferObject m_fbo;
144};
145
146struct VertexDescription
147{
148 enum
149 {
150 Null = 0, // Terminates a VertexDescription array
151 Position,
152 TexCoord,
153 Normal,
154 Color,
155 };
156 int field; // Position, TexCoord, Normal, Color
157 int type; // GL_FLOAT, GL_UNSIGNED_BYTE
158 int count; // number of elements
159 int offset; // field's offset into vertex struct
160 int index; // 0 (unused at the moment)
161};
162
163// Implementation of interleaved buffers.
164// 'T' is a struct which must include a null-terminated static array
165// 'VertexDescription* description'.
166// Example:
167/*
168struct Vertex
169{
170 GLfloat position[3];
171 GLfloat texCoord[2];
172 GLfloat normal[3];
173 GLbyte color[4];
174 static VertexDescription description[];
175};
176
177VertexDescription Vertex::description[] = {
178 {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(Vertex, position) / sizeof(GLfloat), offsetof(Vertex, position), 0},
179 {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(Vertex, texCoord) / sizeof(GLfloat), offsetof(Vertex, texCoord), 0},
180 {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(Vertex, normal) / sizeof(GLfloat), offsetof(Vertex, normal), 0},
181 {VertexDescription::Color, GL_BYTE, SIZE_OF_MEMBER(Vertex, color) / sizeof(GLbyte), offsetof(Vertex, color), 0},
182 {VertexDescription::Null, 0, 0, 0, 0},
183};
184*/
185template<class T>
186class GLVertexBuffer
187{
188public:
189 GLVertexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
190 : m_length(0)
191 , m_mode(mode)
192 , m_buffer(0)
193 , m_failed(false)
194 {
195 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
196
197 glGenBuffers(1, &m_buffer);
198 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
199 glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
200 }
201
202 ~GLVertexBuffer()
203 {
204 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::~GLVertexBuffer", glDeleteBuffers, return)
205
206 glDeleteBuffers(1, &m_buffer);
207 }
208
209 void bind()
210 {
211 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::bind", glBindBuffer, return)
212
213 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
214 for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
215 switch (desc->field) {
216 case VertexDescription::Position:
217 glVertexPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
218 glEnableClientState(GL_VERTEX_ARRAY);
219 break;
220 case VertexDescription::TexCoord:
221 glTexCoordPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
222 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
223 break;
224 case VertexDescription::Normal:
225 glNormalPointer(desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
226 glEnableClientState(GL_NORMAL_ARRAY);
227 break;
228 case VertexDescription::Color:
229 glColorPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
230 glEnableClientState(GL_COLOR_ARRAY);
231 break;
232 default:
233 break;
234 }
235 }
236 }
237
238 void unbind()
239 {
240 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unbind", glBindBuffer, return)
241
242 glBindBuffer(GL_ARRAY_BUFFER, 0);
243 for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
244 switch (desc->field) {
245 case VertexDescription::Position:
246 glDisableClientState(GL_VERTEX_ARRAY);
247 break;
248 case VertexDescription::TexCoord:
249 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
250 break;
251 case VertexDescription::Normal:
252 glDisableClientState(GL_NORMAL_ARRAY);
253 break;
254 case VertexDescription::Color:
255 glDisableClientState(GL_COLOR_ARRAY);
256 break;
257 default:
258 break;
259 }
260 }
261 }
262
263 int length() const {return m_length;}
264
265 T *lock()
266 {
267 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
268
269 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
270 //glBufferData(GL_ARRAY_BUFFER, m_length, NULL, m_mode);
271 GLvoid* buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
272 m_failed = (buffer == 0);
273 return reinterpret_cast<T *>(buffer);
274 }
275
276 void unlock()
277 {
278 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
279
280 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
281 glUnmapBuffer(GL_ARRAY_BUFFER);
282 }
283
284 bool failed()
285 {
286 return m_failed;
287 }
288
289private:
290 int m_length, m_mode;
291 GLuint m_buffer;
292 bool m_failed;
293};
294
295template<class T>
296class GLIndexBuffer
297{
298public:
299 GLIndexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
300 : m_length(0)
301 , m_mode(mode)
302 , m_buffer(0)
303 , m_failed(false)
304 {
305 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::GLIndexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
306
307 glGenBuffers(1, &m_buffer);
308 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
309 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
310 }
311
312 ~GLIndexBuffer()
313 {
314 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::~GLIndexBuffer", glDeleteBuffers, return)
315
316 glDeleteBuffers(1, &m_buffer);
317 }
318
319 void bind()
320 {
321 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::bind", glBindBuffer, return)
322
323 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
324 }
325
326 void unbind()
327 {
328 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unbind", glBindBuffer, return)
329
330 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
331 }
332
333 int length() const {return m_length;}
334
335 T *lock()
336 {
337 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
338
339 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
340 GLvoid* buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE);
341 m_failed = (buffer == 0);
342 return reinterpret_cast<T *>(buffer);
343 }
344
345 void unlock()
346 {
347 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
348
349 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
350 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
351 }
352
353 bool failed()
354 {
355 return m_failed;
356 }
357
358private:
359 int m_length, m_mode;
360 GLuint m_buffer;
361 bool m_failed;
362};
363
364#endif
Note: See TracBrowser for help on using the repository browser.