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
bool csGLShaderFFP::ParseFog (iDocumentNode* node, FogInfo& fog)
{
  csRef<iDocumentNodeIterator> it = node->GetNodes();

  while(it->HasNext())
  {
    csRef<iDocumentNode> child = it->Next();
    if(child->GetType() != CS_NODE_ELEMENT) continue;
    csStringID id = tokens.Request(child->GetValue());
    switch (id)
    {
      case XMLTOKEN_MODE:
	{
	  const char* type = child->GetContentsValue ();
	  if (type == 0)
	  {
	    Report (CS_REPORTER_SEVERITY_WARNING,
	      child,
	      "Node has no contents");
	    return false;
	  }
	  if (strcmp (type, "linear") == 0)
	  {
	    fog.mode = CS_FOG_MODE_LINEAR;
	  }
	  else if (strcmp (type, "exp") == 0)
	  {
	    fog.mode = CS_FOG_MODE_EXP;
	  }
	  else if (strcmp (type, "exp2") == 0)
	  {
	    fog.mode = CS_FOG_MODE_EXP2;
	  }
	}
	break;
      case XMLTOKEN_DENSITY:
	{
	  if (!ParseProgramParam (child, fog.density, ParamFloat))
	    return false;
	}
	break;
      case XMLTOKEN_START:
	{
	  if (!ParseProgramParam (child, fog.start, ParamFloat))
	    return false;
	}
	break;
      case XMLTOKEN_END:
	{
	  if (!ParseProgramParam (child, fog.end, ParamFloat))
	    return false;
	}
	break;
      case XMLTOKEN_FOGCOLOR:
	{
	  if (!ParseProgramParam (child, fog.color, ParamFloat | ParamVector3 |
	    ParamVector4))
	    return false;
	}
	break;
      default:
	synsrv->ReportBadToken (child);
        return false;
    }
  }
  return true;
}
Exemple #4
0
  bool csVProcStandardProgram::Load (iShaderDestinationResolver* /*resolve*/, 
    iDocumentNode* program)
  {
    if (!program)
      return false;

    csRef<iDocumentNode> pnode = program->GetNode("vproc_std");
    if(pnode)
    {
      csRef<iDocumentNodeIterator> it = pnode->GetNodes ();
      while(it->HasNext())
      {
        csRef<iDocumentNode> child = it->Next();
        if(child->GetType() != CS_NODE_ELEMENT) continue;
        const char* value = child->GetValue ();
        csStringID id = tokens.Request (value);
        switch(id)
        {
        case XMLTOKEN_LIGHTS:
          numLights = child->GetContentsValueAsInt ();
          break;
        case XMLTOKEN_FINALFACTOR:
          if (!ParseProgramParam (child, finalLightFactor,
            ParamFloat | ParamShaderExp))
            return false;
          break;
        case XMLTOKEN_ATTENUATION:
          if (!synsrv->ParseBool (child, useAttenuation, true))
            return false;
          break;
        case XMLTOKEN_LIGHTMIXMODE:
          if (!ParseLightMixMode (child, lightMixMode))
            return false;
          break;
        case XMLTOKEN_COLORMIXMODE:
          if (!ParseLightMixMode (child, colorMixMode))
            return false;
          break;
        case XMLTOKEN_POSITIONBUFFER:
          if (!ParseBufferName (child, positionBuffer))
            return false;
          break;
        case XMLTOKEN_NORMALBUFFER:
          if (!ParseBufferName (child, normalBuffer))
            return false;
          break;
        case XMLTOKEN_COLORBUFFER:
          if (!ParseBufferName (child, colorBuffer))
            return false;
          break;
        case XMLTOKEN_ENABLELIGHT:
          {
            size_t n = (size_t)child->GetAttributeValueAsInt ("num");
            bool b;
            if (!synsrv->ParseBool (child, b, true))
              return false;
            if (!b)
            {
              if (disableMask.GetSize() <= n)
                disableMask.SetSize (n+1);
              disableMask.SetBit (n);
            }
            break;
          }
        case XMLTOKEN_DIFFUSE:
          {
            if (!synsrv->ParseBool (child, doDiffuse, true))
              return false;
          }
          break;
        case XMLTOKEN_SPECULAR:
          {
            if (!synsrv->ParseBool (child, doSpecular, true))
              return false;
            const char* buffer = child->GetAttributeValue ("buffer");
            if (!buffer)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "'buffer' attribute missing");
              return false;
            }
            csRenderBufferName bufferName = csRenderBuffer::GetBufferNameFromDescr (buffer);
            if (bufferName == CS_BUFFER_NONE)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "buffer name '%s' invalid here", buffer);
              return false;
            }
            specularOutputBuffer = bufferName;
          }
          break;
        case XMLTOKEN_SPECULAREXP:
          if (!ParseProgramParam (child, shininessParam,
            ParamFloat | ParamShaderExp))
            return false;
          break;
        case XMLTOKEN_SPECULARONDIFFUSE:
          {
            if (!synsrv->ParseBool (child, specularOnDiffuse, true))
              return false;
          }
          break;
        case XMLTOKEN_SKINNED_POSITION:
          {
            if (!synsrv->ParseBool (child, doVertexSkinning, true))
              return false;
            const char* buffer = child->GetAttributeValue ("buffer");
            if (!buffer)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "'buffer' attribute missing");
              return false;
            }
            csRenderBufferName bufferName = csRenderBuffer::GetBufferNameFromDescr (buffer);
            if (bufferName == CS_BUFFER_NONE)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "buffer name '%s' invalid here", buffer);
              return false;
            }
            skinnedPositionOutputBuffer = bufferName;
          }
          break;
        case XMLTOKEN_SKINNED_NORMAL:
          {
            if (!synsrv->ParseBool (child, doNormalSkinning, true))
              return false;
            const char* buffer = child->GetAttributeValue ("buffer");
            if (!buffer)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "'buffer' attribute missing");
              return false;
            }
            csRenderBufferName bufferName = csRenderBuffer::GetBufferNameFromDescr (buffer);
            if (bufferName == CS_BUFFER_NONE)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "buffer name '%s' invalid here", buffer);
              return false;
            }
            skinnedNormalOutputBuffer = bufferName;
          }
          break;
        case XMLTOKEN_SKINNED_TANGENT:
          {
            if (!synsrv->ParseBool (child, doTangentSkinning, true))
              return false;
            const char* buffer = child->GetAttributeValue ("buffer");
            if (!buffer)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "'buffer' attribute missing");
              return false;
            }
            csRenderBufferName bufferName = csRenderBuffer::GetBufferNameFromDescr (buffer);
            if (bufferName == CS_BUFFER_NONE)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "buffer name '%s' invalid here", buffer);
              return false;
            }
            skinnedTangentOutputBuffer = bufferName;
          }
          break;
        case XMLTOKEN_SKINNED_BITANGENT:
          {
            if (!synsrv->ParseBool (child, doBiTangentSkinning, true))
              return false;
            const char* buffer = child->GetAttributeValue ("buffer");
            if (!buffer)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "'buffer' attribute missing");
              return false;
            }
            csRenderBufferName bufferName = csRenderBuffer::GetBufferNameFromDescr (buffer);
            if (bufferName == CS_BUFFER_NONE)
            {
              synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
                pnode, "buffer name '%s' invalid here", buffer);
              return false;
            }
            skinnedBiTangentOutputBuffer = bufferName;
          }
          break;
        default:
          {
            switch (commonTokens.Request (value))
            {
            case XMLTOKEN_PROGRAM:
            case XMLTOKEN_VARIABLEMAP:
              // Don't want those
              synsrv->ReportBadToken (child);
              return false;
              break;
            default:
              if (!ParseCommon (child))
                return false;
            }
          }
        }
      }
    }
    else
    {
      synsrv->ReportError ("crystalspace.graphics3d.shader.vproc_std",
        pnode, "<vproc_std> node missing");
    }

    return true;
  }
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;
}