1 /****************************************************************************
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
6 ** This file is part of the demonstration applications of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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."); \
61 void qgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
72 virtual void bind() = 0;
73 virtual void unbind() = 0;
74 virtual bool failed() const {return m_failed;}
80 class GLFrameBufferObject
83 friend class GLRenderTargetCube;
84 // friend class GLRenderTarget2D;
86 GLFrameBufferObject(int width, int height);
87 virtual ~GLFrameBufferObject();
89 virtual bool failed() const {return m_failed;}
91 void setAsRenderTarget(bool state = true);
94 int m_width, m_height;
98 class GLTexture2D : public GLTexture
101 GLTexture2D(int width, int height);
102 GLTexture2D(const QString& fileName, int width = 0, int height = 0);
103 void load(int width, int height, QRgb *data);
105 virtual void unbind();
108 class GLTexture3D : public GLTexture
111 GLTexture3D(int width, int height, int depth);
112 // TODO: Implement function below
113 //GLTexture3D(const QString& fileName, int width = 0, int height = 0);
114 void load(int width, int height, int depth, QRgb *data);
116 virtual void unbind();
119 class GLTextureCube : public GLTexture
122 GLTextureCube(int size);
123 GLTextureCube(const QStringList& fileNames, int size = 0);
124 void load(int size, int face, QRgb *data);
126 virtual void unbind();
129 // TODO: Define and implement class below
130 //class GLRenderTarget2D : public GLTexture2D
132 class GLRenderTargetCube : public GLTextureCube
135 GLRenderTargetCube(int size);
136 // begin rendering to one of the cube's faces. 0 <= face < 6
137 void begin(int face);
140 virtual bool failed() {return m_failed || m_fbo.failed();}
142 static void getViewMatrix(QMatrix4x4& mat, int face);
143 static void getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ);
145 GLFrameBufferObject m_fbo;
148 struct VertexDescription
152 Null = 0, // Terminates a VertexDescription array
158 int field; // Position, TexCoord, Normal, Color
159 int type; // GL_FLOAT, GL_UNSIGNED_BYTE
160 int count; // number of elements
161 int offset; // field's offset into vertex struct
162 int index; // 0 (unused at the moment)
165 // Implementation of interleaved buffers.
166 // 'T' is a struct which must include a null-terminated static array
167 // 'VertexDescription* description'.
176 static VertexDescription description[];
179 VertexDescription Vertex::description[] = {
180 {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(Vertex, position) / sizeof(GLfloat), offsetof(Vertex, position), 0},
181 {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(Vertex, texCoord) / sizeof(GLfloat), offsetof(Vertex, texCoord), 0},
182 {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(Vertex, normal) / sizeof(GLfloat), offsetof(Vertex, normal), 0},
183 {VertexDescription::Color, GL_BYTE, SIZE_OF_MEMBER(Vertex, color) / sizeof(GLbyte), offsetof(Vertex, color), 0},
184 {VertexDescription::Null, 0, 0, 0, 0},
191 GLVertexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
197 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
199 glGenBuffers(1, &m_buffer);
200 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
201 glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
206 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::~GLVertexBuffer", glDeleteBuffers, return)
208 glDeleteBuffers(1, &m_buffer);
213 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::bind", glBindBuffer, return)
215 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
216 for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
217 switch (desc->field) {
218 case VertexDescription::Position:
219 glVertexPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
220 glEnableClientState(GL_VERTEX_ARRAY);
222 case VertexDescription::TexCoord:
223 glTexCoordPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
224 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
226 case VertexDescription::Normal:
227 glNormalPointer(desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
228 glEnableClientState(GL_NORMAL_ARRAY);
230 case VertexDescription::Color:
231 glColorPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset));
232 glEnableClientState(GL_COLOR_ARRAY);
242 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unbind", glBindBuffer, return)
244 glBindBuffer(GL_ARRAY_BUFFER, 0);
245 for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) {
246 switch (desc->field) {
247 case VertexDescription::Position:
248 glDisableClientState(GL_VERTEX_ARRAY);
250 case VertexDescription::TexCoord:
251 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
253 case VertexDescription::Normal:
254 glDisableClientState(GL_NORMAL_ARRAY);
256 case VertexDescription::Color:
257 glDisableClientState(GL_COLOR_ARRAY);
265 int length() const {return m_length;}
269 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
271 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
272 //glBufferData(GL_ARRAY_BUFFER, m_length, NULL, m_mode);
273 GLvoid* buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
274 m_failed = (buffer == 0);
275 return reinterpret_cast<T *>(buffer);
280 GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
282 glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
283 glUnmapBuffer(GL_ARRAY_BUFFER);
292 int m_length, m_mode;
301 GLIndexBuffer(int length, const T *data = 0, int mode = GL_STATIC_DRAW)
307 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::GLIndexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
309 glGenBuffers(1, &m_buffer);
310 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
311 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
316 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::~GLIndexBuffer", glDeleteBuffers, return)
318 glDeleteBuffers(1, &m_buffer);
323 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::bind", glBindBuffer, return)
325 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
330 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unbind", glBindBuffer, return)
332 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
335 int length() const {return m_length;}
339 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::lock", glBindBuffer && glMapBuffer, return 0)
341 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
342 GLvoid* buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE);
343 m_failed = (buffer == 0);
344 return reinterpret_cast<T *>(buffer);
349 GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unlock", glBindBuffer && glUnmapBuffer, return)
351 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
352 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
361 int m_length, m_mode;