00001
00008 #include <fstream>
00009 #include <string>
00010 #include "Error.h"
00011 #include "Shader.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 bool LoadShaderFromMemory(GLenum type, const char *src, GLuint &shader)
00023 {
00024 if(!src)
00025 return false;
00026
00027 shader = glCreateShader(type);
00028
00029 glShaderSource(shader, 1, &src, NULL);
00030 glCompileShader(shader);
00031
00032 GLint err;
00033 glGetShaderiv(shader, GL_COMPILE_STATUS, &err);
00034 if(err == GL_FALSE)
00035 {
00036
00037 GLint maxLogLen;
00038 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLogLen);
00039
00040 char *log = new char[maxLogLen];
00041 GLsizei logLen;
00042 glGetShaderInfoLog(shader, maxLogLen, &logLen, log);
00043
00044 std::string title = "ERROR";
00045 ErrorMessage(title.c_str(), log);
00046
00047 delete log;
00048 return false;
00049 }
00050
00051 return true;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 bool LoadShader(GLenum type, const char *file, GLuint &shader)
00064 {
00065 std::fstream f(file);
00066
00067 if(!f.is_open())
00068 {
00069 std::string msg = "Could Not open shader source file : ";
00070 msg += file;
00071 ErrorMessage(msg.c_str());
00072 return false;
00073 }
00074
00075 std::string source = "";
00076 std::string line = "";
00077
00078 while(getline(f, line))
00079 {
00080 source += line;
00081 }
00082
00083 return LoadShaderFromMemory(type, source.c_str(), shader);
00084
00085
00086 }
00087
00088
00089 PixelShader::PixelShader() : shader(0) {}
00090
00091
00092 PixelShader::~PixelShader()
00093 {
00094 if(shader)
00095 glDeleteShader(shader);
00096 }
00097
00098
00099 bool PixelShader::Load(const char *file)
00100 {
00101 return LoadShader(GL_FRAGMENT_SHADER, file, shader);
00102 }
00103
00104
00105 bool PixelShader::LoadFromMemory(const char *src)
00106 {
00107 return LoadShaderFromMemory(GL_FRAGMENT_SHADER, src, shader);
00108 }
00109
00110
00111 VertexShader::VertexShader() : shader(0) {}
00112
00113
00114 VertexShader::~VertexShader()
00115 {
00116 if(shader)
00117 glDeleteShader(shader);
00118 }
00119
00120
00121 bool VertexShader::Load(const char *file)
00122 {
00123 return LoadShader(GL_VERTEX_SHADER, file, shader);
00124 }
00125
00126
00127 bool VertexShader::LoadFromMemory(const char *src)
00128 {
00129 return LoadShaderFromMemory(GL_VERTEX_SHADER, src, shader);
00130 }
00131
00132
00133 ShaderProgram::ShaderProgram() : program(0) {}
00134
00135
00136 ShaderProgram::~ShaderProgram()
00137 {
00138 if(program)
00139 {
00140 if(vshader.GetShaderID())
00141 glDetachShader(program, vshader.GetShaderID());
00142
00143 if(pshader.GetShaderID())
00144 glDetachShader(program, pshader.GetShaderID());
00145
00146 glDeleteProgram(program);
00147 }
00148 }
00149
00150
00151 bool ShaderProgram::Load(const char *vertexFile, const char *pixelFile)
00152 {
00153 if(!vertexFile && !pixelFile)
00154 return false;
00155
00156 if(vertexFile)
00157 {
00158 if(!vshader.Load(vertexFile))
00159 return false;
00160 }
00161
00162 if(pixelFile)
00163 {
00164 if(!pshader.Load(pixelFile))
00165 return false;
00166 }
00167
00168 return CreateShaderProgram();
00169 }
00170
00171
00172 bool ShaderProgram::LoadFromMemory(const char *vertexSrc, const char *pixelSrc)
00173 {
00174 if(!vertexSrc && !pixelSrc)
00175 return false;
00176
00177 if(vertexSrc)
00178 {
00179 if(!vshader.LoadFromMemory(vertexSrc))
00180 return false;
00181 }
00182
00183 if(pixelSrc)
00184 {
00185 if(!pshader.LoadFromMemory(pixelSrc))
00186 return false;
00187 }
00188
00189 return CreateShaderProgram();
00190 }
00191
00192
00193
00194 bool ShaderProgram::CreateShaderProgram()
00195 {
00196 program = glCreateProgram();
00197
00198 if(vshader.GetShaderID())
00199 glAttachShader(program, vshader.GetShaderID());
00200
00201 if(pshader.GetShaderID())
00202 glAttachShader(program, pshader.GetShaderID());
00203
00204 glLinkProgram(program);
00205
00206 GLint err;
00207 glGetProgramiv(program, GL_LINK_STATUS, &err);
00208 if(err == GL_FALSE)
00209 {
00210
00211 GLint maxLogLen;
00212 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLogLen);
00213
00214 char *log = new char[maxLogLen];
00215 GLsizei logLen;
00216 glGetProgramInfoLog(program, maxLogLen, &logLen, log);
00217
00218 std::string title = "ERROR";
00219 ErrorMessage(title.c_str(), log);
00220
00221 delete log;
00222 return false;
00223 }
00224
00225 return true;
00226 }
00227
00228
00229 void ShaderProgram::Attach()
00230 {
00231 glUseProgram(program);
00232 }
00233
00234
00235 void ShaderProgram::Detach()
00236 {
00237 glUseProgram(0);
00238 }
00239
00240
00241 void ShaderProgram::SetTexture(GLuint texID, const char *name)
00242 {
00243 glUseProgram(program);
00244
00245 GLint loc = glGetUniformLocation(program, name);
00246 if(loc > -1)
00247 {
00248 glUniform1i(loc, texID);
00249 }
00250
00251 glUseProgram(0);
00252 }
00253
00254
00255 void ShaderProgram::SetVector(float x, float y, float z, const char *name)
00256 {
00257 glUseProgram(program);
00258
00259 GLint loc = glGetUniformLocation(program, name);
00260 if(loc > -1)
00261 {
00262 glUniform3f(loc, x, y, z);
00263 }
00264
00265 glUseProgram(0);
00266 }
00267
00268
00269 void ShaderProgram::SetFloat(float val, const char *name)
00270 {
00271 glUseProgram(program);
00272
00273 GLint loc = glGetUniformLocation(program, name);
00274 if(loc > -1)
00275 {
00276 glUniform1f(loc, val);
00277 }
00278
00279 glUseProgram(0);
00280 }