

/***********************************************************************************/
/*																				   */
/*	  Copyright 2003 University of Texas at Austin                                 */
/*	  Authors: Dr C Bajaj bajaj@cs.utexas.edu,                                     */
/*             S K Vinay  skvinay@cs.utexas.edu                                    */
/*             Anthony Thane thanea@ices.utexas.edu                                */
/*																				   */
/*    This program is free software; you can redistribute it and/or modify         */
/*    it under the terms of the GNU General Public License as published by         */
/*    the Free Software Foundation; either version 2 of the License, or            */
/*    (at your option) any later version.                                          */
/*																				   */
/*    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 the                */
/*    GNU General Public License for more details.                                 */
/*																				   */
/*    You should have received a copy of the GNU General Public License			   */
/*    along with this program; if not, write to the Free Software                  */
/*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    */
/*                                                                                 */
/***********************************************************************************/

// StickRenderer.h: interface for the StickRenderer class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_STICKRENDERER_H__55F98E43_5A95_4CB7_9F7D_B6ADBD4D0FA9__INCLUDED_)
#define AFX_STICKRENDERER_H__55F98E43_5A95_4CB7_9F7D_B6ADBD4D0FA9__INCLUDED_

#include <Cg/cgGL.h>
#include <stdio.h>
#include "Texture.h"
#include "ExpandableBuffer.h"
#include "MyExtensions.h"

namespace CCVImposterRenderer {

	class StickRenderer  
	{
	public:
		StickRenderer( MyExtensions* extensions );
		virtual ~StickRenderer();
		
		void clearSticks();
		inline void addStick(float x1, float y1, float z1, float x2, float y2, float z2, float radius, 
			float red1, float green1, float blue1,
			float red2, float green2, float blue2);
		int getNumSticks() const;
		void initRenderer( bool drawFunction );
		void renderBuffer( bool useHardwareBuffer, bool useFunctionOnSurface, double* rotations, double* translations, int numberOfTransformations, bool randomizeColors );
                static void forceMeshRendering(bool status) { m_UseGLFallback = status; }
	protected:
		bool initCG(bool drawFunction);
		bool initExtensions();
		void initDefaults( MyExtensions* extensions );

		bool m_Initialized;
                static bool m_UseGLFallback;

		// profiles
		CGprofile m_VertexProfile;
		CGprofile m_FragmentProfile;

		CGprogram m_VertexProgram;
		CGparameter m_ModelViewITParam;
		CGparameter m_ModelViewInverseParam;
		CGparameter m_ModelViewProjParam;
		CGparameter m_ModelViewParam;
		CGparameter m_ProjParam;

		CGprogram m_FragmentProgram;
		CGparameter m_MainColorParam;
		CGparameter m_NormalMapParam;
		CGparameter m_DepthMapParam;
		Texture* m_TextureNormalMap;
		Texture* m_TextureDepthMap;

		// the buffers
		ExpandableBuffer<GLfloat> m_TextureCoord1;
		ExpandableBuffer<GLfloat> m_TextureCoord2;
		ExpandableBuffer<GLfloat> m_Position;
		ExpandableBuffer<GLfloat> m_Color;

		unsigned int m_NumSticks;
		MyExtensions* m_Extensions;
	};

	inline void StickRenderer::addStick(
		float x1, float y1, float z1, 
		float x2, float y2, float z2, 
		float radius, 
		float red1, float green1, float blue1,
		float red2, float green2, float blue2)
	{
		double length = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2);
		if( length > 50 ) return;

		bool result = true;
		// position - stores the offsets
		result &= m_Position.add(0);
		result &= m_Position.add(-1);
		result &= m_Position.add(radius);
		result &= m_Position.add(1);

		result &= m_Position.add(0);
		result &= m_Position.add(1);
		result &= m_Position.add(radius);
		result &= m_Position.add(1);

		result &= m_Position.add(1);
		result &= m_Position.add(1);
		result &= m_Position.add(radius);
		result &= m_Position.add(1);

		result &= m_Position.add(1);
		result &= m_Position.add(-1);
		result &= m_Position.add(radius);
		result &= m_Position.add(1);

		// texturecoord - stores the 2 end points
		result &= m_TextureCoord1.add(x1);
		result &= m_TextureCoord1.add(y1);
		result &= m_TextureCoord1.add(z1);
		result &= m_TextureCoord1.add(1);
		result &= m_TextureCoord1.add(x1);
		result &= m_TextureCoord1.add(y1);
		result &= m_TextureCoord1.add(z1);
		result &= m_TextureCoord1.add(1);
		result &= m_TextureCoord1.add(x1);
		result &= m_TextureCoord1.add(y1);
		result &= m_TextureCoord1.add(z1);
		result &= m_TextureCoord1.add(1);
		result &= m_TextureCoord1.add(x1);
		result &= m_TextureCoord1.add(y1);
		result &= m_TextureCoord1.add(z1);
		result &= m_TextureCoord1.add(1);

		result &= m_TextureCoord2.add(x2);
		result &= m_TextureCoord2.add(y2);
		result &= m_TextureCoord2.add(z2);
		result &= m_TextureCoord2.add(1);
		result &= m_TextureCoord2.add(x2);
		result &= m_TextureCoord2.add(y2);
		result &= m_TextureCoord2.add(z2);
		result &= m_TextureCoord2.add(1);
		result &= m_TextureCoord2.add(x2);
		result &= m_TextureCoord2.add(y2);
		result &= m_TextureCoord2.add(z2);
		result &= m_TextureCoord2.add(1);
		result &= m_TextureCoord2.add(x2);
		result &= m_TextureCoord2.add(y2);
		result &= m_TextureCoord2.add(z2);
		result &= m_TextureCoord2.add(1);

		// color
		result &= m_Color.add(red1);
		result &= m_Color.add(green1);
		result &= m_Color.add(blue1);
		result &= m_Color.add(0.4f);

		result &= m_Color.add(red1);
		result &= m_Color.add(green1);
		result &= m_Color.add(blue1);
		result &= m_Color.add(0.0f);

		result &= m_Color.add(red2);
		result &= m_Color.add(green2);
		result &= m_Color.add(blue2);
		result &= m_Color.add(0.0f);

		result &= m_Color.add(red2);
		result &= m_Color.add(green2);
		result &= m_Color.add(blue2);
		result &= m_Color.add(0.4f);

		if (!result) {
			printf("Warning, could not add Stick");
		}

		m_NumSticks++;
	}

};

#endif // !defined(AFX_STICKRENDERER_H__55F98E43_5A95_4CB7_9F7D_B6ADBD4D0FA9__INCLUDED_)
