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