//---------------------------------------------------------------------------- bool FxCompiler::Process (const Program& program, InputArray& inputs, OutputArray& outputs, ConstantArray& constants, SamplerArray& samplers) { // Variable lines are one of the following: // var TYPE NAME : $vin.SEMANTIC : inputType : index : 1 // var TYPE NAME : $vout.SEMANTIC : outputType : index : 1 // var TYPE NAME : : c[REGISTER] : index : 1 // var TYPE NAME : : c[REGISTER], NUMREG : index : 1 // var TYPE NAME : : texunit UNITNUMBER : -1 : 1 // The last field is "used", a value of "0" or "1". However, the parser // stored in 'program' only those variables with a used value "1". The // all-capitals identifiers are needed by the Wild Magic FX system. TokenArrays::const_iterator iter = program.Variables.begin(); TokenArrays::const_iterator end = program.Variables.end(); for (/**/; iter != end; ++iter) { const TokenArray& tokens = *iter; // The token array has 10 or 11 tokens. if (tokens.size() < 10 || tokens.size() > 11) { ReportError("Invalid number of tokens", &tokens); return false; } // Get the variable type. Shader::VariableType vartype = Shader::VT_NONE; Shader::SamplerType samtype = Shader::ST_NONE; std::string::size_type begin = tokens[1].find("sampler", 0); if (begin != std::string::npos) { SamplerTypeMap::iterator iter = mSamplerTypes.find(tokens[1]); if (iter == mSamplerTypes.end()) { ReportError("Invalid sampler type", &tokens); return false; } samtype = iter->second; } else { VariableTypeMap::iterator iter = mVariableTypes.find(tokens[1]); if (iter == mVariableTypes.end()) { ReportError("Invalid variable type", &tokens); return false; } vartype = iter->second; } // Get the variable name. std::string name = tokens[2]; // Test whether the variable is a singleton or was declared as an // array. If it is an array, we need to determine how many registers // it uses. This requires processing variable lines with the same // variable index. bool varArray; begin = name.find("[", 0); if (begin != std::string::npos) { varArray = true; name = name.substr(0, begin); // strip off "[register]" } else { varArray = false; } // Get the separator before the classifier. if (tokens[3] != ":") { ReportError("Expecting separator character at index 3", &tokens); return false; } // Get the classifier. begin = tokens[4].find("$vin.", 0); if (begin != std::string::npos) { // The variable is a shader input. if (!GetInput(tokens, name, vartype, inputs)) { return false; } continue; } begin = tokens[4].find("$vout.", 0); if (begin != std::string::npos) { // The variable is a shader output. if (!GetOutput(tokens, name, vartype, outputs)) { return false; } continue; } if (tokens[4] == ":") { begin = tokens[1].find("sampler", 0); if (begin != std::string::npos) { // The variable is a shader sampler. if (!GetSampler(tokens, name, samtype, samplers)) { return false; } } else { // The variable is a shader constant. if (varArray) { if (constants.size() > 0 && name == constants.back().Name) { // This is another occurrence of the array variable. // Just increment the register count. ++constants.back().NumRegistersUsed; } else { // Create the constant with the first occurrence of // the array variable. if (!GetConstant(tokens, name, vartype, constants)) { return false; } } } else { if (!GetConstant(tokens, name, vartype, constants)) { return false; } } } continue; } ReportError("Failed to find classifier", &tokens); return false; } return true; }