2012-04-30 20:23:53 +02:00
|
|
|
#ifndef GLW_FRAMEBUFFER_H
|
|
|
|
#define GLW_FRAMEBUFFER_H
|
|
|
|
|
2012-05-08 12:46:00 +02:00
|
|
|
#include "./texture2d.h"
|
2012-05-07 15:18:05 +02:00
|
|
|
#include "./renderbuffer.h"
|
|
|
|
|
2012-04-30 20:23:53 +02:00
|
|
|
#include <vector>
|
2012-05-07 15:18:05 +02:00
|
|
|
#include <map>
|
2012-05-08 18:46:59 +02:00
|
|
|
#include <set>
|
2012-04-30 20:23:53 +02:00
|
|
|
|
|
|
|
namespace glw
|
|
|
|
{
|
|
|
|
|
|
|
|
class RenderTarget
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef void BaseType;
|
|
|
|
typedef RenderTarget ThisType;
|
|
|
|
|
|
|
|
RenderableHandle target;
|
|
|
|
GLint level;
|
|
|
|
GLint layer;
|
|
|
|
GLenum face;
|
|
|
|
|
|
|
|
RenderTarget(void)
|
|
|
|
{
|
|
|
|
this->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderTarget(RenderableHandle & rTarget, GLint rLevel, GLint rLayer, GLenum rFace)
|
|
|
|
: target (rTarget)
|
|
|
|
, level (rLevel)
|
|
|
|
, layer (rLayer)
|
|
|
|
, face (rFace)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-05-23 20:02:22 +02:00
|
|
|
RenderTarget(RenderableHandle & rTarget)
|
|
|
|
: target (rTarget)
|
|
|
|
, level (0)
|
|
|
|
, layer (0)
|
2012-08-22 14:38:09 +02:00
|
|
|
, face (GL_TEXTURE_CUBE_MAP_POSITIVE_X)
|
2012-05-23 20:02:22 +02:00
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-04-30 20:23:53 +02:00
|
|
|
void clear(void)
|
|
|
|
{
|
|
|
|
this->target.setNull();
|
|
|
|
this->level = 0;
|
|
|
|
this->layer = -1;
|
2012-08-22 14:38:09 +02:00
|
|
|
this->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
2012-05-08 18:46:59 +02:00
|
|
|
|
|
|
|
bool isNull(void) const
|
|
|
|
{
|
|
|
|
return this->target.isNull();
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<RenderTarget> RenderTargetVector;
|
|
|
|
|
|
|
|
inline RenderTarget texture2DTarget(Texture2DHandle & handle, GLint level = 0)
|
|
|
|
{
|
|
|
|
return RenderTarget(handle, level, 0, GL_NONE);
|
|
|
|
}
|
|
|
|
|
2012-08-22 14:38:09 +02:00
|
|
|
inline RenderTarget textureCubeTarget(TextureCubeHandle & handle, GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X, GLint level = 0)
|
|
|
|
{
|
|
|
|
return RenderTarget(handle, level, 0, face);
|
|
|
|
}
|
|
|
|
|
2012-04-30 20:23:53 +02:00
|
|
|
inline RenderTarget renderbufferTarget(RenderbufferHandle & handle)
|
|
|
|
{
|
|
|
|
return RenderTarget(handle, 0, 0, GL_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
class RenderTargetMapping
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef void BaseType;
|
|
|
|
typedef RenderTargetMapping ThisType;
|
|
|
|
|
|
|
|
typedef std::map<GLuint, RenderTarget> Map;
|
|
|
|
typedef Map::const_iterator ConstIterator;
|
|
|
|
typedef Map::iterator Iterator;
|
|
|
|
typedef Map::value_type Value;
|
|
|
|
|
|
|
|
Map bindings;
|
|
|
|
|
|
|
|
RenderTargetMapping(void)
|
|
|
|
{
|
|
|
|
this->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear(void)
|
|
|
|
{
|
|
|
|
this->bindings.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
const RenderTarget & operator [] (GLuint attachmentIndex) const
|
|
|
|
{
|
|
|
|
return this->bindings.find(attachmentIndex)->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderTarget & operator [] (GLuint attachmentIndex)
|
|
|
|
{
|
|
|
|
return this->bindings[attachmentIndex];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class RenderTargetBinding
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef void BaseType;
|
|
|
|
typedef RenderTargetBinding ThisType;
|
|
|
|
|
|
|
|
typedef std::map<GLuint, GLuint> Map;
|
|
|
|
typedef Map::const_iterator ConstIterator;
|
|
|
|
typedef Map::iterator Iterator;
|
|
|
|
typedef Map::value_type Value;
|
|
|
|
|
|
|
|
Map bindings;
|
|
|
|
|
|
|
|
RenderTargetBinding(void)
|
|
|
|
{
|
|
|
|
this->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clear(void)
|
|
|
|
{
|
|
|
|
this->bindings.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
GLuint operator [] (GLuint attachmentIndex) const
|
|
|
|
{
|
|
|
|
return this->bindings.find(attachmentIndex)->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLuint & operator [] (GLuint attachmentIndex)
|
|
|
|
{
|
|
|
|
return this->bindings[attachmentIndex];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class FramebufferArguments : public ObjectArguments
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef ObjectArguments BaseType;
|
|
|
|
typedef FramebufferArguments ThisType;
|
|
|
|
|
|
|
|
RenderTargetMapping colorTargets;
|
|
|
|
RenderTarget depthTarget;
|
|
|
|
RenderTarget stencilTarget;
|
|
|
|
RenderTargetBinding targetInputs;
|
|
|
|
|
|
|
|
FramebufferArguments(void)
|
2012-05-07 15:18:05 +02:00
|
|
|
: BaseType()
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void clear(void)
|
|
|
|
{
|
|
|
|
BaseType::clear();
|
2012-08-22 14:38:09 +02:00
|
|
|
this->colorTargets .clear();
|
|
|
|
this->depthTarget .clear();
|
|
|
|
this->stencilTarget .clear();
|
|
|
|
this->targetInputs .clear();
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
class Framebuffer : public Object
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
friend class Context;
|
|
|
|
|
2012-04-30 20:23:53 +02:00
|
|
|
public:
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
typedef Object BaseType;
|
|
|
|
typedef Framebuffer ThisType;
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
virtual ~Framebuffer(void)
|
|
|
|
{
|
|
|
|
this->destroy();
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
virtual Type type(void) const
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
return FramebufferType;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
const FramebufferArguments & arguments(void) const
|
|
|
|
{
|
|
|
|
return this->m_config;
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool setColorTarget(GLenum target, GLint unit, GLint index, const RenderTarget & renderTarget)
|
|
|
|
{
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
this->m_config.colorTargets[index].clear();
|
|
|
|
const bool r = this->attachTarget(target, GL_COLOR_ATTACHMENT0 + index, renderTarget);
|
|
|
|
if (!r) return false;
|
|
|
|
this->m_config.colorTargets[index] = renderTarget;
|
|
|
|
return true;
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool removeColorTarget(GLenum target, GLint unit, GLint index)
|
|
|
|
{
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
glFramebufferRenderbuffer(target, GL_COLOR_ATTACHMENT0 + index, GL_RENDERBUFFER, 0);
|
|
|
|
this->m_config.colorTargets[index].clear();
|
|
|
|
return true;
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-06-01 18:57:42 +02:00
|
|
|
bool removeAllColorTargets(GLenum target, GLint unit)
|
|
|
|
{
|
|
|
|
(void)unit;
|
|
|
|
for (RenderTargetMapping::ConstIterator it=this->m_config.colorTargets.bindings.begin(); it!=this->m_config.colorTargets.bindings.end(); ++it)
|
|
|
|
{
|
|
|
|
glFramebufferRenderbuffer(target, GL_COLOR_ATTACHMENT0 + it->first, GL_RENDERBUFFER, 0);
|
|
|
|
}
|
|
|
|
this->m_config.colorTargets.clear();
|
2012-06-02 00:36:14 +02:00
|
|
|
return true;
|
2012-06-01 18:57:42 +02:00
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool setDepthTarget(GLenum target, GLint unit, const RenderTarget & renderTarget)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
this->m_config.depthTarget.clear();
|
|
|
|
const bool r = this->attachTarget(target, GL_DEPTH_ATTACHMENT, renderTarget);
|
|
|
|
if (!r) return false;
|
|
|
|
this->m_config.depthTarget = renderTarget;
|
|
|
|
return true;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool removeDepthTarget(GLenum target, GLint unit)
|
|
|
|
{
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
glFramebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
|
|
|
this->m_config.depthTarget.clear();
|
|
|
|
return true;
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool setStencilTarget(GLenum target, GLint unit, const RenderTarget & renderTarget)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
this->m_config.stencilTarget.clear();
|
|
|
|
const bool r = this->attachTarget(target, GL_STENCIL_ATTACHMENT, renderTarget);
|
|
|
|
if (!r) return false;
|
|
|
|
this->m_config.stencilTarget = renderTarget;
|
|
|
|
return true;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool removeStencilTarget(GLenum target, GLint unit)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
glFramebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
|
|
|
this->m_config.stencilTarget.clear();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-06-01 18:57:42 +02:00
|
|
|
bool removeAllTargets(GLenum target, GLint unit)
|
|
|
|
{
|
|
|
|
this->removeAllColorTargets (target, unit);
|
|
|
|
this->removeDepthTarget (target, unit);
|
|
|
|
this->removeStencilTarget (target, unit);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setTargetInputs(GLenum target, GLint unit, const RenderTargetBinding & targetInputs)
|
|
|
|
{
|
|
|
|
(void)target;
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
this->configureTargetInputs(targetInputs);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-08 18:46:59 +02:00
|
|
|
bool readColorPixels(GLenum target, GLint unit, GLint index, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
(void)target;
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
if (this->m_config.colorTargets.bindings.count(index) <= 0)
|
|
|
|
{
|
|
|
|
GLW_ASSERT(0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0 + index);
|
|
|
|
glReadPixels(x, y, width, height, format, type, data);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readDepthPixels(GLenum target, GLint unit, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
(void)target;
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
if (this->m_config.depthTarget.isNull())
|
|
|
|
{
|
|
|
|
GLW_ASSERT(0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
glReadPixels(x, y, width, height, GL_DEPTH_COMPONENT, type, data);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readStencilPixels(GLenum target, GLint unit, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
(void)target;
|
|
|
|
(void)unit;
|
|
|
|
GLW_ASSERT(this->isValid());
|
|
|
|
if (this->m_config.stencilTarget.isNull())
|
|
|
|
{
|
|
|
|
GLW_ASSERT(0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
glReadPixels(x, y, width, height, GL_STENCIL_INDEX, type, data);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
protected:
|
|
|
|
|
|
|
|
Framebuffer(Context * ctx)
|
|
|
|
: BaseType(ctx)
|
|
|
|
{
|
|
|
|
;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool create(const FramebufferArguments & args)
|
|
|
|
{
|
|
|
|
this->destroy();
|
|
|
|
|
|
|
|
GLint boundNameDraw = 0;
|
|
|
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundNameDraw);
|
|
|
|
|
|
|
|
GLint boundNameRead = 0;
|
|
|
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundNameRead);
|
|
|
|
|
|
|
|
glGenFramebuffers(1, &(this->m_name));
|
2012-05-07 15:18:05 +02:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, this->m_name);
|
2012-05-08 18:46:59 +02:00
|
|
|
this->configure(GL_FRAMEBUFFER, args);
|
2012-05-07 15:18:05 +02:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2012-04-30 20:23:53 +02:00
|
|
|
|
|
|
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundNameDraw);
|
|
|
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, boundNameRead);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
virtual void doDestroy(void)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
glDeleteFramebuffers(1, &(this->m_name));
|
2012-04-30 20:23:53 +02:00
|
|
|
this->m_config.clear();
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
virtual bool doIsValid(void) const
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
return true;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
FramebufferArguments m_config;
|
|
|
|
|
2012-05-08 18:46:59 +02:00
|
|
|
void configure(GLenum target, const FramebufferArguments & args)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-08 18:46:59 +02:00
|
|
|
this->m_config.clear();
|
|
|
|
|
|
|
|
for (RenderTargetMapping::ConstIterator it=args.colorTargets.bindings.begin(); it!=args.colorTargets.bindings.end(); ++it)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-08 18:46:59 +02:00
|
|
|
const bool colorAttached = this->attachTarget(target, GL_COLOR_ATTACHMENT0 + it->first, it->second);
|
|
|
|
if (!colorAttached) continue;
|
|
|
|
this->m_config.colorTargets[it->first] = it->second;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-08 18:46:59 +02:00
|
|
|
const bool depthAttached = this->attachTarget(target, GL_DEPTH_ATTACHMENT, args.depthTarget);
|
|
|
|
if (depthAttached) this->m_config.depthTarget = args.depthTarget;
|
|
|
|
|
|
|
|
const bool stencilAttached = this->attachTarget(target, GL_STENCIL_ATTACHMENT, args.stencilTarget);
|
|
|
|
if (stencilAttached) this->m_config.stencilTarget = args.stencilTarget;
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-06-01 18:57:42 +02:00
|
|
|
this->configureTargetInputs(args.targetInputs);
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool attachTarget(GLenum target, GLenum attachment, const RenderTarget & renderTarget)
|
2012-04-30 20:23:53 +02:00
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
const RenderableHandle & handle = renderTarget.target;
|
2012-04-30 20:23:53 +02:00
|
|
|
|
|
|
|
if (!handle)
|
|
|
|
{
|
2012-05-07 15:18:05 +02:00
|
|
|
glFramebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, 0);
|
2012-04-30 20:23:53 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (handle->type())
|
|
|
|
{
|
2012-08-22 14:38:09 +02:00
|
|
|
case RenderbufferType : glFramebufferRenderbuffer (target, attachment, GL_RENDERBUFFER, handle->name() ); break;
|
|
|
|
case Texture2DType : glFramebufferTexture2D (target, attachment, GL_TEXTURE_2D, handle->name(), renderTarget.level); break;
|
|
|
|
case TextureCubeType : glFramebufferTexture2D (target, attachment, renderTarget.face, handle->name(), renderTarget.level); break;
|
|
|
|
default : GLW_ASSERT(0); break;
|
2012-04-30 20:23:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-06-01 18:57:42 +02:00
|
|
|
|
|
|
|
void configureTargetInputs(const RenderTargetBinding & targetInputs)
|
|
|
|
{
|
|
|
|
if (this->m_config.colorTargets.bindings.empty() && targetInputs.bindings.empty())
|
|
|
|
{
|
|
|
|
glDrawBuffer(GL_NONE);
|
|
|
|
glReadBuffer(GL_NONE);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<GLenum> drawBuffers;
|
|
|
|
drawBuffers.reserve(targetInputs.bindings.size());
|
|
|
|
for (RenderTargetBinding::ConstIterator it=targetInputs.bindings.begin(); it!=targetInputs.bindings.end(); ++it)
|
|
|
|
{
|
|
|
|
const GLuint fragOutput = it->second;
|
|
|
|
const GLuint attachmentIndex = GL_COLOR_ATTACHMENT0 + it->first;
|
|
|
|
if (drawBuffers.size() <= size_t(fragOutput))
|
|
|
|
{
|
|
|
|
drawBuffers.resize(size_t(fragOutput + 1), GL_NONE);
|
|
|
|
}
|
|
|
|
drawBuffers[fragOutput] = attachmentIndex;
|
|
|
|
this->m_config.targetInputs[it->first] = fragOutput;
|
|
|
|
}
|
|
|
|
glDrawBuffers(GLsizei(drawBuffers.size()), &(drawBuffers[0]));
|
|
|
|
glReadBuffer(drawBuffers[0]);
|
|
|
|
}
|
2012-04-30 20:23:53 +02:00
|
|
|
};
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
namespace detail { template <> struct BaseOf <Framebuffer> { typedef Object Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <Framebuffer> ::Type FramebufferPtr;
|
|
|
|
|
|
|
|
class SafeFramebuffer : public SafeObject
|
|
|
|
{
|
|
|
|
friend class Context;
|
|
|
|
friend class BoundFramebuffer;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef SafeObject BaseType;
|
|
|
|
typedef SafeFramebuffer ThisType;
|
|
|
|
|
|
|
|
const FramebufferArguments & arguments(void) const
|
|
|
|
{
|
|
|
|
return this->object()->arguments();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
SafeFramebuffer(const FramebufferPtr & program)
|
|
|
|
: BaseType(program)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
const FramebufferPtr & object(void) const
|
|
|
|
{
|
|
|
|
return static_cast<const FramebufferPtr &>(BaseType::object());
|
|
|
|
}
|
|
|
|
|
|
|
|
FramebufferPtr & object(void)
|
|
|
|
{
|
|
|
|
return static_cast<FramebufferPtr &>(BaseType::object());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace detail { template <> struct BaseOf <SafeFramebuffer> { typedef SafeObject Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBase <SafeFramebuffer> { typedef Framebuffer Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectSafe <Framebuffer > { typedef SafeFramebuffer Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <SafeFramebuffer> ::Type FramebufferHandle;
|
|
|
|
|
|
|
|
class FramebufferBindingParams : public ObjectBindingParams
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef ObjectBindingParams BaseType;
|
|
|
|
typedef FramebufferBindingParams ThisType;
|
|
|
|
|
|
|
|
FramebufferBindingParams(void)
|
|
|
|
: BaseType()
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
FramebufferBindingParams(GLenum target)
|
|
|
|
: BaseType(target, 0)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundFramebuffer : public BoundObject
|
|
|
|
{
|
|
|
|
friend class Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef BoundObject BaseType;
|
|
|
|
typedef BoundFramebuffer ThisType;
|
|
|
|
|
|
|
|
BoundFramebuffer(void)
|
|
|
|
: BaseType()
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
const FramebufferHandle & handle(void) const
|
|
|
|
{
|
|
|
|
return static_cast<const FramebufferHandle &>(BaseType::handle());
|
|
|
|
}
|
|
|
|
|
|
|
|
FramebufferHandle & handle(void)
|
|
|
|
{
|
|
|
|
return static_cast<FramebufferHandle &>(BaseType::handle());
|
|
|
|
}
|
|
|
|
|
|
|
|
GLenum getStatus(void) const
|
|
|
|
{
|
|
|
|
return glCheckFramebufferStatus(this->m_target);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isComplete(void) const
|
|
|
|
{
|
|
|
|
return (this->getStatus() == GL_FRAMEBUFFER_COMPLETE);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setColorTarget(GLint index, const RenderTarget & renderTarget)
|
|
|
|
{
|
|
|
|
return this->object()->setColorTarget(this->m_target, this->m_unit, index, renderTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool removeColorTarget(GLint index)
|
|
|
|
{
|
|
|
|
return this->object()->removeColorTarget(this->m_target, this->m_unit, index);
|
|
|
|
}
|
|
|
|
|
2012-06-01 18:57:42 +02:00
|
|
|
bool removeAllColorTargets(void)
|
|
|
|
{
|
|
|
|
return this->object()->removeAllColorTargets(this->m_target, this->m_unit);
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
bool setDepthTarget(const RenderTarget & renderTarget)
|
|
|
|
{
|
|
|
|
return this->object()->setDepthTarget(this->m_target, this->m_unit, renderTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool removeDepthTarget(void)
|
|
|
|
{
|
|
|
|
return this->object()->removeDepthTarget(this->m_target, this->m_unit);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setStencilTarget(const RenderTarget & renderTarget)
|
|
|
|
{
|
|
|
|
return this->object()->setStencilTarget(this->m_target, this->m_unit, renderTarget);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool removeStencilTarget(void)
|
|
|
|
{
|
|
|
|
return this->object()->removeStencilTarget(this->m_target, this->m_unit);
|
|
|
|
}
|
|
|
|
|
2012-06-01 18:57:42 +02:00
|
|
|
bool removeAllTargets(void)
|
|
|
|
{
|
|
|
|
return this->object()->removeAllTargets(this->m_target, this->m_unit);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setTargetInputs(const RenderTargetBinding & targetInputs)
|
|
|
|
{
|
|
|
|
return this->object()->setTargetInputs(this->m_target, this->m_unit, targetInputs);
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
protected:
|
|
|
|
|
|
|
|
BoundFramebuffer(const FramebufferHandle & handle, const FramebufferBindingParams & params)
|
|
|
|
: BaseType(handle, params)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
const FramebufferPtr & object(void) const
|
|
|
|
{
|
|
|
|
return this->handle()->object();
|
|
|
|
}
|
|
|
|
|
|
|
|
FramebufferPtr & object(void)
|
|
|
|
{
|
|
|
|
return this->handle()->object();
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void bind(void)
|
|
|
|
{
|
|
|
|
glBindFramebuffer(this->m_target, this->object()->name());
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void unbind(void)
|
|
|
|
{
|
|
|
|
glBindFramebuffer(this->m_target, 0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace detail { template <> struct ParamsOf <BoundFramebuffer> { typedef FramebufferBindingParams Type; }; };
|
|
|
|
namespace detail { template <> struct BaseOf <BoundFramebuffer> { typedef BoundObject Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBase <BoundFramebuffer> { typedef Framebuffer Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBound <Framebuffer > { typedef BoundFramebuffer Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <BoundFramebuffer> ::Type BoundFramebufferHandle;
|
|
|
|
|
|
|
|
class ReadFramebufferBindingParams : public FramebufferBindingParams
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef FramebufferBindingParams BaseType;
|
|
|
|
typedef ReadFramebufferBindingParams ThisType;
|
|
|
|
|
|
|
|
ReadFramebufferBindingParams(void)
|
|
|
|
: BaseType(GL_READ_FRAMEBUFFER)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundReadFramebuffer : public BoundFramebuffer
|
|
|
|
{
|
|
|
|
friend class Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef BoundFramebuffer BaseType;
|
|
|
|
typedef BoundReadFramebuffer ThisType;
|
2012-04-30 20:23:53 +02:00
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
BoundReadFramebuffer(void)
|
|
|
|
: BaseType()
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-05-08 18:46:59 +02:00
|
|
|
bool readColorPixels(GLint index, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readColorPixels(this->m_target, this->m_unit, index, x, y, width, height, format, type, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readDepthPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readDepthPixels(this->m_target, this->m_unit, x, y, width, height, type, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readStencilPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readStencilPixels(this->m_target, this->m_unit, x, y, width, height, type, data);
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
protected:
|
|
|
|
|
|
|
|
BoundReadFramebuffer(const FramebufferHandle & handle, const ReadFramebufferBindingParams & params)
|
|
|
|
: BaseType(handle, params)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace detail { template <> struct ParamsOf <BoundReadFramebuffer> { typedef ReadFramebufferBindingParams Type; }; };
|
|
|
|
namespace detail { template <> struct BaseOf <BoundReadFramebuffer> { typedef BoundFramebuffer Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBase <BoundReadFramebuffer> { typedef Framebuffer Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <BoundReadFramebuffer> ::Type BoundReadFramebufferHandle;
|
|
|
|
|
|
|
|
class DrawFramebufferBindingParams : public FramebufferBindingParams
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef FramebufferBindingParams BaseType;
|
|
|
|
typedef DrawFramebufferBindingParams ThisType;
|
|
|
|
|
|
|
|
DrawFramebufferBindingParams(void)
|
|
|
|
: BaseType(GL_DRAW_FRAMEBUFFER)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundDrawFramebuffer : public BoundFramebuffer
|
|
|
|
{
|
|
|
|
friend class Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef BoundFramebuffer BaseType;
|
|
|
|
typedef BoundDrawFramebuffer ThisType;
|
|
|
|
|
|
|
|
BoundDrawFramebuffer(void)
|
|
|
|
: BaseType()
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
BoundDrawFramebuffer(const FramebufferHandle & handle, const DrawFramebufferBindingParams & params)
|
|
|
|
: BaseType(handle, params)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace detail { template <> struct ParamsOf <BoundDrawFramebuffer> { typedef DrawFramebufferBindingParams Type; }; };
|
|
|
|
namespace detail { template <> struct BaseOf <BoundDrawFramebuffer> { typedef BoundFramebuffer Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBase <BoundDrawFramebuffer> { typedef Framebuffer Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <BoundDrawFramebuffer> ::Type BoundDrawFramebufferHandle;
|
|
|
|
|
|
|
|
class ReadDrawFramebufferBindingParams : public FramebufferBindingParams
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef FramebufferBindingParams BaseType;
|
|
|
|
typedef ReadDrawFramebufferBindingParams ThisType;
|
|
|
|
|
|
|
|
ReadDrawFramebufferBindingParams(void)
|
|
|
|
: BaseType(GL_FRAMEBUFFER)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class BoundReadDrawFramebuffer : public BoundFramebuffer
|
|
|
|
{
|
|
|
|
friend class Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef BoundFramebuffer BaseType;
|
|
|
|
typedef BoundReadDrawFramebuffer ThisType;
|
|
|
|
|
|
|
|
BoundReadDrawFramebuffer(void)
|
|
|
|
: BaseType()
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2012-05-08 18:46:59 +02:00
|
|
|
bool readColorPixels(GLint index, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readColorPixels(this->m_target, this->m_unit, index, x, y, width, height, format, type, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readDepthPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readDepthPixels(this->m_target, this->m_unit, x, y, width, height, type, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool readStencilPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, GLvoid * data)
|
|
|
|
{
|
|
|
|
return this->object()->readStencilPixels(this->m_target, this->m_unit, x, y, width, height, type, data);
|
|
|
|
}
|
|
|
|
|
2012-05-07 15:18:05 +02:00
|
|
|
protected:
|
|
|
|
|
|
|
|
BoundReadDrawFramebuffer(const FramebufferHandle & handle, const ReadDrawFramebufferBindingParams & params)
|
|
|
|
: BaseType(handle, params)
|
|
|
|
{
|
|
|
|
;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace detail { template <> struct ParamsOf <BoundReadDrawFramebuffer> { typedef ReadDrawFramebufferBindingParams Type; }; };
|
|
|
|
namespace detail { template <> struct BaseOf <BoundReadDrawFramebuffer> { typedef BoundFramebuffer Type; }; };
|
|
|
|
namespace detail { template <> struct ObjectBase <BoundReadDrawFramebuffer> { typedef Framebuffer Type; }; };
|
|
|
|
typedef detail::ObjectSharedPointerTraits <BoundReadDrawFramebuffer> ::Type BoundReadDrawFramebufferHandle;
|
|
|
|
|
|
|
|
};
|
2012-04-30 20:23:53 +02:00
|
|
|
|
|
|
|
#endif // GLW_FRAMEBUFFER_H
|