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
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