/*======================================================================================

	Program:		Range Imaging Toolkit (RITK)
	Module:			ritkOpenGLFloatVolumeCudaRayCastEntity.h
	Version:		$Revision: 2908 $
	Date:			$Date: 2012-04-03 22:28:42 +0200 (Di, 03 Apr 2012) $

	Copyright (c) 2010-2011
	Pattern Recognition Lab, 
    University Erlangen-Nuremberg, Germany
    All rights reserved.

	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 RITKCopyright.txt for more information.

	http://www5.informatik.uni-erlangen.de/research/software/ritk

========================================================================================*/


#ifndef RITKOPENGLFLOATVOLUMECUDARAYCASTENTITY_H__
#define RITKOPENGLFLOATVOLUMECUDARAYCASTENTITY_H__

#if defined(WIN32)
	#include <windows.h>
	// Due to explicit template instantiation
	#pragma warning(disable : 4661)
#endif


#include <GL/glu.h>

#include "ritkCuda.h"
#include "ritkVisualization.h"
#include "ritkOpenGLVolumeRayCastEntity.h"
#include "ritkOpenGLFloatVolumeRayCastControlUnit.h"
#include "ritkCudaRayCaster.h"


namespace ritk
{

/**	@ingroup	Cuda
 *	@class		OpenGLFloatVolumeCudaRayCastEntity
 *	@author		Jakob Wasza
 *	@brief		Float volume ray casting
 *
 *	@details
 */
class CUDA_EXPORT OpenGLFloatVolumeCudaRayCastEntity : public OpenGLVolumeRayCastEntity<itk::Image<float,3>, itk::Image<float,2> >
{
	Q_OBJECT

public:
	/**	@name	Standard ITK typedefs */
	//@{
	typedef OpenGLFloatVolumeCudaRayCastEntity										Self;
	typedef OpenGLVolumeRayCastEntity<itk::Image<float,3>, itk::Image<float,2> >	Superclass;
	typedef itk::SmartPointer<Self>													Pointer;
	typedef itk::SmartPointer<const Self>											ConstPointer;
	//@}

	/**	@name	Volume and image typedefs */
	//@{
	typedef Superclass::VolumeType					FloatVolumeType;
	typedef FloatVolumeType::Pointer				FloatVolumePointer;
	typedef FloatVolumeType::ConstPointer			FloatVolumeConstPointer;
	typedef Superclass::OutputImageType				FloatProjectionImageType;
	typedef FloatProjectionImageType::Pointer		FloatProjectionImagePointer;
	typedef FloatProjectionImageType::ConstPointer	FloatProjectionImageConstPointer;
	//@}

	/**	@name	The ray caster */
	//@{
	typedef Superclass::RayCasterType			RayCasterType;
	typedef Superclass::RayCasterPointer		RayCasterPointer;
	//@}

	/// RTTI
	itkTypeMacro(OpenGLFloatVolumeRayCastEntity, OpenGLVolumeRayCastEntity);

	/// Object creation
	itkNewMacro(Self);

	/// Rendering
	virtual void PostProcessAndRender();

	/// The controlunit of this entity.
	virtual QDockWidget* GetControlUnit() const;

protected:
	/// Constructor
	OpenGLFloatVolumeCudaRayCastEntity();
	/// Destructor
	virtual ~OpenGLFloatVolumeCudaRayCastEntity();

	/**	@name The Cuda ray caster */
	//@{
	typedef CudaRayCaster<FloatVolumeType, FloatProjectionImageType> CudaRayCasterType;
	//@}

	/// Initialize all OpenGL related members
	virtual void InitGL();
	/// Release all OpenGL related members
	virtual void CloseGL();

	/// Load a shader
	virtual GLuint LoadShader(const char *Program, bool VertexFlag);

protected slots:
	/// Set whether to render the bounding box
	void RenderBoundingBox(bool);
	/// Set the LUT to render
	void SetLUT(int id);

protected:
	/// Flag to indicate initialization
	bool m_InitFlag;

	/// The control unit
	OpenGLFloatVolumeRayCastControlUnit *m_ControlUnit;

	/// The texture
	GLuint m_Texture;

	/// The LUT texture
	GLuint m_LUTTexture;

	/**	@name Shader */
	//@{
	/// The shader program
	GLuint m_ShaderProgram;
	/// Handles to the shader objects
	std::vector<GLuint> m_ShaderHandles;
	//@}

private:
	/// purposely not implemented
	OpenGLFloatVolumeCudaRayCastEntity(Self&); 
	/// purposely not implemented
	void operator=(const Self&); 
};

} // ritk

#endif // RITKOPENGLFLOATVOLUMERAYCASTENTITY_H__
