#pragma once

#include "GlInclude.h"


namespace lib_gl
{


// ---------------------------------------------------------------------------
//! GlFramebufferに割り当てるレンダーバッファオブジェクト管理クラス
class GlRenderbuffer
{
public:
	GlRenderbuffer(void);
	virtual ~GlRenderbuffer(void);

	//! オブジェクト生成
	bool Generate(void);
	//! 破棄
	void Release(void);

	//! バッファ確保
	void CreateBuffer(GLenum internal_format, int width, int height);

	//! バインド
	void Bind(void);

	const GLuint& GetID(void) const;

protected:
	GLuint m_BufferID;
};


// ---------------------------------------------------------------------------
//! FBOオブジェクト
class GlFramebuffer
{
public:
	GlFramebuffer(void);
	virtual ~GlFramebuffer(void);

	//! 生成
	bool Generate(void);
	//! 破棄
	void Release(void);

	//! 有効化、無効化を切り替え
	void BeginFBO(void);
	void EndFBO(void);

	const GLuint& GetID(void) const;

	void BindFboTexture(GLenum attachment, GLuint texture, GLint level)
	{
		glFramebufferTexture2DEXT(
			GL_FRAMEBUFFER_EXT,
			attachment,
			GL_TEXTURE_2D,
			texture,
			0);
	}

	void BindRenderBuffer(GLenum attachment, GLuint renderbuffer)
	{
		glFramebufferRenderbufferEXT(
			GL_FRAMEBUFFER_EXT,
			attachment,
			GL_RENDERBUFFER_EXT,
			renderbuffer);
	}

protected:
	GLuint m_FboID;
};



// ---------------------------------------------------------------------------
// implements GlRenderbuffer

inline GlRenderbuffer::GlRenderbuffer(void)
{
	m_BufferID = 0;
}

inline GlRenderbuffer::~GlRenderbuffer(void)
{
	if( m_BufferID != 0 )
	{
		glDeleteRenderbuffersEXT( 1 , &m_BufferID );
	}
}


inline bool GlRenderbuffer::Generate(void)
{
	glGenRenderbuffersEXT( 1 , &m_BufferID );

	return true;
}

inline void GlRenderbuffer::CreateBuffer(GLenum internal_format, int width, int height)
{
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internal_format, width, height);
}

inline void GlRenderbuffer::Release(void)
{
	if( m_BufferID != 0 )
	{
		glDeleteRenderbuffersEXT( 1 , &m_BufferID );
		m_BufferID = 0;
	}
}


inline void GlRenderbuffer::Bind(void)
{
	glBindRenderbufferEXT( GL_RENDERBUFFER_EXT , m_BufferID );
}


inline const GLuint& GlRenderbuffer::GetID(void) const
{
	return m_BufferID;
}


// ---------------------------------------------------------------------------
// implements GlFramebuffer

inline GlFramebuffer::GlFramebuffer(void)
{
	m_FboID = 0;
}

inline GlFramebuffer::~GlFramebuffer(void)
{
	if( m_FboID != 0 )
	{
		glDeleteFramebuffersEXT( 1 , &m_FboID );
	}
}


inline bool GlFramebuffer::Generate(void)
{
	glGenFramebuffersEXT( 1 , &m_FboID );

	return true;
}

inline void GlFramebuffer::Release(void)
{
	if( m_FboID != 0 )
	{
		glDeleteFramebuffersEXT( 1 , &m_FboID );
		m_FboID = 0;
	}
}


inline void GlFramebuffer::BeginFBO(void)
{
	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT , m_FboID );
}

inline void GlFramebuffer::EndFBO(void)
{
	glBindFramebufferEXT( GL_FRAMEBUFFER_EXT , 0 );
}

inline const GLuint& GlFramebuffer::GetID(void) const
{
	return m_FboID;
}


}
