static void AddParameter(JSON &json, CGparameter param)
{
    const char * const parameterName = cgGetParameterName(param);

    if (sVerbose)
    {
        puts(parameterName);
    }

    json.AddObject(parameterName);

    const CGtype type = cgGetParameterType(param);
    const CGtype baseType = cgGetParameterBaseType(param);
    int numRows = cgGetParameterRows(param);
    const int numColumns = cgGetParameterColumns(param);
    if (CG_ARRAY == type)
    {
        const int totalArraySize = cgGetArrayTotalSize(param);
        numRows *= totalArraySize;
    }
    json.AddString("type", cgGetTypeString(baseType));
    if (1 < numRows)
    {
        json.AddValue("rows", numRows);
    }
    if (1 < numColumns)
    {
        json.AddValue("columns", numColumns);
    }

    const int maxNumElements = (numColumns * numRows);
    int n;
    if (CG_FLOAT == baseType)
    {
        float * const values = (float *)malloc(maxNumElements * sizeof(float));
        const int numValues = cgGetParameterValuefr(param, maxNumElements, values);
        if (numValues)
        {
            for (n = 0; n < numValues; n++)
            {
                if (values[n] != 0.0f)
                {
                    break;
                }
            }
            if (n < numValues)
            {
                json.AddArray("values", true);
                json.BeginData(true);
                for (n = 0; n < numValues; n++)
                {
                    json.AddData(values[n]);
                }
                json.EndData();
                json.CloseArray(true);
            }
        }
        free(values);
    }
    else if (CG_INT == baseType)
    {
        int * const values = (int *)malloc(maxNumElements * sizeof(int));
        const int numValues = cgGetParameterValueir(param, maxNumElements, values);
        if (numValues)
        {
            for (n = 0; n < numValues; n++)
            {
                if (values[n])
                {
                    break;
                }
            }
            if (n < numValues)
            {
                json.AddArray("values", true);
                json.BeginData(true);
                for (n = 0; n < numValues; n++)
                {
                    json.AddData(values[n]);
                }
                json.EndData();
                json.CloseArray(true);
            }
        }
        free(values);
    }
    else if (CG_BOOL == baseType)
    {
        int * const values = (int *)malloc(maxNumElements * sizeof(int));
        const int numValues = cgGetParameterValueir(param, maxNumElements, values);
        if (numValues)
        {
            for (n = 0; n < numValues; n++)
            {
                if (values[n])
                {
                    break;
                }
            }
            if (n < numValues)
            {
                json.AddArray("values", true);
                json.BeginData(true);
                for (n = 0; n < numValues; n++)
                {
                    json.AddData(values[n]);
                }
                json.EndData();
                json.CloseArray(true);
            }
        }
        free(values);
    }

    json.CloseObject(); // parameter
}
Exemple #2
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;
	}
}