GLSLShader.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2005 Dave Griffiths
00002 //
00003 // This program is free software; you can redistribute it and/or modify
00004 // it under the terms of the GNU General Public License as published by
00005 // the Free Software Foundation; either version 2 of the License, or
00006 // (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00016 
00017 #include "GLSLShader.h"
00018 #include <iostream>
00019 #include "Trace.h"
00020 #include "SearchPaths.h"
00021 
00022 using namespace std;
00023 using namespace Fluxus;
00024 
00025 bool GLSLShader::m_Enabled(false);
00026 
00027 
00028 GLSLShaderPair::GLSLShaderPair(const string &vertexfilename, const string &fragmentfilename)
00029 {
00030     if (!Load(vertexfilename, fragmentfilename))
00031     {
00032         Trace::Stream<<"Problem loading shaderpair ["<<vertexfilename<<", "<<fragmentfilename<<"]"<<endl;
00033     }
00034 }
00035 
00036 GLSLShaderPair::~GLSLShaderPair()
00037 {
00038 }
00039 
00040 bool GLSLShaderPair::Load(const string &vertexfilename, const string &fragmentfilename)
00041 {
00042     #ifdef GLSL
00043     if (!GLSLShader::m_Enabled) return true;
00044 
00045     m_VertexShader = LoadShader(SearchPaths::Get()->GetFullPath(vertexfilename),GL_VERTEX_SHADER);
00046     if (m_VertexShader==0) return false; 
00047     m_FragmentShader = LoadShader(SearchPaths::Get()->GetFullPath(fragmentfilename),GL_FRAGMENT_SHADER);
00048     if (m_FragmentShader==0) return false; 
00049 
00050     #endif
00051     return true;
00052 }
00053     
00054     
00055 unsigned int GLSLShaderPair::LoadShader(string filename, unsigned int type)
00056 {
00057     #ifdef GLSL
00058     if (!GLSLShader::m_Enabled) return 0;
00059     FILE* file = fopen(filename.c_str(), "r");
00060     if (!file) 
00061     {
00062         Trace::Stream<<"Couldn't open shader ["<<filename<<"]"<<endl;
00063         return 0;
00064     }
00065 
00066     fseek(file, 0, SEEK_END);
00067     unsigned int size = ftell(file);
00068     fseek(file, 0, SEEK_SET);
00069 
00070     char* code = new char[size+1];
00071     code[size]='\0';
00072 
00073     if (fread(code,1,size,file)!=size)
00074     {
00075         Trace::Stream<<"Error reading shader ["<<filename<<"]"<<endl;
00076         delete[] code;
00077         fclose(file);
00078         return 0;
00079     }
00080     else
00081     {
00082         unsigned int shader = glCreateShader(type);
00083         glShaderSource(shader, 1, (const char**)&code, NULL);
00084         glCompileShader(shader);
00085 
00086         GLint status = GL_FALSE;
00087         glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
00088         if(status != GL_TRUE)
00089         {   
00090             GLsizei size = 0;
00091             char log[1024];
00092 
00093             glGetShaderInfoLog(shader, 1024, &size, log);
00094             Trace::Stream<<"compile errors for ["<<filename<<"]"<<endl;
00095             Trace::Stream<<log<<endl;
00096 
00097             glDeleteShader(shader);
00098             delete[] code;
00099             fclose(file);
00100             return 0;
00101         }
00102         
00103         delete[] code;
00104         fclose(file);
00105         return shader;
00106     }
00107     #endif
00108     return 0;
00109 }
00110 
00112 
00113 GLSLShader::GLSLShader(const GLSLShaderPair &pair) :
00114 m_Program(0),
00115 m_RefCount(1)
00116 {   
00117     #ifdef GLSL
00118     m_Program = glCreateProgram();
00119     glAttachShader(m_Program, pair.GetVertexShader());
00120     glAttachShader(m_Program, pair.GetFragmentShader());
00121     glLinkProgram(m_Program);
00122 
00123     GLint status = GL_FALSE;
00124     glGetProgramiv(m_Program, GL_LINK_STATUS, &status);
00125     if(status != GL_TRUE)
00126     {
00127         GLsizei size = 0;
00128         char log[1024];
00129         glGetProgramInfoLog(m_Program, 1024, &size, log);
00130         Trace::Stream<<log<<endl;
00131     }   
00132     else
00133     {
00134         m_IsValid = true;
00135     }
00136     #endif
00137 }
00138 
00139 GLSLShader::~GLSLShader()
00140 {
00141     #ifdef GLSL
00142     if (!m_Enabled) return;
00143     glDeleteProgram(m_Program);
00144     #endif
00145 }
00146 
00147 void GLSLShader::Init()
00148 {
00149     #ifdef GLSL
00150     m_Enabled = glewIsSupported("GL_VERSION_2_0");
00151     #endif
00152 }
00153 
00154 void GLSLShader::Apply() 
00155 { 
00156     #ifdef GLSL
00157     if (!m_Enabled) return;
00158     glUseProgram(m_Program); 
00159     #endif
00160 }
00161 
00162 void GLSLShader::Unapply() 
00163 { 
00164     #ifdef GLSL
00165     if (!m_Enabled) return;
00166     glUseProgram(0); 
00167     #endif
00168 }
00169 
00170 void GLSLShader::SetInt(const string &name, int s)
00171 {
00172     #ifdef GLSL
00173     if (!m_Enabled) return;
00174     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00175     glUniform1i(param,s);
00176     #endif
00177 }
00178 
00179 void GLSLShader::SetFloat(const string &name, float s)
00180 {
00181     #ifdef GLSL
00182     if (!m_Enabled) return;
00183     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00184     glUniform1f(param,s);
00185     #endif
00186 }
00187 
00188 void GLSLShader::SetVector(const string &name, dVector s)
00189 {
00190     #ifdef GLSL
00191     if (!m_Enabled) return;
00192     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00193     glUniform3f(param,s.x,s.y,s.z);
00194     #endif
00195 }
00196 
00197 void GLSLShader::SetColour(const string &name, dColour s)
00198 {
00199     #ifdef GLSL
00200     if (!m_Enabled) return;
00201     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00202     glUniform4f(param,s.r,s.g,s.b,s.a);
00203     #endif
00204 }
00205 
00206 void GLSLShader::SetFloatArray(const string &name, const vector<float> &s)
00207 {
00208     #ifdef GLSL
00209     if (!m_Enabled) return;
00210     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00211     glEnableVertexAttribArray(attrib);
00212     glVertexAttribPointer(attrib,1,GL_FLOAT,false,0,&(*s.begin()));
00213     #endif
00214 }
00215 
00216 void GLSLShader::SetVectorArray(const string &name, const vector<dVector> &s)
00217 {
00218     #ifdef GLSL
00219     if (!m_Enabled) return;
00220     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00221     glEnableVertexAttribArray(attrib);
00222     glVertexAttribPointer(attrib,4,GL_FLOAT,false,0,&(*s.begin()));
00223     #endif
00224 }
00225 
00226 void GLSLShader::SetColourArray(const string &name, const vector<dColour> &s)
00227 {
00228     #ifdef GLSL
00229     if (!m_Enabled) return;
00230     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00231     glEnableVertexAttribArray(attrib);
00232     glVertexAttribPointer(attrib,4,GL_FLOAT,false,0,&(*s.begin()));
00233     #endif
00234 }
00235 
00236 

Generated on Wed Sep 17 21:16:30 2008 for The Fluxus Renderer (libfluxus) by  doxygen 1.5.1