******************************************************************
Postprocessing Class by Nils Daumann (nils_daumann@online.de)
******************************************************************
Version: 0.1

******************************************************************
Thanks
******************************************************************
I especially want to thank "thephoenix" for cleaning up my code
and for answering to my endless beginner questions.
But I also want to thank everyone else answering my questions.


******************************************************************
Overview
******************************************************************
This is a c++ class to make postprocessing in Irrlicht a lot
more comfortable.
A very important concept of this class is to make the chaining
of several shaders easy.

I also want to provide a collection of shaders supporting both,
OpenGL and DirectX. They can be found in the "Shaders" folder.
Please read the ReadMe there as well.

The requirements are OpenGl 2.0 and/or DirectX9.0c with support
for GLSL/HLSL. Shadermodel 1.1 is needed for every effect.
Higher versions are usually needed depending on the shaders.
I would recomment to use postprocessing only if at least
shadermodel 2.0 is supported by the hardware.

If you need more information as this ReadMe provides,
look at the code.


******************************************************************
How to implement it into an existing project
******************************************************************
1) Copy Postprocessing.h, Postprocessing.cpp, PP_GL_Vertex.fx
   and PP_DX_Vertex.fx into your projectfolder and include
   Postprocessing.h into you project.

2) Create an instance of the PostProcessing class:
	PostProcessing *pp_main = new PostProcessing
		(
		smgr,			//pointer to the scene manager
		"PP_GL_Invert.fx",	//the GLSL shader file
		"PP_DX_Invert.fx",	//the HLSL shader file
		video::EPST_PS_2_0,	//pixel shader version
		512,			//horizontal resolution
		256			//vertical resolution
		);

3) Integrate the postprocessing into the rendering process:
	driver->beginScene(true, true, video::SColor(255,150,180,255));
	
	//set the rendertarget to the first postprocessing texture
	driver->setRenderTarget(pp_main->getFirstMap(),
				true, true,
				video::SColor(255,150,180,255));
	
	//draw the meshes
	smgr->drawAll();
	
	//set the rendertarget back to NULL
	driver->setRenderTarget(0);
	
	//render the effect
	pp_main->renderEffect();
	
	//render the gui and similar things here!

	driver->endScene();

4) You can add more effects through calling pp_main->addMaterial() once:
	pp_main->addMaterial
		(
		"PP_GL_Invert.fx",	//the GLSL shader file
		"PP_DX_Invert.fx",	//the HLSL shader file
		video::EPST_PS_2_0,	//pixel shader version
		512,			//horizontal resolution
		256			//vertical resolution
		);
   This returns a pointer to a new instance of the PostProcessing class
   which has to be stored if you want to add another shader to the chain.
   The rendering is done automaticaly.


******************************************************************
How to create your own shaders
******************************************************************
Create a version of the shader in GLSL and one in HLSL and
save them in seperate files.
The shaderfunction has to be called "main".
There is a maximum of 8 parameters and two textures
to be passed to the shader.
You can access the parameters through:
	uniform vec4 vecValues[2];	//in GLSL
	float4 vecValues[2];		//in HLSL

The GLSL samplers have to be called texture1 and texture2:
	uniform sampler2D texture1;
	uniform sampler2D texture2;

The samplers can be accesed in a HLSL shader through the registers:
	sampler2D firstSampler : register(s0);
	sampler2D secondSampler : register(s1);

The texture coordinates can be accesed through
"gl_TexCoord[0]"(GLSL) or "TEXCOORD0" (HLSL)


******************************************************************
ToDo List
******************************************************************
- make it easy to add shaders into an effect chain
- make it easy to remove a shader from within a chain
- make it possible to add a shader to the end of a chain
  without storing the pointer to the previous element
- make a function to refresh the texture sizes on a resolution change
- allow an infinate number of values for the shader
- allow sending an infinate number of matrices to the shader
- allow more than two textures
- fallback
- get rid of the need to pass both, a GLSL and a HLSL shader file
- automatic disabling of postprocessing if a software renderer is used
- get rid of the error the HLSL invert shader writes into the console
- everything else I may come up with when using the class

- tell me what you are missing and I will try to add it as well!


******************************************************************
License
******************************************************************
Copyright (c) 2008 Nils Daumann
 
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
 
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.