vcglib/wrap/glw/shader.h

175 lines
3.0 KiB
C++

#ifndef GLW_SHADER_H
#define GLW_SHADER_H
#include <string>
#include "./object.h"
namespace glw
{
class ShaderArguments : public ObjectArguments
{
public:
typedef ObjectArguments BaseType;
typedef ShaderArguments ThisType;
std::string source;
ShaderArguments(void)
{
this->clear();
}
void clear(void)
{
BaseType::clear();
this->source.clear();
}
};
class SafeShader : public virtual SafeObject
{
public:
typedef SafeObject BaseType;
typedef SafeShader ThisType;
const std::string & source(void) const
{
return this->m_source;
}
const std::string & log(void) const
{
return this->m_log;
}
bool isCompiled(void) const
{
return this->m_compiled;
}
protected:
std::string m_source;
std::string m_log;
bool m_compiled;
SafeShader(Context * ctx)
: BaseType (ctx)
, m_compiled (false)
{
;
}
};
class Shader : public Object, public virtual SafeShader
{
public:
typedef Object BaseType;
typedef SafeShader SafeType;
typedef Shader ThisType;
protected:
Shader(Context * ctx)
: SafeObject (ctx)
, BaseType (ctx)
, SafeType (ctx)
{
;
}
virtual ~Shader(void)
{
this->destroy();
}
virtual GLenum shaderType(void) const = 0;
bool create(const ShaderArguments & args)
{
this->destroy();
const GLenum shType = this->shaderType();
this->m_name = glCreateShader(shType);
this->setBinding(shType, 0);
this->bind();
this->compile(args.source);
return this->m_compiled;
}
virtual void doDestroy(Context * ctx, GLuint name)
{
(void)ctx;
if (name == 0) return;
this->m_source.clear();
this->m_log.clear();
this->m_compiled = false;
glDeleteShader(name);
}
virtual void doBind(void)
{
;
}
virtual void doUnbind(void)
{
;
}
void compile(const std::string & source)
{
GLW_ASSERT(this->isValid());
const char * src = source.c_str();
glShaderSource(this->m_name, 1, &src, 0);
glCompileShader(this->m_name);
GLint compileStatus = 0;
glGetShaderiv(this->m_name, GL_COMPILE_STATUS, &compileStatus);
this->m_source = source;
this->m_log = ThisType::getInfoLog(this->m_name);
this->m_compiled = (compileStatus != GL_FALSE);
}
private:
static std::string getInfoLog(GLuint Shader)
{
std::string log;
GLint logLen = 0;
glGetShaderiv(Shader, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0)
{
char * sLog = new char[logLen + 1];
glGetShaderInfoLog(Shader, logLen, &logLen, sLog);
if (logLen > 0)
{
if (sLog[0] != '\0')
{
sLog[logLen - 1] = '\0';
log = sLog;
}
}
delete [] sLog;
}
return log;
}
};
typedef detail::SafeHandle <Shader> ShaderHandle;
typedef detail::UnsafeHandle <Shader> BoundShader;
};
#endif // GLW_SHADER_H