#include "OglFrameBuffer.h"

/*void error( )
{
	//cout << "error " << glGetError( ) << endl;
}*/

void OglFrameBuffer::init(vector<OglTexTarget*> tex, int depthFlags, uint wi_, uint he_, uint depth_, bool init)
{
	id = 0;
	wi = wi_; he = he_; depth = depth_;
	glGenFramebuffers( 1, &id );
	glBindFramebuffer( GL_FRAMEBUFFER, id );

	GLenum typeTex = depth ? GL_TEXTURE_2D_ARRAY: GL_TEXTURE_2D;

	if ( depthFlags & DEPTHBUF )
	{
		glGenRenderbuffers( 1, &depthId );
		glBindRenderbuffer( GL_RENDERBUFFER, depthId );
		glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, wi, he );
		glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthId );
	}
	else if ( depthFlags & DEPTHBUF_TEXTURE )
	{
		depthTexture.intFormat = GL_DEPTH_COMPONENT32F;
		depthTexture.format = GL_DEPTH_COMPONENT;
		depthTexture.type = GL_FLOAT;
		if ( depthFlags & DEPTHBUF_LINEAR )
		{
			depthTexture.magFilter = GL_LINEAR;
			depthTexture.minFilter = GL_LINEAR;
		}
		if ( depthFlags & DEPTHBUF_SHADOW )
			depthTexture.compMode = GL_COMPARE_REF_TO_TEXTURE;

		depthTexture.init( wi, he, depth );

		glFramebufferTexture( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture.getId(), 0 );
		glTexParameteri(typeTex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
		glTexParameteri(typeTex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
		float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
		glTexParameterfv(typeTex, GL_TEXTURE_BORDER_COLOR, color );
	}

	vector<GLenum> DrawBuffers;
	for ( int i = 0; i < tex.size(); i++ )
	{
		if (init)
			tex[i]->init(wi, he, depth);
		if (depth)
			glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, tex[i]->getId(), 0);
		else
			glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, tex[i]->getId(), 0);
		DrawBuffers.push_back( GL_COLOR_ATTACHMENT0 + i );
	}

	if (DrawBuffers.size( ))
		glDrawBuffers( DrawBuffers.size(), &DrawBuffers[0] );

	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if (status != GL_FRAMEBUFFER_COMPLETE)
		//cout << "framebuffer error " << hex << status << dec << endl;
		LOGERROR("framebuffer error " + status);
}

void OglFrameBuffer::enable()
{
	glBindFramebuffer( GL_FRAMEBUFFER, id );
	glViewport( 0, 0, wi, he );
}