示例#1
0
CrtInt CrtRender::LoadCgProgram( CrtChar * fileName, const CrtInt programType )
{
	CrtChar fullFileName[CRT_MAX_NAME_SIZE]; 
	
	CrtCpy( fullFileName, ShaderFilePrefix );
	CrtCat( fullFileName, fileName ); 

	CrtPrint(" Loading %s Shader From Binary \n", fullFileName ); 

	// get the name extention 
	CrtChar * ext = CrtGetExtention( fullFileName );                 
	
	if ( !CrtCmpIn( ext, ".cg" ) && !CrtCmpIn( ext, ".CG" ) )
	{
		CrtPrint("CrtRender::LoadCgProgram: Invalid File Name %s \n", fullFileName ); 
		return -1; 
	}
	// Load And Compile The Vertex Shader From File
	if ( programType == CrtFragmentProgram )
	{	
		CrtCpy( ext, ".cg" ); 
		cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgFragmentProfile, NULL, NULL);
	}
	else
	{
		CrtCpy( ext, ".cg" ); 
		cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgVertexProfile, "main", 0);
	}

	// Validate Success
	if (cgPrograms[NumCgPrograms] == NULL)
	{
		// Check for a Cg Error, If So switch to FixedFunction
		if ( ! CrtCheckForCgError() )
			return -1;

		// failed to load CgShader 
		CrtChar buff[CRT_MAX_NAME_SIZE];
		sprintf(buff," Shader Load Failed %s \n", fileName ); 
		return -1;													
	}
	
	CrtPrint(" Shader ID %d \n", cgPrograms[NumCgPrograms] ); 

	cgGLLoadProgram(cgPrograms[NumCgPrograms]);	
	NumCgPrograms ++;

	return NumCgPrograms - 1; 
}
示例#2
0
CrtInt CrtRender::LoadCgProgram( CrtChar * fileName, const CrtInt programType )
{
	CrtChar fullFileName[CRT_MAX_NAME_SIZE]; 
	
	sprintf(fullFileName, "%s%s", ShaderFilePrefix, fileName ); 
	//CrtCpy( fullFileName, fileName ); 

	CrtPrint("CrtRender::LoadCgProgram: Loading %s Shader From File \n", fileName ); 

	// Load And Compile The Vertex Shader From File
	if ( programType == CrtFragmentProgram )
		cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgFragmentProfile, "main", 0);
	else
		cgPrograms[NumCgPrograms] = cgCreateProgramFromFile(cgContext, CG_SOURCE, fullFileName, cgVertexProfile, "main", 0);

	// Validate Success
	if (cgPrograms[NumCgPrograms] == NULL)
	{
		// Check for a Cg Error, If So switch to FixedFunction
		if ( ! CrtCheckForCgError() )
			return -1;

		// failed to load CgShader 
		CrtChar buff[100];
		sprintf(buff,"CrtRender::LoadCgProgram: Failed Compile CgFile %s \n", fileName ); 
		MessageBox(NULL, buff, "Cg Compile Error", MB_OK );   
		return -1;													
	}

	cgGLLoadProgram(cgPrograms[NumCgPrograms]);	
	NumCgPrograms ++;

	return NumCgPrograms - 1; 
}
示例#3
0
CrtBool CrtExitCg()
{
	CrtPrint("destroying CG context\n");
	_CrtRender.DisableCgProfiles();
	_CrtRender.DestroyCg();
	return CrtFalse;
}
示例#4
0
CrtVoid	CrtInitExtentions()
{
	// get the arb extention 
	if ( !glClientActiveTexture || !glActiveTexture )
	{
		glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
		glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB");		
	}

	if ( !glClientActiveTexture || !glActiveTexture )
	{
		CrtPrint( " Needed Arb Entension was not found \n" ); 
		MessageBox(NULL, "Failed to find Needed ARB Entension!", "Error", MB_OK);
		CrtPrint( " This app will not be rendered with Cg \n" ); 
		MessageBox(NULL, "Switching to Fixed Function OpenGL \n", "Error", MB_OK ); 
		_CrtRender.DisableCgProfiles();
		_CrtRender.DisableCg(); 
		return; 
	}
}
示例#5
0
CrtBool CrtInitCg()
{
	CrtPrint("creating CG context\n");
	cgContext = cgCreateContext();
	if(cgContext == NULL)
	{
		printf("Failed to create CG context\n");
		return CrtFalse;
	}

	// Register GL states
	cgGLRegisterStates(cgContext);
	
	// Get the latest GL Vertex Profile
	cgVertexProfile   = cgGLGetLatestProfile(CG_GL_VERTEX);    // Was hardcoded to CG_PROFILE_SCE_VP_TYPEB
	cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);  // Was hardcoded to CG_PROFILE_SCE_FP_TYPEB

	// Make sure the profiles came back valid
	if(cgVertexProfile == CG_PROFILE_UNKNOWN || cgFragmentProfile == CG_PROFILE_UNKNOWN)
	{
		CrtPrint("Invalid profile type returned from cgGLGetLatestProfile\n");
		return CrtFalse;
	}
	
	// Set Optimal Options for this profile 
	cgGLSetOptimalOptions(cgVertexProfile);
	cgGLSetOptimalOptions(cgFragmentProfile);
	
	// Check for Cg errors
	if ( !CrtCheckForCgError() )
		return CrtFalse;

	CrtPrint("CG context created\n");

	return CrtTrue; 
}
示例#6
0
CrtBool CrtInitCg()
{
	// Create a context for the CG programs we are going to load and validate it was successful
	CrtPrint("Creating CG context\n");
	cgContext = cgCreateContext();
	if (cgContext == NULL)
	{
		// BLahhh exit here 
		MessageBox(NULL, "Failed To Create Cg Context", "Error", MB_OK);
		return CrtFalse;													
	}

//	cgSetAutoCompile(cgContext, CG_COMPILE_MANUAL);

	// Register GL states (ugly crashes if you don't do this)
	cgGLRegisterStates(cgContext);

	// Get The Latest GL Vertex Profile
	cgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);				
	cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
    
	// Validate Our Profile Determination Was Successful
	if (cgVertexProfile == CG_PROFILE_UNKNOWN || cgFragmentProfile == CG_PROFILE_UNKNOWN)
	{
		MessageBox(NULL, "Invalid profile type", "Error", MB_OK);
		return CrtFalse;			
	}

	// Set The Current Profile
	cgGLSetOptimalOptions(cgVertexProfile);
	cgGLSetOptimalOptions(cgFragmentProfile);

	// Check for errors
	if(!CrtCheckForCgError())
		return CrtFalse;

	return CrtTrue; 
}
示例#7
0
	void handleWarning(daeString msg)
	{
		CrtPrint( "DOM Warning: %s\n", msg );
	}
示例#8
0
	void handleError(daeString msg)
	{
		CrtPrint( "DOM Error: %s\n", msg );
	}
示例#9
0
//----------------------------------------------------------------------------------------------------
// Standard windows mainline, this is the program entry point
//
CrtInt32 WINAPI WinMain(	HINSTANCE	hInstance,		
					HINSTANCE	hPrevInstance,	
					LPSTR		lpCmdLine,			
					CrtInt32			nCmdShow)	
{
	(void)hPrevInstance; // Avoid warnings
	(void)nCmdShow; // Avoid warnings
	(void)hInstance; // Avoid warnings

#ifndef NO_DEVIL
	ilInit();
#endif

	MSG		msg;									
	BOOL	done=FALSE;								
	
	// Avoid warnings later
	msg.wParam = 0;

	// Turns on windows heap debugging
#if HEAP_DEBUG
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF /*| _CRTDBG_DELAY_FREE_MEM_DF*/);
#endif

	// Ask The User Which Screen Mode They Prefer
	//	if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullscreen=FALSE;							
	}

	// Set the default screen size
	_CrtRender.SetScreenWidth( 640);
	_CrtRender.SetScreenHeight( 480);

	// Create an OpenGL Window
	if (!CreateGLWindow("Collada Viewer for PC", _CrtRender.GetScreenWidth(), _CrtRender.GetScreenHeight(),32,fullscreen))
	{
		return 0;									
	}
	
	// Turn data dumping (debug) off
	//CrtBool dumpData = CrtFalse; 

	// Initialize the renderer
	// !!!GAC for compatibility with the new COLLADA_FX code, Init now forces UsingCg and UsingVBOs to
	// !!!GAC false.  It also calls CrtInitCg, creating the CG context and calling cgGLRegisterStates.
	// !!!GAC All these things are currently required for the cfx rendering path to work, changing them
	// !!!GAC may cause problems.  This is work in progress and will be much cleaner when the refactor is done.
	
	_CrtRender.Init();
	//_CrtRender.SetRenderDebug( CrtTrue ); 

	// !!!GAC kept for reference, changing these may cause problems with the cfx include path
	//_CrtRender.SetUsingCg( CrtFalse );
	// Turn off VBOs (the GL skinning path doesn't work with VBOs yet)
	_CrtRender.SetUsingVBOs( CrtTrue ); 
	_CrtRender.SetUsingNormalMaps( CrtTrue ); 	
	//_CrtRender.SetRenderDebug( CrtTrue ); 
	//_CrtRender.SetUsingShadowMaps(CrtTrue);

	// We might get a windows-style path on the command line, this can mess up the DOM which expects
	// all paths to be URI's.  This block of code does some conversion to try and make the input
	// compliant without breaking the ability to accept a properly formatted URI.  Right now this only
	// displays the first filename
	char
		file[512],
		*in = lpCmdLine,
		*out = file;
	*out = NULL;
	// If the first character is a ", skip it (filenames with spaces in them are quoted)
	if(*in == '\"')
	{
		in++;
	}
	if(*(in+1) == ':')
	{
		// Second character is a :, assume we have a path with a drive letter and add a slash at the beginning
		*(out++) = '/';
	}
	int i;
	for(i =0; i<512; i++)
	{
		// If we hit a null or a quote, stop copying.  This will get just the first filename.
		if(*in == NULL || *in == '\"')
			break;
		// Copy while swapping backslashes for forward ones
		if(*in == '\\')
		{
			*out = '/';
		}
		else
		{
			*out = *in;
		}
		in++;
		out++;
	}
	
	// Should throw an error if i>= 512, but we don't have error dialongs in the code yet so just let it try to load and fail
	if(i < 511)
		*out = NULL;

	time_t seconds =  time (NULL);
	clock_t clocka = clock ();

	cleaned_file_name = file;
	// Load the file name provided on the command line
	if ( !_CrtRender.Load( cleaned_file_name ))
	{
		exit(0);
	}
	time_t loadtime = time (NULL) - seconds;
	int clockload = (int) clock () - clocka;

	CrtPrint("\nLOAD TIME OF %s\n", file);
	CrtPrint("IS %d SECONDS\n", loadtime);
	CrtPrint("IS %d CLOCK TICKS\n\n", clockload);


	// This block of code shows how to enumerate all the effects, get their parameters and then
	// get their UI information.
#if 1
	{
		// Get the scene and setup to iterate over all the effects stored in the cfxLoader
		CrtScene *scene = _CrtRender.GetScene();
		std::map<std::string, cfxEffect*>::iterator effectIterator;
		effectIterator = scene->cfxEffects.begin();
		// Iterate over all the effects
		while(effectIterator != scene->cfxEffects.end())
		{
			// This is the effect name you would use in a UI
			CrtPrint("Effect name %s\n", effectIterator->first.c_str());
			cfxEffect *thiscfxEffect = effectIterator->second;
			CGeffect thisCGEffect = thiscfxEffect->getEffect();
			CGparameter thisCGParameter = cgGetFirstEffectParameter(thisCGEffect);
			while(thisCGParameter != NULL)
			{
				// This is the parameter name you would use in the UI
				const char *parameterName = cgGetParameterName(thisCGParameter);
				// This is for the example of how to tweek a parameter (doesn't work yet)
				if(CrtCmp(parameterName, "Amplitude"))
				{
					// Capture the parameter and save it in a global, in a GUI you would
					// save this handle in the widget so it would know what to tweek.
					amplitudeGlobalParameter = thisCGParameter;
				}
#if 0
				// This is here for debugging, it iterates over all the annotations and prints them out
				// so you can see what's in them.  Normally this code will be turned off.
				CrtPrint("  Parameter name %s\n",parameterName);
				CGannotation dbgCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter);
				while(dbgCGAnnotation != NULL)
				{
					const char *annotationName = cgGetAnnotationName(dbgCGAnnotation);
					CrtPrint("      Annotation: %s",annotationName);
					if(cgGetAnnotationType(dbgCGAnnotation) == CG_STRING)
					{
						const char *annotationString = cgGetStringAnnotationValue(dbgCGAnnotation);
						CrtPrint(" value: %s\n",annotationString);
					}
					else if(cgGetAnnotationType(dbgCGAnnotation) == CG_FLOAT)
					{
						int nvalues; 
						const float *value = cgGetFloatAnnotationValues(dbgCGAnnotation, &nvalues);
						CrtPrint(" value: %f\n",*value);  // Assume there is one value
					}
					else
					{
						CrtPrint("\n");
					}
					dbgCGAnnotation = cgGetNextAnnotation(dbgCGAnnotation);
				}
#endif
				// This code looks at the parameter annotations to see if they specify some kind of UI
				// cgGetNamedParameterAnnotation isn't used for this because it is case sensitive and at
				// least some of the annotations FXcomposer uses for UI appear to NOT be case sensitive.
				// This method should collect the parameter values regardless of case, but it has to scan
				// ALL the parameters and do case-blind compares on each one, which is slower.
				// This code currently only collects the annotation values for defining sliders and color pickers.
				const char *UIName		= "unknown";
				const char *UIWidget	= "unknown";
				float UIMin				= -99999.0f;
				float UIMax				= 99999.0f;
				float UIStep			= 0.0f;
				int   nvalues;
				CGannotation thisCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter);
				// Iterate over all the annotations
				while(thisCGAnnotation != NULL)
				{
					// Get the name of this annotation
					const char *annotationName = cgGetAnnotationName(thisCGAnnotation);
					// Do case-blind compares to see if the annotation is one of the ones used to make UI
					// and save the value if it is.
					if(CrtICmp("UIWidget",annotationName))
					{
						// This is the widget type
						UIWidget = cgGetStringAnnotationValue(thisCGAnnotation);
					}
					if(CrtICmp("UIName",annotationName))
					{
						// This is the name to attach to the widget
						UIName = cgGetStringAnnotationValue(thisCGAnnotation);
					}
					if(CrtICmp("UIMin",annotationName))
					{
						// This is the minimum value for a slider widget
						const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
						if(nvalues == 1)
							UIMin = *value;
					}
					if(CrtICmp("UIMax",annotationName))
					{
						// This is the maximum value for a slider widget
						const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
						if(nvalues == 1)
							UIMax = *value;
					}
					if(CrtICmp("UIStep",annotationName))
					{
						// This is the step (minimum change) for a slider widget
						const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
						if(nvalues == 1)
							UIStep = *value;
					}
					// Get the next annotation
					thisCGAnnotation = cgGetNextAnnotation(thisCGAnnotation);
				}
				// Is the UIWidget a type that we recognize? (just slider and color picker for now)
				// Replace the CrtPrint with the code that generates the UI, remember the UI needs to
				// store thisCGParameter someplace so it can use it to change the parameter later. 
				if(CrtICmp("slider", UIWidget))
				{
					CrtPrint("Parameter %s needs a slider named %s going from %f to %f with step %f\n",parameterName,UIName,UIMin,UIMax, UIStep );
				}
				if(CrtICmp("color", UIWidget))
				{
					CrtPrint("Parameter %s needs a color picker named %s\n",parameterName,UIName);
				}
				// Move on to the next parameter
				thisCGParameter = cgGetNextParameter(thisCGParameter);
			}
			// Move on to the next effect
			effectIterator++;
		}
	}
#endif
	while(!done)									
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	
		{
			if (msg.message==WM_QUIT)				
			{
				done=TRUE;							
			}
			else									
			{
				TranslateMessage(&msg);				
				DispatchMessage(&msg);				
			}
		}
		else										
		{
			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
			if ((active && !DrawGLScene()) || keys[VK_ESCAPE])	// Active?  Was There A Quit Received?
			{
				done=TRUE;							
			}
			else									
			{
				SwapBuffers(hDC);					
				ProcessInput( keys ); 				
			}
		}
	}

	_CrtRender.Destroy();

	// Shutdown
#ifndef NO_DEVIL
	ilShutDown();
#endif
	DestroyGLWindow();								
	return (int)(msg.wParam);						
}
示例#10
0
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
int main(int LArgC, char** LArgV)
{
    atexit(DestroyCrt);		// Need this, because old GLUT never returns from glutMainLoop()

    // Create an OpenGL Window
    if (!CreateGLWindow(LArgC, LArgV, (char*)"COLLADA_DOM Sample Viewer", _CrtRender.GetScreenWidth(), _CrtRender.GetScreenHeight()))
    {
        return 0;
    }

    // Initialize the renderer
    // !!!GAC for compatibility with the new COLLADA_FX code, Init now forces UsingCg and UsingVBOs to
    // !!!GAC false.  It also calls CrtInitCg, creating the CG context and calling cgGLRegisterStates.
    // !!!GAC All these things are currently required for the cfx rendering path to work, changing them
    // !!!GAC may cause problems.  This is work in progress and will be much cleaner when the refactor is done.

    _CrtRender.Init();

    _CrtRender.SetUsingVBOs( CrtTrue );
    _CrtRender.SetUsingNormalMaps( CrtTrue );

    // Load the file name provided on the command line
    if(LArgC > 1 && LArgV[1])
    {
        printf("%s(): Loading %s...\n", __FUNCTION__, LArgV[1]);
        fflush(stdout);
        if ( !_CrtRender.Load( LArgV[1] ))
        {
            exit(0);
        }
    }
    else
    {
        printf("%s(): Loading default document cage.dae... \n", __FUNCTION__);
        fflush(stdout);
        if ( !_CrtRender.Load( "cage.dae" ))
        {
            exit(0);
        }
    }

    // This block of code shows how to enumerate all the effects, get their parameters and then
    // get their UI information.
#if 1
    if(_CrtRender.GetScene())
    {
        // Get the scene and setup to iterate over all the effects stored in the cfxLoader
        CrtScene *scene = _CrtRender.GetScene();


        std::map<std::string, cfxEffect*>::iterator effectIterator;
        effectIterator = scene->cfxEffects.begin();
        // Iterate over all the effects
        while(effectIterator != scene->cfxEffects.end())
        {
            // This is the effect name you would use in a UI
            CrtPrint("Effect name %s\n", effectIterator->first.c_str());
            cfxEffect *thiscfxEffect = effectIterator->second;
            CGeffect thisCGEffect = thiscfxEffect->getEffect();
            CGparameter thisCGParameter = cgGetFirstEffectParameter(thisCGEffect);
            while(thisCGParameter != NULL)
            {
                // This is the parameter name you would use in the UI
                const char *parameterName = cgGetParameterName(thisCGParameter);
                // This is for the example of how to tweek a parameter (doesn't work yet)
                if(CrtCmp(parameterName, "Amplitude"))
                {
                    // Capture the parameter and save it in a global, in a GUI you would
                    // save this handle in the widget so it would know what to tweek.
                    amplitudeGlobalParameter = thisCGParameter;
                }
#if 0
                // This is here for debugging, it iterates over all the annotations and prints them out
                // so you can see what's in them.  Normally this code will be turned off.
                CrtPrint("  Parameter name %s\n",parameterName);
                CGannotation dbgCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter);
                while(dbgCGAnnotation != NULL)
                {
                    const char *annotationName = cgGetAnnotationName(dbgCGAnnotation);
                    CrtPrint("      Annotation: %s",annotationName);
                    if(cgGetAnnotationType(dbgCGAnnotation) == CG_STRING)
                    {
                        const char *annotationString = cgGetStringAnnotationValue(dbgCGAnnotation);
                        CrtPrint(" value: %s\n",annotationString);
                    }
                    else if(cgGetAnnotationType(dbgCGAnnotation) == CG_FLOAT)
                    {
                        int nvalues;
                        const float *value = cgGetFloatAnnotationValues(dbgCGAnnotation, &nvalues);
                        CrtPrint(" value: %f\n",*value);  // Assume there is one value
                    }
                    else
                    {
                        CrtPrint("\n");
                    }
                    dbgCGAnnotation = cgGetNextAnnotation(dbgCGAnnotation);
                }
#endif
                // This code looks at the parameter annotations to see if they specify some kind of UI
                // cgGetNamedParameterAnnotation isn't used for this because it is case sensitive and at
                // least some of the annotations FXcomposer uses for UI appear to NOT be case sensitive.
                // This method should collect the parameter values regardless of case, but it has to scan
                // ALL the parameters and do case-blind compares on each one, which is slower.
                // This code currently only collects the annotation values for defining sliders and color pickers.
                const char *UIName		= "unknown";
                const char *UIWidget	= "unknown";
                float UIMin				= -99999.0f;
                float UIMax				= 99999.0f;
                float UIStep			= 0.0f;
                int   nvalues;
                CGannotation thisCGAnnotation = cgGetFirstParameterAnnotation(thisCGParameter);
                // Iterate over all the annotations
                while(thisCGAnnotation != NULL)
                {
                    // Get the name of this annotation
                    const char *annotationName = cgGetAnnotationName(thisCGAnnotation);
                    // Do case-blind compares to see if the annotation is one of the ones used to make UI
                    // and save the value if it is.
                    if(CrtICmp("UIWidget",annotationName))
                    {
                        // This is the widget type
                        UIWidget = cgGetStringAnnotationValue(thisCGAnnotation);
                    }
                    if(CrtICmp("UIName",annotationName))
                    {
                        // This is the name to attach to the widget
                        UIName = cgGetStringAnnotationValue(thisCGAnnotation);
                    }
                    if(CrtICmp("UIMin",annotationName))
                    {
                        // This is the minimum value for a slider widget
                        const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
                        if(nvalues == 1)
                            UIMin = *value;
                    }
                    if(CrtICmp("UIMax",annotationName))
                    {
                        // This is the maximum value for a slider widget
                        const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
                        if(nvalues == 1)
                            UIMax = *value;
                    }
                    if(CrtICmp("UIStep",annotationName))
                    {
                        // This is the step (minimum change) for a slider widget
                        const float *value = cgGetFloatAnnotationValues(thisCGAnnotation, &nvalues);
                        if(nvalues == 1)
                            UIStep = *value;
                    }
                    // Get the next annotation
                    thisCGAnnotation = cgGetNextAnnotation(thisCGAnnotation);
                }
                // Is the UIWidget a type that we recognize? (just slider and color picker for now)
                // Replace the CrtPrint with the code that generates the UI, remember the UI needs to
                // store thisCGParameter someplace so it can use it to change the parameter later.
                if(CrtICmp("slider", UIWidget))
                {
                    CrtPrint("Parameter %s needs a slider named %s going from %f to %f with step %f\n",parameterName,UIName,UIMin,UIMax, UIStep );
                }
                if(CrtICmp("color", UIWidget))
                {
                    CrtPrint("Parameter %s needs a color picker named %s\n",parameterName,UIName);
                }
                // Move on to the next parameter
                thisCGParameter = cgGetNextParameter(thisCGParameter);
            }
            // Move on to the next effect
            effectIterator++;
        }
    }
#endif

    glutMainLoop();

    return(0);
}