1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 ** This file is part of the demonstration applications of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the Technology Preview License Agreement accompanying
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.
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.1, included in the file LGPL_EXCEPTION.txt in this
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
45 //#include <GL/glew.h>
46 #include "glextensions.h"
51 #define BUFFER_OFFSET(i) ((char*)0 + (i))
52 #define SIZE_OF_MEMBER(cls, member) sizeof(static_cast<cls *>(0)->member)
54 #define GLBUFFERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \
55 if (m_failed || !(assertion)) { \
56 if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \
70 virtual void bind() = 0;
71 virtual void unbind() = 0;
72 virtual bool failed() const {return m_failed
;}
78 class GLFrameBufferObject
81 friend class GLRenderTargetCube
;
82 // friend class GLRenderTarget2D;
84 GLFrameBufferObject(int width
, int height
);
85 virtual ~GLFrameBufferObject();
87 virtual bool failed() const {return m_failed
;}
89 void setAsRenderTarget(bool state
= true);
92 int m_width
, m_height
;
96 class GLTexture2D
: public GLTexture
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
);
103 virtual void unbind();
106 class GLTexture3D
: public GLTexture
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
);
114 virtual void unbind();
117 class GLTextureCube
: public GLTexture
120 GLTextureCube(int size
);
121 GLTextureCube(const QStringList
& fileNames
, int size
= 0);
122 void load(int size
, int face
, QRgb
*data
);
124 virtual void unbind();
127 // TODO: Define and implement class below
128 //class GLRenderTarget2D : public GLTexture2D
130 class GLRenderTargetCube
: public GLTextureCube
133 GLRenderTargetCube(int size
);
134 // begin rendering to one of the cube's faces. 0 <= face < 6
135 void begin(int face
);
138 virtual bool failed() {return m_failed
|| m_fbo
.failed();}
140 static void getViewMatrix(QMatrix4x4
& mat
, int face
);
141 static void getProjectionMatrix(QMatrix4x4
& mat
, float nearZ
, float farZ
);
143 GLFrameBufferObject m_fbo
;
146 struct VertexDescription
150 Null
= 0, // Terminates a VertexDescription array
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)
163 // Implementation of interleaved buffers.
164 // 'T' is a struct which must include a null-terminated static array
165 // 'VertexDescription* description'.
174 static VertexDescription description[];
177 VertexDescription 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},
189 GLVertexBuffer(int length
, const T
*data
= 0, int mode
= GL_STATIC_DRAW
)
195 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers
&& glBindBuffer
&& glBufferData
, return)
197 glGenBuffers(1, &m_buffer
);
198 glBindBuffer(GL_ARRAY_BUFFER
, m_buffer
);
199 glBufferData(GL_ARRAY_BUFFER
, (m_length
= length
) * sizeof(T
), data
, mode
);
204 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::~GLVertexBuffer", glDeleteBuffers
, return)
206 glDeleteBuffers(1, &m_buffer
);
211 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::bind", glBindBuffer
, return)
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
);
220 case VertexDescription::TexCoord
:
221 glTexCoordPointer(desc
->count
, desc
->type
, sizeof(T
), BUFFER_OFFSET(desc
->offset
));
222 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
224 case VertexDescription::Normal
:
225 glNormalPointer(desc
->type
, sizeof(T
), BUFFER_OFFSET(desc
->offset
));
226 glEnableClientState(GL_NORMAL_ARRAY
);
228 case VertexDescription::Color
:
229 glColorPointer(desc
->count
, desc
->type
, sizeof(T
), BUFFER_OFFSET(desc
->offset
));
230 glEnableClientState(GL_COLOR_ARRAY
);
240 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unbind", glBindBuffer
, return)
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
);
248 case VertexDescription::TexCoord
:
249 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
251 case VertexDescription::Normal
:
252 glDisableClientState(GL_NORMAL_ARRAY
);
254 case VertexDescription::Color
:
255 glDisableClientState(GL_COLOR_ARRAY
);
263 int length() const {return m_length
;}
267 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::lock", glBindBuffer
&& glMapBuffer
, return 0)
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
);
278 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unlock", glBindBuffer
&& glUnmapBuffer
, return)
280 glBindBuffer(GL_ARRAY_BUFFER
, m_buffer
);
281 glUnmapBuffer(GL_ARRAY_BUFFER
);
290 int m_length
, m_mode
;
299 GLIndexBuffer(int length
, const T
*data
= 0, int mode
= GL_STATIC_DRAW
)
305 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::GLIndexBuffer", glGenBuffers
&& glBindBuffer
&& glBufferData
, return)
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
);
314 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::~GLIndexBuffer", glDeleteBuffers
, return)
316 glDeleteBuffers(1, &m_buffer
);
321 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::bind", glBindBuffer
, return)
323 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, m_buffer
);
328 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unbind", glBindBuffer
, return)
330 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
333 int length() const {return m_length
;}
337 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::lock", glBindBuffer
&& glMapBuffer
, return 0)
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
);
347 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unlock", glBindBuffer
&& glUnmapBuffer
, return)
349 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, m_buffer
);
350 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER
);
359 int m_length
, m_mode
;