vec4 Grove::getPixelData( const ci::vec2 &position, const CameraPersp &cam )
{
	// bring window space position to fbo space
	vec2 pos = position / vec2( getWindowSize() ) * vec2( mFbo->getSize() );
	
	// sample the fbo to get the pixel data
	gl::ScopedFramebuffer scopedReadFbo( mFbo, GL_READ_FRAMEBUFFER );
	
	Area pickingArea( pos, ivec2( pos ) + ivec2( 1 ) );
	
	gl::readBuffer( GL_COLOR_ATTACHMENT1 );
	
	GLubyte pixels[4];
	//GLint oldPackAlignment;
	//glGetIntegerv( GL_PACK_ALIGNMENT, &oldPackAlignment );
	//glPixelStorei( GL_PACK_ALIGNMENT, 1 );
	gl::readPixels( pickingArea.getX1(), mFbo->getHeight() - pickingArea.getY2(), pickingArea.getWidth(), pickingArea.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0] );
	//glPixelStorei( GL_PACK_ALIGNMENT, oldPackAlignment );
	
	//float unpackedDepth = glm::dot( vec3( pixels[1], pixels[2], pixels[3] ) / 255.0f, vec3( 1.0, 1.0 / 255.0, 1.0 / 65025.0 ) );
	float unpackedDepth = static_cast<float>( pixels[0] ) / 255.0f + ( static_cast<float>( pixels[1] ) / 255.0f * 0.00390625 );
	float data			= static_cast<float>( pixels[2] );
	
	mat4 viewProj = cam.getProjectionMatrix() * cam.getViewMatrix();
	mat4 invViewProj = inverse( viewProj );
	
	vec4 clipSpace;
	clipSpace.x		= ( (float) pos.x / (float) mFbo->getWidth() ) * 2.0f - 1.0f;
	clipSpace.y		= ( 1.0f - (float) pos.y / (float) mFbo->getHeight() ) * 2.0f - 1.0f;
	clipSpace.z		= unpackedDepth * 2.0f - 1.0f;
	clipSpace.w		= 1.0f;
	vec4 worldSpace = invViewProj * clipSpace;
	return vec4( vec3( worldSpace ) / worldSpace.w, data );
}
void ShadowMappingBasic::draw()
{
	renderDepthFbo();

	gl::clear( Color::black() );
	gl::setMatrices( mCam );

	gl::ScopedTextureBind texScope( mShadowMapTex, (uint8_t) 0 );

	vec3 mvLightPos	= vec3( gl::getModelView() * vec4( mLightPos, 1.0f ) ) ;
	mat4 shadowMatrix = mLightCam.getProjectionMatrix() * mLightCam.getViewMatrix();

	mGlsl->uniform( "uShadowMap", 0 );
	mGlsl->uniform( "uLightPos", mvLightPos );
	mGlsl->uniform( "uShadowMatrix", shadowMatrix );
	
	drawScene( false );
    
    // Uncomment for debug
    /*
    gl::setMatricesWindow( getWindowSize() );
    gl::color( 1.0f, 1.0f, 1.0f );
    float size = 0.5f*std::min( getWindowWidth(), getWindowHeight() );
    gl::draw( mShadowMapTex, Rectf( 0, 0, size, size ) );
    */
}
// Sets the current view matrix to fit a fullscreen texture exactly in the camera
void TextParticlesApp::lookAtTexture( const CameraPersp &cam, const ci::vec2 &size  )
{
	auto ctx = gl::context();
	ctx->getModelMatrixStack().back() = mat4();
	ctx->getProjectionMatrixStack().back() = cam.getProjectionMatrix();
	ctx->getViewMatrixStack().back() = cam.getViewMatrix();
	ctx->getViewMatrixStack().back() *= glm::scale( vec3( 1, -1, 1 ) );									// invert Y axis so increasing Y goes down.
	ctx->getViewMatrixStack().back() *= glm::translate( vec3( size.x / 2, (float) - size.y / 2, 0 ) );	// shift origin up to upper-left corner.
}
void ShadowMappingBasic::draw()
{
	renderDepthFbo();

	gl::clear( Color::black() );
	gl::setMatrices( mCam );

	gl::ScopedTextureBind texScope( mShadowMapTex, (uint8_t) 0 );

	vec3 mvLightPos	= vec3( gl::getModelView() * vec4( mLightPos, 1.0f ) ) ;
	mat4 shadowMatrix = mLightCam.getProjectionMatrix() * mLightCam.getViewMatrix();

	mGlsl->uniform( "uShadowMap", 0 );
	mGlsl->uniform( "uLightPos", mvLightPos );
	mGlsl->uniform( "uShadowMatrix", shadowMatrix );
	
	drawScene( false );
}
void ParticleSortingApp::update()
{
    mRotation += 0.0015f;
    
    // Create the matrices
    mat4 modelMatrix = glm::rotate(mRotation, vec3(1.0f, 1.0f, 1.0f));
    modelMatrix = glm::scale(modelMatrix, vec3(mModelScale));
    mat4 modelViewMatrix = mCamera.getViewMatrix() * modelMatrix;
    mat4 modelViewProjectionMatrix = mCamera.getProjectionMatrix() * modelViewMatrix;
    
    // Set the uniform data
    mUniforms.updateData([&]( auto data )
    {
        data.modelViewProjectionMatrix = toMtl(modelViewProjectionMatrix);
        data.modelMatrix = toMtl(modelMatrix);
        return data;
    });

    bitonicSort( false );
}
void CinderProjectionTestApp::draw()
{
	
	// clear out the window with black
	gl::clear( Color( 0, 0, 0 ), true );
	
	
	gl::enableDepthRead();
	gl::enableDepthWrite();
	
	//gl::enableAlphaBlending();
	
	
	if ( mActiveCam == CAM_LOOK )
	{
		gl::setMatrices( mLookCam );
		gl::rotate( mArcball.getQuat() );
	}
	else if ( mActiveCam == CAM_SWEET )
		gl::setMatrices( mSweetCam );
	else if ( mActiveCam == CAM_PROJ )
		gl::setMatrices( mProjCam );
	
	// Green = Cam from 'sweet spot'
	gl::color( Color( 0, 1, 0 ) );
	gl::drawFrustum( mSweetCam );
	
	// Cyan = Cam from projector
	gl::color( Color( 0, 1, 1 ) );
	gl::drawFrustum( mProjCam );
	
	// Draw a grid in the yz plane
	gl::color( Color( 0.2f, 0.2f, 0.2f ) );
	gl::pushMatrices();
	gl::scale(Vec3f::one() /5 );
	for (int i=0; i<=20; ++i)
	{
		gl::drawLine(Vec3f(-100.0f+(i*10.0f), 0.0f, -100.0f),Vec3f(-100.0f+(i*10.0f), 0.0f, 100.0f));
		gl::drawLine(Vec3f(-100.0f, 0.0f, -100.0f+(i*10.0f)),Vec3f(100.0f, 0.0f, -100.0f+(i*10.0f)));
	}
	gl::popMatrices();
	
	gl::color( Color::white() );
	
	//glEnable( GL_LIGHTING );
	//glEnable( GL_LIGHT0 );
	//GLfloat light_position[] = { mMousePos.x, mMousePos.y, 75.0f, 1.0f };
	//glLightfv( GL_LIGHT0, GL_POSITION, light_position );
	
	
	// Bind texture, so it will be avaible to the fragment shader.
	mTexture.bind();
    // Bind the texture projection shader, let the magic happen!
    mProjShader.bind();
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    mProjShader.uniform("projMap", 0);
    mProjShader.uniform("TexGenMat", mSweetCam.getProjectionMatrix() );
    mProjShader.uniform("InvViewMat", mProjCam.getInverseModelViewMatrix() );
	mProjShader.uniform("texScaling", mTextureScaling );
	//mProjShader.uniform("alpha", 0.6f );
    //mProjShader.uniform("scaling", 10.0f );
	
	gl::pushModelView();
	//gl::rotate( Vec3f( 0.0f, 45.0f, 0.0f ) );
	gl::rotate( mCubeRotation );
	gl::translate( Vec3f(0.0f, 0.5f * mCubeSize, 0.0f) );
	gl::drawColorCube( Vec3f::zero(), Vec3f::one() * mCubeSize );
	gl::popModelView();
	
	
    
    mProjShader.unbind();
	mTexture.unbind();
	
	glDisable( GL_LIGHTING );
	
	gl::color( Color::white() );
	
	
	// Draw the interface
	params::InterfaceGl::draw();
}