Shader.cpp
Go to the documentation of this file.
00001 /* Shader
00002  *
00003  * Copyright (C) 2005, Maurizio Monge <maurizio.monge@gmail.com>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include <blort/Tracker/Shader.h>
00021 #include <blort/Tracker/ShaderUtils.h>
00022 #include <string.h>
00023 #include <stdarg.h>
00024 #include <iostream>
00025 #include <ros/console.h>
00026 
00027 #ifdef HAVE_GTK
00028 #include <gtk/gtk.h>
00029 #endif
00030 
00031 #include <GL/glu.h>
00032 
00033 using namespace Tracking;
00034 
00035 static const char *gl_type_name(GLenum type)
00036 {
00037     switch(type)
00038     {
00039         case GL_FLOAT:             return "float";
00040         case GL_FLOAT_VEC2_ARB:    return "vec2";
00041         case GL_FLOAT_VEC3_ARB:    return "vec3";
00042         case GL_FLOAT_VEC4_ARB:    return "vec4";
00043         case GL_FLOAT_MAT2_ARB:    return "mat2";
00044         case GL_FLOAT_MAT3_ARB:    return "mat3";
00045         case GL_FLOAT_MAT4_ARB:    return "mat4";
00046         case GL_INT:               return "int";
00047         case GL_INT_VEC2_ARB:      return "ivec2";
00048         case GL_INT_VEC3_ARB:      return "ivec3";
00049         case GL_INT_VEC4_ARB:      return "ivec4";
00050         case GL_BOOL_ARB:          return "bool";
00051         case GL_BOOL_VEC2_ARB:     return "bvec2";
00052         case GL_BOOL_VEC3_ARB:     return "bvec3";
00053         case GL_BOOL_VEC4_ARB:     return "bvec4";
00054         case GL_SAMPLER_1D:        return "sampler1D";
00055         case GL_SAMPLER_2D:        return "sampler2D";
00056         case GL_SAMPLER_3D:        return "sampler3D";
00057         case GL_SAMPLER_CUBE:      return "samplerCube";
00058         case GL_SAMPLER_1D_SHADOW: return "sampler1DShadow";
00059         case GL_SAMPLER_2D_SHADOW: return "sampler2DShadow";
00060         default:
00061         {
00062             static char tmp[64];
00063             snprintf(tmp,64,"?0x%x?", type );
00064             return tmp;
00065         }
00066     }
00067 }
00068 
00069 void Shader::dumpVars()
00070 {
00071     int nv;
00072     glGetObjectParameterivARB( program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &nv);
00073     ROS_DEBUG("UNIFORM variables (%d)",nv);
00074 
00075     for(int i=0;i<nv;i++)
00076     {
00077         GLenum type;
00078         int size;
00079         char vname[4096];
00080         glGetActiveUniformARB(program,i,4096,NULL,&size,&type,vname);
00081         ROS_DEBUG("  %s %s;\n", gl_type_name(type),vname);
00082     }
00083 
00084     glGetObjectParameterivARB( program, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &nv);
00085     ROS_DEBUG("ATTRIBUTE variables (%d):\n",nv);
00086     for(int i=0;i<nv;i++)
00087     {
00088         GLenum type;
00089         int size;
00090         char vname[4096];
00091         glGetActiveAttribARB(program,i,4096,NULL,&size,&type,vname);
00092         ROS_DEBUG("  %s %s;\n", gl_type_name(type),vname);
00093     }
00094 }
00095 
00096 void Shader::printInfoLog(GLhandleARB obj, const char *msg, ...)
00097 {
00098     int infologLength = 0;
00099     int charsWritten  = 0;
00100     char *infoLog;
00101 
00102     glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
00103                               &infologLength);
00104     if(infologLength > 1)
00105     {
00106         va_list va;
00107         va_start(va, msg);
00108         infoLog = (char *)malloc(infologLength);
00109         glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
00110 #ifdef HAVE_GTK
00111         char *m = g_strdup_vprintf(msg, va);
00112         GtkWidget *dialog = gtk_message_dialog_new(NULL,GTK_DIALOG_MODAL,
00113                 GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,"%s (%d):",m,infologLength);
00114         g_free(m);
00115         gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),"%s",infoLog);
00116         gtk_dialog_run(GTK_DIALOG(dialog));
00117         gtk_widget_destroy(dialog);
00118 #else
00119         vprintf(msg, va);
00120         ROS_DEBUG(" (%d):\n",infologLength);
00121         ROS_DEBUG("%s",infoLog);
00122 #endif
00123         va_end(va);
00124         free(infoLog);
00125     }
00126 }
00127 
00128 bool Shader::getStatus(){
00129     if(program)
00130         return true;
00131     
00132     std::cerr << "No program" << std::endl;
00133     return false;
00134 }
00135 
00136 Shader::Shader(const char *vertex_file, const char *fragment_file, const char *header)
00137 {
00138     GLint status;
00139     const char *vs = read_text_file(vertex_file);
00140     const char *fs = read_text_file(fragment_file);
00141     
00142         if(header)  {
00143         if(vs) {
00144             char *tmp = (char*)malloc(strlen(header)+strlen(vs)+1);
00145             strcpy(tmp,header);
00146             strcat(tmp,vs);
00147             free((void*)vs);
00148             vs = tmp;
00149         }
00150         if(fs) {
00151             char *tmp = (char*)malloc(strlen(header)+strlen(fs)+1);
00152             strcpy(tmp,header);
00153             strcat(tmp,fs);
00154             free((void*)fs);
00155             fs = tmp;
00156         }
00157     }
00158 
00159     if(vs)
00160     {
00161         vertex = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
00162         glShaderSourceARB(vertex, 1, &vs, NULL);
00163         glCompileShaderARB(vertex);
00164 
00165         glGetObjectParameterivARB( vertex, GL_OBJECT_COMPILE_STATUS_ARB, &status);
00166         if(!status)
00167         {
00168             std::cerr << "compile vert" << std::endl;
00169             printInfoLog(vertex,"[Shader::Shader] Error compiling vertex shader \"%s\"",vertex_file);
00170             program = 0;
00171             return;
00172         }
00173         free((void*)vs);
00174     }
00175     else
00176         vertex = 0;
00177 
00178     if(fs)
00179     {
00180         fragment = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
00181         glShaderSourceARB(fragment, 1, &fs,NULL);
00182         glCompileShaderARB(fragment);
00183 
00184         glGetObjectParameterivARB( fragment, GL_OBJECT_COMPILE_STATUS_ARB, &status);
00185         if(!status)
00186         {
00187             std::cerr << "compile frag" << std::endl;
00188             printInfoLog(fragment,"[Shader::Shader] Error compiling fragment shader \"%s\"",fragment_file);
00189             program = 0;
00190             return;
00191         }
00192         free((void*)fs);
00193     }
00194     else
00195         fragment = 0;
00196 
00197     if(fragment==0 && vertex==0)
00198     {
00199         std::cerr << "fragment==0 and vertex==0" << std::endl;
00200         program = 0;
00201         return;
00202     }
00203 
00204     program = glCreateProgramObjectARB();
00205     if(vertex!=0)
00206     {
00207         glAttachObjectARB(program,vertex);
00208         glDeleteObjectARB(vertex);
00209     }
00210     if(fragment!=0)
00211     {
00212         glAttachObjectARB(program,fragment);
00213         glDeleteObjectARB(fragment);
00214     }
00215     glLinkProgramARB(program);
00216 
00217     glGetObjectParameterivARB( program, GL_OBJECT_LINK_STATUS_ARB, &status);
00218     if(!status)
00219     {
00220         std::cerr << "linking" << std::endl;
00221         printInfoLog(program,"Error linking program with \"%s\" and \"%s\"",
00222                                                     vertex_file,fragment_file);
00223         glDeleteObjectARB(program);
00224         program = 0;
00225         return;
00226     }
00227 
00228     glValidateProgramARB(program);
00229     glGetObjectParameterivARB( program, GL_OBJECT_VALIDATE_STATUS_ARB,&status);
00230     printInfoLog(program,"%s validating program",status?"Information":"Error");
00231     if(!status)
00232     {
00233         std::cerr << "validation" << std::endl;
00234         glDeleteObjectARB(program);
00235         program = 0;
00236     }
00237 
00238     //dumpVars();
00239 }
00240 
00241 Shader::~Shader()
00242 {
00243     if(program!=0){
00244         glDeleteObjectARB(program);
00245     }
00246 }
00247 
00248 void Shader::bind()
00249 {
00250     if(program)
00251         glUseProgramObjectARB(program);
00252 }
00253 
00254 void Shader::unbind()
00255 {
00256     if(program)
00257         glUseProgramObjectARB(0);
00258 }
00259 
00260 GLuint Shader::getAttribLoc(const char *attr)
00261 {
00262     return glGetAttribLocationARB( program, attr);
00263 }
00264 
00265 GLint Shader::getUniformLoc(const char* var)
00266 {
00267     return glGetUniformLocationARB(program,var);
00268 }
00269 
00270 void Shader::setUniform(const char* var,int f)
00271 {
00272     int loc = glGetUniformLocationARB(program,var);
00273     glUniform1iARB(loc,f);
00274 }
00275 
00276 void Shader::setUniform(const char* var,unsigned f)
00277 {
00278     int loc = glGetUniformLocationARB(program,var);
00279     glUniform1iARB(loc,(int)f);
00280 }
00281 
00282 void Shader::setUniform(const char* var,int n,const int* f)
00283 {
00284     int loc = glGetUniformLocationARB(program,var);
00285     glUniform1ivARB(loc,n,f);
00286 }
00287 
00288 void Shader::setUniform(const char* var,float f)
00289 {
00290     int loc = glGetUniformLocationARB(program,var);
00291     glUniform1fARB(loc,f);
00292 }
00293 
00294 void Shader::setUniform(const char* var,int n,const float* f)
00295 {
00296     int loc = glGetUniformLocationARB(program,var);
00297     glUniform1fvARB(loc,n,f);
00298     //ROS_DEBUG("f: %f %f %f\n", f[0],f[1],f[2]);
00299 }
00300 
00301 void Shader::setUniform(const char* var,vec2 f)
00302 {
00303     int loc = glGetUniformLocationARB(program,var);
00304     glUniform2fvARB(loc,1,f.v);
00305 }
00306 
00307 void Shader::setUniform(const char* var,int n,vec2* f)
00308 {
00309     int loc = glGetUniformLocationARB(program,var);
00310     glUniform1fvARB(loc,2*n,f->v);
00311 }
00312 
00313 void Shader::setUniform(const char* var,vec3 f)
00314 {
00315     int loc = glGetUniformLocationARB(program,var);
00316     glUniform3fvARB(loc,1,f.v);
00317 }
00318 
00319 void Shader::setUniform(const char* var,int n,vec3* f)
00320 {
00321     int loc = glGetUniformLocationARB(program,var);
00322     glUniform1fvARB(loc,3*n,f->v);
00323 }
00324 
00325 void Shader::setUniform(const char* var,vec4 f)
00326 {
00327     int loc = glGetUniformLocationARB(program,var);
00328     glUniform4fv(loc,1,f.v);
00329 }
00330 
00331 void Shader::setUniform(const char* var,int n,vec4* f)
00332 {
00333     int loc = glGetUniformLocationARB(program,var);
00334     glUniform1fvARB(loc,4*n,f->v);
00335 }
00336 
00337 void Shader::setUniform(const char* var,mat3 f,bool transpose)
00338 {
00339     int loc = glGetUniformLocationARB(program,var);
00340     glUniformMatrix3fvARB(loc,1,transpose,f.mat);
00341 }
00342 
00343 void Shader::setUniform(const char* var,int n,mat3* f,bool transpose)
00344 {
00345     int loc = glGetUniformLocationARB(program,var);
00346     glUniformMatrix3fvARB(loc,n,transpose,f->mat);
00347 }
00348 
00349 void Shader::setUniform(const char* var,mat4 f,bool transpose)
00350 {
00351     int loc = glGetUniformLocationARB(program,var);
00352     glUniformMatrix4fvARB(loc,1,transpose,f.mat);
00353 }
00354 
00355 void Shader::setUniform(const char* var,int n,mat4* f,bool transpose)
00356 {
00357     int loc = glGetUniformLocationARB(program,var);
00358     glUniformMatrix4fvARB(loc,n,transpose,f->mat);
00359 }
00360 
00361 
00362 


blort
Author(s): Thomas Mörwald , Michael Zillich , Andreas Richtsfeld , Johann Prankl , Markus Vincze , Bence Magyar
autogenerated on Wed Aug 26 2015 15:24:12