/*************************************************************************
** Mode_ParaboloidShadowMaps.cpp                                        **
** --------------------------                                           **
**                                                                      **
** This display mode renders a cow inside a Cornell Box with shadows    **
**    from a paraboloid shadow map.  When this display is active, a     **
**    variety of variables are modifiable from the widget window to     **
**    change the behavior of the display.                               **
**                                                                      **
** Chris Wyman (04/06/2012)                                             **
*************************************************************************/

#include "../projectIncludes.h"
#include "Mode_ParaboloidShadowMaps.h"

// A global data structure containing all shared data for this program
extern RenderingData *data;


// Move the light via a slider
void UpdateLightPosition( IGLUVariable *uiFloat )
{
	float pos = ((IGLUFloat *)uiFloat)->GetValue();
	if (pos >=0 && pos<1)
		data->param->lightPos = vec3(5.360,(1.0f-pos)*5.15+0.2,2.795);
	else if (pos >= 1 && pos<2)
		data->param->lightPos = vec3((2.0-pos)*5.360+0.1, 0.2, 2.795);
	else if (pos >= 2 && pos<3)
		data->param->lightPos = vec3( 0.1, (pos-2.0)*5.15+0.2, 2.795);
	else if (pos >= 3 && pos<4)
		data->param->lightPos = vec3( (pos-3.0)*5.360+0.1, 5.35, 2.795);
}

void UpdateLightProjection( void )
{
	data->glsl->parabSMapCreate["nearDist"]   = data->ui->lightNear;
	data->glsl->parabSMapCreate["farDist"]    = data->ui->lightFar;
	data->glsl->parabSMapQuery["nearDist"]    = data->ui->lightNear;
	data->glsl->parabSMapQuery["farDist"]     = data->ui->lightFar;
}

void UpdateVSVResolution( void )
{
	// Identify w & h of padded VSV.  
	//   -> The 0.9999 rounds up, unless inputs are power of 2  (XXX: Works for w & h < 8192)
	data->ui->vsvPadWidth  = 1 << int( log(float(data->ui->vsvWidth))/log(2.0f) + 0.9999 );
	data->ui->vsvPadHeight = 1 << int( log(float(data->ui->vsvHeight))/log(2.0f) + 0.9999 );
	data->ui->vsvPadCoef   = vec2( data->ui->vsvWidth / float(data->ui->vsvPadWidth), 
		                           data->ui->vsvHeight / float(data->ui->vsvPadHeight) );

	// Resize the VSV
	data->fbo->epipolarVoxels->Resize( data->ui->vsvPadWidth, data->ui->vsvPadHeight );

	// OK, resize our temporary buffers we use when creating the VSV.
	int nextBufWidth  = data->fbo->epipolarVoxels->GetRenderableWidth();
	int nextBufHeight = data->fbo->epipolarVoxels->GetRenderableHeight();
	for (int i=11; i>=0; i--)
	{
		data->fbo->voxelMipScan[i]->Resize( nextBufWidth, nextBufHeight );
		if (nextBufWidth > 1) 
			nextBufWidth /= 2;
	}
}