1 #ifndef GLW_SHADER_H 2 #define GLW_SHADER_H 3 4 #include <string> 5 #include <iostream> 6 7 #include "./object.h" 8 9 namespace glw 10 { 11 12 class ShaderArguments : public ObjectArguments 13 { 14 public: 15 16 typedef ObjectArguments BaseType; 17 typedef ShaderArguments ThisType; 18 19 std::string source; 20 ShaderArguments(void)21 ShaderArguments(void) 22 : BaseType() 23 { 24 ; 25 } 26 clear(void)27 void clear(void) 28 { 29 BaseType::clear(); 30 this->source.clear(); 31 } 32 }; 33 34 class Shader : public Object 35 { 36 friend class Context; 37 38 public: 39 40 typedef Object BaseType; 41 typedef Shader ThisType; 42 ~Shader(void)43 virtual ~Shader(void) 44 { 45 this->destroy(); 46 } 47 source(void)48 const std::string & source(void) const 49 { 50 return this->m_source; 51 } 52 log(void)53 const std::string & log(void) const 54 { 55 return this->m_log; 56 } 57 isCompiled(void)58 bool isCompiled(void) const 59 { 60 return this->m_compiled; 61 } 62 63 protected: 64 65 std::string m_source; 66 std::string m_log; 67 bool m_compiled; 68 Shader(Context * ctx)69 Shader(Context * ctx) 70 : BaseType (ctx) 71 , m_compiled (false) 72 { 73 ; 74 } 75 76 virtual GLenum shaderType(void) const = 0; 77 create(const ShaderArguments & args)78 bool create(const ShaderArguments & args) 79 { 80 this->destroy(); 81 const GLenum shType = this->shaderType(); 82 this->m_name = glCreateShader(shType); 83 this->compile(args.source); 84 return this->m_compiled; 85 } 86 doDestroy(void)87 virtual void doDestroy(void) 88 { 89 glDeleteShader(this->m_name); 90 this->m_source.clear(); 91 this->m_log.clear(); 92 this->m_compiled = false; 93 } 94 doIsValid(void)95 virtual bool doIsValid(void) const 96 { 97 return this->m_compiled; 98 } 99 compile(const std::string & source)100 void compile(const std::string & source) 101 { 102 const char * src = source.c_str(); 103 glShaderSource(this->m_name, 1, &src, 0); 104 glCompileShader(this->m_name); 105 106 GLint compileStatus = 0; 107 glGetShaderiv(this->m_name, GL_COMPILE_STATUS, &compileStatus); 108 109 this->m_source = source; 110 this->m_log = ThisType::getInfoLog(this->m_name); 111 this->m_compiled = (compileStatus != GL_FALSE); 112 113 #if GLW_PRINT_LOG_TO_STDERR 114 std::cerr << "---------------------------" << std::endl; 115 std::cerr << "["; 116 switch (this->shaderType()) 117 { 118 case GL_VERTEX_SHADER : std::cerr << "Vertex "; break; 119 case GL_GEOMETRY_SHADER : std::cerr << "Geometry "; break; 120 case GL_FRAGMENT_SHADER : std::cerr << "Fragment "; break; 121 default: break; 122 } 123 std::cerr << "Shader Compile Log]: " << ((this->m_compiled) ? ("OK") : ("FAILED")) << std::endl; 124 std::cerr << this->m_log << std::endl; 125 std::cerr << "---------------------------" << std::endl; 126 #endif 127 } 128 129 private: 130 getInfoLog(GLuint Shader)131 static std::string getInfoLog(GLuint Shader) 132 { 133 std::string log; 134 135 GLint logLen = 0; 136 glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &logLen); 137 if (logLen > 0) 138 { 139 char * sLog = new char[logLen + 1]; 140 glGetShaderInfoLog(Shader, logLen, &logLen, sLog); 141 if (logLen > 0) 142 { 143 if (sLog[0] != '\0') 144 { 145 sLog[logLen - 1] = '\0'; 146 log = sLog; 147 } 148 } 149 delete [] sLog; 150 } 151 return log; 152 } 153 }; 154 155 namespace detail { template <> struct BaseOf <Shader> { typedef Object Type; }; }; 156 typedef detail::ObjectSharedPointerTraits <Shader> ::Type ShaderPtr; 157 158 class SafeShader : public SafeObject 159 { 160 friend class Context; 161 friend class BoundShader; 162 163 public: 164 165 typedef SafeObject BaseType; 166 typedef SafeShader ThisType; 167 168 SafeShader(void) 169 : BaseType() 170 { 171 ; 172 } 173 174 const std::string & source(void) const 175 { 176 return this->object()->source(); 177 } 178 179 const std::string & log(void) const 180 { 181 return this->object()->log(); 182 } 183 184 bool isCompiled(void) const 185 { 186 return this->object()->isCompiled(); 187 } 188 189 protected: 190 191 SafeShader(const ShaderPtr & shader) 192 : BaseType(shader) 193 { 194 ; 195 } 196 197 const ShaderPtr & object(void) const 198 { 199 return static_cast<const ShaderPtr &>(BaseType::object()); 200 } 201 202 ShaderPtr & object(void) 203 { 204 return static_cast<ShaderPtr &>(BaseType::object()); 205 } 206 }; 207 208 namespace detail { template <> struct BaseOf <SafeShader> { typedef SafeObject Type; }; }; 209 namespace detail { template <> struct ObjectBase <SafeShader> { typedef Shader Type; }; }; 210 namespace detail { template <> struct ObjectSafe <Shader > { typedef SafeShader Type; }; }; 211 typedef detail::ObjectSharedPointerTraits <SafeShader> ::Type ShaderHandle; 212 213 class ShaderBindingParams : public ObjectBindingParams 214 { 215 public: 216 217 typedef ObjectBindingParams BaseType; 218 typedef ShaderBindingParams ThisType; 219 220 ShaderBindingParams(void) 221 : BaseType() 222 { 223 ; 224 } 225 226 ShaderBindingParams(GLenum aTarget, GLenum aUnit) 227 : BaseType(aTarget, aUnit) 228 { 229 ; 230 } 231 }; 232 233 class BoundShader : public BoundObject 234 { 235 friend class Context; 236 237 public: 238 239 typedef BoundObject BaseType; 240 typedef BoundShader ThisType; 241 242 BoundShader(void) 243 : BaseType() 244 { 245 ; 246 } 247 248 const ShaderHandle & handle(void) const 249 { 250 return static_cast<const ShaderHandle &>(BaseType::handle()); 251 } 252 253 ShaderHandle & handle(void) 254 { 255 return static_cast<ShaderHandle &>(BaseType::handle()); 256 } 257 258 protected: 259 260 BoundShader(const ShaderHandle & handle, const ShaderBindingParams & params) 261 : BaseType(handle, params) 262 { 263 ; 264 } 265 266 const ShaderPtr & object(void) const 267 { 268 return this->handle()->object(); 269 } 270 271 ShaderPtr & object(void) 272 { 273 return this->handle()->object(); 274 } 275 276 virtual void bind(void) 277 { 278 ; 279 } 280 281 virtual void unbind(void) 282 { 283 ; 284 } 285 }; 286 287 namespace detail { template <> struct ParamsOf <BoundShader> { typedef ShaderBindingParams Type; }; }; 288 namespace detail { template <> struct BaseOf <BoundShader> { typedef BoundObject Type; }; }; 289 namespace detail { template <> struct ObjectBase <BoundShader> { typedef Shader Type; }; }; 290 namespace detail { template <> struct ObjectBound <Shader > { typedef BoundShader Type; }; }; 291 typedef detail::ObjectSharedPointerTraits <BoundShader> ::Type BoundShaderHandle; 292 293 }; 294 295 #endif // GLW_SHADER_H 296