Ejemplo n.º 1
0
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const
{
    // Check the function names first
    if (lhs.getFunctionName() < rhs.getFunctionName())
        return true;

    // Next check the return type
    if (lhs.getReturnType() < rhs.getReturnType())
        return true;

    // Check the number of operands
    if (lhs.mOperands.size() < rhs.mOperands.size())
        return true;

    // Now that we've gotten past the two quick tests, iterate over operands
    // Check the semantic and type.  The operands must be in the same order as well.
    OperandVector::const_iterator itLHSOps = lhs.mOperands.begin();
    OperandVector::const_iterator itRHSOps = rhs.mOperands.begin();

    for ( ; itLHSOps != lhs.mOperands.end(), itRHSOps != rhs.mOperands.end(); ++itLHSOps, ++itRHSOps)
    {
        if (itLHSOps->getSemantic() < itRHSOps->getSemantic())
            return true;

        if (itLHSOps->getParameter()->getType() < itRHSOps->getParameter()->getType())
            return true;
    }

    return false;
}
Ejemplo n.º 2
0
bool FunctionInvocation::FunctionInvocationCompare::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const
{
    // Check the function names first
    if (lhs.getFunctionName() != rhs.getFunctionName())
        return false;

    // Next check the return type
    if (lhs.getReturnType() != rhs.getReturnType())
        return false;

    // Check the number of operands
    if (lhs.mOperands.size() != rhs.mOperands.size())
        return false;

    // Now that we've gotten past the two quick tests, iterate over operands
    // Check the semantic and type.  The operands must be in the same order as well.
    OperandVector::const_iterator itLHSOps = lhs.mOperands.begin();
    OperandVector::const_iterator itRHSOps = rhs.mOperands.begin();
    for ( ; ((itLHSOps != lhs.mOperands.end()) && (itRHSOps != rhs.mOperands.end())); ++itLHSOps, ++itRHSOps)
    {
        if (itLHSOps->getSemantic() != itRHSOps->getSemantic())
            return false;

        GpuConstantType leftType    = itLHSOps->getParameter()->getType();
        GpuConstantType rightType   = itRHSOps->getParameter()->getType();
        
        if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos)
        {
            if (leftType == GCT_SAMPLER1D)
                leftType = GCT_SAMPLER2D;

            if (rightType == GCT_SAMPLER1D)
                rightType = GCT_SAMPLER2D;
        }

        // If a swizzle mask is being applied to the parameter, generate the GpuConstantType to
        // perform the parameter type comparison the way that the compiler will see it.
        if ((itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) ||
           (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0))
        {
            if (itLHSOps->getFloatCount(itLHSOps->getMask()) > 0)
            {
                leftType = (GpuConstantType)((itLHSOps->getParameter()->getType() - itLHSOps->getParameter()->getType()) +
                                             itLHSOps->getFloatCount(itLHSOps->getMask()));
            }
            if (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0)
            {
                rightType = (GpuConstantType)((itRHSOps->getParameter()->getType() - itRHSOps->getParameter()->getType()) +
                                             itRHSOps->getFloatCount(itRHSOps->getMask()));
            }
        }

        if (leftType != rightType)
            return false;
    }

    // Passed all tests, they are the same
    return true;
}
Ejemplo n.º 3
0
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const
{
    // Check the function names first
    // Adding an exception to std::string sorting.  I feel that functions beginning with an underscore should be placed before
    // functions beginning with an alphanumeric character.  By default strings are sorted based on the ASCII value of each character.
    // Underscores have an ASCII value in between capital and lowercase characters.  This is why the exception is needed.
    if (lhs.getFunctionName() < rhs.getFunctionName())
    {
        if(rhs.getFunctionName().at(0) == '_')
            return false;
        else
            return true;
    }
    if (lhs.getFunctionName() > rhs.getFunctionName())
    {
        if(lhs.getFunctionName().at(0) == '_')
            return true;
        else
            return false;
    }

    // Next check the return type
    if (lhs.getReturnType() < rhs.getReturnType())
        return true;
    if (lhs.getReturnType() > rhs.getReturnType())
        return false;

    // Check the number of operands
    if (lhs.mOperands.size() < rhs.mOperands.size())
        return true;
    if (lhs.mOperands.size() > rhs.mOperands.size())
        return false;

    // Now that we've gotten past the two quick tests, iterate over operands
    // Check the semantic and type.  The operands must be in the same order as well.
    OperandVector::const_iterator itLHSOps = lhs.mOperands.begin();
    OperandVector::const_iterator itRHSOps = rhs.mOperands.begin();

    for ( ; itLHSOps != lhs.mOperands.end(), itRHSOps != rhs.mOperands.end(); ++itLHSOps, ++itRHSOps)
    {
        if (itLHSOps->getSemantic() < itRHSOps->getSemantic())
            return true;
        if (itLHSOps->getSemantic() > itRHSOps->getSemantic())
            return false;

        if (itLHSOps->getParameter()->getType() < itRHSOps->getParameter()->getType())
            return true;
        if (itLHSOps->getParameter()->getType() > itRHSOps->getParameter()->getType())
            return false;
    }

    return true;
}
Ejemplo n.º 4
0
bool FunctionInvocation::FunctionInvocationLessThan::operator ()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const
{
    // Check the function names first
    // Adding an exception to std::string sorting.  I feel that functions beginning with an underscore should be placed before
    // functions beginning with an alphanumeric character.  By default strings are sorted based on the ASCII value of each character.
    // Underscores have an ASCII value in between capital and lowercase characters.  This is why the exception is needed.
    if (lhs.getFunctionName() < rhs.getFunctionName())
    {
        if(rhs.getFunctionName().at(0) == '_')
            return false;
        else
            return true;
    }
    if (lhs.getFunctionName() > rhs.getFunctionName())
    {
        if(lhs.getFunctionName().at(0) == '_')
            return true;
        else
            return false;
    }

    // Next check the return type
    if (lhs.getReturnType() < rhs.getReturnType())
        return true;
    if (lhs.getReturnType() > rhs.getReturnType())
        return false;

    // Check the number of operands
    if (lhs.mOperands.size() < rhs.mOperands.size())
        return true;
    if (lhs.mOperands.size() > rhs.mOperands.size())
        return false;

    // Now that we've gotten past the two quick tests, iterate over operands
    // Check the semantic and type.  The operands must be in the same order as well.
    OperandVector::const_iterator itLHSOps = lhs.mOperands.begin();
    OperandVector::const_iterator itRHSOps = rhs.mOperands.begin();

    for ( ; ((itLHSOps != lhs.mOperands.end()) && (itRHSOps != rhs.mOperands.end())); ++itLHSOps, ++itRHSOps)
    {
        if (itLHSOps->getSemantic() < itRHSOps->getSemantic())
            return true;
        if (itLHSOps->getSemantic() > itRHSOps->getSemantic())
            return false;

        GpuConstantType leftType    = itLHSOps->getParameter()->getType();
        GpuConstantType rightType   = itRHSOps->getParameter()->getType();
        
        if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos)
        {
            if (leftType == GCT_SAMPLER1D)
                leftType = GCT_SAMPLER2D;

            if (rightType == GCT_SAMPLER1D)
                rightType = GCT_SAMPLER2D;
        }

        // If a swizzle mask is being applied to the parameter, generate the GpuConstantType to
        // perform the parameter type comparison the way that the compiler will see it.
        if ((itLHSOps->getFloatCount(itLHSOps->getMask()) > 0) ||
           (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0))
        {
            if (itLHSOps->getFloatCount(itLHSOps->getMask()) > 0)
            {
                leftType = (GpuConstantType)((itLHSOps->getParameter()->getType() - itLHSOps->getParameter()->getType()) +
                                             itLHSOps->getFloatCount(itLHSOps->getMask()));
            }
            if (itRHSOps->getFloatCount(itRHSOps->getMask()) > 0)
            {
                rightType = (GpuConstantType)((itRHSOps->getParameter()->getType() - itRHSOps->getParameter()->getType()) +
                                             itRHSOps->getFloatCount(itRHSOps->getMask()));
            }
        }

        if (leftType < rightType)
            return true;
        if (leftType > rightType)
            return false;
    }

    return false;
}
//-----------------------------------------------------------------------
void GLSLProgramWriter::writeForwardDeclarations(std::ostream& os, Program* program)
{
	os << "//-----------------------------------------------------------------------------" << std::endl;
	os << "//                         FORWARD DECLARATIONS" << std::endl;
	os << "//-----------------------------------------------------------------------------" << std::endl;

	StringVector forwardDecl; // holds all generated function declarations 
	const ShaderFunctionList& functionList = program->getFunctions();
	ShaderFunctionConstIterator itFunction;

	// Iterate over all functions in the current program (in our case this is always the main() function)
	for ( itFunction = functionList.begin(); itFunction != functionList.end(); ++itFunction)
	{
		Function* curFunction = *itFunction;
		const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances();
		FunctionAtomInstanceConstIterator itAtom = atomInstances.begin();
		FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end();

		// Now iterate over all function atoms
		for ( ; itAtom != itAtomEnd; ++itAtom)
		{	
			// Skip non function invocation atoms.
			if ((*itAtom)->getFunctionAtomType() != FunctionInvocation::Type)
				continue;

			FunctionInvocation* pFuncInvoc = static_cast<FunctionInvocation*>(*itAtom);			
			FunctionInvocation::OperandVector::iterator itOperator = pFuncInvoc->getOperandList().begin();
			FunctionInvocation::OperandVector::iterator itOperatorEnd = pFuncInvoc->getOperandList().end();

			// Start with function declaration 
			String funcDecl = pFuncInvoc->getReturnType() + " " + pFuncInvoc->getFunctionName() + "(";

			// Now iterate overall operands
			for (; itOperator != itOperatorEnd; )
			{
				ParameterPtr pParam = (*itOperator).getParameter();				
				Operand::OpSemantic opSemantic = (*itOperator).getSemantic();
				int opMask = (*itOperator).getMask();
				GpuConstantType gpuType = GCT_UNKNOWN;

				// Write the semantic in, out, inout
				switch(opSemantic)
				{
				case Operand::OPS_IN:
					funcDecl += "in ";
					break;

				case Operand::OPS_OUT:
					funcDecl += "out ";
					break;

				case Operand::OPS_INOUT:
					funcDecl += "inout ";
					break;

				default:
					break;
				}				
				
				//  Swizzle masks are only defined for types like vec2, vec3, vec4.
				if (opMask == Operand::OPM_ALL)
				{
					gpuType = pParam->getType();
				}
				else 
				{
					// Now we have to convert the mask to operator
					gpuType = Operand::getGpuConstantType(opMask);
				}

				// We need a valid type otherwise glsl compilation will not work
				if (gpuType == GCT_UNKNOWN)
				{
					OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, 
						"Can not convert Operand::OpMask to GpuConstantType", 
						"GLSLProgramWriter::writeForwardDeclarations" );	
				}

				// Write the operand type.
				funcDecl += mGpuConstTypeMap[gpuType];

				++itOperator;
				//move over all operators with indirection
				while ((itOperator != itOperatorEnd) && (itOperator->getIndirectionLevel() != 0)) 
				{
					++itOperator;
				}

				// Prepare for the next operand
				if (itOperator != itOperatorEnd)
				{
					funcDecl += ", ";
				}
			}
			// Write function call closer.
			funcDecl += ");\n";

			// Push the generated declaration into the vector
			// duplicate declarations will be removed later.
			forwardDecl.push_back(funcDecl);
		}
	}

	// Now remove duplicate declaration, first we have to sort the vector.
	std::sort(forwardDecl.begin(), forwardDecl.end());
	StringVector::iterator endIt = std::unique(forwardDecl.begin(), forwardDecl.end()); 

	// Finally write all function declarations to the shader file
	for (StringVector::iterator it = forwardDecl.begin(); it != endIt; it++)
	{
		os << *it;
	}
}