/******************************************************************************
 
 @File         OGLES2ColourGrading.cpp
 
 @Title        Colour grading
 
 @Version
 
 @Copyright    Copyright (c) Imagination Technologies Limited.
 
 @Platform     Independent
 
 @Description  Demonstrates how to colour grade your render.
 
 ******************************************************************************/
#include "PVRShell.h"
#include "OGLES2Tools.h"

/******************************************************************************
 Constants
 ******************************************************************************/
const char* const c_pszMaskTexture = "MaskTexture.pvr";
const char* const c_pszBackgroundTexture = "Background.pvr";

// Our colour lookup tables
const char* const c_pszLUTs[] = 
{ 
	"identity.pvr",
	"bw.pvr",
	"cooler.pvr",
	"warmer.pvr",
	"sepia.pvr",
	"inverted.pvr",
	"highcontrast.pvr",
	"bluewhitegradient.pvr"
};

// Shader source
const char* const c_szFragShaderSrcFile	= "FragShader.fsh";
const char* const c_szVertShaderSrcFile	= "VertShader.vsh";
const char* const c_szSceneFragShaderSrcFile	= "SceneFragShader.fsh";
const char* const c_szSceneVertShaderSrcFile	= "SceneVertShader.vsh";
const char* const c_szBackgroundFragShaderSrcFile = "BackgroundFragShader.fsh";

// POD scene files
const char c_szSceneFile[] = "Mask.pod";

// Camera constants. Used for making the projection matrix
const float CAM_FOV  = PVRT_PI / 6;
const float CAM_NEAR = 4.0f;
const float CAM_FAR = 5000.0f;

// Index to bind the attributes to vertex shaders
const int VERTEX_ARRAY   = 0;
const int TEXCOORD_ARRAY = 1;
const int NORMAL_ARRAY   = 2;

// Look up table enumeration
enum ELUTs
{
	eIdentity,
	eBW,
	eCooler,
	eWarmer,
	eSepia,
	eInverted,
	eHighContrast,
	eBlueWhiteGradient,
	eLast,

	// The range to cycle through
	eA = eBW,
	eB = eBlueWhiteGradient
};

const char* const c_pszLUTNames[] =
{
	"Identity",
	"Black and white",
	"Cooler",
	"Warmer",
	"Sepia",
	"Inverted",
	"High Contrast",
	"Blue White Gradient"
};

/*!****************************************************************************
 Class implementing the PVRShell functions.
 ******************************************************************************/
class OGLES2ColourGrading : public PVRShell
{
	enum EMultisampleExtension
	{
		eMultisampleExtension_None,
		eMultisampleExtension_IMG,
		eMultisampleExtension_ANGLE
	};

	// Print3D object
	CPVRTPrint3D			m_Print3D;
	
	// Texture handle
	GLuint					m_uiMaskTexture;
	GLuint					m_uiBackgroundTexture;
	GLuint					m_uiLUTs[eLast];
	int						m_iCurrentLUT;

	// VBO handle
	GLuint					m_ui32FullScreenRectVBO;
	
	// Stride for vertex data
	unsigned int			m_ui32VertexStride;
	
	// 3D Model
	CPVRTModelPOD	m_Mask;
	GLuint* m_puiMaskVBO;
	GLuint* m_puiMaskIBO;

	GLuint m_ui32BackgroundVBO;

	// Projection and view matrices
	PVRTMat4 m_mViewProjection;

	// Shaders
	GLuint m_uiPostVertShader;
	GLuint m_uiPostFragShader;

	struct
	{
		GLuint uiId;
	}
	m_PostShaderProgram;

	GLuint m_uiBackgroundFragShader;

	struct
	{
		GLuint uiId;
	}
	m_BackgroundShaderProgram;

	GLuint m_uiSceneVertShader;
	GLuint m_uiSceneFragShader;

	struct
	{
		GLuint uiId;
		GLuint uiMVPMatrixLoc;
		GLuint uiLightDirLoc;
		GLuint uiMaterialBiasLoc;
		GLuint uiMaterialScaleLoc;
	}
	m_SceneShaderProgram;

	// Render contexts, etc
	GLint	  m_i32OriginalFbo;

	// Texture IDs used by the app
	GLuint	m_uiTextureToRenderTo;
	GLuint  m_uiDepthToRenderTo;

	// Handle for our FBO and the depth buffer that it requires
	GLuint m_uiFBO;

	// Handle for our multi-sampled FBO and the depth buffer that it requires
	GLuint m_uiFBOMultisampled;
	GLuint m_uiDepthBufferMultisampled;
	GLuint m_uiColourBufferMultisampled;	

	// Start time
	unsigned long m_ulStartTime;

	// Extensions
	CPVRTgles2Ext m_Extensions;

	// Discard the frame buffer attachments
	bool m_bDiscard;
	bool m_bMultisampledSupported;
	EMultisampleExtension m_eMultisampleMode;

	bool m_flipX;
	bool m_flipY;

public:
	OGLES2ColourGrading() :
		m_uiMaskTexture(0),
		m_uiBackgroundTexture(0),
		m_iCurrentLUT(0),
		m_ui32FullScreenRectVBO(0),
		m_ui32VertexStride(0),
		m_puiMaskVBO(0),
		m_puiMaskIBO(0),
		m_ui32BackgroundVBO(0),
		m_uiPostVertShader(0),
		m_uiPostFragShader(0),
		m_uiBackgroundFragShader(0),
		m_uiSceneVertShader(0),
		m_uiSceneFragShader(0),
		m_i32OriginalFbo(0),
		m_uiTextureToRenderTo(0),
		m_uiDepthToRenderTo(0),
		m_uiFBO(0),
		m_uiFBOMultisampled(0),
		m_uiDepthBufferMultisampled(0),
		m_uiColourBufferMultisampled(0),
		m_ulStartTime(0),
		m_bDiscard(false),
		m_bMultisampledSupported(false),
		m_flipX(false),
		m_flipY(false)
	{
	}

	// PVRShell functions
	virtual bool InitApplication();
	virtual bool InitView();
	virtual bool ReleaseView();
	virtual bool QuitApplication();
	virtual bool RenderScene();

private:
	bool LoadShaders(CPVRTString& ErrorStr);
	bool CreateFBO();
	void LoadVbos(const bool bRotated);
	void DrawMesh(const int i32NodeIndex);
};


/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occurred
 @Description	Code in InitApplication() will be called by PVRShell once per
                run, before the rendering context is created.
                Used to initialize variables that are not dependent on it
                (e.g. external modules, loading meshes, etc.)
                If the rendering context is lost, InitApplication() will
                not be called again.
 ******************************************************************************/
bool OGLES2ColourGrading::InitApplication()
{
	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));
	
	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	// Load the scene
	if(m_Mask.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
	}

	// Initialise some variables
	m_puiMaskVBO = m_puiMaskIBO = 0;
	m_iCurrentLUT = eA;
	return true;
}

/*!****************************************************************************
 @Function		QuitApplication
 @Return		bool		true if no error occurred
 @Description	Code in QuitApplication() will be called by PVRShell once per
                run, just before exiting the program.
                If the rendering context is lost, QuitApplication() will
                not be called.
 ******************************************************************************/
bool OGLES2ColourGrading::QuitApplication()
{
	// Free the memory allocated for the scene
	m_Mask.Destroy();

	delete[] m_puiMaskVBO;
	m_puiMaskVBO = 0;

	delete[] m_puiMaskIBO;
	m_puiMaskIBO = 0;
    return true;
}

/*!****************************************************************************
 @Function		LoadEffects
 @Output		ErrorStr	A description of an error, if one occurs.
 @Return		bool		true if no error occurred
 @Description	Loads and parses the bundled PFX and generates the various
                effect objects.
 ******************************************************************************/
bool OGLES2ColourGrading::LoadShaders(CPVRTString& ErrorStr)
{
	// Load and compile the shaders from files.
	if(PVRTShaderLoadFromFile(NULL, c_szVertShaderSrcFile, GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiPostVertShader, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	if(PVRTShaderLoadFromFile(NULL, c_szFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiPostFragShader, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Setup and link the shader program
	const char* aszAttribs[] = { "inVertex", "inTexCoord" };
	if(PVRTCreateProgram(&m_PostShaderProgram.uiId, m_uiPostVertShader, m_uiPostFragShader, aszAttribs, 2, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Set the sampler variables to their respective texture unit
	glUniform1i(glGetUniformLocation(m_PostShaderProgram.uiId, "sTexture"), 0);
	glUniform1i(glGetUniformLocation(m_PostShaderProgram.uiId, "sColourLUT"), 1);

	// Background shader

	if(PVRTShaderLoadFromFile(NULL, c_szBackgroundFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiBackgroundFragShader, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Set up and link the shader program re-using the vertex shader from the main shader program
	const char* aszBackgroundAttribs[] = { "inVertex", "inTexCoord" };
	if(PVRTCreateProgram(&m_BackgroundShaderProgram.uiId, m_uiPostVertShader, m_uiBackgroundFragShader, aszBackgroundAttribs, 2, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Set the sampler2D variable to the first texture unit
	glUniform1i(glGetUniformLocation(m_BackgroundShaderProgram.uiId, "sTexture"), 0);

	// Scene shaders - Used for rendering the mask
	if(PVRTShaderLoadFromFile(NULL, c_szSceneVertShaderSrcFile, GL_VERTEX_SHADER, GL_SGX_BINARY_IMG, &m_uiSceneVertShader, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	if(PVRTShaderLoadFromFile(NULL, c_szSceneFragShaderSrcFile, GL_FRAGMENT_SHADER, GL_SGX_BINARY_IMG, &m_uiSceneFragShader, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Setup and link the shader program
	const char* aszSceneAttribs[] = { "inVertex", "inTexCoord", "inNormal" };
	if (PVRTCreateProgram(&m_SceneShaderProgram.uiId, m_uiSceneVertShader, m_uiSceneFragShader, aszSceneAttribs, 3, &ErrorStr) != PVR_SUCCESS)
	{
		return false;
	}

	// Set the sampler2D variable to the first texture unit
	glUniform1i(glGetUniformLocation(m_SceneShaderProgram.uiId, "sTexture"), 0);

	// Store the location of uniforms for later use
	m_SceneShaderProgram.uiMVPMatrixLoc		= glGetUniformLocation(m_SceneShaderProgram.uiId, "MVPMatrix");
	m_SceneShaderProgram.uiLightDirLoc		= glGetUniformLocation(m_SceneShaderProgram.uiId, "LightDirection");
	m_SceneShaderProgram.uiMaterialBiasLoc	= glGetUniformLocation(m_SceneShaderProgram.uiId, "MaterialBias");
	m_SceneShaderProgram.uiMaterialScaleLoc	= glGetUniformLocation(m_SceneShaderProgram.uiId, "MaterialScale");

	// Set default shader material uniforms
	float fSpecularConcentration = 0.6f;	// a value from 0 to 1 (wider, concentrated)
	float fSpecularIntensity = 0.3f;		// a value from 0 to 1

	// Specular bias
	glUniform1f(m_SceneShaderProgram.uiMaterialBiasLoc, fSpecularConcentration);
	// Specular intensity scale
	glUniform1f(m_SceneShaderProgram.uiMaterialScaleLoc, fSpecularIntensity / (1.0f - fSpecularConcentration));

	return true;
}

/*!****************************************************************************
 @Function		LoadVbos
 @Description	Loads the mesh data required for this training course into
				vertex buffer objects
******************************************************************************/
void OGLES2ColourGrading::LoadVbos(const bool bRotated)
{
	if(!m_puiMaskVBO)      
		m_puiMaskVBO = new GLuint[m_Mask.nNumMesh];

	if(!m_puiMaskIBO) 
		m_puiMaskIBO = new GLuint[m_Mask.nNumMesh];

	/*
		Load vertex data of all meshes in the scene into VBOs

		The meshes have been exported with the "Interleave Vectors" option,
		so all data is interleaved in the buffer at pMesh->pInterleaved.
		Interleaving data improves the memory access pattern and cache efficiency,
		thus it can be read faster by the hardware.
	*/
	glGenBuffers(m_Mask.nNumMesh, m_puiMaskVBO);
	for(unsigned int i = 0; i < m_Mask.nNumMesh; ++i)
	{
		// Load vertex data into buffer object
		SPODMesh& Mesh = m_Mask.pMesh[i];
		unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;
		glBindBuffer(GL_ARRAY_BUFFER, m_puiMaskVBO[i]);
		glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);

		// Load index data into buffer object if available
		m_puiMaskIBO[i] = 0;
		if (Mesh.sFaces.pData)
		{
			glGenBuffers(1, &m_puiMaskIBO[i]);
			uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiMaskIBO[i]);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);
		}
	}

	// Create VBO for the fullscreen rect that we'll be rendering our FBO to

	// Interleaved vertex data
	GLfloat afVertices[] = {
		// Left quad
		-1.0f,  1.0f, 0.0f,	1.0f,	// Pos
		0.0f,  1.0f,			    // UVs

		-1.0f, -1.0f, 0.0f,	1.0f,
		0.0f,  0.0f,

		0.0f,  1.0f, 0.0f,	1.0f,
		0.5f,  1.0f,

		0.0f, -1.0f, 0.0f,	1.0f,
		0.5f,  0.0f,

		1.0f,  1.0f, 0.0f,	1.0f,
		1.0f,  1.0f,

		1.0f, -1.0f, 0.0f,	1.0f,
		1.0f,  0.0f,
	};

	if(bRotated) // If we're rotated then pre-process the fullscreen rect's geometry to compensate
	{
		for(unsigned int i = 0; i < 6; ++i)
		{
			float fTmp = afVertices[i * 6 + 1];
			afVertices[i * 6 + 1] = afVertices[i * 6];
			afVertices[i * 6] = fTmp;

			fTmp = afVertices[i * 6 + 5];
			afVertices[i * 6 + 5] = afVertices[i * 6 + 4];
			afVertices[i * 6 + 4] = fTmp;
		}
	}

	glGenBuffers(1, &m_ui32FullScreenRectVBO);
	m_ui32VertexStride = 6 * sizeof(GLfloat); // 4 floats for the pos, 2 for the UVs

	// Bind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_ui32FullScreenRectVBO);

	// Set the buffer's data
	glBufferData(GL_ARRAY_BUFFER, 6 * m_ui32VertexStride, afVertices, GL_STATIC_DRAW);

	// Create the VBO for the background
	GLfloat afBackgroundVertices[] = {
		// Left quad
		-1.0f,  1.0f, 0.0f,	1.0f,	// Pos
		0.0f,  1.0f,			    // UVs

		-1.0f, -1.0f, 0.0f,	1.0f,
		0.0f,  0.0f,

		1.0f,  1.0f, 0.0f,	1.0f,
		1.0f,  1.0f,

		1.0f, -1.0f, 0.0f,	1.0f,
		1.0f,  0.0f,
	};

	if(bRotated) // If we're rotated then pre-process the background geometry
	{
		for(unsigned int i = 0; i < 4; ++i)
		{
			float fTmp = afBackgroundVertices[i * 6 + 1];
			afBackgroundVertices[i * 6 + 1] = -afBackgroundVertices[i * 6];
			afBackgroundVertices[i * 6] = -fTmp;
		}
	}

	glGenBuffers(1, &m_ui32BackgroundVBO);

	// Bind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_ui32BackgroundVBO);

	// Set the buffer's data
	glBufferData(GL_ARRAY_BUFFER, 4 * m_ui32VertexStride, afBackgroundVertices, GL_STATIC_DRAW);

	// Unbind our buffers
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

bool OGLES2ColourGrading::CreateFBO()
{
	// Figure out if the platform supports either EXT or IMG extension
	m_eMultisampleMode = eMultisampleExtension_IMG;
	if(m_Extensions.glRenderbufferStorageMultisampleANGLE)
	{
		m_eMultisampleMode = eMultisampleExtension_ANGLE;
	}

	GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };

	// Query the max amount of samples that are supported, we are going to use the max
	GLint samples;
	glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);

	// Get the currently bound frame buffer object. On most platforms this just gives 0.
	glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);

	// Create a texture for rendering to
	glGenTextures(1, &m_uiTextureToRenderTo);
	glBindTexture(GL_TEXTURE_2D, m_uiTextureToRenderTo);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PVRShellGet(prefWidth), PVRShellGet(prefHeight), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Create the object that will allow us to render to the aforementioned texture
	glGenFramebuffers(1, &m_uiFBO);
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBO);

	// Attach the texture to the FBO
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uiTextureToRenderTo, 0);
	if(!m_bMultisampledSupported)
	{
		glGenTextures(1, &m_uiDepthToRenderTo);
		glBindTexture(GL_TEXTURE_2D, m_uiDepthToRenderTo);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, PVRShellGet(prefWidth), PVRShellGet(prefHeight), 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 0);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_uiDepthToRenderTo, 0);
	}

	// Check that our FBO creation was successful
	GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(uStatus != GL_FRAMEBUFFER_COMPLETE)
	{
		PVRShellSet(prefExitMessage, "ERROR: Failed to initialise FBO");
		return false;
	}

	// Generate and bind a render buffer which will become a multisampled depth buffer shared between our two FBOs
	if(m_bMultisampledSupported)
	{
		// Create and initialize the multi-sampled FBO.

		// Create the object that will allow us to render to the aforementioned texture
		glGenFramebuffers(1, &m_uiFBOMultisampled);
		glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBOMultisampled);

		glGenRenderbuffers(1, &m_uiDepthBufferMultisampled);
		glBindRenderbuffer(GL_RENDERBUFFER, m_uiDepthBufferMultisampled);

		if(m_eMultisampleMode == eMultisampleExtension_ANGLE)
			m_Extensions.glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
		else
			m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

		glGenRenderbuffers(1, &m_uiColourBufferMultisampled);
		glBindRenderbuffer(GL_RENDERBUFFER, m_uiColourBufferMultisampled);
		if(m_eMultisampleMode == eMultisampleExtension_ANGLE)
			m_Extensions.glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, GL_RGB8_OES, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
		else
			m_Extensions.glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, samples, GL_RGB8_OES, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

		glBindRenderbuffer(GL_RENDERBUFFER, 0);

		// Attach the multisampled depth buffer we created earlier to our FBO.
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uiDepthBufferMultisampled);

		// Attach the multisampled colour renderbuffer to the FBO
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_uiColourBufferMultisampled);

		// Check that our FBO creation was successful
		uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
		if(uStatus != GL_FRAMEBUFFER_COMPLETE)
		{
			PVRShellSet(prefExitMessage, "ERROR: Failed to initialise multisampled FBO");
			return false;
		}
	}

	// Unbind the frame buffer object so rendering returns back to the backbuffer
	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);

	return true;
}

/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occurred
 @Description	Code in InitView() will be called by PVRShell upon
                initialization or after a change in the rendering context.
                Used to initialize variables that are dependent on the rendering
                context (e.g. textures, vertex buffers, etc.)
 ******************************************************************************/
bool OGLES2ColourGrading::InitView()
{
	m_Extensions.LoadExtensions();

	// Initialize the textures used by Print3D.
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	
	if(m_Print3D.SetTextures(0, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}	
		
	// Create the texture
	if(PVRTTextureLoadFromPVR(c_pszMaskTexture, &m_uiMaskTexture) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Failed to load mask texture\n");
		return false;
	}
	
	if(PVRTTextureLoadFromPVR(c_pszBackgroundTexture, &m_uiBackgroundTexture) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Failed to load background texture\n");
		return false;
	}
	
	// Load our 3D texture look up tables
	for(unsigned int i = 0; i < eLast; ++i)
	{
		if(PVRTTextureLoadFromPVR(c_pszLUTs[i], &m_uiLUTs[i]) != PVR_SUCCESS)
		{
			PVRShellSet(prefExitMessage, "ERROR: Failed to load a 3D texture\n");
			return false;
		}

		glTexParameteri(GL_TEXTURE_3D_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_3D_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_3D_OES, GL_TEXTURE_WRAP_R_OES, GL_CLAMP_TO_EDGE);

		glTexParameteri(GL_TEXTURE_3D_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_3D_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}

	// Load the effects
	CPVRTString ErrorStr;
	if(!LoadShaders(ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}
	
	// Create a multisampled FBO if the required extension is supported
	m_eMultisampleMode = eMultisampleExtension_None;
	m_bMultisampledSupported = false;
	m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_ANGLE_framebuffer_multisample");
	m_bMultisampledSupported |= CPVRTgles2Ext::IsGLExtensionSupported("GL_IMG_multisampled_render_to_texture");

	// Create FBOs
	if(!CreateFBO())
	{
		PVRShellSet(prefExitMessage, "Failed to create FBO");
		return false;
	}

	// Check to see if the GL_EXT_discard_framebuffer extension is supported
	m_bDiscard = CPVRTgles2Ext::IsGLExtensionSupported("GL_EXT_discard_framebuffer");
	if(m_bDiscard)
	{
		m_bDiscard = m_Extensions.glDiscardFramebufferEXT != 0;
	}

	// Initialise VBO data
	LoadVbos(bRotate);

	// Calculate the projection and view matrices
	float fAspect = PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight);
	m_mViewProjection = PVRTMat4::PerspectiveFovRH(CAM_FOV, fAspect, CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);
	m_mViewProjection *= PVRTMat4::LookAtRH(PVRTVec3(0.f, 0.f, 150.f), PVRTVec3(0.f), PVRTVec3(0.f, 1.f, 0.f));

	// Enable backface culling and depth test
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

	// Set the clear colour
	glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

	// Store initial time
	m_ulStartTime = PVRShellGetTime();

	return true;
}

/*!****************************************************************************
 @Function		ReleaseView
 @Return		bool		true if no error occurred
 @Description	Code in ReleaseView() will be called by PVRShell when the
                application quits or before a change in the rendering context.
 ******************************************************************************/
bool OGLES2ColourGrading::ReleaseView()
{
	// Frees the texture
	glDeleteTextures(1, &m_uiMaskTexture);
	glDeleteTextures(1, &m_uiBackgroundTexture);
	glDeleteTextures(eLast, m_uiLUTs);
	glDeleteTextures(1, &m_uiTextureToRenderTo);
	glDeleteTextures(1, &m_uiDepthToRenderTo);

	// Release Vertex buffer object.
	glDeleteBuffers(1, &m_ui32FullScreenRectVBO);
	glDeleteBuffers(1, &m_ui32BackgroundVBO);

	// Release effects
	glDeleteShader(m_uiPostVertShader);
	glDeleteShader(m_uiPostFragShader);
	glDeleteShader(m_uiBackgroundFragShader);
	glDeleteShader(m_uiSceneVertShader);
	glDeleteShader(m_uiSceneFragShader);

	glDeleteProgram(m_PostShaderProgram.uiId);
	glDeleteProgram(m_BackgroundShaderProgram.uiId);
	glDeleteProgram(m_SceneShaderProgram.uiId);

	// Tidy up the FBOs and renderbuffers

	// Delete frame buffer objects
	glDeleteFramebuffers(1, &m_uiFBO);
	glDeleteFramebuffers(1, &m_uiFBOMultisampled);

	// Delete our depth buffer
	glDeleteRenderbuffers(1, &m_uiDepthBufferMultisampled);
	glDeleteRenderbuffers(1, &m_uiColourBufferMultisampled);

	// Delete buffer objects
	glDeleteBuffers(m_Mask.nNumMesh, m_puiMaskVBO);
	glDeleteBuffers(m_Mask.nNumMesh, m_puiMaskIBO);

	// Release Print3D Textures
	m_Print3D.ReleaseTextures();

	return true;
}

/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occurred
 @Description	Main rendering loop function of the program. The shell will
                call this function every frame.
                eglSwapBuffers() will be performed by PVRShell automatically.
                PVRShell will also manage important OS events.
                Will also manage relevant OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
 ******************************************************************************/
bool OGLES2ColourGrading::RenderScene()
{
	// Clears the colour buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
	unsigned long ulTime = PVRShellGetTime() - m_ulStartTime;

	// Process input to switch between tone mapping operators
	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		++m_iCurrentLUT;

		if(m_iCurrentLUT > eB)
			m_iCurrentLUT = eA;
	}
	else if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		--m_iCurrentLUT;

		if(m_iCurrentLUT < eA)
			m_iCurrentLUT = eB;
	}
	else if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_flipX = !m_flipX;
	}
	else if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		m_flipY = !m_flipY;
	}

	// Render to our texture
	{
		// Bind our FBO
		glBindFramebuffer(GL_FRAMEBUFFER, m_bMultisampledSupported ? m_uiFBOMultisampled : m_uiFBO);

		// Clear the colour and depth buffer of our FBO surface
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glDisable(GL_CULL_FACE);
		glDisable(GL_DEPTH_TEST);

		// Bind the VBO
		glBindBuffer(GL_ARRAY_BUFFER, m_ui32BackgroundVBO);

		// Use shader program
		glUseProgram(m_BackgroundShaderProgram.uiId);

		// Enable the vertex attribute arrays
		glEnableVertexAttribArray(VERTEX_ARRAY);
		glEnableVertexAttribArray(TEXCOORD_ARRAY);

		// Set the vertex attribute offsets
		glVertexAttribPointer(VERTEX_ARRAY, 4, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
		glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (4 * sizeof(GLfloat)));

		// Bind texture
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiBackgroundTexture);

		// Draw a screen-aligned quad.

		// Draws a non-indexed triangle array
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		// Safely disable the vertex attribute arrays
		glDisableVertexAttribArray(VERTEX_ARRAY);
		glDisableVertexAttribArray(TEXCOORD_ARRAY);

		glEnable(GL_CULL_FACE);
		glEnable(GL_DEPTH_TEST);

		// Use shader program
		glUseProgram(m_SceneShaderProgram.uiId);

		// Rotate the model matrix
		PVRTMat4 mModel = PVRTMat4::RotationY(ulTime * 0.0015f);

		// Calculate model view projection matrix
		PVRTMat4 mMVP = m_mViewProjection * mModel;

		// Feeds Projection Model View matrix to the shaders
		glUniformMatrix4fv(m_SceneShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

		PVRTVec3 vMsLightDir = (PVRTVec3(1, 1, 1) * PVRTMat3(mModel)).normalized();
		glUniform3fv(m_SceneShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr());

		glBindTexture(GL_TEXTURE_2D, m_uiMaskTexture);

		// Now that the uniforms are set, call another function to actually draw the mesh.
		DrawMesh(0);

		// Unbind the VBO
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
		{
			/*
			Give the drivers a hint that we don't want the depth and stencil information stored for future use.

			Note: This training course doesn't have any stencil information so the STENCIL_ATTACHMENT enum
			is used for demonstrations purposes only and will be ignored by the driver.
			*/
			const GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
			m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments);
		}

		// Blit and resolve the multisampled render buffer to the non-multisampled FBO
		if(m_bMultisampledSupported)
		{
			glBindFramebuffer(GL_READ_FRAMEBUFFER_NV, m_uiFBOMultisampled);
			glBindFramebuffer(GL_DRAW_FRAMEBUFFER_NV, m_uiFBO);
			int w = PVRShellGet(prefWidth);
			int h = PVRShellGet(prefHeight);
			int destX0 = m_flipX ? w : 0;
			int destX1 = m_flipX ? 0 : w;
			int destY0 = m_flipY ? h : 0;
			int destY1 = m_flipY ? 0 : h;
			m_Extensions.glBlitFramebufferNV(0, 0, w, h, destX0, destY0, destX1, destY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		}

		// We are done with rendering to our FBO so switch back to the back buffer.
		glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);
	}

	GLenum error = glGetError();

	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);

	error = glGetError();

	// Use shader program
	glUseProgram(m_PostShaderProgram.uiId);

	// Bind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_ui32FullScreenRectVBO);

	error = glGetError();

	// Enable the vertex attribute arrays
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(TEXCOORD_ARRAY);

	error = glGetError();

	// Set the vertex attribute offsets
	glVertexAttribPointer(VERTEX_ARRAY, 4, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);
	glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (4 * sizeof(GLfloat)));

	error = glGetError();

	// Bind texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiTextureToRenderTo);

	error = glGetError();

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_3D_OES, m_uiLUTs[m_iCurrentLUT]);

	error = glGetError();

	// Draw a screen-aligned quad.

	// Draw the left-hand side that shows the scene with the colour grading applied
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
	// Draw the right-hande side showing the scene how it looks without
	glBindTexture(GL_TEXTURE_3D_OES, m_uiLUTs[eIdentity]);
	glDrawArrays(GL_TRIANGLE_STRIP, 2, 4);

	// Safely disable the vertex attribute arrays
	glDisableVertexAttribArray(VERTEX_ARRAY);
	glDisableVertexAttribArray(TEXCOORD_ARRAY);
	
	// Unbind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// Render title
	m_Print3D.DisplayDefaultTitle("Colour grading using 3D textures", c_pszLUTNames[m_iCurrentLUT], ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	
	return true;
}

/*!****************************************************************************
 @Function		DrawMesh
 @Input			i32NodeIndex		Node index of the mesh to draw
 @Description	Draws a SPODMesh after the model view matrix has been set and
				the material prepared.
******************************************************************************/
void OGLES2ColourGrading::DrawMesh(const int i32NodeIndex)
{
	int i32MeshIndex = m_Mask.pNode[i32NodeIndex].nIdx;
	SPODMesh* pMesh = &m_Mask.pMesh[i32MeshIndex];

	// bind the VBO for the mesh
	glBindBuffer(GL_ARRAY_BUFFER, m_puiMaskVBO[i32MeshIndex]);
	// bind the index buffer, won't hurt if the handle is 0
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiMaskIBO[i32MeshIndex]);

	// Enable the vertex attribute arrays
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(NORMAL_ARRAY);
	glEnableVertexAttribArray(TEXCOORD_ARRAY);

	// Set the vertex attribute offsets
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
	glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
	glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);

	// Indexed Triangle list
	glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0);
	
	// Safely disable the vertex attribute arrays
	glDisableVertexAttribArray(VERTEX_ARRAY);
	glDisableVertexAttribArray(NORMAL_ARRAY);
	glDisableVertexAttribArray(TEXCOORD_ARRAY);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

/*!****************************************************************************
 @Function		NewDemo
 @Return		PVRShell*		The demo supplied by the user
 @Description	This function must be implemented by the user of the shell.
                The user should return its PVRShell object defining the
				behaviour of the application.
 ******************************************************************************/
PVRShell* NewDemo()
{
	return new OGLES2ColourGrading();
}

/******************************************************************************
 End of file (OGLES2ColourGrading.cpp)
 ******************************************************************************/

