/*****************************************************************************/
/*                             ______________________                        */
/*                            / _ _ _ _ _ _ _ _ _ _ _)                       */
/*            ____  ____  _  / /__  __  _____  __                            */
/*           (_  _)( ___)( \/ /(  \/  )(  _  )(  )                           */
/*             )(   )__)  )  (  )    (  )(_)(  )(__                          */
/*            (__) (____)/ /\_)(_/\/\_)(_____)(____)                         */
/*            _ _ _ _ __/ /                                                  */
/*           (___________/                     ___  ___                      */
/*                                      \  )| |   ) _ _|\   )                */
/*                                 ---   \/ | |  / |___| \_/                 */
/*                                                       _/                  */
/*                                                                           */
/*   Copyright (C) The University of Texas at Austin                         */
/*                                                                           */
/*     Author:     Vinay Siddavanahalli <skvinay@cs.utexas.edu>   2004-2005  */
/*                                                                           */
/*     Principal Investigator: Chandrajit Bajaj <bajaj@ices.utexas.edu>      */
/*                                                                           */
/*         Professor of Computer Sciences,                                   */
/*         Computational and Applied Mathematics Chair in Visualization,     */
/*         Director, Computational Visualization Center (CVC),               */
/*         Institute of Computational Engineering and Sciences (ICES)        */
/*         The University of Texas at Austin,                                */
/*         201 East 24th Street, ACES 2.324A,                                */
/*         1 University Station, C0200                                       */
/*         Austin, TX 78712-0027                                             */
/*         http://www.cs.utexas.edu/~bajaj                                   */
/*                                                                           */
/*         http://www.ices.utexas.edu/CVC                                    */
/*  This software comes with a license. Using this code implies that you     */
/*  read, understood and agreed to all the terms and conditions in that      */
/*  license.                                                                 */
/*                                                                           */
/*  We request that you agree to acknowledge the use of the software that    */
/*  results in any published work, including scientific papers, films and    */
/*  videotapes by citing the reference listed below                          */
/*                                                                           */
/*    C. Bajaj, P. Djeu, V. Siddavanahalli, A. Thane,                        */
/*    Interactive Visual Exploration of Large Flexible Multi-component       */
/*    Molecular Complexes,                                                   */
/*    Proc. of the Annual IEEE Visualization Conference, October 2004,       */
/*    Austin, Texas, IEEE Computer Society Press, pp. 243-250.               */
/*                                                                           */
/*****************************************************************************/
// HelixRenderer.cpp: implementation of the HelixRenderer class.
//
//////////////////////////////////////////////////////////////////////

#include "HelixRenderer.h"
#include "GlobalCGContext.h"
#include "Vector.h"
#include "cgGLHelixVertexShader.h"
#include "cgGLHelixFragmentShader.h"
#include "MeshHelixRenderer.h"

using CCVImposterRenderer::HelixRenderer;

bool HelixRenderer::m_UseGLFallback = false;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

HelixRenderer::HelixRenderer( MyExtensions* extensions )
{
	initDefaults( extensions );
}

void HelixRenderer::initDefaults( MyExtensions* extensions )
{
	m_Initialized = false;
	m_NumberOfHelices = 0;
	m_Extensions = extensions;
	m_VertexProgram = 0;
	m_FragmentProgram = 0;
}

HelixRenderer::~HelixRenderer()
{
	if( m_FragmentProgram ) cgDestroyProgram(m_FragmentProgram);
	if( m_VertexProgram ) cgDestroyProgram(m_VertexProgram);
}

void HelixRenderer::clear()
{
	m_TextureCoord1.clearBuffer();
	m_TextureCoord2.clearBuffer();
	m_Color.clearBuffer();
	m_Position.clearBuffer();

	m_NumberOfHelices = 0;
}

int HelixRenderer::getNum() const
{
	return m_NumberOfHelices;
}

void HelixRenderer::initRenderer( bool drawFunction )
{
        // without extensions we cannot operate at all
        if(!initExtensions()) {
                m_Initialized = false;
                fprintf(stderr, "ERROR: OpenGL extensions unavailable, update your graphics drivers.\n");
                return;
        }
        // if FP30 isn't present we will use a different branch of every render method
        if(!initCG( drawFunction )) {
                fprintf(stderr, "WARNING: FP30 not found, falling back on GL Rendering.\n");
                m_UseGLFallback = true;
        }        
	m_Initialized = true;
}

void HelixRenderer::renderOnce()
{
        // MESH RENDERING
        if(m_UseGLFallback) {
                MeshHelixRenderer::DrawHelixBuffer(m_Position, m_Color, m_TextureCoord1, m_TextureCoord2);
        }
        // CG RENDERING
        else {
                // rendering individually, not as a buffer because we need to send parameters which vary
                // per cylinder and there is no more space  left in those arrays!
                int i;
                for( i=0; i<(int)m_NumberOfHelices; i++ )
                {
                        int index = 16*i;
                        
                        float radius = m_Position.get(index+2);
                        CCVOpenGLMath::Vector ePoint = CCVOpenGLMath::Vector( m_TextureCoord1.get(index+0),
                                                                              m_TextureCoord1.get(index+1),
                                                                              m_TextureCoord1.get(index+2),
                                                                              1 );
                        CCVOpenGLMath::Vector begPoint = CCVOpenGLMath::Vector( m_TextureCoord2.get(index+0),
                                                                                m_TextureCoord2.get(index+1),
                                                                                m_TextureCoord2.get(index+2),
                                                                                1 );
                        CCVOpenGLMath::Vector axis = ePoint - begPoint;
                        float helixLength = axis.norm();
                        
                        axis = axis.normalize();
                        
                        CCVOpenGLMath::Vector refVector(0,0,0,0);
                        if (axis[0] < 0.1 && axis[0] > -0.1 )
                        {
                                refVector[1] = axis[2];
                                refVector[2] = -1*axis[1];
                        }
                        else
                        {
                                refVector[0] = axis[1];
                                refVector[1] = -1*axis[0];
                        }
                        refVector = refVector.normalize();
                        
                        CCVOpenGLMath::Vector helixDCsCrossRefVector = axis.cross( refVector );
                        helixDCsCrossRefVector = helixDCsCrossRefVector.normalize();
                        
                        cgGLSetParameter3f(m_HelixDCs, axis[0], axis[1], axis[2]);
                        cgGLSetParameter3f(m_RefVector, refVector[0], refVector[1], refVector[2]); // vector
                        cgGLSetParameter3f(m_HelixDCsCrossRefVector, helixDCsCrossRefVector[0], helixDCsCrossRefVector[1], helixDCsCrossRefVector[2]);
                        cgGLSetParameter1f(m_LengthOfHelix, helixLength);
                        
                        int c;
                        for( c =0; c<2; c++ )
                        {
                                cgGLSetParameter4f(m_EndPoint1, begPoint[0], begPoint[1], begPoint[2], radius); // point
                                radius = radius * -1;
                                glBegin( GL_QUADS );
                                
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE0_ARB, m_TextureCoord1.get(index+0), m_TextureCoord1.get(index+1), m_TextureCoord1.get(index+2), m_TextureCoord1.get(index+3) );
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE1_ARB, m_TextureCoord2.get(index+0), m_TextureCoord2.get(index+1), m_TextureCoord2.get(index+2), m_TextureCoord2.get(index+3) );
                                glColor4f(m_Color.get(index+0), m_Color.get(index+1), m_Color.get(index+2), m_Color.get(index+3) );
                                glVertex4f(m_Position.get(index+0), m_Position.get(index+1), m_Position.get(index+2), m_Position.get(index+3) );
                                
                                index += 4;
                                
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE0_ARB, m_TextureCoord1.get(index+0), m_TextureCoord1.get(index+1), m_TextureCoord1.get(index+2), m_TextureCoord1.get(index+3) );
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE1_ARB, m_TextureCoord2.get(index+0), m_TextureCoord2.get(index+1), m_TextureCoord2.get(index+2), m_TextureCoord2.get(index+3) );
                                glColor4f(m_Color.get(index+0), m_Color.get(index+1), m_Color.get(index+2), m_Color.get(index+3) );
                                glVertex4f(m_Position.get(index+0), m_Position.get(index+1), m_Position.get(index+2), m_Position.get(index+3) );
                                
                                index += 4;
                                
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE0_ARB, m_TextureCoord1.get(index+0), m_TextureCoord1.get(index+1), m_TextureCoord1.get(index+2), m_TextureCoord1.get(index+3) );
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE1_ARB, m_TextureCoord2.get(index+0), m_TextureCoord2.get(index+1), m_TextureCoord2.get(index+2), m_TextureCoord2.get(index+3) );
                                glColor4f(m_Color.get(index+0), m_Color.get(index+1), m_Color.get(index+2), m_Color.get(index+3) );
                                glVertex4f(m_Position.get(index+0), m_Position.get(index+1), m_Position.get(index+2), m_Position.get(index+3) );
                                
                                index += 4;
                                
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE0_ARB, m_TextureCoord1.get(index+0), m_TextureCoord1.get(index+1), m_TextureCoord1.get(index+2), m_TextureCoord1.get(index+3) );
                                m_Extensions->glMultiTexCoord4dARB(GL_TEXTURE1_ARB, m_TextureCoord2.get(index+0), m_TextureCoord2.get(index+1), m_TextureCoord2.get(index+2), m_TextureCoord2.get(index+3) );
                                glColor4f(m_Color.get(index+0), m_Color.get(index+1), m_Color.get(index+2), m_Color.get(index+3) );
                                glVertex4f(m_Position.get(index+0), m_Position.get(index+1), m_Position.get(index+2), m_Position.get(index+3) );
                                
                                glEnd();
                                index -= 12;
                        }
                }
        }
}

void HelixRenderer::renderBuffer( bool useHardwareBuffer, bool useFunctionOnSurface, double* rotations, double* translations, int numberOfTransformations, bool randomizeColors )
{
        if(m_UseGLFallback) {
                // bail if not initialized
                if (!m_Initialized) {
                        return;
                }
                
                if (m_NumberOfHelices==0) {
                        // we are done
                        return;
                }
                
                glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
                
                // Set up for Stick rendering
                // cgGLEnableProfile(m_VertexProfile);
                // cgGLBindProgram(m_VertexProgram);
                
                // cgGLEnableProfile(m_FragmentProfile);
                // cgGLBindProgram(m_FragmentProgram);
                
                // glDisable(GL_CULL_FACE);
                // glDisable(GL_LIGHTING);
                // glEnable(GL_ALPHA_TEST);
                // glAlphaFunc(GL_GREATER, 0.5 );
                // glEnable(GL_COLOR_SUM_ARB);
                
                glDisable(GL_CULL_FACE);
                glEnable(GL_LIGHTING);
                glEnable(GL_ALPHA_TEST);
                glAlphaFunc(GL_GREATER, 0.5 );
                glEnable(GL_COLOR_SUM_ARB);
                
                // cgGLEnableTextureParameter(m_NormalMapParam);
                // cgGLEnableTextureParameter(m_DepthMapParam);
                // cgGLEnableTextureParameter(m_OpacityMapParam);
                
                m_Extensions->glSecondaryColor3fEXT(0.,0.,1.);
                
                // cgGLSetParameter4f(m_MainColorParam, 0.7f, 0.7f, 0.7f, 1.0f); // gray
                
                if( rotations && translations && (numberOfTransformations>0) )
                {
                        int i;
                        for( i=0; i<numberOfTransformations; i++ )
                        {
                                GLfloat trans[16];
                                trans[0]  = (GLfloat)rotations[i*9+0];
                                trans[1]  = (GLfloat)rotations[i*9+3];
                                trans[2]  = (GLfloat)rotations[i*9+6];
                                trans[3]  = (GLfloat)translations[i*3+0];
                                trans[4]  = (GLfloat)rotations[i*9+1];
                                trans[5]  = (GLfloat)rotations[i*9+4];
                                trans[6]  = (GLfloat)rotations[i*9+7];
                                trans[7]  = (GLfloat)translations[i*3+1];
                                trans[8]  = (GLfloat)rotations[i*9+2];
                                trans[9]  = (GLfloat)rotations[i*9+5];
                                trans[10] = (GLfloat)rotations[i*9+8];
                                trans[11] = (GLfloat)translations[i*3+2];
                                trans[12] = (GLfloat)0;
                                trans[13] = (GLfloat)0;
                                trans[14] = (GLfloat)0;
                                trans[15] = (GLfloat)1;
                                // perform the rotation needed
                                glMatrixMode(GL_MODELVIEW);
                                glPushMatrix();
                                glMultMatrixf(trans);
                                
                                // cgGLSetStateMatrixParameter(m_ModelViewITParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE);
                                // cgGLSetStateMatrixParameter(m_ModelViewProjParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                                // cgGLSetStateMatrixParameter(m_ModelViewParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);	
                                // cgGLSetStateMatrixParameter(m_ProjParam, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                                // cgGLSetStateMatrixParameter(m_ModelViewInverseParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE);	
                                // cgGLSetStateMatrixParameter(m_ModelViewProjInverseParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_INVERSE);
                                
                                renderOnce();
                                glPopMatrix();
                                
                        }
                }
                else
                {
                        // cgGLSetStateMatrixParameter(m_ModelViewITParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE);
                        // cgGLSetStateMatrixParameter(m_ModelViewProjParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                        // cgGLSetStateMatrixParameter(m_ModelViewParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);	
                        // cgGLSetStateMatrixParameter(m_ProjParam, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                        // cgGLSetStateMatrixParameter(m_ModelViewInverseParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE);	
                        // cgGLSetStateMatrixParameter(m_ModelViewProjInverseParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_INVERSE);
                        
                        renderOnce();
                }
                
                // cgGLDisableTextureParameter(m_OpacityMapParam);
                // cgGLDisableTextureParameter(m_DepthMapParam);
                // cgGLDisableTextureParameter(m_NormalMapParam);
                
                glDisable(GL_DEPTH_TEST);
                glDisable(GL_LIGHTING);
                glDisable(GL_BLEND);
                glDisable(GL_COLOR_SUM_ARB);
                
                // cgGLDisableProfile(m_VertexProfile);
                // cgGLDisableProfile(m_FragmentProfile); 	
                
                glPopAttrib();
        }
        else
        {
                // bail if not initialized
                if (!m_Initialized) {
                        return;
                }
                
                if (m_NumberOfHelices==0) {
                        // we are done
                        return;
                }
                
                glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT);
                
                // Set up for Stick rendering
                cgGLEnableProfile(m_VertexProfile);
                cgGLBindProgram(m_VertexProgram);
                
                cgGLEnableProfile(m_FragmentProfile);
                cgGLBindProgram(m_FragmentProgram);
                
                glDisable(GL_CULL_FACE);
                glDisable(GL_LIGHTING);
                glEnable(GL_ALPHA_TEST);
                glAlphaFunc(GL_GREATER, 0.5 );
                glEnable(GL_COLOR_SUM_ARB);
                
                
                cgGLEnableTextureParameter(m_NormalMapParam);
                cgGLEnableTextureParameter(m_DepthMapParam);
                cgGLEnableTextureParameter(m_OpacityMapParam);
                
                m_Extensions->glSecondaryColor3fEXT(0.,0.,1.);
                
                cgGLSetParameter4f(m_MainColorParam, 0.7f, 0.7f, 0.7f, 1.0f); // gray
                
                if( rotations && translations && (numberOfTransformations>0) )
                {
                        int i;
                        for( i=0; i<numberOfTransformations; i++ )
                        {
                                GLfloat trans[16];
                                trans[0]  = (GLfloat)rotations[i*9+0];
                                trans[1]  = (GLfloat)rotations[i*9+3];
                                trans[2]  = (GLfloat)rotations[i*9+6];
                                trans[3]  = (GLfloat)translations[i*3+0];
                                trans[4]  = (GLfloat)rotations[i*9+1];
                                trans[5]  = (GLfloat)rotations[i*9+4];
                                trans[6]  = (GLfloat)rotations[i*9+7];
                                trans[7]  = (GLfloat)translations[i*3+1];
                                trans[8]  = (GLfloat)rotations[i*9+2];
                                trans[9]  = (GLfloat)rotations[i*9+5];
                                trans[10] = (GLfloat)rotations[i*9+8];
                                trans[11] = (GLfloat)translations[i*3+2];
                                trans[12] = (GLfloat)0;
                                trans[13] = (GLfloat)0;
                                trans[14] = (GLfloat)0;
                                trans[15] = (GLfloat)1;
                                // perform the rotation needed
                                glMatrixMode(GL_MODELVIEW);
                                glPushMatrix();
                                glMultMatrixf(trans);
                                
                                cgGLSetStateMatrixParameter(m_ModelViewITParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE);
                                cgGLSetStateMatrixParameter(m_ModelViewProjParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                                cgGLSetStateMatrixParameter(m_ModelViewParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);	
                                cgGLSetStateMatrixParameter(m_ProjParam, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                                cgGLSetStateMatrixParameter(m_ModelViewInverseParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE);	
                                cgGLSetStateMatrixParameter(m_ModelViewProjInverseParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_INVERSE);
                                
                                renderOnce();
                                glPopMatrix();
                                
                        }
                }
                else
                {
                        cgGLSetStateMatrixParameter(m_ModelViewITParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE_TRANSPOSE);
                        cgGLSetStateMatrixParameter(m_ModelViewProjParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                        cgGLSetStateMatrixParameter(m_ModelViewParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);	
                        cgGLSetStateMatrixParameter(m_ProjParam, CG_GL_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
                        cgGLSetStateMatrixParameter(m_ModelViewInverseParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_INVERSE);	
                        cgGLSetStateMatrixParameter(m_ModelViewProjInverseParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_INVERSE);
                        
                        renderOnce();
                }
                
                cgGLDisableTextureParameter(m_OpacityMapParam);
                cgGLDisableTextureParameter(m_DepthMapParam);
                cgGLDisableTextureParameter(m_NormalMapParam);
                
                glDisable(GL_BLEND);
                glDisable(GL_COLOR_SUM_ARB);
                
                cgGLDisableProfile(m_VertexProfile);
                cgGLDisableProfile(m_FragmentProfile); 	
                
                glPopAttrib();
        }
}

bool HelixRenderer::initCG( bool drawFunction )
{
	if ( cgGLIsProfileSupported(CG_PROFILE_VP20) ) 
		m_VertexProfile = CG_PROFILE_VP20;
	else 
		return false;
        
	if ( cgGLIsProfileSupported(CG_PROFILE_FP30) ) 
		m_FragmentProfile = CG_PROFILE_FP30;
	else 
		return false;

	CGcontext context = GlobalCGContext::getCGContext();

	// Create Vertex Program for Cylinder
//	m_VertexProgram = cgCreateProgramFromFile(context, CG_SOURCE,
//		"cgGLHelixVertexShader.cg", m_VertexProfile, NULL, NULL);
	m_VertexProgram = cgCreateProgram(context, CG_SOURCE,cgGLHelixVertexShader,
		m_VertexProfile, NULL, NULL );

	// Load Vertex Program for Cylinder
	cgGLLoadProgram(m_VertexProgram);

	m_ModelViewITParam = cgGetNamedParameter(m_VertexProgram, "ModelViewIT");
	m_ModelViewInverseParam = cgGetNamedParameter(m_VertexProgram, "ModelViewInverse");
	m_ModelViewProjParam = cgGetNamedParameter(m_VertexProgram, "ModelViewProj");
	m_ModelViewParam = cgGetNamedParameter(m_VertexProgram, "ModelView");
	m_ProjParam = cgGetNamedParameter(m_VertexProgram, "Proj");

	if (!m_ModelViewITParam || !m_ModelViewInverseParam || !m_ModelViewProjParam || !m_ModelViewParam || !m_ProjParam) 
	//if (!m_ModelViewITParam || !m_ModelViewInverseParam || !m_ModelViewProjParam || !m_ProjParam) 
		return false;

	// Create Fragment Program
//	m_FragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE,
//		"cgGLHelixFragmentShader.cg", m_FragmentProfile, NULL, NULL);
	m_FragmentProgram = cgCreateProgram(context, CG_SOURCE,cgGLHelixFragmentShader,
		m_FragmentProfile, NULL, NULL );

	// Load Fragment Program
	cgGLLoadProgram(m_FragmentProgram);

	m_MainColorParam = cgGetNamedParameter(m_FragmentProgram, "maincolor");
	m_NormalMapParam = cgGetNamedParameter(m_FragmentProgram, "normalmap");
	m_DepthMapParam = cgGetNamedParameter(m_FragmentProgram, "depthmap");
	m_OpacityMapParam = cgGetNamedParameter(m_FragmentProgram, "opacitymap");
	m_ModelViewProjInverseParam = cgGetNamedParameter(m_FragmentProgram, "ModelViewProjInverse");
	m_HelixDCs = cgGetNamedParameter(m_FragmentProgram, "helixDCs");
	m_RefVector = cgGetNamedParameter(m_FragmentProgram, "refVector");
	m_EndPoint1 = cgGetNamedParameter(m_FragmentProgram, "endPoint1");
	m_HelixDCsCrossRefVector = cgGetNamedParameter(m_FragmentProgram, "helixDCsCrossRefVector");
	m_LengthOfHelix = cgGetNamedParameter(m_FragmentProgram, "lengthOfHelix");

	m_TextureNormalMap = new Texture();
	m_TextureNormalMap->calculateCylinderNormalMap(512);

	m_TextureDepthMap = new Texture();
	m_TextureDepthMap->calculateCylinderDepthMap(512);

	m_TextureOpacityMap = new Texture();
	m_TextureOpacityMap->calculateHelixOpacityMap(512, 512);

	cgGLSetTextureParameter(m_NormalMapParam, m_TextureNormalMap->getTextureID());
	cgGLSetTextureParameter(m_DepthMapParam, m_TextureDepthMap->getTextureID());
	cgGLSetTextureParameter(m_OpacityMapParam, m_TextureOpacityMap->getTextureID());
	
	return true;
}

bool HelixRenderer::initExtensions()
{
	return true;
}
