Go to the documentation of this file.00001 #ifndef GLW_SHADER_H
00002 #define GLW_SHADER_H
00003
00004 #include <string>
00005 #include <iostream>
00006
00007 #include "./object.h"
00008
00009 namespace glw
00010 {
00011
00012 class ShaderArguments : public ObjectArguments
00013 {
00014 public:
00015
00016 typedef ObjectArguments BaseType;
00017 typedef ShaderArguments ThisType;
00018
00019 std::string source;
00020
00021 ShaderArguments(void)
00022 : BaseType()
00023 {
00024 ;
00025 }
00026
00027 void clear(void)
00028 {
00029 BaseType::clear();
00030 this->source.clear();
00031 }
00032 };
00033
00034 class Shader : public Object
00035 {
00036 friend class Context;
00037
00038 public:
00039
00040 typedef Object BaseType;
00041 typedef Shader ThisType;
00042
00043 virtual ~Shader(void)
00044 {
00045 this->destroy();
00046 }
00047
00048 const std::string & source(void) const
00049 {
00050 return this->m_source;
00051 }
00052
00053 const std::string & log(void) const
00054 {
00055 return this->m_log;
00056 }
00057
00058 bool isCompiled(void) const
00059 {
00060 return this->m_compiled;
00061 }
00062
00063 protected:
00064
00065 std::string m_source;
00066 std::string m_log;
00067 bool m_compiled;
00068
00069 Shader(Context * ctx)
00070 : BaseType (ctx)
00071 , m_compiled (false)
00072 {
00073 ;
00074 }
00075
00076 virtual GLenum shaderType(void) const = 0;
00077
00078 bool create(const ShaderArguments & args)
00079 {
00080 this->destroy();
00081 const GLenum shType = this->shaderType();
00082 this->m_name = glCreateShader(shType);
00083 this->compile(args.source);
00084 return this->m_compiled;
00085 }
00086
00087 virtual void doDestroy(void)
00088 {
00089 glDeleteShader(this->m_name);
00090 this->m_source.clear();
00091 this->m_log.clear();
00092 this->m_compiled = false;
00093 }
00094
00095 virtual bool doIsValid(void) const
00096 {
00097 return this->m_compiled;
00098 }
00099
00100 void compile(const std::string & source)
00101 {
00102 const char * src = source.c_str();
00103 glShaderSource(this->m_name, 1, &src, 0);
00104 glCompileShader(this->m_name);
00105
00106 GLint compileStatus = 0;
00107 glGetShaderiv(this->m_name, GL_COMPILE_STATUS, &compileStatus);
00108
00109 this->m_source = source;
00110 this->m_log = ThisType::getInfoLog(this->m_name);
00111 this->m_compiled = (compileStatus != GL_FALSE);
00112
00113 #if GLW_PRINT_LOG_TO_STDERR
00114 std::cerr << "---------------------------" << std::endl;
00115 std::cerr << "[";
00116 switch (this->shaderType())
00117 {
00118 case GL_VERTEX_SHADER : std::cerr << "Vertex "; break;
00119 case GL_GEOMETRY_SHADER : std::cerr << "Geometry "; break;
00120 case GL_FRAGMENT_SHADER : std::cerr << "Fragment "; break;
00121 default: break;
00122 }
00123 std::cerr << "Shader Compile Log]: " << ((this->m_compiled) ? ("OK") : ("FAILED")) << std::endl;
00124 std::cerr << this->m_log << std::endl;
00125 std::cerr << "---------------------------" << std::endl;
00126 #endif
00127 }
00128
00129 private:
00130
00131 static std::string getInfoLog(GLuint Shader)
00132 {
00133 std::string log;
00134
00135 GLint logLen = 0;
00136 glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &logLen);
00137 if (logLen > 0)
00138 {
00139 char * sLog = new char[logLen + 1];
00140 glGetShaderInfoLog(Shader, logLen, &logLen, sLog);
00141 if (logLen > 0)
00142 {
00143 if (sLog[0] != '\0')
00144 {
00145 sLog[logLen - 1] = '\0';
00146 log = sLog;
00147 }
00148 }
00149 delete [] sLog;
00150 }
00151 return log;
00152 }
00153 };
00154
00155 namespace detail { template <> struct BaseOf <Shader> { typedef Object Type; }; };
00156 typedef detail::ObjectSharedPointerTraits <Shader> ::Type ShaderPtr;
00157
00158 class SafeShader : public SafeObject
00159 {
00160 friend class Context;
00161 friend class BoundShader;
00162
00163 public:
00164
00165 typedef SafeObject BaseType;
00166 typedef SafeShader ThisType;
00167
00168 SafeShader(void)
00169 : BaseType()
00170 {
00171 ;
00172 }
00173
00174 const std::string & source(void) const
00175 {
00176 return this->object()->source();
00177 }
00178
00179 const std::string & log(void) const
00180 {
00181 return this->object()->log();
00182 }
00183
00184 bool isCompiled(void) const
00185 {
00186 return this->object()->isCompiled();
00187 }
00188
00189 protected:
00190
00191 SafeShader(const ShaderPtr & shader)
00192 : BaseType(shader)
00193 {
00194 ;
00195 }
00196
00197 const ShaderPtr & object(void) const
00198 {
00199 return static_cast<const ShaderPtr &>(BaseType::object());
00200 }
00201
00202 ShaderPtr & object(void)
00203 {
00204 return static_cast<ShaderPtr &>(BaseType::object());
00205 }
00206 };
00207
00208 namespace detail { template <> struct BaseOf <SafeShader> { typedef SafeObject Type; }; };
00209 namespace detail { template <> struct ObjectBase <SafeShader> { typedef Shader Type; }; };
00210 namespace detail { template <> struct ObjectSafe <Shader > { typedef SafeShader Type; }; };
00211 typedef detail::ObjectSharedPointerTraits <SafeShader> ::Type ShaderHandle;
00212
00213 class ShaderBindingParams : public ObjectBindingParams
00214 {
00215 public:
00216
00217 typedef ObjectBindingParams BaseType;
00218 typedef ShaderBindingParams ThisType;
00219
00220 ShaderBindingParams(void)
00221 : BaseType()
00222 {
00223 ;
00224 }
00225
00226 ShaderBindingParams(GLenum aTarget, GLenum aUnit)
00227 : BaseType(aTarget, aUnit)
00228 {
00229 ;
00230 }
00231 };
00232
00233 class BoundShader : public BoundObject
00234 {
00235 friend class Context;
00236
00237 public:
00238
00239 typedef BoundObject BaseType;
00240 typedef BoundShader ThisType;
00241
00242 BoundShader(void)
00243 : BaseType()
00244 {
00245 ;
00246 }
00247
00248 const ShaderHandle & handle(void) const
00249 {
00250 return static_cast<const ShaderHandle &>(BaseType::handle());
00251 }
00252
00253 ShaderHandle & handle(void)
00254 {
00255 return static_cast<ShaderHandle &>(BaseType::handle());
00256 }
00257
00258 protected:
00259
00260 BoundShader(const ShaderHandle & handle, const ShaderBindingParams & params)
00261 : BaseType(handle, params)
00262 {
00263 ;
00264 }
00265
00266 const ShaderPtr & object(void) const
00267 {
00268 return this->handle()->object();
00269 }
00270
00271 ShaderPtr & object(void)
00272 {
00273 return this->handle()->object();
00274 }
00275
00276 virtual void bind(void)
00277 {
00278 ;
00279 }
00280
00281 virtual void unbind(void)
00282 {
00283 ;
00284 }
00285 };
00286
00287 namespace detail { template <> struct ParamsOf <BoundShader> { typedef ShaderBindingParams Type; }; };
00288 namespace detail { template <> struct BaseOf <BoundShader> { typedef BoundObject Type; }; };
00289 namespace detail { template <> struct ObjectBase <BoundShader> { typedef Shader Type; }; };
00290 namespace detail { template <> struct ObjectBound <Shader > { typedef BoundShader Type; }; };
00291 typedef detail::ObjectSharedPointerTraits <BoundShader> ::Type BoundShaderHandle;
00292
00293 };
00294
00295 #endif // GLW_SHADER_H