//##########################################################################
//#                                                                        #
//#                       CLOUDCOMPARE PLUGIN: qSSAO                       #
//#                                                                        #
//#  This program is free software; you can redistribute it and/or modify  #
//#  it under the terms of the GNU General Public License as published by  #
//#  the Free Software Foundation; version 2 or later of the License.      #
//#                                                                        #
//#  This program is distributed in the hope that it will be useful,       #
//#  but WITHOUT ANY WARRANTY; without even the implied warranty of        #
//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the          #
//#  GNU General Public License for more details.                          #
//#                                                                        #
//#          COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI)             #
//#                                                                        #
//##########################################################################

/***************************************************************/
//
//		FILTER_SSAO
//
//		Screen Space Ambient Occlusion
//		Adapted from Crytek and Inigo Quilez
//
//		Output:
//			shaded image
//
//		creation:		23 avril 2008
//						Christian Boucheny (EDF R&D / INRIA)
//		modification:	Avril 2009
//						Daniel Girardeau-Montaut
//
/*****************************************************************/

#ifndef	CC_FILTER_SSAO_H
#define	CC_FILTER_SSAO_H

//CC_FBO
#include <ccGlFilter.h>

//Qt
#include <QOpenGLFunctions_2_1>

//system
#include <vector>

class ccShader;
class ccBilateralFilter;
class ccFrameBufferObject;

class ccSSAOFilter : public ccGlFilter
{
public:

	ccSSAOFilter();
	virtual ~ccSSAOFilter();

	void reset();

	//inherited from ccGlFilter
	virtual ccGlFilter* clone() const override;
	virtual bool init(unsigned width, unsigned height, const QString& shadersPath, QString& error) override;
	virtual void shade(GLuint texDepth, GLuint texColor, ViewportParameters& parameters) override;
	virtual GLuint getTexture() override;

	bool init(	unsigned width,
				unsigned height,
				bool enableBilateralFilter,
				bool useReflectTexture,
				const QString& shadersPath,
				QString& error);

	void setParameters(int N, float Kz, float R, float F);

protected:

	void initReflectTexture();
	void sampleSphere();

	unsigned m_w;
	unsigned m_h;

	ccFrameBufferObject* m_fbo;
	ccShader* m_shader;
	GLuint m_texReflect;

	int   m_N;								// nb of neighbours
	float m_Kz;								// attenuation with distance
	float m_R;								// radius in image of neighbour sphere
	float m_F;								// amplification

	//! Maximum number of sampling directions
	static const int MAX_N = 256;

	//!	Full sphere sampling
	float m_ssao_neighbours[3 * MAX_N];

	ccBilateralFilter* m_bilateralFilter;
	bool               m_bilateralFilterEnabled;
	unsigned           m_bilateralGHalfSize;
	float              m_bilateralGSigma;
	float              m_bilateralGSigmaZ;

	//! Associated OpenGL functions set
	QOpenGLFunctions_2_1 m_glFunc;
	//! Associated OpenGL functions set validity
	bool m_glFuncIsValid;
};

#endif
