source: branches/4.5.1/demos/boxes/glshaders.cpp@ 921

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

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

File size: 8.7 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 "glshaders.h"
43
44#define GLSHADERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \
45if (m_failed || !(assertion)) { \
46 if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \
47 m_failed = true; \
48 returnStatement; \
49}
50
51
52GLShader::GLShader(const char *data, int size, GLenum shaderType)
53: m_compileError(false), m_failed(false)
54{
55 GLSHADERS_ASSERT_OPENGL("GLShader::GLShader",
56 glCreateShaderObjectARB && glShaderSourceARB && glCompileShaderARB && glGetObjectParameterivARB, return)
57
58 m_shader = glCreateShaderObjectARB(shaderType);
59
60 GLint glSize = size;
61 glShaderSourceARB(m_shader, 1, &data, &glSize);
62 glCompileShaderARB(m_shader);
63 int status;
64 glGetObjectParameterivARB(m_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
65 m_compileError = (status != 1);
66}
67
68GLShader::GLShader(const QString& fileName, GLenum shaderType)
69 : m_compileError(false), m_failed(false)
70{
71 GLSHADERS_ASSERT_OPENGL("GLShader::GLShader",
72 glCreateShaderObjectARB && glShaderSourceARB && glCompileShaderARB && glGetObjectParameterivARB, return)
73
74 m_shader = glCreateShaderObjectARB(shaderType);
75
76 QFile file(fileName);
77 if (file.open(QIODevice::ReadOnly)) {
78 QByteArray bytes = file.readAll();
79 GLint size = file.size();
80 const char *p = bytes.data();
81 file.close();
82 glShaderSourceARB(m_shader, 1, &p, &size);
83 glCompileShaderARB(m_shader);
84 int status;
85 glGetObjectParameterivARB(m_shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
86 m_compileError = (status != 1);
87 } else {
88 m_compileError = true;
89 }
90}
91
92GLShader::~GLShader()
93{
94 GLSHADERS_ASSERT_OPENGL("GLShader::~GLShader", glDeleteObjectARB, return)
95
96 glDeleteObjectARB(m_shader);
97}
98
99QString GLShader::log()
100{
101 GLSHADERS_ASSERT_OPENGL("GLShader::log", glGetObjectParameterivARB
102 && glGetInfoLogARB, return QLatin1String("GLSL not supported."))
103
104 int length;
105 glGetObjectParameterivARB(m_shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
106 char *log = new char[length + 1];
107 GLsizei glLength = length;
108 glGetInfoLogARB(m_shader, glLength, &glLength, log);
109 log[glLength] = '\0';
110 QString result(log);
111 delete log;
112 return result;
113}
114
115GLVertexShader::GLVertexShader(const char *data, int size) : GLShader(data, size, GL_VERTEX_SHADER_ARB)
116{
117}
118
119GLVertexShader::GLVertexShader(const QString& fileName) : GLShader(fileName, GL_VERTEX_SHADER_ARB)
120{
121}
122
123GLFragmentShader::GLFragmentShader(const char *data, int size) : GLShader(data, size, GL_FRAGMENT_SHADER_ARB)
124{
125}
126
127GLFragmentShader::GLFragmentShader(const QString& fileName) : GLShader(fileName, GL_FRAGMENT_SHADER_ARB)
128{
129}
130
131GLProgram::GLProgram() : m_linked(false), m_linkError(false), m_failed(false)
132{
133 GLSHADERS_ASSERT_OPENGL("GLProgram::GLProgram", glCreateProgramObjectARB, return)
134
135 m_program = glCreateProgramObjectARB();
136}
137
138GLProgram::~GLProgram()
139{
140 GLSHADERS_ASSERT_OPENGL("GLProgram::~GLProgram", glDeleteObjectARB, return)
141
142 glDeleteObjectARB(m_program);
143}
144
145void GLProgram::attach(const GLShader &shader)
146{
147 GLSHADERS_ASSERT_OPENGL("GLProgram::attach", glAttachObjectARB, return)
148
149 glAttachObjectARB(m_program, shader.m_shader);
150 m_linked = m_linkError = false;
151}
152
153void GLProgram::detach(const GLShader &shader)
154{
155 GLSHADERS_ASSERT_OPENGL("GLProgram::detach", glDetachObjectARB, return)
156
157 glDetachObjectARB(m_program, shader.m_shader);
158 m_linked = m_linkError = false;
159}
160
161bool GLProgram::failed()
162{
163 if (m_failed || m_linkError)
164 return true;
165
166 if (m_linked)
167 return false;
168
169 GLSHADERS_ASSERT_OPENGL("GLProgram::failed", glLinkProgramARB && glGetObjectParameterivARB, return true)
170
171 glLinkProgramARB(m_program);
172 int status;
173 glGetObjectParameterivARB(m_program, GL_OBJECT_LINK_STATUS_ARB, &status);
174 m_linkError = !(m_linked = (status == 1));
175 return m_linkError;
176}
177
178QString GLProgram::log()
179{
180 GLSHADERS_ASSERT_OPENGL("GLProgram::log", glGetObjectParameterivARB && glGetInfoLogARB,
181 return QLatin1String("Failed."))
182
183 int length;
184 glGetObjectParameterivARB(m_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
185 char *log = new char[length + 1];
186 GLsizei glLength = length;
187 glGetInfoLogARB(m_program, glLength, &glLength, log);
188 log[glLength] = '\0';
189 QString result(log);
190 delete log;
191 return result;
192}
193
194void GLProgram::bind()
195{
196 GLSHADERS_ASSERT_OPENGL("GLProgram::bind", glUseProgramObjectARB, return)
197
198 if (!failed())
199 glUseProgramObjectARB(m_program);
200}
201
202void GLProgram::unbind()
203{
204 GLSHADERS_ASSERT_OPENGL("GLProgram::bind", glUseProgramObjectARB, return)
205
206 glUseProgramObjectARB(0);
207}
208
209bool GLProgram::hasParameter(const QString& name)
210{
211 GLSHADERS_ASSERT_OPENGL("GLProgram::hasParameter", glGetUniformLocationARB, return false)
212
213 if (!failed()) {
214 QByteArray asciiName = name.toAscii();
215 return -1 != glGetUniformLocationARB(m_program, asciiName.data());
216 }
217 return false;
218}
219
220void GLProgram::setInt(const QString& name, int value)
221{
222 GLSHADERS_ASSERT_OPENGL("GLProgram::setInt", glGetUniformLocationARB && glUniform1iARB, return)
223
224 if (!failed()) {
225 QByteArray asciiName = name.toAscii();
226 int loc = glGetUniformLocationARB(m_program, asciiName.data());
227 glUniform1iARB(loc, value);
228 }
229}
230
231void GLProgram::setFloat(const QString& name, float value)
232{
233 GLSHADERS_ASSERT_OPENGL("GLProgram::setFloat", glGetUniformLocationARB && glUniform1fARB, return)
234
235 if (!failed()) {
236 QByteArray asciiName = name.toAscii();
237 int loc = glGetUniformLocationARB(m_program, asciiName.data());
238 glUniform1fARB(loc, value);
239 }
240}
241
242void GLProgram::setColor(const QString& name, QRgb value)
243{
244 GLSHADERS_ASSERT_OPENGL("GLProgram::setColor", glGetUniformLocationARB && glUniform4fARB, return)
245
246 //qDebug() << "Setting color" << name;
247 if (!failed()) {
248 QByteArray asciiName = name.toAscii();
249 int loc = glGetUniformLocationARB(m_program, asciiName.data());
250 //qDebug() << "Location of" << name << "is" << loc;
251 QColor color(value);
252 glUniform4fARB(loc, color.redF(), color.greenF(), color.blueF(), color.alphaF());
253 }
254}
255
256void GLProgram::setMatrix(const QString& name, const gfx::Matrix4x4f &mat)
257{
258 GLSHADERS_ASSERT_OPENGL("GLProgram::setMatrix", glGetUniformLocationARB && glUniformMatrix4fvARB, return)
259
260 if (!failed()) {
261 QByteArray asciiName = name.toAscii();
262 int loc = glGetUniformLocationARB(m_program, asciiName.data());
263 //qDebug() << "Location of" << name << "is" << loc;
264 glUniformMatrix4fvARB(loc, 1, GL_FALSE, mat.bits());
265 }
266}
Note: See TracBrowser for help on using the repository browser.