First Commit.

This commit is contained in:
Marco Di Benedetto 2006-10-05 18:34:13 +00:00
parent 1ada6a63ce
commit d878081824
3 changed files with 1525 additions and 0 deletions

925
wrap/gl/fbo.h Normal file
View File

@ -0,0 +1,925 @@
#ifndef __FBO_H__
#define __FBO_H__
#pragma warning(disable : 4250)
#include <map>
#include <vector>
#include <GL/glew.h>
#include <GL/glut.h>
#include "gl_object.h"
class FrameBufferSemantic
{
public:
typedef enum
{
COLOR,
DEPTH,
STENCIL
} FBSType;
virtual FBSType Semantic(void) const = 0;
virtual bool ValidateFormat(GLenum format) const = 0;
static bool ValidateFormat(FBSType type, GLenum format)
{
switch (type)
{
case COLOR : return FrameBufferSemantic::ValidateColor(format);
case DEPTH : return FrameBufferSemantic::ValidateDepth(format);
case STENCIL : return FrameBufferSemantic::ValidateStencil(format);
default : return false;
}
}
static bool ValidateColor(GLenum type)
{
return true;
}
static bool ValidateDepth(GLenum type)
{
return true;
}
static bool ValidateStencil(GLenum type)
{
return true;
}
};
class Texture : public GLObject, public Bindable, public FrameBufferSemantic
{
public:
Texture(void) : GLObject(), Bindable(), FrameBufferSemantic()
{
this->format = GL_NONE;
}
void Gen(void)
{
this->Del();
glGenTextures(1, &(this->objectID));
}
void Del(void)
{
if (this->objectID == 0) return;
glDeleteTextures(1, &(this->objectID));
this->objectID = 0;
}
GLenum Format(void) const
{
return this->format;
}
virtual GLint Dimensions(void) const = 0;
virtual GLsizei Size(const unsigned int i) const = 0;
virtual GLenum Target(void) const = 0;
protected:
GLenum format;
void DoBind(void)
{
glBindTexture(this->Target(), this->objectID);
}
void DoUnbind(void)
{
glBindTexture(this->Target(), 0);
}
};
class ColorTexture : public virtual Texture
{
public:
ColorTexture(void) : Texture()
{
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::COLOR;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateColor(format);
}
};
class DepthTexture : public virtual Texture
{
public:
DepthTexture(void) : Texture()
{
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::DEPTH;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateDepth(format);
}
};
class StencilTexture : public virtual Texture
{
public:
StencilTexture(void) : Texture()
{
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::STENCIL;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateStencil(format);
}
};
class Texture1D : public virtual Texture
{
public:
Texture1D(void) : Texture()
{
this->dims[0] = 0;
this->wraps[0] = GL_CLAMP_TO_EDGE;
}
GLsizei Width(void) const
{
return this->dims[0];
}
GLint Dimensions(void) const
{
return 1;
}
GLsizei Size(const unsigned int i) const
{
if (i > 0) return 0;
return this->dims[0];
}
GLenum Target(void) const
{
return GL_TEXTURE_1D;
}
bool Set(GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels)
{
if (!this->ValidateFormat(internalFormat)) return false;
this->Bind();
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, level, internalFormat, width, border, format, type, pixels);
this->Unbind();
this->format = internalFormat;
this->dims[0] = width;
return true;
}
protected:
GLsizei dims[1];
GLenum wraps[1];
};
class Texture2D : public virtual Texture
{
public:
Texture2D(void) : Texture()
{
this->dims[0] = 0;
this->dims[1] = 0;
}
GLsizei Width(void) const
{
return this->dims[0];
}
GLsizei Height(void) const
{
return this->dims[1];
}
GLint Dimensions(void) const
{
return 2;
}
GLsizei Size(const unsigned int i) const
{
if (i > 1) return 0;
return this->dims[i];
}
GLenum Target(void) const
{
return GL_TEXTURE_2D;
}
bool Set(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels)
{
if (!this->ValidateFormat(internalFormat)) return false;
this->Bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, border, format, type, pixels);
this->Unbind();
this->format = internalFormat;
this->dims[0] = width;
this->dims[1] = height;
return true;
}
protected:
GLsizei dims[2];
void DoBind(void)
{
glBindTexture(GL_TEXTURE_2D, this->objectID);
}
void DoUnbind(void)
{
glBindTexture(GL_TEXTURE_2D, 0);
}
};
class Texture3D : public virtual Texture
{
public:
Texture3D(void) : Texture()
{
this->dims[0] = 0;
this->dims[1] = 0;
this->dims[2] = 0;
}
GLsizei Width(void) const
{
return this->dims[0];
}
GLsizei Height(void) const
{
return this->dims[1];
}
GLsizei Depth(void) const
{
return this->dims[2];
}
GLint Dimensions(void) const
{
return 3;
}
GLsizei Size(const unsigned int i) const
{
if (i > 2) return 0;
return this->dims[i];
}
GLenum Target(void) const
{
return GL_TEXTURE_3D;
}
bool Set(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels)
{
if (!this->ValidateFormat(internalFormat)) return false;
this->Bind();
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, internalFormat, width, height, depth, border, format, type, pixels);
this->Unbind();
this->format = internalFormat;
this->dims[0] = width;
this->dims[1] = height;
this->dims[2] = depth;
return true;
}
protected:
GLsizei dims[3];
void DoBind(void)
{
glBindTexture(GL_TEXTURE_3D, this->objectID);
}
void DoUnbind(void)
{
glBindTexture(GL_TEXTURE_3D, 0);
}
};
class ColorTexture1D : public virtual ColorTexture, public virtual Texture1D
{
public:
ColorTexture1D(void) : ColorTexture(), Texture1D()
{
}
};
class ColorTexture2D : public virtual ColorTexture, public virtual Texture2D
{
public:
ColorTexture2D(void) : ColorTexture(), Texture2D()
{
}
};
class ColorTexture3D : public virtual ColorTexture, public virtual Texture3D
{
public:
ColorTexture3D(void) : ColorTexture(), Texture3D()
{
}
};
class DepthTexture2D : public virtual DepthTexture, public virtual Texture2D
{
public:
DepthTexture2D(void) : DepthTexture(), Texture2D()
{
}
};
class StencilTexture2D : public virtual StencilTexture, public virtual Texture2D
{
public:
StencilTexture2D(void) : StencilTexture(), Texture2D()
{
}
};
class FrameBuffer;
class RenderTarget : public GLObject, public Bindable, public FrameBufferSemantic
{
friend class FrameBuffer;
public:
typedef enum
{
BUFFER,
TEXTURE
} RTStorageType;
RenderTarget(void) : GLObject(), Bindable(), FrameBufferSemantic()
{
this->frameBuffer = 0;
}
bool Attach(FrameBuffer * fb);
bool Detach(void);
FrameBuffer * GetFrameBuffer(void)
{
return this->frameBuffer;
}
const FrameBuffer * GetFrameBuffer(void) const
{
return this->frameBuffer;
}
virtual GLsizei Width(void) const = 0;
virtual GLsizei Height(void) const = 0;
virtual GLenum Format(void) const = 0;
virtual GLenum Attachment(void) const = 0;
virtual bool ValidateAttachment(GLenum attachment) const = 0;
virtual RTStorageType StorageType(void) const = 0;
protected:
FrameBuffer * frameBuffer;
virtual bool BindToFB(void) = 0;
};
class BufferRenderTarget : public virtual RenderTarget
{
public:
BufferRenderTarget(void) : RenderTarget()
{
this->width = 0;
this->height = 0;
this->format = GL_NONE;
}
void Gen(void)
{
this->Del();
glGenRenderbuffersEXT(1, &(this->objectID));
}
void Del(void)
{
if (this->objectID == 0) return;
glDeleteRenderbuffersEXT(1, &(this->objectID));
this->objectID = 0;
}
GLsizei Width(void) const
{
return this->width;
}
GLsizei Height(void) const
{
return this->height;
}
GLenum Format(void) const
{
return this->format;
}
RTStorageType StorageType(void) const
{
return RenderTarget::BUFFER;
}
bool Set(GLenum format, GLsizei width, GLsizei height)
{
if (!this->ValidateFormat(format)) return false;
this->Bind();
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, width, height);
this->Unbind();
this->format = format;
this->width = width;
this->height = height;
return true;
}
bool BindToFB(void)
{
if (this->frameBuffer == 0) return false;
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, this->Attachment(), GL_RENDERBUFFER_EXT, this->objectID);
return true;
}
protected:
GLenum format;
GLsizei width;
GLsizei height;
void DoBind(void)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this->objectID);
}
void DoUnbind(void)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
};
class TextureRenderTarget : public virtual RenderTarget
{
public:
TextureRenderTarget(void) : RenderTarget()
{
this->tex = 0;
this->level = 0;
}
void Gen(void)
{
}
void Del(void)
{
}
GLsizei Width(void) const
{
if (this->tex == 0) return 0;
return this->tex->Width();
}
GLsizei Height(void) const
{
if (this->tex == 0) return 0;
return this->tex->Height();
}
GLenum Format(void) const
{
if (this->tex == 0) return GL_NONE;
return this->tex->Format();
}
RTStorageType StorageType(void) const
{
return RenderTarget::TEXTURE;
}
void SetLevel(GLint level)
{
if (level < 0) level = 0;
this->level = level;
}
bool Set(Texture2D * tex)
{
this->Unset();
if (tex == 0) return true;
if (this->Semantic() != tex->Semantic()) return false;
this->tex = tex;
return true;
}
bool Unset(void)
{
this->tex = 0;
return true;
}
Texture2D * GetTexture(void)
{
return (this->tex);
}
bool BindToFB(void)
{
if (this->frameBuffer == 0) return false;
if (this->tex == 0) return false;
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, this->Attachment(), GL_TEXTURE_2D, this->tex->ObjectID(), this->level);
return true;
}
protected:
Texture2D * tex;
GLint level;
void DoBind(void)
{
}
void DoUnbind(void)
{
}
};
class ColorRenderTarget : public virtual RenderTarget
{
public:
ColorRenderTarget(void) : RenderTarget()
{
this->attachment = GL_COLOR_ATTACHMENT0_EXT;
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::COLOR;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateColor(format);
}
bool ValidateAttachment(GLenum attachment) const
{
return (((GL_COLOR_ATTACHMENT0_EXT) <= attachment) && (attachment <= (GL_COLOR_ATTACHMENT0_EXT + 3)));
}
void SetAttachment(GLenum attachment)
{
if (!this->ValidateAttachment(attachment)) return;
this->attachment = attachment;
}
GLenum Attachment(void) const
{
return this->attachment;
}
protected:
GLenum attachment;
};
class DepthRenderTarget : public virtual RenderTarget
{
public:
DepthRenderTarget(void) : RenderTarget()
{
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::DEPTH;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateDepth(format);
}
bool ValidateAttachment(GLenum attachment) const
{
return (attachment == GL_DEPTH_ATTACHMENT_EXT);
}
GLenum Attachment(void) const
{
return GL_DEPTH_ATTACHMENT_EXT;
}
};
class StencilRenderTarget : public virtual RenderTarget
{
public:
StencilRenderTarget(void) : RenderTarget()
{
}
FrameBufferSemantic::FBSType Semantic(void) const
{
return FrameBufferSemantic::STENCIL;
}
bool ValidateFormat(GLenum format) const
{
return FrameBufferSemantic::ValidateStencil(format);
}
bool ValidateAttachment(GLenum attachment) const
{
return (attachment == GL_STENCIL_ATTACHMENT_EXT);
}
GLenum Attachment(void) const
{
return GL_STENCIL_ATTACHMENT_EXT;
}
};
class ColorRenderBuffer : public virtual ColorRenderTarget, public virtual BufferRenderTarget
{
public:
ColorRenderBuffer(void) : ColorRenderTarget(), BufferRenderTarget()
{
}
};
class ColorRenderTexture : public virtual ColorRenderTarget, public virtual TextureRenderTarget
{
public:
ColorRenderTexture(void) : ColorRenderTarget(), TextureRenderTarget()
{
}
ColorRenderTexture(Texture2D * tex) : ColorRenderTarget(), TextureRenderTarget()
{
this->Set(tex);
}
};
class DepthRenderBuffer : public virtual DepthRenderTarget, public virtual BufferRenderTarget
{
public:
DepthRenderBuffer(void) : DepthRenderTarget(), BufferRenderTarget()
{
}
};
class DepthRenderTexture : public virtual DepthRenderTarget, public virtual TextureRenderTarget
{
public:
DepthRenderTexture(void) : DepthRenderTarget(), TextureRenderTarget()
{
}
DepthRenderTexture(Texture2D * tex) : DepthRenderTarget(), TextureRenderTarget()
{
this->Set(tex);
}
};
class StencilRenderBuffer : public virtual StencilRenderTarget, public virtual BufferRenderTarget
{
public:
StencilRenderBuffer(void) : StencilRenderTarget(), BufferRenderTarget()
{
}
};
class StencilRenderTexture : public virtual StencilRenderTarget, public virtual TextureRenderTarget
{
public:
StencilRenderTexture(void) : StencilRenderTarget(), TextureRenderTarget()
{
}
StencilRenderTexture(Texture2D * tex) : StencilRenderTarget(), TextureRenderTarget()
{
this->Set(tex);
}
};
class FrameBuffer : public GLObject, public Bindable
{
friend class RenderTarget;
public:
FrameBuffer(void) : GLObject(), Bindable()
{
}
void Gen(void)
{
this->Del();
glGenFramebuffersEXT(1, &(this->objectID));
}
void Del(void)
{
if (this->objectID == 0) return;
glDeleteFramebuffersEXT(1, &(this->objectID));
this->objectID = 0;
}
bool DetachAll(void)
{
return false;
}
bool IsValid(void) const
{
const GLenum s = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
//return (s == GL_FRAMEBUFFER_COMPLETE_EXT);
switch (s)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
printf("ok\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
printf("i a\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
printf("i m a\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
printf("i d a\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
printf("i d\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
printf("i f\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
printf("i d b\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
printf("i r b\n");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
printf("u\n");
break;
default:
printf("def\n");
break;
}
return (s == GL_FRAMEBUFFER_COMPLETE_EXT);
}
protected:
typedef std::map<GLenum, RenderTarget *> RTMap;
typedef RTMap::iterator RTMap_i;
typedef RTMap::const_iterator RTMap_ci;
RTMap renderTargets;
void DoBind(void)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->objectID);
std::vector<GLenum> colorDrawBuffers;
colorDrawBuffers.reserve(this->renderTargets.size());
for (RTMap_i rt=this->renderTargets.begin(); rt!=this->renderTargets.end(); ++rt)
{
RenderTarget * prt = (*rt).second;
if (prt->Semantic() == FrameBufferSemantic::COLOR)
{
colorDrawBuffers.push_back(prt->Attachment());
}
prt->BindToFB();
}
const GLsizei sz = (GLsizei)(colorDrawBuffers.size());
if (sz > 0)
{
glDrawBuffers(sz, &(colorDrawBuffers[0]));
}
}
void DoUnbind(void)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
bool AddRT(RenderTarget * rt)
{
if (rt == 0) return false;
RTMap_i it = this->renderTargets.find(rt->Attachment());
if (it == this->renderTargets.end())
{
this->renderTargets.insert(std::make_pair(rt->Attachment(), rt));
return true;
}
return false;
}
bool RemoveRT(RenderTarget * rt)
{
if (rt == 0) return false;
RTMap_i it = this->renderTargets.find(rt->Attachment());
if ((*it).second == rt)
{
this->renderTargets.erase(it);
return true;
}
return false;
}
};
bool RenderTarget::Attach(FrameBuffer * fb)
{
this->Detach();
if (fb == 0) return true;
if (fb->AddRT(this))
{
this->frameBuffer = fb;
return true;
}
return false;
}
bool RenderTarget::Detach(void)
{
if (this->frameBuffer == 0) return false;
this->frameBuffer->RemoveRT(this);
this->frameBuffer = 0;
return true;
}
#endif // __FBO_H__

67
wrap/gl/gl_object.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef __GL_OBJECT_H__
#define __GL_OBJECT_H__
#include <GL/gl.h>
class GLObject
{
public:
GLObject(void)
{
this->objectID = 0;
}
virtual ~GLObject(void)
{
}
GLuint ObjectID(void) const
{
return this->objectID;
}
bool ValidObject(void) const
{
return (this->objectID != 0);
}
virtual void Gen(void) = 0;
virtual void Del(void) = 0;
protected:
GLuint objectID;
};
class Bindable
{
public:
Bindable(void)
{
this->bound = false;
}
void Bind(void)
{
this->bound = true;
this->DoBind();
}
void Unbind(void)
{
this->DoUnbind();
this->bound = false;
}
bool IsBound(void) const
{
return this->bound;
}
protected:
bool bound;
virtual void DoBind(void) = 0;
virtual void DoUnbind(void) = 0;
};
#endif __GL_OBJECT_H__

533
wrap/gl/shaders.h Normal file
View File

@ -0,0 +1,533 @@
#ifndef __SHADERS_H__
#define __SHADERS_H__
#include <GL/glew.h>
#include <stdio.h>
#include <set>
#include "gl_object.h"
class Shader : public GLObject, public Bindable
{
public:
typedef enum
{
VERTEX,
FRAGMENT
} ShaderType;
Shader(void) : GLObject(), Bindable()
{
this->flags = 0;
this->flags |= SOURCE_DIRTY;
this->compiled = false;
}
void Gen(void)
{
this->Del();
GLenum t;
switch (this->Type())
{
case Shader::VERTEX : t = GL_VERTEX_SHADER; break;
case Shader::FRAGMENT : t = GL_FRAGMENT_SHADER; break;
default: return;
};
this->objectID = glCreateShader(t);
}
void Del(void)
{
if (this->objectID == 0) return;
glDeleteShader(this->objectID);
this->objectID = 0;
}
virtual ShaderType Type(void) const = 0;
void SetSource(const char * src)
{
this->flags |= SOURCE_DIRTY;
this->compiled = false;
this->source = src;
const char * pSrc = this->source.c_str();
glShaderSource(this->objectID, 1, &pSrc, 0);
}
bool LoadSource(const char * fileName)
{
this->flags |= SOURCE_DIRTY;
this->compiled = false;
FILE * f = fopen(fileName, "rb");
if (f == 0)
{
this->source = "";
return false;
}
fseek(f, 0, SEEK_END);
const size_t sz = (size_t)ftell(f);
rewind(f);
char * buff = new char[sz + 1];
fread(buff, sizeof(char), sz, f);
fclose(f);
buff[sz] = '\0';
this->source = buff;
delete [] buff;
const char * pSrc = this->source.c_str();
glShaderSource(this->objectID, 1, &pSrc, 0);
return true;
}
bool Compile(void)
{
glCompileShader(this->objectID);
GLint cm = 0;
glGetShaderiv(this->objectID, GL_COMPILE_STATUS, &cm);
this->compiled = (cm != GL_FALSE);
this->flags = 0;
return this->compiled;
}
bool IsCompiled(void)
{
return this->compiled;
}
std::string InfoLog(void)
{
GLint len = 0;
glGetShaderiv(this->objectID, GL_INFO_LOG_LENGTH, &len);
char * ch = new char[len + 1];
glGetShaderInfoLog(this->objectID, len, &len, ch);
std::string infoLog = ch;
delete [] ch;
return infoLog;
}
protected:
enum
{
SOURCE_DIRTY
};
std::string source;
unsigned int flags;
bool compiled;
void DoBind(void)
{
}
void DoUnbind(void)
{
}
};
class VertexShader : public Shader
{
public:
VertexShader(void) : Shader()
{
}
ShaderType Type(void) const
{
return Shader::VERTEX;
}
};
class FragmentShader : public Shader
{
public:
FragmentShader(void) : Shader()
{
}
ShaderType Type(void) const
{
return Shader::FRAGMENT;
}
};
#if 0
class Program;
class Uniform
{
friend class Program;
public:
/*
typedef enum
{
U_BOOL,
U_BVEC2,
U_BVEC3,
U_BVEC4,
U_BMAT2,
U_BMAT3,
U_BMAT4,
U_INT,
U_IVEC2,
U_IVEC3,
U_IVEC4,
U_IMAT2,
U_IMAT3,
U_IMAT4,
U_FLOAT,
U_FVEC2,
U_FVEC3,
U_FVEC4,
U_FMAT2,
U_FMAT3,
U_FMAT4,
U_SAMPLER1D,
U_SAMPLER2D,
U_SAMPLER3D,
U_SAMPLERCUBE,
U_SAMPLER1DSHADOW,
U_SAMPLER2DSHADOW
} UniformType;
*/
const std::string & Name(void) const
{
return this->name;
}
virtual GLenum Type(void) const = 0;
protected:
Program * prog;
GLint location;
std::string name;
Uniform(Program * prog, GLint location, const std::string & name)
{
this->prog = prog;
this->location = location;
this->name = name;
}
virtual void Apply(void) = 0;
};
class Uniform1b : public Uniform;
{
public:
void SetValue(GLboolean x)
{
this->value[0] = x;
}
GLboolean GetValue(void) const
{
return this->value[0];
}
protected:
Program * prog;
GLboolean value[1];
Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name)
{
this->value = GL_FALSE;
}
};
class Uniform2b : public Uniform;
{
public:
void SetValue(GLboolean x, GLboolean y)
{
this->value[0] = x;
this->value[1] = y;
}
GLboolean GetValueX(void) const
{
return this->value[0];
}
GLboolean GetValueY(void) const
{
return this->value[1];
}
protected:
Program * prog;
GLboolean value[2];
Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name)
{
this->value[0] = GL_FALSE;
this->value[1] = GL_FALSE;
}
};
class Uniform3b : public Uniform;
{
public:
void SetValue(GLboolean x, GLboolean y, GLboolean z)
{
this->value[0] = x;
this->value[1] = y;
this->value[2] = z;
}
GLboolean GetValueX(void) const
{
return this->value[0];
}
GLboolean GetValueY(void) const
{
return this->value[1];
}
GLboolean GetValueZ(void) const
{
return this->value[2];
}
protected:
Program * prog;
GLboolean value[2];
Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name)
{
this->value[0] = GL_FALSE;
this->value[1] = GL_FALSE;
}
};
class Uniform1i : public Uniform;
{
public:
void SetValue(GLint v)
{
this->value = v;
}
GLint GetValue(void) const
{
return this->value;
}
protected:
Program * prog;
GLint value;
Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name)
{
this->value = 0;
}
};
#endif
class Program : public GLObject, public Bindable
{
public:
Program(void)
{
this->linked = false;
}
void Gen(void)
{
this->Del();
this->objectID = glCreateProgram();
}
void Del(void)
{
if (this->objectID == 0) return;
glDeleteProgram(this->objectID);
this->objectID = 0;
}
void Attach(Shader * shd)
{
this->shaders.insert(shd);
this->linked = false;
glAttachShader(this->objectID, shd->ObjectID());
}
void Detach(Shader * shd)
{
this->shaders.erase(shd);
this->linked = false;
glDetachShader(this->objectID, shd->ObjectID());
}
GLsizei AttachedShaders(void) const
{
return ((GLsizei)(this->shaders.size()));
}
Shader * AttachedShader(int i)
{
Shader * shd = 0;
int cnt = 0;
for (std::set<Shader *>::iterator it=this->shaders.begin(); (cnt < i) && (it!=this->shaders.end()); ++it)
{
shd = (*it);
}
return shd;
}
bool Link(void)
{
for (std::set<Shader *>::iterator it=this->shaders.begin(); it!=this->shaders.end(); ++it)
{
Shader * shd = (*it);
if (!shd->IsCompiled())
{
shd->Compile();
}
}
glLinkProgram(this->objectID);
GLint cm = 0;
glGetProgramiv(this->objectID, GL_LINK_STATUS, &cm);
this->linked = (cm != GL_FALSE);
return this->linked;
}
bool IsLinked(void) const
{
return this->linked;
}
std::string InfoLog(void)
{
GLint len = 0;
glGetProgramiv(this->objectID, GL_INFO_LOG_LENGTH, &len);
char * ch = new char[len + 1];
glGetProgramInfoLog(this->objectID, len, &len, ch);
std::string infoLog = ch;
delete [] ch;
return infoLog;
}
void Uniform(const char * name, GLint x)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform1i(loc, x);
}
void Uniform(const char * name, GLint x, GLint y)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform2i(loc, x, y);
}
void Uniform(const char * name, GLint x, GLint y, GLint z)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform3i(loc, x, y, z);
}
void Uniform(const char * name, GLint x, GLint y, GLint z, GLint w)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform4i(loc, x, y, z, w);
}
void Uniform(const char * name, GLfloat x)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform1f(loc, x);
}
void Uniform(const char * name, GLfloat x, GLfloat y)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform2f(loc, x, y);
}
void Uniform(const char * name, GLfloat x, GLfloat y, GLfloat z)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform3f(loc, x, y, z);
}
void Uniform(const char * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
const GLint loc = glGetUniformLocation(this->objectID, name);
glUniform4f(loc, x, y, z, w);
}
protected:
std::set<Shader *> shaders;
bool linked;
void DoBind(void)
{
if (!this->IsLinked())
{
this->Link();
}
glUseProgram(this->objectID);
}
void DoUnbind(void)
{
glUseProgram(0);
}
};
class ProgramVF : public Bindable
{
public:
Program prog;
VertexShader vshd;
FragmentShader fshd;
ProgramVF(void) : Bindable()
{
}
void SetSources(const char * vsrc, const char * fsrc)
{
this->vshd.SetSource(vsrc);
this->fshd.SetSource(fsrc);
this->prog.Attach(&(this->vshd));
this->prog.Attach(&(this->fshd));
}
void LoadSources(const char * vfile, const char * ffile)
{
this->vshd.LoadSource(vfile);
this->fshd.LoadSource(ffile);
this->prog.Attach(&(this->vshd));
this->prog.Attach(&(this->fshd));
}
protected:
void DoBind(void)
{
this->prog.Bind();
}
void DoUnbind(void)
{
this->prog.Unbind();
}
};
#endif // __SHADERS_H__