00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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 }