00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include <QApplication>
00057 #include <QDir>
00058 #include <QString>
00059
00060 #include <iostream>
00061 #include <cassert>
00062 #include <sstream>
00063 #include <fstream>
00064
00065 #include <../GL/gl.hh>
00066
00067 #include "gldebug.h"
00068 #include "GLSLShader.hh"
00069
00070 #ifdef WIN32
00071 #define snprintf sprintf_s
00072 #endif
00073
00074
00075
00076 namespace GLSL {
00077
00078
00079
00080
00081
00086 Shader::Shader(GLenum shaderType)
00087 : m_shaderId(0)
00088 {
00089 this->m_shaderId = glCreateShader(shaderType);
00090 assert(this->m_shaderId && "could not create shader");
00091 }
00092
00095 Shader::~Shader()
00096 {
00097 if (this->m_shaderId) {
00098 glDeleteShader(m_shaderId);
00099 }
00100 }
00101
00104 void Shader::setSource(StringList source)
00105 {
00106 assert(this->m_shaderId && "shader not initialized");
00107
00108 const char **stringArray = new const char*[source.size()];
00109
00110 int index = 0;
00111 for (StringList::const_iterator it = source.begin();it != source.end();++it) {
00112 stringArray[index] = (*it).c_str();
00113 ++index;
00114 }
00115
00116 glShaderSource(this->m_shaderId, source.size(), stringArray, 0);
00117
00118 delete[] stringArray;
00119 }
00120
00126 bool Shader::compile()
00127 {
00128 assert(this->m_shaderId && "shader not initialized");
00129
00130 glCompileShader(this->m_shaderId);
00131
00132 GLint compileStatus;
00133 glGetShaderiv(this->m_shaderId, GL_COMPILE_STATUS, &compileStatus);
00134 if (compileStatus == GL_FALSE) {
00135 GLchar *errorLog = new GLchar[GLSL_MAX_LOGSIZE];
00136 GLsizei errorLength;
00137 char shaderSource[32768];
00138 glGetShaderSource(this->m_shaderId, 32768, &errorLength, shaderSource);
00139 std::cout << "shader source: " << std::endl << shaderSource << std::endl;
00140 glGetShaderInfoLog(this->m_shaderId, GLSL_MAX_LOGSIZE, &errorLength, errorLog);
00141 std::cout << "GLSL compile error:" << std::endl << errorLog << std::endl;
00142 delete[] errorLog;
00143
00144 return false;
00145 }
00146 return true;
00147 }
00148
00149
00150
00151
00152
00153 VertexShader::VertexShader() : Shader(GL_VERTEX_SHADER) {}
00154 VertexShader::~VertexShader() {}
00155
00156
00157
00158
00159
00160 FragmentShader::FragmentShader() : Shader(GL_FRAGMENT_SHADER) {}
00161 FragmentShader::~FragmentShader() {}
00162
00163
00164
00165
00166
00169 Program::Program()
00170 {
00171 this->m_programId = glCreateProgram();
00172 assert(this->m_programId && "could not create GLSL program");
00173 }
00174
00177 Program::~Program()
00178 {
00179 if (this->m_programId) {
00180 glDeleteProgram(this->m_programId);
00181 }
00182
00183 this->m_linkedShaders.clear();
00184 }
00185
00188 void
00189 Program::attach(PtrConstShader shader)
00190 {
00191 assert(this->m_programId && "attach invalid program");
00192 assert(shader->m_shaderId && "attach invalid shader");
00193
00194 glAttachShader(this->m_programId, shader->m_shaderId);
00195 m_linkedShaders.push_back(shader);
00196 }
00197
00200 void Program::detach(PtrConstShader shader)
00201 {
00202 assert(this->m_programId && "detach invalid program");
00203 assert(shader->m_shaderId && "detach invalid shader");
00204
00205 glDetachShader(this->m_programId, shader->m_shaderId);
00206 m_linkedShaders.remove(shader);
00207 }
00208
00211 void Program::link()
00212 {
00213 glLinkProgram(this->m_programId);
00214 checkGLError2("link program failed");
00215 }
00216
00219 void Program::use()
00220 {
00221 glUseProgram(this->m_programId);
00222 checkGLError2("use program failed");
00223 }
00224
00227 void Program::disable() {
00228 glUseProgram(0);
00229 checkGLError2("shader disable failed");
00230 }
00231
00234 bool Program::isActive()
00235 {
00236 GLint programId;
00237 glGetIntegerv(GL_CURRENT_PROGRAM, &programId);
00238 return programId == this->m_programId;
00239 }
00240
00243 void Program::setUniform(const char *name, GLint value)
00244 {
00245 checkGLError();
00246 GLint location = glGetUniformLocation(this->m_programId, name);
00247 checkGLError2(name);
00248 glUniform1i(location, value);
00249 checkGLError2(name);
00250 }
00251
00254 void Program::setUniform(const char *name, GLfloat value)
00255 {
00256 checkGLError2("prev opengl error");
00257 GLint location = glGetUniformLocation(this->m_programId, name);
00258 checkGLError2(name);
00259 glUniform1f(location, value);
00260 checkGLError2(name);
00261 }
00262
00265 void Program::setUniform(const char *name, const ACG::Vec3f &value)
00266 {
00267 checkGLError();
00268 GLint location = glGetUniformLocation(this->m_programId, name);
00269 checkGLError2(name);
00270 glUniform3fv(location, 1, value.data());
00271 checkGLError();
00272 }
00273
00274 void Program::setUniform(const char *name, GLint *values, int count)
00275 {
00276 checkGLError();
00277 GLint location = glGetUniformLocation(this->m_programId, name);
00278 checkGLError2(name);
00279 glUniform1iv(location, count, values);
00280 checkGLError();
00281 }
00282
00283 void Program::setUniform(const char *name, int index, bool value)
00284 {
00285 char varName[1024];
00286 snprintf(varName, 1024, "%s[%d]", name, index);
00287 setUniform(varName, (GLint) value);
00288 }
00289
00290 void Program::setUniform(const char *name, int index, int value)
00291 {
00292 char varName[1024];
00293 snprintf(varName, 1024, "%s[%d]", name, index);
00294 setUniform(varName, (GLint) value);
00295 }
00296
00297 void Program::setUniform(const char *name, int index, float value)
00298 {
00299 char varName[1024];
00300 snprintf(varName, 1024, "%s[%d]", name, index);
00301 setUniform(varName, value);
00302 }
00303
00304 void Program::bindAttributeLocation(unsigned int index, const char *name) {
00305 glBindAttribLocation(this->m_programId, index, name);
00306 checkGLError2(name);
00307 }
00308
00309 int Program::getAttributeLocation(const char *name) {
00310 int attributeLocation = glGetAttribLocationARB(this->m_programId, name);
00311 checkGLError2(name);
00312 return attributeLocation;
00313 }
00314
00315 int Program::getUniformLocation(const char *name) {
00316 int attributeLocation = glGetUniformLocationARB(this->m_programId, name);
00317 checkGLError2(name);
00318 return attributeLocation;
00319 }
00320
00328 GLSL::StringList loadShader(const char *filename)
00329 {
00330 QString path_file;
00331 if (QDir(filename).isRelative()) {
00332 path_file = qApp->applicationDirPath() + QString("/../shader/")
00333 + QString(filename);
00334 } else {
00335 path_file = QString::fromAscii(filename);
00336 }
00337 std::ifstream iShader(path_file.toAscii());
00338 if (!iShader) {
00339 std::cout << "ERROR: Could not open file " << path_file.toStdString() << std::endl;
00340 return GLSL::StringList();
00341 }
00342
00343 GLSL::StringList shaderSource;
00344
00345 while (!iShader.eof()) {
00346 std::string strLine;
00347 std::getline(iShader, strLine);
00348 strLine += "\n";
00349 shaderSource.push_back(strLine);
00350 }
00351 iShader.close();
00352 return shaderSource;
00353 }
00354
00357 GLSL::PtrVertexShader loadVertexShader(const char *name)
00358 {
00359 PtrVertexShader vertexShader = 0;
00360 StringList sourceVertex = loadShader(name);
00361
00362 if (sourceVertex.size() != 0) {
00363 vertexShader = GLSL::PtrVertexShader(new GLSL::VertexShader());
00364 vertexShader->setSource(sourceVertex);
00365 vertexShader->compile();
00366 }
00367 return vertexShader;
00368 }
00369
00372 GLSL::PtrFragmentShader loadFragmentShader(const char *name)
00373 {
00374 PtrFragmentShader fragmentShader = 0;
00375 StringList sourceVertex = loadShader(name);
00376
00377 if (sourceVertex.size() != 0) {
00378 fragmentShader = GLSL::PtrFragmentShader(new GLSL::FragmentShader());
00379 fragmentShader->setSource(sourceVertex);
00380 fragmentShader->compile();
00381 }
00382 return fragmentShader;
00383 }
00384
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396