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 GLSLShader::GLSLShader(const string &vertexfilename, const string &fragmentfilename) :
00028 m_Program(0)
00029 {
00030     Load(vertexfilename, fragmentfilename);
00031 }
00032 
00033 GLSLShader::~GLSLShader()
00034 {
00035     #ifdef GLSL
00036     if (!m_Enabled) return;
00037     glDeleteProgram(m_Program);
00038     #endif
00039 }
00040 
00041 void GLSLShader::Init()
00042 {
00043     #ifdef GLSL
00044     m_Enabled = glewIsSupported("GL_VERSION_2_0");
00045     #endif
00046 }
00047 
00048 void GLSLShader::Apply() 
00049 { 
00050     #ifdef GLSL
00051     if (!m_Enabled) return;
00052     glUseProgram(m_Program); 
00053     #endif
00054 }
00055 
00056 void GLSLShader::Unapply() 
00057 { 
00058     #ifdef GLSL
00059     if (!m_Enabled) return;
00060     glUseProgram(0); 
00061     #endif
00062 }
00063 
00064 void GLSLShader::SetInt(const string &name, int s)
00065 {
00066     #ifdef GLSL
00067     if (!m_Enabled) return;
00068     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00069     glUniform1i(param,s);
00070     #endif
00071 }
00072 
00073 void GLSLShader::SetFloat(const string &name, float s)
00074 {
00075     #ifdef GLSL
00076     if (!m_Enabled) return;
00077     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00078     glUniform1f(param,s);
00079     #endif
00080 }
00081 
00082 void GLSLShader::SetVector(const string &name, dVector s)
00083 {
00084     #ifdef GLSL
00085     if (!m_Enabled) return;
00086     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00087     glUniform3f(param,s.x,s.y,s.z);
00088     #endif
00089 }
00090 
00091 void GLSLShader::SetColour(const string &name, dColour s)
00092 {
00093     #ifdef GLSL
00094     if (!m_Enabled) return;
00095     GLuint param = glGetUniformLocation(m_Program, name.c_str());
00096     glUniform4f(param,s.r,s.g,s.b,s.a);
00097     #endif
00098 }
00099 
00100 void GLSLShader::SetFloatArray(const string &name, const vector<float> &s)
00101 {
00102     #ifdef GLSL
00103     if (!m_Enabled) return;
00104     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00105     glEnableVertexAttribArray(attrib);
00106     glVertexAttribPointer(attrib,1,GL_FLOAT,false,0,&(*s.begin()));
00107     #endif
00108 }
00109 
00110 void GLSLShader::SetVectorArray(const string &name, const vector<dVector> &s)
00111 {
00112     #ifdef GLSL
00113     if (!m_Enabled) return;
00114     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00115     glEnableVertexAttribArray(attrib);
00116     glVertexAttribPointer(attrib,4,GL_FLOAT,false,0,&(*s.begin()));
00117     #endif
00118 }
00119 
00120 void GLSLShader::SetColourArray(const string &name, const vector<dColour> &s)
00121 {
00122     #ifdef GLSL
00123     if (!m_Enabled) return;
00124     GLuint attrib = glGetAttribLocation(m_Program, name.c_str());
00125     glEnableVertexAttribArray(attrib);
00126     glVertexAttribPointer(attrib,4,GL_FLOAT,false,0,&(*s.begin()));
00127     #endif
00128 }
00129 
00130 bool GLSLShader::Load(const string &vertexfilename, const string &fragmentfilename)
00131 {
00132     #ifdef GLSL
00133     if (!m_Enabled) return true;
00134     if (m_Program!=0) glDeleteProgram(m_Program);
00135 
00136     m_Program = glCreateProgram();
00137 
00138     bool bOk = true;
00139     unsigned int vertex = LoadShader(SearchPaths::Get()->GetFullPath(vertexfilename),GL_VERTEX_SHADER);
00140 
00141     if (vertex==0) 
00142     { 
00143         glDeleteProgram(m_Program);
00144         m_Program = 0;
00145         return false; 
00146     }
00147     glAttachShader(m_Program, vertex);
00148 
00149     unsigned int fragment = LoadShader(SearchPaths::Get()->GetFullPath(fragmentfilename),GL_FRAGMENT_SHADER);
00150     if (fragment==0) 
00151     { 
00152         glDeleteProgram(m_Program);
00153         m_Program = 0;
00154         return false; 
00155     }
00156     glAttachShader(m_Program, fragment);
00157 
00158     glLinkProgram(m_Program);
00159 
00160     GLint status = GL_FALSE;
00161     glGetProgramiv(m_Program, GL_LINK_STATUS, &status);
00162     if(status != GL_TRUE)
00163     {
00164         GLsizei size = 0;
00165         char log[1024];
00166         glGetProgramInfoLog(m_Program, 1024, &size, log);
00167         Trace::Stream<<log<<endl;
00168     }
00169     #endif
00170     return true;
00171 }
00172     
00173     
00174 unsigned int GLSLShader::LoadShader(string filename, unsigned int type)
00175 {
00176     #ifdef GLSL
00177     if (!m_Enabled) return 0;
00178     FILE* file = fopen(filename.c_str(), "r");
00179     if (!file) 
00180     {
00181         Trace::Stream<<"Couldn't open shader ["<<filename<<"]"<<endl;
00182         return 0;
00183     }
00184 
00185     fseek(file, 0, SEEK_END);
00186     unsigned int size = ftell(file);
00187     fseek(file, 0, SEEK_SET);
00188 
00189     char* code = new char[size+1];
00190     code[size]='\0';
00191 
00192     if (fread(code,1,size,file)!=size)
00193     {
00194         Trace::Stream<<"Error reading shader ["<<filename<<"]"<<endl;
00195         delete[] code;
00196         fclose(file);
00197         return 0;
00198     }
00199     else
00200     {
00201         unsigned int shader = glCreateShader(type);
00202         glShaderSource(shader, 1, (const char**)&code, NULL);
00203         glCompileShader(shader);
00204 
00205         GLint status = GL_FALSE;
00206         glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
00207         if(status != GL_TRUE)
00208         {   
00209             GLsizei size = 0;
00210             char log[1024];
00211 
00212             glGetShaderInfoLog(shader, 1024, &size, log);
00213             Trace::Stream<<"compile errors for ["<<filename<<"]"<<endl;
00214             Trace::Stream<<log<<endl;
00215 
00216             glDeleteShader(shader);
00217             delete[] code;
00218             fclose(file);
00219             return 0;
00220         }
00221         
00222         delete[] code;
00223         fclose(file);
00224         return shader;
00225     }
00226     #endif
00227     return 0;
00228 }

Generated on Tue Sep 4 23:22:18 2007 for The Fluxus Renderer (libfluxus) by  doxygen 1.5.1