source: branches/4.5.1/demos/boxes/glbuffers.h@ 1003

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

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

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