bool csShaderProgram::ParseCommon (iDocumentNode* child)
{
  const char* value = child->GetValue ();
  csStringID id = commonTokens.Request (value);
  switch (id)
  {
  case XMLTOKEN_VARIABLEMAP:
    {
      //@@ REWRITE
      const char* destname = child->GetAttributeValue ("destination");
      if (!destname)
      {
        synsrv->Report ("crystalspace.graphics3d.shader.common",
          CS_REPORTER_SEVERITY_WARNING, child,
          "<variablemap> has no %s attribute",
          CS::Quote::Single ("destination"));
        return false;
      }

      const char* varname = child->GetAttributeValue ("variable");
      if (!varname)
      {
        // "New style" variable mapping
        VariableMapEntry vme (CS::InvalidShaderVarStringID, destname);
        if (!ParseProgramParam (child, vme.mappingParam,
          ParamInt | ParamFloat | ParamVector2 | ParamVector3 | ParamVector4))
          return false;
        variablemap.Push (vme);
      }
      else
      {
        // "Classic" variable mapping
        CS::Graphics::ShaderVarNameParser nameParse (varname);
        VariableMapEntry vme (
          stringsSvName->Request (nameParse.GetShaderVarName()),
          destname);
        for (size_t n = 0; n < nameParse.GetIndexNum(); n++)
        {
          vme.mappingParam.indices.Push (nameParse.GetIndexValue (n));
        }
        variablemap.Push (vme);
      }
    }
    break;
  case XMLTOKEN_PROGRAM:
    {
      if (!ParseProgramNode (child, programSource))
        return false;
    }
    break;

  case XMLTOKEN_DESCRIPTION:
    description = child->GetContentsValue();
    break;
  default:
    synsrv->ReportBadToken (child);
    return false;
  }
  return true;
}
Exemple #2
0
bool csShaderGLCGCommon::ParseVmap (iDocumentNode* node)
{
  //@@ REWRITE
  const char* destname = node->GetAttributeValue ("destination");
  if (!destname)
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING, node,
      "<variablemap> has no 'destination' attribute");
    return false;
  }
  
  bool assumeConst = node->GetAttributeValueAsBool ("assumeconst",
    false);

  const char* varname = node->GetAttributeValue ("variable");
  if (!varname)
  {
    // "New style" variable mapping
    VariableMapEntry vme (CS::InvalidShaderVarStringID, destname);
    if (!ParseProgramParam (node, vme.mappingParam,
      ParamFloat | ParamVector2 | ParamVector3 | ParamVector4))
      return false;
    ShaderParameter* sparam = shaderPlug->paramAlloc.Alloc();
    sparam->assumeConstant = assumeConst;
    vme.userVal = reinterpret_cast<intptr_t> (sparam);
    variablemap.Push (vme);
  }
  else
  {
    // "Classic" variable mapping
    CS::Graphics::ShaderVarNameParser nameParse (varname);
    VariableMapEntry vme (
      stringsSvName->Request (nameParse.GetShaderVarName()),
      destname);
    for (size_t n = 0; n < nameParse.GetIndexNum(); n++)
    {
      vme.mappingParam.indices.Push (nameParse.GetIndexValue (n));
    }
    ShaderParameter* sparam = shaderPlug->paramAlloc.Alloc();
    sparam->assumeConstant = assumeConst;
    vme.userVal = reinterpret_cast<intptr_t> (sparam);
    variablemap.Push (vme);
  }
  
  return true;
}
Exemple #3
0
const char* csConditionEvaluator::ResolveSVIdentifier (
  csExpression* expression, CondOperand& operand)
{
  if (expression->type == csExpression::Value)
  {
    csExpressionToken::Extractor svIdentifier (expression->valueValue);
    CS::Graphics::ShaderVarNameParser svParser (svIdentifier.Get());
    
    operand.type = operandSV;
    operand.svLocation.svName = strings->Request (svParser.GetShaderVarName());
    operand.svLocation.indices = AllocSVIndicesInternal (svParser);
    return 0;
  }
  else
  {
    const csExpressionToken& t = expression->expressionValue.op;
    if (!TokenEquals (t.tokenStart, t.tokenLen, "."))
    {
      return SetLastError ("Unexpected operator '%s'",
	csExpressionToken::Extractor (t).Get ());
    }
    if (expression->expressionValue.left->type != csExpression::Value)
    {
      CS_ASSERT_MSG ("It should not happen that the 'left' subexpression "
	"is not a value", false);
      return "Left subexpression is not of type 'value'";
    }
    if (expression->expressionValue.right->type != csExpression::Value)
    {
      /* @@@ Happens for stuff like vars.foo.bar.baz, where bar.baz
       * will incarnate here as a right expression of type Expression.
       * Clearer error msg?
       */
      return "Right subexpression is not of type 'value'";
    }
    {
      csExpressionToken::Extractor svIdentifier (expression->expressionValue.left->valueValue);
      CS::Graphics::ShaderVarNameParser svParser (svIdentifier.Get());
      
      operand.type = operandSV;
      operand.svLocation.svName = strings->Request (svParser.GetShaderVarName());
      operand.svLocation.indices = AllocSVIndicesInternal (svParser);
      operand.svLocation.bufferName = csRenderBuffer::GetBufferNameFromDescr (
        svParser.GetShaderVarName());
    }
    const csExpressionToken& right = 
      expression->expressionValue.right->valueValue;
    if (TokenEquals (right.tokenStart, right.tokenLen, "int"))
    {
      operand.type = operandSVValueInt;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "float"))
    {
      operand.type = operandSVValueFloat;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "x"))
    {
      operand.type = operandSVValueX;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "y"))
    {
      operand.type = operandSVValueY;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "z"))
    {
      operand.type = operandSVValueZ;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "w"))
    {
      operand.type = operandSVValueW;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "buffer"))
    {
      operand.type = operandSVValueBuffer;
    }
    else if (TokenEquals (right.tokenStart, right.tokenLen, "texture"))
    {
      operand.type = operandSVValueTexture;
    }
    else
    {
      return SetLastError ("Unknown shader variable specializer '%s'",
	csExpressionToken::Extractor (right).Get ());
    }
    return 0;
  }
  CS_ASSERT (false);
  return 0;
}
bool csShaderProgram::ProgramParamParser::ParseProgramParam (
  iDocumentNode* node, ProgramParam& param, uint types)
{
  const char* type = node->GetAttributeValue ("type");
  if (type == 0)
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "No %s attribute",
      CS::Quote::Single ("type"));
    return false;
  }

  // Var for static data
  csRef<csShaderVariable> var;
  var.AttachNew (new csShaderVariable (CS::InvalidShaderVarStringID));

  ProgramParamType paramType = ParamInvalid;
  if (strcmp (type, "shadervar") == 0)
  {
    const char* value = node->GetContentsValue();
    if (!value)
    {
      synsrv->Report ("crystalspace.graphics3d.shader.common",
	CS_REPORTER_SEVERITY_WARNING,
	node,
	"Node has no contents");
      return false;
    }
    
    CS::Graphics::ShaderVarNameParser nameParse (value);
    param.name = stringsSvName->Request (nameParse.GetShaderVarName());
    for (size_t n = 0; n < nameParse.GetIndexNum(); n++)
    {
      param.indices.Push (nameParse.GetIndexValue (n));
    }
    param.valid = true;
    return true;
  }
  else if (strcmp (type, "int") == 0)
  {
    paramType = ParamInt;
  }
  else if (strcmp (type, "float") == 0)
  {
    paramType = ParamFloat;
  }
  else if (strcmp (type, "vector2") == 0)
  {
    paramType = ParamVector2;
  }
  else if (strcmp (type, "vector3") == 0)
  {
    paramType = ParamVector3;
  }
  else if (strcmp (type, "vector4") == 0)
  {
    paramType = ParamVector4;
  }
  else if (strcmp (type, "matrix") == 0)
  {
    paramType = ParamMatrix;
  }
  else if (strcmp (type, "transform") == 0)
  {
    paramType = ParamTransform;
  }
  else if ((strcmp (type, "expression") == 0) || (strcmp (type, "expr") == 0))
  {
    // Parse exp and save it
    csRef<iShaderVariableAccessor> acc = synsrv->ParseShaderVarExpr (node);
    var->SetAccessor (acc);
    param.var = var;
    param.valid = true;
    return true;
  }
  else if (strcmp (type, "array") == 0)
  {
    csArray<ProgramParam> allParams;
    ProgramParam tmpParam;
    csRef<iDocumentNodeIterator> it = node->GetNodes ();
    while (it->HasNext ())
    {
      csRef<iDocumentNode> child = it->Next ();
      ParseProgramParam (child, tmpParam, types & 0x3F);
      allParams.Push (tmpParam);
    }

    //Save the params
    var->SetType (csShaderVariable::ARRAY);
    var->SetArraySize (allParams.GetSize ());

    for (uint i = 0; i < allParams.GetSize (); i++)
    {
      var->SetArrayElement (i, allParams[i].var);
    }
    paramType = ParamArray;
  }
  else 
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "Unknown type %s", CS::Quote::Single (type));
    return false;
  }

  if (!(types & paramType))
  {
    synsrv->Report ("crystalspace.graphics3d.shader.common",
      CS_REPORTER_SEVERITY_WARNING,
      node,
      "Type %s not supported by this parameter", CS::Quote::Single (type));
    return false;
  }

  const uint directValueTypes = ParamInt | ParamFloat | ParamVector2
    | ParamVector3 | ParamVector4 | ParamMatrix | ParamTransform;
  switch (paramType & directValueTypes)
  {
    case ParamInvalid:
      return false;
      break;
    case ParamInt:
      {
	int x = node->GetContentsValueAsInt ();
	var->SetValue (x);
      }
      break;
    case ParamFloat:
      {
	float x = node->GetContentsValueAsFloat ();
	var->SetValue (x);
      }
      break;
    case ParamVector2:
      {
	float x, y;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f", &x, &y) != 2)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector2 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector2 (x,y));
      }
      break;
    case ParamVector3:
      {
	float x, y, z;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f,%f", &x, &y, &z) != 3)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector3 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector3 (x,y,z));
      }
      break;
    case ParamVector4:
      {
	float x, y, z, w;
	const char* value = node->GetContentsValue();
	if (!value)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Node has no contents");
	  return false;
	}
	if (csScanStr (value, "%f,%f,%f,%f", &x, &y, &z, &w) != 4)
	{
	  synsrv->Report ("crystalspace.graphics3d.shader.common",
	    CS_REPORTER_SEVERITY_WARNING,
	    node,
	    "Couldn't parse vector4 %s", CS::Quote::Single (value));
	  return false;
	}
	var->SetValue (csVector4 (x,y,z,w));
      }
      break;
    case ParamMatrix:
      {
        csMatrix3 matrix;
	if (!synsrv->ParseMatrix (node, matrix))
	  return false;
        var->SetValue (matrix);
      }
      break;
    case ParamTransform:
      {
        csReversibleTransform t;
        csRef<iDocumentNode> matrix_node = node->GetNode ("matrix");
        if (matrix_node)
        {
          csMatrix3 m;
          if (!synsrv->ParseMatrix (matrix_node, m))
            return false;
          t.SetT2O (m);
        }
        csRef<iDocumentNode> vector_node = node->GetNode ("v");
        if (vector_node)
        {
          csVector3 v;
          if (!synsrv->ParseVector (vector_node, v))
            return false;
          t.SetOrigin (v);
        }
        var->SetValue (t);
      }
      break;
  }
  
  param.var = var;
  param.valid = true;
  return true;
}