Пример #1
0
static INLINE CGparameter find_param_from_semantic(
      CGparameter param, const char *sem)
{
   while (param)
   {
      if (cgGetParameterType(param) == CG_STRUCT)
      {
         CGparameter ret = find_param_from_semantic(
               cgGetFirstStructParameter(param), sem);

         if (ret)
            return ret;
      }
      else
      {
         if (cgGetParameterSemantic(param) &&
               !strcmp(sem, cgGetParameterSemantic(param)) &&
               cgGetParameterDirection(param) == CG_IN &&
               cgGetParameterVariability(param) == CG_VARYING &&
               validate_param_name(cgGetParameterName(param)))
            return param;
      }
      param = cgGetNextParameter(param);
   }

   return NULL;
}
static INLINE CGparameter d3d9_cg_find_param_from_semantic(
      CGparameter param, const char *sem)
{
   for (; param; param = cgGetNextParameter(param))
   {
      const char *semantic = NULL;
      if (cgGetParameterType(param) == CG_STRUCT)
      {
         CGparameter ret = d3d9_cg_find_param_from_semantic(
               cgGetFirstStructParameter(param), sem);

         if (ret)
            return ret;
      }

      if (     cgGetParameterDirection(param)   != CG_IN
            || cgGetParameterVariability(param) != CG_VARYING)
         continue;

      semantic = cgGetParameterSemantic(param);
      if (!semantic)
         continue;

      if (string_is_equal(sem, semantic) &&
            d3d9_cg_validate_param_name(cgGetParameterName(param)))
         return param;
   }

   return NULL;
}
Пример #3
0
static void set_program_base_attrib(unsigned i)
{
   CGparameter param = cgGetFirstParameter(prg[i].vprg, CG_PROGRAM);
   for (; param; param = cgGetNextParameter(param))
   {
      if (cgGetParameterDirection(param) != CG_IN || cgGetParameterVariability(param) != CG_VARYING)
         continue;

      const char *semantic = cgGetParameterSemantic(param);
      if (!semantic)
         continue;

      RARCH_LOG("CG: Found semantic \"%s\" in prog #%u.\n", semantic, i);

      if (strcmp(semantic, "TEXCOORD") == 0 || strcmp(semantic, "TEXCOORD0") == 0)
         prg[i].tex = param;
      else if (strcmp(semantic, "COLOR") == 0 || strcmp(semantic, "COLOR0") == 0)
         prg[i].color = param;
      else if (strcmp(semantic, "POSITION") == 0)
         prg[i].vertex = param;
      else if (strcmp(semantic, "TEXCOORD1") == 0)
         prg[i].lut_tex = param;
   }

   if (!prg[i].tex)
      prg[i].tex = cgGetNamedParameter(prg[i].vprg, "IN.tex_coord");
   if (!prg[i].color)
      prg[i].color = cgGetNamedParameter(prg[i].vprg, "IN.color");
   if (!prg[i].vertex)
      prg[i].vertex = cgGetNamedParameter(prg[i].vprg, "IN.vertex_coord");
   if (!prg[i].lut_tex)
      prg[i].lut_tex = cgGetNamedParameter(prg[i].vprg, "IN.lut_tex_coord");
}
Пример #4
0
void GLCgShader::FillParameters(const CGenum domain)
{
	CGparameter param = cgGetFirstParameter(m_cgProgam, domain);
	while (param)
	{
		const char* name = cgGetParameterName(param);
		m_params[name] = param;
		param = cgGetNextParameter(param);
	}
}
Пример #5
0
static void gl_cg_set_program_base_attrib(void *data, unsigned i)
{
   cg_shader_data_t *cg = (cg_shader_data_t*)data;
   CGparameter         param = cgGetFirstParameter(
         cg->prg[i].vprg, CG_PROGRAM);

   for (; param; param = cgGetNextParameter(param))
   {
      uint32_t semantic_hash;
      const char *semantic = NULL;
      if (cgGetParameterDirection(param) != CG_IN 
            || cgGetParameterVariability(param) != CG_VARYING)
         continue;

      semantic = cgGetParameterSemantic(param);
      if (!semantic)
         continue;

      RARCH_LOG("CG: Found semantic \"%s\" in prog #%u.\n", semantic, i);

      semantic_hash = djb2_calculate(semantic);

      switch (semantic_hash)
      {
         case SEMANTIC_TEXCOORD:
         case SEMANTIC_TEXCOORD0:
            cg->prg[i].tex     = param;
            break;
         case SEMANTIC_COLOR:
         case SEMANTIC_COLOR0:
            cg->prg[i].color   = param;
            break;
         case SEMANTIC_POSITION:
            cg->prg[i].vertex  = param;
            break;
         case SEMANTIC_TEXCOORD1:
            cg->prg[i].lut_tex = param;
            break;
      }
   }

   if (!cg->prg[i].tex)
      cg->prg[i].tex     = cgGetNamedParameter(cg->prg[i].vprg, "IN.tex_coord");
   if (!cg->prg[i].color)
      cg->prg[i].color   = cgGetNamedParameter(cg->prg[i].vprg, "IN.color");
   if (!cg->prg[i].vertex)
      cg->prg[i].vertex  = cgGetNamedParameter(cg->prg[i].vprg, "IN.vertex_coord");
   if (!cg->prg[i].lut_tex)
      cg->prg[i].lut_tex = cgGetNamedParameter(cg->prg[i].vprg, "IN.lut_tex_coord");
}
Пример #6
0
/* iterate all parameters and record input variyings
   with their semantic and resource index
*/
void CD3DCG::fillParameterMap(std::vector<parameterEntry> &map, CGparameter param)
{
	parameterEntry mapEntry;
	while (param) {
		if(cgGetParameterType(param)==CG_STRUCT)
			fillParameterMap(map,cgGetFirstStructParameter(param));
		else
			if (cgGetParameterDirection(param) == CG_IN && cgGetParameterVariability(param) == CG_VARYING) {
				mapEntry.rIndex = cgGetParameterResourceIndex(param);
				mapEntry.semantic = cgGetParameterSemantic(param);
				mapEntry.isKnownParam = isKnownParameter(cgGetParameterName(param));
				if(map.size()<mapEntry.rIndex+1)
					map.resize(mapEntry.rIndex+1);
				map[mapEntry.rIndex] = mapEntry;
			}
		param = cgGetNextParameter(param);
	}
}
Пример #7
0
static void gl_cg_set_program_base_attrib(void *data, unsigned i)
{
   cg_shader_data_t      *cg = (cg_shader_data_t*)data;
   CGparameter         param = cgGetFirstParameter(
         cg->prg[i].vprg, CG_PROGRAM);

   for (; param; param = cgGetNextParameter(param))
   {
      const char *semantic = NULL;
      if (     (cgGetParameterDirection(param)   != CG_IN)
            || (cgGetParameterVariability(param) != CG_VARYING))
         continue;

      semantic = cgGetParameterSemantic(param);
      if (!semantic)
         continue;

      RARCH_LOG("[CG]: Found semantic \"%s\" in prog #%u.\n", semantic, i);

      if (
            string_is_equal(semantic, "TEXCOORD") ||
            string_is_equal(semantic, "TEXCOORD0")
         )
         cg->prg[i].tex     = param;
      else if (
            string_is_equal(semantic, "COLOR") ||
            string_is_equal(semantic, "COLOR0")
            )
            cg->prg[i].color   = param;
      else if (string_is_equal(semantic, "POSITION"))
         cg->prg[i].vertex  = param;
      else if (string_is_equal(semantic, "TEXCOORD1"))
         cg->prg[i].lut_tex = param;
   }

   if (!cg->prg[i].tex)
      cg->prg[i].tex     = cgGetNamedParameter(cg->prg[i].vprg, "IN.tex_coord");
   if (!cg->prg[i].color)
      cg->prg[i].color   = cgGetNamedParameter(cg->prg[i].vprg, "IN.color");
   if (!cg->prg[i].vertex)
      cg->prg[i].vertex  = cgGetNamedParameter(cg->prg[i].vprg, "IN.vertex_coord");
   if (!cg->prg[i].lut_tex)
      cg->prg[i].lut_tex = cgGetNamedParameter(cg->prg[i].vprg, "IN.lut_tex_coord");
}
Пример #8
0
// ========== cgfxEffect::attrsFromEffect ==========
//
// This function parses through an effect and builds a list of
// cgfxAttrDef objects.
//
cgfxRCPtr<cgfxAttrDefList> cgfxEffect::attrsFromEffect() const
{
	if (!fEffect)
        return cgfxRCPtr<cgfxAttrDefList>();

	cgfxRCPtr<cgfxAttrDefList> list(new cgfxAttrDefList);

    CGparameter cgParameter = cgGetFirstEffectParameter(fEffect);
    int i = 0;
    while (cgParameter)
    {
        cgfxAttrDef* aDef = new cgfxAttrDef(cgParameter);
        list->add(aDef);

        cgParameter = cgGetNextParameter(cgParameter);
        ++i;
    } // end of for each parameter

    return list;
}
Пример #9
0
cgfxPass::cgfxPass(
    CGpass                  pass,
    const cgfxProfile*      profile
)
 :	fPass( pass),
	fProgram( NULL),
	fParameters( NULL),
    fDefaultProfile("default", pass),
	fNext( NULL)
{
	if( pass)
	{
		fName = cgGetPassName( pass);
		CGstateassignment stateAssignment = cgGetFirstStateAssignment( pass);
		cgfxVaryingParameter** nextParameter = &fParameters;
		while( stateAssignment )
		{
			CGstate state = cgGetStateAssignmentState( stateAssignment);
			if( cgGetStateType( state) == CG_PROGRAM_TYPE && 
					( stricmp( cgGetStateName( state), "vertexProgram") == 0 ||
					  stricmp( cgGetStateName( state), "vertexShader") == 0))
			{
				fProgram = cgGetProgramStateAssignmentValue( stateAssignment);
				if( fProgram)
				{
					CGparameter parameter = cgGetFirstParameter( fProgram, CG_PROGRAM);
					while( parameter)
					{
                        cgfxVaryingParameter::addRecursive( parameter, nextParameter);
						parameter = cgGetNextParameter( parameter);
					}
				}
			}
            setProfile(profile);
			stateAssignment = cgGetNextStateAssignment( stateAssignment);
		}
	}
}
Пример #10
0
inline void cgfxVaryingParameter::addRecursive(
    CGparameter parameter,
    cgfxVaryingParameter**& nextParameter
)
{
	if( cgGetParameterVariability( parameter) == CG_VARYING)
	{
		if( cgGetParameterType( parameter) == CG_STRUCT)
		{
			CGparameter input = cgGetFirstStructParameter( parameter);
			while( input)
			{
				addRecursive( input, nextParameter);
				input = cgGetNextParameter( input);
			}
		}
		else if( cgIsParameterReferenced( parameter))
		{
			*nextParameter = new cgfxVaryingParameter( parameter);
			nextParameter = &(*nextParameter)->fNext;
		}
	}
}
Пример #11
0
static bool AddPass(CGtechnique technique, JSON &json, CGpass pass, UniformsMap &uniformRemapping)
{
    bool success = true;
    json.AddObject(NULL);

    const char * const passName = cgGetPassName(pass);
    if (NULL != passName)
    {
        json.AddString("name", passName);
    }

    bool firstParameter = true;

#if CG_VERSION_NUM >= 3000
    const int CG_NUMBER_OF_DOMAINS = (CG_TESSELLATION_EVALUATION_DOMAIN + 1);
#endif

    for (int domain = CG_FIRST_DOMAIN; domain < CG_NUMBER_OF_DOMAINS; domain++)
    {
        const CGprogram program = cgGetPassProgram(pass, (CGdomain)domain);
        if (NULL != program)
        {
            const char * const programString = cgGetProgramString(program, CG_COMPILED_PROGRAM);

            CGparameter param = cgGetFirstParameter(program, CG_GLOBAL);
            while (NULL != param)
            {
                if (cgIsParameterUsed(param, program) &&
                    CG_UNIFORM == cgGetParameterVariability(param))
                {
                    if (firstParameter)
                    {
                        firstParameter = false;
                        json.AddArray("parameters", true);
                        json.BeginData(true);
                    }
                    const char * const paramName = cgGetParameterName(param);
                    AddMappedParameter(json, paramName, programString, uniformRemapping);
                }
                param = cgGetNextParameter(param);
            }

            param = cgGetFirstParameter(program, CG_PROGRAM);
            while (NULL != param)
            {
                if (cgIsParameterUsed(param, program) &&
                    CG_UNIFORM == cgGetParameterVariability(param))
                {
                    if (firstParameter)
                    {
                        firstParameter = false;
                        json.AddArray("parameters", true);
                        json.BeginData(true);
                    }
                    const char * const paramName = cgGetParameterName(param);
                    AddMappedParameter(json, paramName, programString, uniformRemapping);
                }
                param = cgGetNextParameter(param);
            }
        }
    }

    if (!firstParameter)
    {
        json.EndData();
        json.CloseArray(true); // parameters
    }


    json.AddArray("semantics", true);
    json.BeginData(true);

    CGprogram vertexProgram = cgGetPassProgram(pass, CG_VERTEX_DOMAIN);
    CGparameter vertexInputParameter = cgGetFirstLeafParameter(vertexProgram, CG_PROGRAM);
    while (NULL != vertexInputParameter)
    {
        const CGenum variability = cgGetParameterVariability(vertexInputParameter);
        if (CG_VARYING == variability)
        {
            const CGenum direction = cgGetParameterDirection(vertexInputParameter);
            if (CG_IN == direction ||
                CG_INOUT == direction)
            {
                const char * const semantic = cgGetParameterSemantic(vertexInputParameter);
                json.AddData(semantic, strlen(semantic));
            }
        }
        vertexInputParameter = cgGetNextLeafParameter(vertexInputParameter);
    }

    json.EndData();
    json.CloseArray(true); // semantics


    json.AddObject("states");

    CGstateassignment state = cgGetFirstStateAssignment(pass);
    if (NULL != state)
    {
        do
        {
            success &= AddState(json, state);
            state = cgGetNextStateAssignment(state);
        }
        while (NULL != state);
    }

    json.CloseObject(); // states


    json.AddArray("programs", true);
    json.BeginData(true);

    for (int domain = CG_FIRST_DOMAIN; domain < CG_NUMBER_OF_DOMAINS; domain++)
    {
        const CGprogram program = cgGetPassProgram(pass, (CGdomain)domain);
        if (NULL != program)
        {
            const char * const entryPoint = cgGetProgramString(program, CG_PROGRAM_ENTRY);
            json.AddData(entryPoint, strlen(entryPoint));
        }
        else if (domain == CG_VERTEX_DOMAIN)
        {

            ErrorMessage("%s : No vertex program.", cgGetTechniqueName(technique));
            success = false;
        }
        else if(domain == CG_FRAGMENT_DOMAIN)
        {
            ErrorMessage("%s : No fragment program.", cgGetTechniqueName(technique));
            success = false;
        }
    }

    json.EndData();
    json.CloseArray(true); // programs

    json.CloseObject(); // pass

    return success;
}
Пример #12
0
	//---------------------------------------------------------------------
	void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize) const
	{
		while (parameter != 0)
        {
            // Look for uniform (non-sampler) parameters only
            // Don't bother enumerating unused parameters, especially since they will
            // be optimised out and therefore not in the indexed versions
            CGtype paramType = cgGetParameterType(parameter);

            if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
                paramType != CG_SAMPLER1D &&
                paramType != CG_SAMPLER2D &&
                paramType != CG_SAMPLER3D &&
                paramType != CG_SAMPLERCUBE &&
                paramType != CG_SAMPLERRECT &&
                cgGetParameterDirection(parameter) != CG_OUT && 
                cgIsParameterReferenced(parameter))
            {
				int arraySize;

				switch(paramType)
				{
				case CG_STRUCT:
					recurseParams(cgGetFirstStructParameter(parameter));
					break;
				case CG_ARRAY:
					// Support only 1-dimensional arrays
					arraySize = cgGetArraySize(parameter, 0);
					recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize);
					break;
				default:
					// Normal path (leaf)
					String paramName = cgGetParameterName(parameter);
					size_t logicalIndex = cgGetParameterResourceIndex(parameter);

					// Get the parameter resource, to calculate the physical index
					CGresource res = cgGetParameterResource(parameter);
					bool isRegisterCombiner = false;
					size_t regCombinerPhysicalIndex = 0;
					switch (res)
					{
					case CG_COMBINER_STAGE_CONST0:
						// register combiner, const 0
						// the index relates to the texture stage; store this as (stage * 2) + 0
						regCombinerPhysicalIndex = logicalIndex * 2;
						isRegisterCombiner = true;
						break;
					case CG_COMBINER_STAGE_CONST1:
						// register combiner, const 1
						// the index relates to the texture stage; store this as (stage * 2) + 1
						regCombinerPhysicalIndex = (logicalIndex * 2) + 1;
						isRegisterCombiner = true;
						break;
					default:
						// normal constant
						break;
					}

					// Trim the '[0]' suffix if it exists, we will add our own indexing later
					if (StringUtil::endsWith(paramName, "[0]", false))
					{
						paramName.erase(paramName.size() - 3);
					}


					GpuConstantDefinition def;
					def.arraySize = contextArraySize;
					mapTypeAndElementSize(paramType, isRegisterCombiner, def);

					if (def.constType == GCT_UNKNOWN)
					{
						LogManager::getSingleton().logMessage(
							"Problem parsing the following Cg Uniform: '"
							+ paramName + "' in file " + mName);
						// next uniform
						continue;
					}
					if (isRegisterCombiner)
					{
						def.physicalIndex = regCombinerPhysicalIndex;
					}
					else
					{
						// base position on existing buffer contents
						if (def.isFloat())
						{
							def.physicalIndex = mFloatLogicalToPhysical.bufferSize;
						}
						else
						{
							def.physicalIndex = mIntLogicalToPhysical.bufferSize;
						}
					}


					mConstantDefs.map.insert(GpuConstantDefinitionMap::value_type(paramName, def));

					// Record logical / physical mapping
					if (def.isFloat())
					{
						OGRE_LOCK_MUTEX(mFloatLogicalToPhysical.mutex)
						mFloatLogicalToPhysical.map.insert(
							GpuLogicalIndexUseMap::value_type(logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize)));
						mFloatLogicalToPhysical.bufferSize += def.arraySize * def.elementSize;
						mConstantDefs.floatBufferSize = mFloatLogicalToPhysical.bufferSize;
					}
					else
					{
						OGRE_LOCK_MUTEX(mIntLogicalToPhysical.mutex)
						mIntLogicalToPhysical.map.insert(
							GpuLogicalIndexUseMap::value_type(logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize)));
						mIntLogicalToPhysical.bufferSize += def.arraySize * def.elementSize;
						mConstantDefs.intBufferSize = mIntLogicalToPhysical.bufferSize;
					}

					// Deal with array indexing
					mConstantDefs.generateConstantDefinitionArrayEntries(paramName, def);

					break;
		
				}
					
            }
            // Get next
            parameter = cgGetNextParameter(parameter);
        }

        
    }
Пример #13
0
void CCgMaterialRenderer::getUniformList()
{
	for(unsigned int i = 0; i < UniformInfo.size(); ++i)
		delete UniformInfo[i];

	UniformInfo.clear();

	for(unsigned int i = 0; i < 2; ++i)
	{
		CGenum Space = CG_GLOBAL;
		bool IsGlobal = 1;

		if(i == 1)
		{
			Space = CG_PROGRAM;
			IsGlobal = 0;
		}

		for(unsigned int j = 0; j < 3; ++j)
		{
			CGprogram* Program = 0;

			switch(j)
			{
			case 0:
				Program = &VertexProgram;
				break;
			case 1:
				Program = &FragmentProgram;
				break;
			case 2:
				Program = &GeometryProgram;
				break;
			}

			if(*Program)
			{
				CGparameter Parameter = cgGetFirstParameter(*Program, Space);

				while(Parameter)
				{
					if(cgGetParameterVariability(Parameter) == CG_UNIFORM && cgGetParameterDirection(Parameter) == CG_IN)
					{
						CCgUniform* Uniform = 0;

						CGtype Type = cgGetParameterType(Parameter);

						switch(Type)
						{
						case CG_FLOAT:
						case CG_FLOAT1:
							Uniform = new CCgUniform1f(Parameter, IsGlobal);
							break;
						case CG_FLOAT2:
							Uniform = new CCgUniform2f(Parameter, IsGlobal);
							break;
						case CG_FLOAT3:
							Uniform = new CCgUniform3f(Parameter, IsGlobal);
							break;
						case CG_FLOAT4:
							Uniform = new CCgUniform4f(Parameter, IsGlobal);
							break;
						case CG_INT:
						case CG_INT1:
							Uniform = new CCgUniform1i(Parameter, IsGlobal);
							break;
						case CG_INT2:
							Uniform = new CCgUniform2i(Parameter, IsGlobal);
							break;
						case CG_INT3:
							Uniform = new CCgUniform3i(Parameter, IsGlobal);
							break;
						case CG_INT4:
							Uniform = new CCgUniform4i(Parameter, IsGlobal);
							break;
						case CG_FLOAT4x4:
							Uniform = new CCgUniform4x4f(Parameter, IsGlobal);
							break;
						case CG_SAMPLER2D:
							Uniform = new CCgUniformSampler2D(Parameter, IsGlobal);
							break;
						}

						if(Uniform)
							UniformInfo.push_back(Uniform);
					}

					Parameter = cgGetNextParameter(Parameter);
				}
			}
		}
	}
}
Пример #14
0
void cgfxVaryingParameter::setupAttributes( cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes, CGprogram program)
{
	// Make sure our parameter name is acceptable is a Maya attribute name
	MString attrName = fName;
	int lastDot = attrName.rindex( '.');
	if( lastDot >= 0)
		attrName = attrName.substring( lastDot + 1, attrName.length() - 1);
	
    MString semanticName = cgGetParameterSemantic( fParameter);

    MString semantic(semanticName);
    cgGetParameterSemantic( fParameter);
	semantic.toUpperCase();

	// Is this varying parameter packed or atomic?
	CGtype type = cgGetNamedUserType( program, attrName.asChar());
	if( type != CG_UNKNOWN_TYPE)
	{
		// It's packed: explode the inputs into the structure elements
		CGcontext context = cgGetProgramContext( program); 
		CGparameter packing = cgCreateParameter( context, type);
		fVertexStructure = new cgfxVaryingParameterStructure();
		fVertexStructure->fLength = 0;
		fVertexStructure->fSize = 0;
		CGparameter element = cgGetFirstStructParameter( packing);
		while( element)
		{
			MString elementName = cgGetParameterName( element);
			int lastDot = elementName.rindex( '.');
			if( lastDot >= 0)
				elementName = elementName.substring( lastDot + 1, elementName.length() - 1);
			cgfxRCPtr<cgfxVertexAttribute> attr = setupAttribute( elementName, semantic, element, vertexAttributes);
			fVertexStructure->fElements[ fVertexStructure->fLength].fVertexAttribute = attr;
			int size = cgGetParameterRows( element) * cgGetParameterColumns( element);
			CGtype type = cgGetParameterBaseType( element);
			if( type == CG_FLOAT) size *= sizeof( GLfloat);
			else if( type == CG_INT) size *= sizeof( GLint);
			fVertexStructure->fElements[ fVertexStructure->fLength].fSize = size;
			fVertexStructure->fLength++;
			fVertexStructure->fSize += size;
			element = cgGetNextParameter( element);
		}
		cgDestroyParameter( packing); 
	}
	else
	{
		// It's atomic - create a single, simple input
		fVertexAttribute = setupAttribute( attrName, semantic, fParameter, vertexAttributes);
	}

	// Now pull apart the semantic string to work out where to bind
	// this value in open GL (as the automagic binding through cgGL
	// didn't work so well when this was written)
	int radix = 1;
	fGLIndex = 0;
	unsigned int length = semantic.length();
	const char* str = semantic.asChar();

	// If sematic is NULL then stop here, bug 327649
	if (length == 0) {
		 fGLType = glRegister::kUnknown;
		 return;
	}

	for(;;)
	{
		char c = str[ length - 1];
		if( c < '0' || c > '9') break;
		fGLIndex += radix * (c - '0');
		radix *= 10;
		--length;
	}
	if( semantic.length() != length)
		semantic = semantic.substring( 0, length - 1);
	
	// Determine the semantic and setup the gl binding type we should use
	// to set this parameter. If there's a sensible default value, set that
	// while we're here.
	// Note there is no need to set the source type, this gets determined
	// when the vertex attribute sources are analysed
	if( semantic == "POSITION")
	{
		fGLType = glRegister::kPosition;
		fVertexAttribute->fSourceName = "position";
	}
	else if( semantic == "NORMAL")
	{
		fGLType = glRegister::kNormal;
		if( fVertexAttribute.isNull() == false ) 
			fVertexAttribute->fSourceName = "normal";
	}
	else if( semantic == "TEXCOORD")
	{
		fGLType = glRegister::kTexCoord;
		if( fVertexAttribute.isNull() == false ) 
		{
			if( attrName.toLowerCase() == "tangent")
				fVertexAttribute->fSourceName = "tangent:map1";
			else if( attrName.toLowerCase() == "binormal")
				fVertexAttribute->fSourceName = "binormal:map1";
			else
				fVertexAttribute->fSourceName = "uv:map1";
		}
	}
	else if( semantic == "TANGENT")
	{
		fGLType = glRegister::kTexCoord;
		fGLIndex += 6; // TANGENT is TEXCOORD6
		if( fVertexAttribute.isNull() == false ) 
			fVertexAttribute->fSourceName = "tangent:map1";
	}
	else if( semantic == "BINORMAL")
	{
		fGLType = glRegister::kTexCoord;
		fGLIndex += 7; // BINORMAL is TEXCOORD7
		if( fVertexAttribute.isNull() == false ) 
			fVertexAttribute->fSourceName = "binormal:map1";
	}
	else if( semantic == "COLOR")
	{
		fGLType = fGLIndex == 1 ? glRegister::kSecondaryColor : glRegister::kColor;
	}
	else if( semantic == "ATTR")
	{
		fGLType = glRegister::kVertexAttrib;
        if( fVertexAttribute.isNull() == false ) 
        {
            fVertexAttribute->fSourceName = semanticName;
        }
	}
	else if( semantic == "PSIZE")
	{
		fGLType = glRegister::kVertexAttrib;
		fGLIndex = 6;
	}
	else
	{
		fGLType = glRegister::kUnknown;
	}
}
Пример #15
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);
}
bool CgShaderProgramGL::setConstant(const io::stringc &Name, const f32* Buffer, s32 Count)
{
    if (!Buffer)
        return false;

    /* Get top-level parameter */
    CGparameter Param = cgGetNamedParameter(cgProgram_, Name.c_str());

    if (!Param)
        return false;

    /* Get array parameter */
    if (cgGetParameterType(Param) != CG_ARRAY)
        return false;

    s32 ArraySize = cgGetArraySize(Param, 0);

    for (s32 i = 0; i < ArraySize; ++i)
    {
        /* Get array element parameter */
        CGparameter ElementParam = cgGetArrayParameter(Param, i);

        switch (cgGetParameterType(ElementParam))
        {
        case CG_FLOAT:
            cgGLSetParameterArray1f(Param, 0, Count, Buffer);
            return true;
        case CG_FLOAT2:
            cgGLSetParameterArray2f(Param, 0, Count/2, Buffer);
            return true;
        case CG_FLOAT3:
            cgGLSetParameterArray3f(Param, 0, Count/3, Buffer);
            return true;
        case CG_FLOAT4:
            cgGLSetParameterArray4f(Param, 0, Count/4, Buffer);
            return true;
        case CG_FLOAT4x4:
            cgGLSetMatrixParameterArrayfc(Param, 0, Count/16, Buffer);
            return true;

        case CG_STRUCT:
        {
            /* Get structure field parameter */
            CGparameter FieldParam = cgGetFirstStructParameter(ElementParam);

            while (FieldParam)
            {
                switch (cgGetParameterType(FieldParam))
                {
                case CG_FLOAT:
                    cgGLSetParameter1f(FieldParam, *Buffer);
                    Buffer += 1;
                    break;
                case CG_FLOAT2:
                    cgGLSetParameter2fv(FieldParam, Buffer);
                    Buffer += 2;
                    break;
                case CG_FLOAT3:
                    cgGLSetParameter3fv(FieldParam, Buffer);
                    Buffer += 3;
                    break;
                case CG_FLOAT4:
                    cgGLSetParameter4fv(FieldParam, Buffer);
                    Buffer += 4;
                    break;
                case CG_FLOAT4x4:
                    cgGLSetMatrixParameterfc(FieldParam, Buffer);
                    Buffer += 16;
                    break;
                case CG_INT:
                    cgSetParameter1i(FieldParam, *((s32*)Buffer));
                    Buffer += 1;
                    break;
                default:
                    break;
                }

                FieldParam = cgGetNextParameter(FieldParam);
            }
        }
        break;

        default:
            break;
        }
    }

    return true;
}
Пример #17
0
	//---------------------------------------------------------------------
	void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize)
	{
		while (parameter != 0)
		{
			// Look for uniform parameters only
			// Don't bother enumerating unused parameters, especially since they will
			// be optimised out and therefore not in the indexed versions
			CGtype paramType = cgGetParameterType(parameter);

			if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
				paramType != CG_SAMPLER1D &&
				paramType != CG_SAMPLER2D &&
				paramType != CG_SAMPLER3D &&
				paramType != CG_SAMPLERCUBE &&
				paramType != CG_SAMPLERRECT &&
				cgGetParameterDirection(parameter) != CG_OUT && 
				cgIsParameterReferenced(parameter))
			{
				int arraySize;

				switch(paramType)
				{
				case CG_STRUCT:
					recurseParams(cgGetFirstStructParameter(parameter));
					break;
				case CG_ARRAY:
					// Support only 1-dimensional arrays
					arraySize = cgGetArraySize(parameter, 0);
					recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize);
					break;
				default:
					// Normal path (leaf)
					String paramName = cgGetParameterName(parameter);
					size_t logicalIndex = cgGetParameterResourceIndex(parameter);

					// Get the parameter resource, to calculate the physical index
					CGresource res = cgGetParameterResource(parameter);
					bool isRegisterCombiner = false;
					size_t regCombinerPhysicalIndex = 0;
					switch (res)
					{
					case CG_COMBINER_STAGE_CONST0:
						// register combiner, const 0
						// the index relates to the texture stage; store this as (stage * 2) + 0
						regCombinerPhysicalIndex = logicalIndex * 2;
						isRegisterCombiner = true;
						break;
					case CG_COMBINER_STAGE_CONST1:
						// register combiner, const 1
						// the index relates to the texture stage; store this as (stage * 2) + 1
						regCombinerPhysicalIndex = (logicalIndex * 2) + 1;
						isRegisterCombiner = true;
						break;
					default:
						// normal constant
						break;
					}

					// Trim the '[0]' suffix if it exists, we will add our own indexing later
					if (StringUtil::endsWith(paramName, "[0]", false))
					{
						paramName.erase(paramName.size() - 3);
					}


					GpuConstantDefinition def;
					def.arraySize = contextArraySize;
					mapTypeAndElementSize(paramType, isRegisterCombiner, def);

					if (def.constType == GCT_UNKNOWN)
					{
						LogManager::getSingleton().logMessage(
							"Problem parsing the following Cg Uniform: '"
							+ paramName + "' in file " + mName);
						// next uniform
						parameter = cgGetNextParameter(parameter);
						continue;
					}
					if (isRegisterCombiner)
					{
						def.physicalIndex = regCombinerPhysicalIndex;
					}
					else
					{
						// base position on existing buffer contents
						if (def.isFloat())
						{
							def.physicalIndex = mFloatLogicalToPhysical->bufferSize;
						}
						else
						{
							def.physicalIndex = mIntLogicalToPhysical->bufferSize;
						}
					}

					def.logicalIndex = logicalIndex;
					if( mParametersMap.find(paramName) == mParametersMap.end())
					{
						mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def));
						mParametersMapSizeAsBuffer += sizeof(size_t);
						mParametersMapSizeAsBuffer += paramName.size();
						mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition);
					}

					// Record logical / physical mapping
					if (def.isFloat())
					{
											OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex);
						mFloatLogicalToPhysical->map.insert(
							GpuLogicalIndexUseMap::value_type(def.logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
						mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
					}
					else
					{
											OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex);
						mIntLogicalToPhysical->map.insert(
							GpuLogicalIndexUseMap::value_type(def.logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
						mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
					}

					break;
				}                   
			}

			// now handle uniform samplers. This is needed to fix their register positions
			// if delegating to a GLSL shader.
			if (mDelegate && cgGetParameterVariability(parameter) == CG_UNIFORM && (
				paramType == CG_SAMPLER1D ||
				paramType == CG_SAMPLER2D ||
				paramType == CG_SAMPLER3D ||
				paramType == CG_SAMPLERCUBE ||
				paramType == CG_SAMPLERRECT) &&
				cgGetParameterDirection(parameter) != CG_OUT && 
				cgIsParameterReferenced(parameter))
			{
				String paramName = cgGetParameterName(parameter);
				CGresource res = cgGetParameterResource(parameter);
				int pos = -1;
				switch (res)
				{
				case CG_TEXUNIT0: pos = 0; break;
				case CG_TEXUNIT1: pos = 1; break;
				case CG_TEXUNIT2: pos = 2; break;
				case CG_TEXUNIT3: pos = 3; break;
				case CG_TEXUNIT4: pos = 4; break;
				case CG_TEXUNIT5: pos = 5; break;
				case CG_TEXUNIT6: pos = 6; break;
				case CG_TEXUNIT7: pos = 7; break;
				case CG_TEXUNIT8: pos = 8; break;
				case CG_TEXUNIT9: pos = 9; break;
				case CG_TEXUNIT10: pos = 10; break;
				case CG_TEXUNIT11: pos = 11; break;
				case CG_TEXUNIT12: pos = 12; break;
				case CG_TEXUNIT13: pos = 13; break;
				case CG_TEXUNIT14: pos = 14; break;
				case CG_TEXUNIT15: pos = 15; break;
#if(CG_VERSION_NUM >= 3000)
				case CG_TEXUNIT16: pos = 16; break;
				case CG_TEXUNIT17: pos = 17; break;
				case CG_TEXUNIT18: pos = 18; break;
				case CG_TEXUNIT19: pos = 19; break;
				case CG_TEXUNIT20: pos = 20; break;
				case CG_TEXUNIT21: pos = 21; break;
				case CG_TEXUNIT22: pos = 22; break;
				case CG_TEXUNIT23: pos = 23; break;
				case CG_TEXUNIT24: pos = 24; break;
				case CG_TEXUNIT25: pos = 25; break;
				case CG_TEXUNIT26: pos = 26; break;
				case CG_TEXUNIT27: pos = 27; break;
				case CG_TEXUNIT28: pos = 28; break;
				case CG_TEXUNIT29: pos = 29; break;
				case CG_TEXUNIT30: pos = 30; break;
				case CG_TEXUNIT31: pos = 31; break;
#endif
				default:
					break;
				}
				if (pos != -1)
				{
					mSamplerRegisterMap.insert(std::make_pair(paramName, pos));
				}
			}

			// Get next
			parameter = cgGetNextParameter(parameter);
		}

		
	}
Пример #18
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);						
}