First Commit.
This commit is contained in:
parent
1ada6a63ce
commit
d878081824
|
@ -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__
|
|
@ -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__
|
|
@ -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__
|
Loading…
Reference in New Issue