/*
								+---------------------------------+
								|                                 |
								|      ***   OpenGL ES   ***      |
								|                                 |
								|  Copyright  © -tHE SWINe- 2009  |
								|                                 |
								|         FrameBuffer.inl         |
								|                                 |
								+---------------------------------+
*/

#pragma once
#ifndef __RENDER_BUFFER2_INLINES_INCLUDED
#define __RENDER_BUFFER2_INLINES_INCLUDED

/**
 *	@file gles2/FrameBuffer.inl
 *	@author -tHE SWINe-
 *	@date 2009
 *	@brief OpenGL ES frame-buffer object
 *
 */

inline bool CGLFrameBufferObject::Bind(GLenum n_target /*= GL_FRAMEBUFFER*/) const
{
	if(!m_n_framebuffer)
		return false;

	glBindFramebuffer(n_target, m_n_framebuffer);
	// bind framebuffer

	return true;
}

inline void CGLFrameBufferObject::Release(GLenum n_target /*= GL_FRAMEBUFFER*/)
{
	glBindFramebuffer(n_target, 0);
	// release the framebuffer object (restores draw buffers state)
}

inline void CGLFrameBufferObject::Bind_ColorTexture(int n_attachment_index, GLuint n_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, n_Draw_Buffer(n_attachment_index), GL_TEXTURE_2D, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthTexture(GLuint n_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_StencilTexture(GLuint n_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTexture(GLuint n_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, n_texture, n_level);
	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, n_texture, n_level);
	// GLES binds twice
}

inline void CGLFrameBufferObject::Bind_ColorTextureLayer(int n_attachment_index, GLuint n_texture, int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTextureLayerEXT(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, n_Draw_Buffer(n_attachment_index), n_texture, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthTextureLayer(GLuint n_texture, int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTextureLayerEXT(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_texture, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_StencilTextureLayer(GLuint n_texture, int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTextureLayerEXT(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_texture, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTextureLayer(GLuint n_texture, int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTextureLayerEXT(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_texture, n_level, n_layer);
	glFramebufferTextureLayerEXT(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_texture, n_level, n_layer);
	// GLES binds twice
}

inline void CGLFrameBufferObject::Bind_ColorTextureFace(int n_attachment_index, GLuint n_texture, int n_level, GLenum n_face) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, n_Draw_Buffer(n_attachment_index), n_face, n_texture, n_level);
	// glFramebufferTextureFace was removed from the specs, use glFramebufferTexture2D instead
}

inline void CGLFrameBufferObject::Bind_DepthTextureFace(GLuint n_texture, int n_level, GLenum n_face) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_face, n_texture, n_level);
	// glFramebufferTextureFace was removed from the specs, use glFramebufferTexture2D instead
}

inline void CGLFrameBufferObject::Bind_StencilTextureFace(GLuint n_texture, int n_level, GLenum n_face) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_face, n_texture, n_level);
	// glFramebufferTextureFace was removed from the specs, use glFramebufferTexture2D instead
}

inline void CGLFrameBufferObject::Bind_DepthStencilTextureFace(GLuint n_texture, int n_level, GLenum n_face) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_face, n_texture, n_level);
	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_face, n_texture, n_level);
	// glFramebufferTextureFace was removed from the specs, use glFramebufferTexture2D instead
	// GLES binds twice
}

inline void CGLFrameBufferObject::Bind_ColorTexture(int n_attachment_index,
	const CGLTexture &r_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_level);
}

inline void CGLFrameBufferObject::Bind_DepthTexture(const CGLTexture &r_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_level);
}

inline void CGLFrameBufferObject::Bind_StencilTexture(const CGLTexture &r_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTexture(const CGLTexture &r_texture, int n_level) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_level);
	r_texture.FramebufferTexture(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_level);
	// GLES binds twice
}

inline void CGLFrameBufferObject::Bind_ColorTextureLayer(int n_attachment_index,
	const CGLTexture &r_texture, int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureLayer(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthTextureLayer(const CGLTexture &r_texture,
	int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureLayer(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_StencilTextureLayer(const CGLTexture &r_texture,
	int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureLayer(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTextureLayer(const CGLTexture &r_texture,
	int n_level, int n_layer) const
{
#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureLayer(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_level, n_layer);
	r_texture.FramebufferTextureLayer(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_level, n_layer);
	// GLES binds twice
}

inline void CGLFrameBufferObject::Bind_ColorTextureFace(int n_attachment_index,
	const CGLTexture &r_texture, int n_level, GLenum n_face) const
{
	_ASSERTE(b_IsTextureFace(n_face));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureFace(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_level, n_face);
}

inline void CGLFrameBufferObject::Bind_DepthTextureFace(const CGLTexture &r_texture,
	int n_level, GLenum n_face) const
{
	_ASSERTE(b_IsTextureFace(n_face));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureFace(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_level, n_face);
}

inline void CGLFrameBufferObject::Bind_StencilTextureFace(const CGLTexture &r_texture,
	int n_level, GLenum n_face) const
{
	_ASSERTE(b_IsTextureFace(n_face));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureFace(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_level, n_face);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTextureFace(const CGLTexture &r_texture,
	int n_level, GLenum n_face) const
{
	_ASSERTE(b_IsTextureFace(n_face));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTextureFace(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_level, n_face);
	r_texture.FramebufferTextureFace(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_level, n_face);
	// GLES binds twice
}

#if 0
inline void CGLFrameBufferObject::Bind_ColorTexture1D(int n_attachment_index, GLenum n_target, GLuint n_texture, int n_level) const
{
	_ASSERTE(b_IsTexture1D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture1D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_COLOR_ATTACHMENT0 + n_attachment_index, n_target, n_texture, n_level);
}
#endif // 0

inline void CGLFrameBufferObject::Bind_ColorTexture2D(int n_attachment_index, GLenum n_target, GLuint n_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_COLOR_ATTACHMENT0 + n_attachment_index, n_target, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_ColorTexture3D(int n_attachment_index, GLenum n_target, GLuint n_texture, int n_level, int n_layer) const
{
	_ASSERTE(b_IsTexture3D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture3DOES(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_COLOR_ATTACHMENT0 + n_attachment_index, n_target, n_texture, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthTexture2D(GLenum n_target, GLuint n_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_target, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_StencilTexture2D(GLenum n_target, GLuint n_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_target, n_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTexture2D(GLenum n_target, GLuint n_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_DEPTH_ATTACHMENT, n_target, n_texture, n_level);
	glFramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/, GL_STENCIL_ATTACHMENT, n_target, n_texture, n_level);
	// GLES binds twice
}

#if 0
inline void CGLFrameBufferObject::Bind_ColorTexture1D(int n_attachment_index, GLenum n_target,
	CGLTexture_1D_Base &r_texture, int n_level) const
{
	_ASSERTE(b_IsTexture1D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture1D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_target, n_level);
}
#endif // 0

inline void CGLFrameBufferObject::Bind_ColorTexture2D(int n_attachment_index, GLenum n_target,
	CGLTexture_2D_Base &r_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_target, n_level);
}

inline void CGLFrameBufferObject::Bind_ColorTexture3D(int n_attachment_index, GLenum n_target,
	CGLTexture_3D_Base &r_texture, int n_level, int n_layer) const
{
	_ASSERTE(b_IsTexture3D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(n_attachment_index >= 0 && n_attachment_index < m_t_config.n_color_buffer_num);
	_ASSERTE(m_t_config.p_color_buffer[n_attachment_index].b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture3D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		n_Draw_Buffer(n_attachment_index), n_target, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthTexture2D(GLenum n_target,
	CGLTexture_2D_Base &r_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_target, n_level);
}

inline void CGLFrameBufferObject::Bind_StencilTexture2D(GLenum n_target,
	CGLTexture_2D_Base &r_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(!m_t_config.b_depth_stencil_buffer_packed);
	_ASSERTE(m_t_config.b_stencil_buffer && m_t_config.t_stencil_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_target, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTexture2D(GLenum n_target,
	CGLTexture_2D_Base &r_texture, int n_level) const
{
	_ASSERTE(b_IsTexture2D(n_target));

#ifdef __GL_FRAMEBUFFER_STORE_CONFIG
	_ASSERTE(m_t_config.b_depth_stencil_buffer_packed);

	_ASSERTE(m_t_config.b_depth_buffer == m_t_config.b_stencil_buffer);
	_ASSERTE(m_t_config.t_depth_buffer.b_texture_target ==
		m_t_config.t_stencil_buffer.b_texture_target);
	_ASSERTE(m_t_config.t_depth_buffer.n_internal_format ==
		m_t_config.t_stencil_buffer.n_internal_format);
	_ASSERTE(m_t_config.t_depth_buffer.n_multisample_sample_num ==
		m_t_config.t_stencil_buffer.n_multisample_sample_num);
	// format should be set to the same

	_ASSERTE(m_t_config.b_depth_buffer && m_t_config.t_depth_buffer.b_texture_target);
#endif // __GL_FRAMEBUFFER_STORE_CONFIG

	r_texture.FramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_DEPTH_ATTACHMENT, n_target, n_level);
	r_texture.FramebufferTexture2D(GL_FRAMEBUFFER/*GL_DRAW_FRAMEBUFFER*/,
		GL_STENCIL_ATTACHMENT, n_target, n_level);
	// GLES binds twice
}

#if 0 // 1D textures not supported in GLES
inline void CGLFrameBufferObject::Bind_ColorTexture1D(int n_attachment_index,
	CGLTexture_1D_Base &r_texture, int n_level) const
{
	Bind_ColorTexture1D(n_attachment_index, r_texture.n_Target(), r_texture, n_level);
}
#endif // 0

inline void CGLFrameBufferObject::Bind_ColorTexture2D(int n_attachment_index,
	CGLTexture_2D_Base &r_texture, int n_level) const
{
	Bind_ColorTexture2D(n_attachment_index, r_texture.n_Target(), r_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_ColorTexture3D(int n_attachment_index,
	CGLTexture_3D_Base &r_texture, int n_level, int n_layer) const
{
	Bind_ColorTexture3D(n_attachment_index, r_texture.n_Target(), r_texture, n_level, n_layer);
}

inline void CGLFrameBufferObject::Bind_DepthTexture2D(CGLTexture_2D_Base &r_texture, int n_level) const
{
	Bind_DepthTexture2D(r_texture.n_Target(), r_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_StencilTexture2D(CGLTexture_2D_Base &r_texture, int n_level) const
{
	Bind_StencilTexture2D(r_texture.n_Target(), r_texture, n_level);
}

inline void CGLFrameBufferObject::Bind_DepthStencilTexture2D(CGLTexture_2D_Base &r_texture, int n_level) const
{
	Bind_DepthStencilTexture2D(r_texture.n_Target(), r_texture, n_level);
}

#endif // !__RENDER_BUFFER2_INLINES_INCLUDED
